///
///
module TurnSequence {
export var rulebook = new Rulebook("Turn Sequence");
export var playerActions = [];
export let lastTurnTime : number = 0;
export let currentTurnActions : Array = [];
export let currentTurnActionsTargets : Array = [];
export let currentTurnActionsActors : Array = [];
export let repeatedAction : Action;
export function clearActions () {
console.debug(Rulebook.getIndentation() + "Clearing Turn Sequence Actions");
currentTurnActions = [];
currentTurnActionsTargets = [];
currentTurnActionsActors = [];
}
export function addAction (action : Action) {
currentTurnActions.push(action);
currentTurnActionsTargets.push(action.getNoun(0));
currentTurnActionsActors.push(action.actor);
action.actor.lastActionTurn = WorldState.getCurrentTurn();
}
export async function execute (action? : Action) {
// Only one action at a time
if (playerActions.push(action) == 1) {
let t0 = performance.now();
console.debug(Rulebook.getIndentation() + " Player Action: " + (action ? action.getCommandText() : "none"));
await rulebook.execute({
noun: action
});
playerActions = [];
let t1 = performance.now();
lastTurnTime = t1 - t0;
console.debug("Total: " + (t1 - t0) + " milliseconds.");
if (Settings.sayTurnTime) {
Elements.CurrentTurnHandler.printAsContent(new Say(new SayBold("Time taken for turn: "), (t1 - t0), " milliseconds."));
}
}
if (repeatedAction != undefined) {
setTimeout(() => {
let action = TurnSequence.repeatedAction;
TurnSequence.repeatedAction = undefined;
TurnSequence.execute(action);
}, 1);
}
}
/**
* This is the Prepare Elements for the turn rule.
* @type {Rule}
*/
export var PrepareElementsRule = new Rule({
firstPriority: Rule.PRIORITY_HIGHEST, // This will be about the first Rule to be executed
priority: Rule.PRIORITY_MEDIUM, // This needs to be done before the majority of the rules, but we don't want it to be the very first no matter what
name: "Begin Turn (Elements Side)",
code: function (runner : RulebookRunner) {
Elements.CurrentTurnHandler.startTurn(runner.noun);
}
});
TurnSequence.rulebook.addRule(PrepareElementsRule);
/**
* This is the Do Player Action Rule.
* @type {Rule}
*/
export let PlayerActionRule = new Rule({
firstPriority: Rule.PRIORITY_HIGH,
priority: Rule.PRIORITY_MEDIUM,
name: "Do Player Action",
code: async (rulebook : RulebookRunner) => {
let playerAction = rulebook.noun;
if (playerAction != undefined) {
let promise = playerAction.execute();
await promise;
Elements.CurrentTurnHandler.printAsContent(playerAction.say);
if (playerAction.requiresTurn) {
WorldState.incrementPlayerTurn();
}
}
}
});
rulebook.addRule(PlayerActionRule);
/**
* This is the Run Every Turn Rules.
* @type {Rule}
*/
export var RunEveryTurnRulesRule = new Rule({
firstPriority: PlayerActionRule.firstPriority,
priority: PlayerActionRule.priority - 1,
name: "Run Every Turn Rules",
code: async function () {
while (WorldState.isTurnWaiting()) {
await EveryTurn.EveryTurn.execute({});
}
}
});
rulebook.addRule(RunEveryTurnRulesRule);
/**
* This is the Clean up Turn Actions Rule
*/
/**
* This is the Run Every Turn Rules.
* @type {Rule}
*/
export var CleanTurnActionsRule = new Rule({
firstPriority: RunEveryTurnRulesRule.firstPriority,
priority: RunEveryTurnRulesRule.priority - 1,
name: "Clear Turn Actions Rule",
code: async function () {
TurnSequence.clearActions();
}
});
rulebook.addRule(CleanTurnActionsRule);
/**
* This is the Inform Elements the turn has ended rule.
* @type {Rule}
*/
export var RemoveTurnFromElementsRule = new Rule({
firstPriority: Rule.PRIORITY_LOWEST, // This will be about the last rule to be executed
priority: Rule.PRIORITY_MEDIUM, // This needs to be done after the majority of the rules, but we don't care if it's the very last or not
name: "End Turn (Elements/Controls Side)",
code: async function (rulebook : RulebookRunner) {
Elements.CurrentTurnHandler.endTurn();
Controls.KeyHandler.reset();
await Elements.HyperlinkHandler.hyperlinkCommonActions();
await Elements.RoomHandler.updateRoom();
await Elements.RememberedHandler.updateMap();
let playerAction = rulebook.noun;
if (playerAction) {
await Elements.HyperlinkHandler.hyperlinkObject(playerAction.getNoun(0));
} else {
await Elements.HyperlinkHandler.hyperlinkObject();
}
await Elements.InventoryHandler.updateInventory();
await Elements.AppearanceHandler.updateAppearance();
//await Elements.StatusLineHandler.updateStatusLine();
}
});
TurnSequence.rulebook.addRule(RemoveTurnFromElementsRule);
}