浏览代码

Halfway through actual dialogue

Reddo 5 年之前
父节点
当前提交
36537f10be

+ 21 - 10
app/Controls/Controls.ts

@@ -1,27 +1,38 @@
 module Controls {
-    export function createBigButton (text : string, resolve : (t : string) => void) {
+    export function createBigButton (text : string, index : number, resolve : (t : number) => void) {
         let p = document.createElement("p");
         p.classList.add("choice");
         p.appendChild(document.createTextNode(text));
 
+        markButton(p, index, resolve);
+
+        return p;
+    }
+
+    function markButton (p : HTMLElement, index : number, resolve : (t : number) => void) {
         p.addEventListener("click", () => {
-            resolve(text);
+            resolve(index);
         });
 
         Controls.KeyHandler.applyCode(p, Controls.KeyHandler.getFirstKeyCode());
-
-        return p;
     }
 
-    export async function giveChoices (big? : boolean, ...choices : Array<string>) {
+    export async function giveChoices (big? : boolean, ...choices : Array<Say | string>) : Promise<Array<any>> {
         let buttons;
-        let chosenPromise = <Promise<string>> new Promise((async (resolve) => {
+        let chosenPromise = <Promise<number>> new Promise((async (resolve) => {
             Controls.KeyHandler.reset();
             let say = new Say();
 
-            choices.forEach(choice => {
-                say.add(createBigButton(choice, resolve))
-            });
+            for (let i = 0; i < choices.length; i++) {
+                let choice = choices[i];
+                if (choice instanceof Say) {
+                    let button = (await choice.getHTML("p", ["choice"], true))[0];
+                    markButton(button, i, resolve);
+                    say.add(button);
+                } else {
+                    say.add(createBigButton(choice, i, resolve))
+                }
+            }
 
             buttons = await say.getHTMLContent();
             Elements.CurrentTurnHandler.print(...(buttons));
@@ -29,6 +40,6 @@ module Controls {
 
         let chosen = await chosenPromise;
         Elements.CurrentTurnHandler.unprint(...buttons);
-        return [chosen, choices.indexOf(chosen)];
+        return [choices[chosen], chosen];
     }
 }

+ 4 - 0
app/Elements/Classes/Say.ts

@@ -44,6 +44,10 @@ class Say {
         }
     }
 
+    public static YouThem (target : Thing, uppercase = true) {
+        return Say.Mention(target, uppercase);
+    }
+
     public static YourTheir (target : Thing, uppercase = true) {
         if (target == WorldState.player) {
             return [new SayYour(uppercase)];

+ 29 - 2
app/World/Classes/AI.ts

@@ -14,6 +14,19 @@ interface AIOptions {
     retaliates? : boolean;
 }
 
+interface DialogueHook {
+    text : Say;
+    tree : DialogueTree;
+}
+
+interface TalkingHeads {
+    greeter : Person;
+    answerer : Person;
+    options : Array<DialogueHook>;
+    runFirst : Array<DialogueTree>;
+    runAndStop : Array<DialogueTree>;
+}
+
 class AI {
     public actor : Person;
     public wanderer = true;
@@ -38,8 +51,10 @@ class AI {
     public extraRules : Array<Rulebook<Thing>> = [];
     public static combatRules = new Rulebook<Thing>("Default AI Combat Rules");
     public extraCombatRules : Array<Rulebook<Thing>> = [];
-    public static talktoRules = new Rulebook<Thing>("Default Talk To Rules");
-    public extraTalktoRules : Array<Rulebook<Thing>> = [];
+    public static talktoRules = new Rulebook<TalkingHeads>("Default Talk To Rules");
+    public extraTalktoRules : Array<Rulebook<TalkingHeads>> = [];
+    public static investigateRules = new Rulebook<TalkingHeads>("Default Ask About Rules");
+    public extraInvestigateRules : Array<Rulebook<TalkingHeads>> = [];
     public static reacttoRules = new Rulebook<Thing>("Default React To Rules");
     public extraReacttoRules : Array<Rulebook<Thing>> = [];
     public reactingTo : Action;
@@ -180,6 +195,18 @@ class AI {
             }, ...this.extraReacttoRules);
         }
     }
+
+    public answerTo (noun : TalkingHeads) {
+        return AI.talktoRules.execute({
+            noun : noun
+        }, ...this.extraTalktoRules);
+    }
+
+    public interrogateTo (noun : TalkingHeads) {
+        return AI.investigateRules.execute({
+            noun : noun
+        }, ...this.extraInvestigateRules);
+    }
 }
 
 module AIRules {

+ 66 - 1
app/World/Classes/Action/ActionTalk.ts

@@ -13,10 +13,75 @@ class ActionTalk extends Action {
     public static carry: Rulebook<ActionTalk> = new Rulebook("Carry out Talking");
 
     public static defaultCarryTalkingRule = ActionTalk.carry.createAndAddRule({
+        name : "Talking - Check with the AI",
+        firstPriority : Rule.PRIORITY_HIGHEST,
+        priority : Rule.PRIORITY_HIGHEST,
+        code : async (rulebook : RulebookRunner<ActionTalk>) => {
+            let action = <ActionGo> rulebook.noun;
+            //let actor = action.actor;
+            let thing = (<Thing>action.getNoun(0));
+
+            if (thing instanceof Person && action.actor instanceof Person) {
+                let runAndStop : Array<DialogueTree> = [];
+                let runAndContinue : Array<DialogueTree> = [];
+                let circumstantialOptions : Array<DialogueHook> = [];
+
+                await thing.AI.answerTo({greeter : action.actor, answerer : thing, options : circumstantialOptions, runAndStop : runAndStop, runFirst : runAndContinue});
+
+                if (runAndStop.length > 0) {
+                    return await runAndStop[0].execute();
+                } else if (runAndContinue.length > 0) {
+                    for (let i = 0; i < runAndContinue.length; i++) {
+                        await runAndContinue[i].execute();
+                    }
+                }
+
+                let investigativeOptions : Array<DialogueHook> = [];
+                await thing.AI.interrogateTo({greeter : action.actor, answerer : thing, options : investigativeOptions, runAndStop : runAndStop, runFirst : runAndContinue});
+
+
+                let choices : Array<Say> = [];
+                let results = [];
+                if (investigativeOptions.length > 0) {
+                    // TODO: Add more textx
+                    choices.push(new Say(new OneOf(OneOf.PURELY_AT_RANDOM, "Ask about...")));
+                    results.push(null);
+                }
+                for (let i = 0; i < circumstantialOptions.length; i++) {
+                    choices.push(circumstantialOptions[i].text);
+                    results.push(circumstantialOptions[i].tree);
+                }
+
+                // TODO: Add more texts
+                choices.push(new Say(new OneOf(OneOf.PURELY_AT_RANDOM, "Goodbye")));
+                results.push(undefined);
+
+
+                let choice = await Controls.giveChoices(true, ...choices);
+
+                if (results[choice[1]] === null) {
+                    choices = [];
+                    results = [];
+                    for (let i = 0; i < investigativeOptions.length; i++) {
+                        choices.push(investigativeOptions[i].text);
+                        results.push(investigativeOptions[i].tree);
+                    }
+                    choice = await Controls.giveChoices(true, ...choices);
+                    if (results[choice[1]] instanceof DialogueTree) {
+                        await (results[choice[1]]).execute();
+                    }
+                } else if (results[choice[1]] instanceof DialogueTree) {
+                    await (results[choice[1]]).execute();
+                }
+            }
+        }
+    });
+
+    public static lastCarryTalkingRule = ActionTalk.carry.createAndAddRule({
         name : "Talking - Doesn't want to talk",
         firstPriority : -1,
         priority : -1,
-        code : (rulebook : RulebookRunner<ActionTake>) => {
+        code : (rulebook : RulebookRunner<ActionTalk>) => {
             let action = <ActionGo> rulebook.noun;
             //let actor = action.actor;
             let thing = (<Thing>action.getNoun(0));

+ 23 - 23
app/World/Classes/Things/Humanoid/Orc/OrcDebugger.ts

@@ -23,26 +23,26 @@ class OrcDebugger extends Humanoid {
     }
 }
 
-ActionTalk.carry.createAndAddRule({
-    name : "Talking to the orc",
-    firstPriority : ActionTalk.PRIORITY_GLOBAL_DIALOGUE,
-    priority : ActionTalk.PRIORITY_COMMON_DIALOGUE,
-    conditions : (runner : RulebookRunner<ActionTalk>) => {
-        return runner.noun.getNoun(0) instanceof OrcDebugger;
-    },
-    code : (runner : RulebookRunner<ActionTalk>) => {
-        let orc = <OrcDebugger> runner.noun.getNoun(0);
-        //await DialogueTrees.CompilableTest.execute();
-        let result = Dice.testAgainstRoll(
-            {name: "Charm + 2", value : WorldState.player.getStat(Attributes.Charm) + 2},
-            {name: "Orc's wits + 2", value : orc.getStat(Attributes.Intelligence) + 2}
-        );
-
-        if (result > 0) {
-            Elements.CurrentTurnHandler.printAsContent(new Say("You win!"));
-        } else {
-            Elements.CurrentTurnHandler.printAsContent(new Say("You lose."));
-        }
-        return true;
-    }
-});
+// ActionTalk.carry.createAndAddRule({
+//     name : "Talking to the orc",
+//     firstPriority : ActionTalk.PRIORITY_GLOBAL_DIALOGUE,
+//     priority : ActionTalk.PRIORITY_COMMON_DIALOGUE,
+//     conditions : (runner : RulebookRunner<ActionTalk>) => {
+//         return runner.noun.getNoun(0) instanceof OrcDebugger;
+//     },
+//     code : (runner : RulebookRunner<ActionTalk>) => {
+//         let orc = <OrcDebugger> runner.noun.getNoun(0);
+//         //await DialogueTrees.CompilableTest.execute();
+//         let result = Dice.testAgainstRoll(
+//             {name: "Charm + 2", value : WorldState.player.getStat(Attributes.Charm) + 2},
+//             {name: "Orc's wits + 2", value : orc.getStat(Attributes.Intelligence) + 2}
+//         );
+//
+//         if (result > 0) {
+//             Elements.CurrentTurnHandler.printAsContent(new Say("You win!"));
+//         } else {
+//             Elements.CurrentTurnHandler.printAsContent(new Say("You lose."));
+//         }
+//         return true;
+//     }
+// });