PlotUtils.ts 3.42 KB
import { ConditionItem, ConditionOprandType, ConditionOperator, ConditionExpression, ConditionRelation } from "../model/ConditionModel";
import { GameRecord } from "../game-data/GameRecord";
import { uniqArray, DeepReadonly } from "simba-utils";
import { ConfigManager } from "../../common/gameplay/managers/ConfigManager";

function evalConditionItem(item: ConditionItem) {
    let op1 = GameRecord.getVariableValue(item.target);
    let op2: string | number;
    if (item.oprand.type === ConditionOprandType.Const) {
        op2 = item.target;
    } else {
        op2 = GameRecord.getVariableValue(item.target)
    }
    switch (item.operator) {
        case ConditionOperator.Equal:
            return op1 == op2;
        case ConditionOperator.Greater:
            return op1 > op2;
        case ConditionOperator.GreaterOrEqual:
            return op1 >= op2;
        case ConditionOperator.Less:
            return op1 < op2;
        case ConditionOperator.LessOrEqual:
            return op1 <= op2;
        case ConditionOperator.NotEqual:
            return op1 != op2;
    }
}

export function evalConditionExpr(condition: DeepReadonly<ConditionExpression>): boolean {
    let ret = condition.relation === ConditionRelation.Or ? false : true;
    for (let group of condition.groups) {
        for (let item of group.items) {
            ret = evalConditionItem(item);
            if ((ret && group.relation === ConditionRelation.Or) || (!ret && group.relation === ConditionRelation.And)) {
                break;
            }
        }
        if ((ret && condition.relation === ConditionRelation.Or) || (!ret && condition.relation === ConditionRelation.And)) {
            break;
        }
    }
    return ret;
}

export function parseTextWithVariables(text: string) {
    if (text.charCodeAt(0) !== 1) return { parsedText: text, variables: [] };
    text = text.substr(1);
    let parsedText = text;
    let matches = parsedText.match(/\${(.*?)}/g);
    if (!matches) return { parsedText: text, variables: [] };
    let matchVars = uniqArray(matches);
    let variables = matchVars.map(v => v.substring(2, v.length - 1));
    for (let i = 0; i < matchVars.length; i++) {
        let varName = variables[i];
        if (/^[gr]\./.test(varName)) {
            parsedText = parsedText.replace(new RegExp(matchVars[i].replace(/\./gm, "\\.").replace(/\$/gm, "\\$"), "gm"), GameRecord.getVariableValue(varName).toString());
        } else { // value from table
            let index = varName.indexOf(".");
            let index1 = varName.indexOf("[");
            if (index >= 0) {
                let tableName = varName.substring(0, index1);
                let valueId = parseInt(varName.substring(index1 + 1, index - 1));
                let fieldName = varName.substring(index + 1);
                try {
                    let text = ConfigManager.getConfig<any>({ name: tableName }, valueId)[fieldName];
                    if (typeof text === "number") {
                        text = text.toString();
                    } else {
                        text = parseTextWithVariables(text);
                    }
                    parsedText = parsedText.replace(new RegExp(matchVars[i].replace(/\./gm, "\\.").replace(/\$/gm, "\\$"), "gm"), text);
                } catch (e) {
                    console.error(e);
                }
            } else {
                console.error("Invalid variable");
            }
        }
    }
    return { parsedText, variables };
}