123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362 |
- /// <reference path="../../World/Classes/Rulebook.ts" />
- /// <reference path="../../World/Classes/Rule.ts" />
- /// <reference path="Say/OneOf.ts" />
- /// <reference path="Say/SayImage.ts" />
- interface Printable {
- getPrintedName () : string;
- }
- interface PrintableElement {
- getPrintedElement () : Array<Element>;
- }
- interface SayNoun {
- say : Say;
- noun : any;
- }
- class SayableObject {}
- class Say {
- // TODO: Separate own sequence from processing queue. This way a Say with functions/other says can be reutilized with fresh values.
- public sequence : Array <Object> = [];
- public skipbreaks : boolean = false;
- public static LINE_BREAK : Object = new SayableObject();
- public static PARAGRAPH_BREAK : Object = new SayableObject();
- public static RUN_PARAGRAPH : Object = new SayableObject();
- public static RUN_PARAGRAPH_OFF : Object = new SayableObject();
- public static CENTERED : Object = new SayableObject();
- public static b : Object = new SayableObject();
- public static DO_PARAGRAPH_BREAK = new SayableObject();
- public static DO_LINE_BREAK = new SayableObject();
- public static COCK = new SayableObject();
- public static PUSSY = new SayableObject();
- private centered : boolean = false;
- public static Mention (target : Thing, uppercase = true) : Array<any> {
- if (target == WorldState.player) {
- return [new SayYou(uppercase)];
- } else {
- return [new SayThe(uppercase), target];
- }
- }
- public static YourTheir (target : Thing, uppercase = true) {
- if (target == WorldState.player) {
- return [new SayYour(uppercase)];
- } else {
- return [new SayHisHersIts(target, uppercase)];
- }
- }
- public constructor (...objs) {
- this.add(...objs);
- }
- public add (...objs : Array<Say | OneOf | Object | Printable | string | number | String | ((say : Say) => string)>) {
- this.sequence.push(...objs);
- return this;
- }
- public remove (...objs) {
- for (let i = 0; i < objs.length; i++) {
- let index = this.sequence.indexOf(objs[i]);
- if (index >= 0) {
- this.sequence.splice(index, 1);
- }
- }
- }
- public isEmpty () {
- return this.sequence.length < 1;
- }
- public paragraphs : Array<Array<Element | Text>>;
- public currentParagraph : Array<Element | Text>;
- public sequenceRunner : number;
- // TODO: Create a single function to get the element of anything
- public async getTextOf (index : number, seq : any) : Promise<string> {
- let elements = await this.getElementFor(index, seq);
- let div = document.createElement("div");
- for (let i = 0; i < elements.length; i++) {
- if (typeof elements[i] != "number") {
- div.appendChild(elements[i]);
- }
- }
- return div.innerText;
- }
- public doLineBreak () {
- if (this.currentParagraph.length > 0 && !this.skipbreaks) {
- let br = document.createElement("br");
- br.classList.add("linebreak");
- let ti = document.createElement("span");
- ti.classList.add("textIndenter");
- this.currentParagraph.push(br, ti);
- }
- }
- public doParagraphBreak () {
- if (this.currentParagraph.length > 0 && !this.skipbreaks) {
- this.paragraphs.push(this.currentParagraph);
- this.currentParagraph = [];
- }
- }
- public async getParagraphs () : Promise<Array<Array<Element|Text>>> {
- this.paragraphs = [];
- this.currentParagraph = [];
- this.skipbreaks = false;
- for (this.sequenceRunner = 0; this.sequenceRunner < this.sequence.length; this.sequenceRunner++) {
- let seq = this.sequence[this.sequenceRunner];
- if (seq instanceof OneOf) {
- seq = seq.getOne();
- }
- if (seq == Say.CENTERED) {
- this.setCentered(true);
- } else if (seq == Say.b) {
- let boldObjects = [];
- for (let i = this.sequenceRunner + 1; i < this.sequence.length; i++) {
- let candidate = this.sequenceRunner[i];
- if (candidate == Say.b) {
- this.sequence.splice(i, 1);
- break;
- } else {
- boldObjects.push(this.sequence.splice(i, 1));
- }
- }
- if (boldObjects.length > 0) {
- let bold = new SayBold(...boldObjects);
- this.sequence.splice(this.sequenceRunner + 1, 0, bold);
- }
- } else if (seq == Say.COCK) {
- if (HumanoidPenis != undefined) {
- let cock = HumanoidPenis.getSynonym();
- this.currentParagraph.push(document.createTextNode(cock))
- }
- } else if (seq == Say.PUSSY) {
- if (HumanoidVagina != undefined) {
- let vagina = HumanoidVagina.getSynonym();
- this.currentParagraph.push(document.createTextNode(vagina))
- }
- } else if (seq == Say.LINE_BREAK) {
- this.doLineBreak();
- } else if (seq == Say.PARAGRAPH_BREAK) {
- this.doParagraphBreak();
- } else if (seq == Say.RUN_PARAGRAPH) {
- this.skipbreaks = true;
- } else if (seq == Say.RUN_PARAGRAPH_OFF) {
- this.skipbreaks = false;
- } else if (typeof seq == "function") {
- let fObj = (<(s: Say) => any> seq)(this);
- if (Array.isArray(fObj)) {
- for (let k = fObj.length - 1; k >= 0; k--) {
- this.sequence.splice(this.sequenceRunner + 1, 0, fObj[k]);
- }
- } else if (fObj != undefined) {
- this.sequence.splice(this.sequenceRunner + 1, 0, fObj);
- }
- this.sequence.splice(this.sequenceRunner, 1);
- this.sequenceRunner--;
- } else if (seq.constructor == this.constructor) {
- for (let k = (<Say> seq).sequence.length - 1; k >= 0; k--) {
- this.sequence.splice(this.sequenceRunner + 1, 0, (<Say> seq).sequence[k]);
- }
- this.sequence.splice(this.sequenceRunner, 1);
- this.sequenceRunner--;
- } else if (seq != undefined) {
- let elements = await this.getElementFor(this.sequenceRunner, seq);
- for (let i = 0; i < elements.length; i++) {
- if (elements[i] === Say.DO_LINE_BREAK) {
- this.doLineBreak();
- } else if (elements[i] === Say.DO_PARAGRAPH_BREAK) {
- this.doParagraphBreak();
- } else {
- this.currentParagraph.push(elements[i]);
- }
- }
- }
- }
- // TODO: Remove line break + text indenter if they are the last in the say
- if (this.currentParagraph.length > 0) {
- this.paragraphs.push(this.currentParagraph);
- }
- return this.paragraphs;
- }
- /**
- * Lord Have mercy, I wish to never have to debug this piece of god.
- * @param {number} index
- * @param {Say | OneOf | Object | Printable | string | number | ((say: Say) => string) | ((say: Say) => Promise<string>) | Element | Text} obj
- * @returns {Promise<Array<Element | Text>>}
- */
- public async getElementFor (index : number, obj : Say | OneOf | Object | Printable | string | number | String | ((say : Say) => string) | ((say : Say) => Promise<string>) | Element | Text) : Promise<Array<Element|Text>> {
- if (obj instanceof Promise) {
- obj = await obj;
- }
- if (typeof obj == "string" || obj instanceof String) {
- return [document.createTextNode(<string> obj)];
- } else if (typeof obj == "number" || obj instanceof Number) {
- return [document.createTextNode((parseFloat((<number> obj).toFixed(2))/1).toString())];
- } else if (typeof obj == "function") {
- let elements = await this.getElementFor(-1, (<any> obj)(this));
- return elements;
- } else if (obj instanceof SayImage) {
- return [obj.getImageElement()];
- } else if (obj instanceof SayLeftRight) {
- return (await obj.getPureElements());
- } else if (obj instanceof Say) {
- let elements = await obj.getPureElements(this);
- return elements;
- } else if (this.isProperElement(obj)) {
- return [<Element> obj];
- } else if (obj instanceof Object) {
- let elements = await this.printName(obj);
- return elements;
- }
- }
- public async getPureElements (say? : Say) : Promise<Array<Element | Text>> {
- let paragraphs = await this.getParagraphs();
- return paragraphs.length == 1 ? paragraphs[0] : Array.prototype.concat.apply([], paragraphs);
- }
- public setCentered (bool : boolean) {
- this.centered = bool;
- }
- public async getHTML (tagName : string, classList : Array<string>, singleParagraph? : boolean) : Promise<Array<HTMLElement>> {
- let paragraphs = await this.getParagraphs();
- // Reduce to single paragraph
- if (singleParagraph == true && paragraphs.length > 1) {
- paragraphs = [Array.prototype.concat.apply([], paragraphs)];
- }
- let elements = [];
- for (let i = 0, paragraph = paragraphs[i]; paragraph != undefined; paragraph = paragraphs[++i]) {
- let parent = <HTMLElement> document.createElement(tagName);
- if (classList.length > 0) {
- parent.classList.add(...classList);
- }
- for (let k = 0, ele = paragraph[k]; ele!= undefined; ele = paragraph[++k]) {
- parent.appendChild(ele);
- }
- elements.push(parent);
- if (this.centered) {
- parent.classList.add("centered");
- }
- }
- return elements;
- }
- public getHTMLContent () : Promise<Array<HTMLElement>> {
- return this.getHTML("p", ["content"]);
- }
- public isProperElement (o) : boolean {
- return (
- typeof Node === "object" ? o instanceof Node :
- o && typeof o === "object" && typeof o.nodeType === "number" && typeof o.nodeName==="string"
- ) || (
- typeof HTMLElement === "object" ? o instanceof HTMLElement : //DOM2
- o && typeof o === "object" && o !== null && o.nodeType === 1 && typeof o.nodeName==="string"
- );
- }
- public static beforePrinting = new Rulebook<any>("Before printing the name of something");
- public static printing = new Rulebook<any>("Printing the name of something");
- public static afterPrinting = new Rulebook<any>("After printing the name of something");
- public currentNoun : any;
- public currentNounElements : Array<Element | Text>;
- public async printName (thing : any) : Promise<Array<Element | Text>> {
- this.currentNoun = thing;
- this.currentNounElements = [];
- let before = Say.beforePrinting.execute({noun : this});
- await before;
- let print = Say.printing.execute({noun : this});
- await print;
- let after = Say.afterPrinting.execute({noun : this});
- await after;
- return this.currentNounElements;
- }
- public static hisHersIts (target : Thing, startOfSentence? : boolean) {
- return new SayHisHersIts(target);
- // let result : String;
- // if (target == WorldState.player) {
- // result = "your";
- // } else if (target instanceof Person) {
- // // TODO: Figure out whether target is male or female
- // result = "his";
- // } else {
- // result = "its";
- // }
- // if (startOfSentence == true) {
- // result = result.charAt(0).toUpperCase() + result.substr(1, result.length -1);
- // }
- // return result;
- }
- }
- Say.printing.addRule(new Rule({
- name : "Printing the name of a Printable Element",
- firstPriority : Rule.PRIORITY_LOW,
- code : (rulebook : RulebookRunner<any>) => {
- let say = <Say> rulebook.noun;
- if ((<any> say.currentNoun).getPrintedElement) {
- say.currentNounElements.push(...(<PrintableElement> say.currentNoun).getPrintedElement());
- return true; // We only want to print something once, so return true to stop others from running
- }
- }
- }));
- Say.printing.addRule(new Rule({
- name : "Printing the name of a Printable",
- firstPriority : Rule.PRIORITY_LOW,
- code : (rulebook : RulebookRunner<any>) => {
- let say = <Say> rulebook.noun;
- if ((<any> say.currentNoun).getPrintedName) {
- let thingEle = document.createTextNode(
- (<Printable> say.currentNoun).getPrintedName()
- );
- say.currentNounElements.push(thingEle);
- return true; // We only want to print something once, so return true to stop others from running
- }
- }
- }));
- Say.printing.addRule(new Rule({
- name : "Printing the name of an unknown object",
- firstPriority : Rule.PRIORITY_LOWEST,
- priority : Rule.PRIORITY_LOWEST,
- code : (rulebook : RulebookRunner<any>) => {
- let say = <Say> rulebook.noun;
- if ((<any> say.currentNoun).getPrintedName) {
- say.currentNounElements.push(
- (document.createTextNode((<Object> say.currentNoun).toString()))
- );
- return true; // We only want to print something once, so return true to stop others from running
- }
- }
- }));
- // var msg = new Say ("Hello! Welcome to The Obelisk! This is a game with ", johnTheOgre, " so you must be careful!");
- //
- // var otherSay = new Say (msg, "Will have to learn how to handle dots.");
|