feat: add condition evaluator with full operator support
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* Condition evaluator for the Rebirth Incremental game.
|
||||
* Evaluates condition objects against the current game state.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Operator functions for comparing values.
|
||||
* All operators perform loose equality/inequality checks where applicable.
|
||||
*/
|
||||
export const OPS = {
|
||||
'==': (a, b) => a == b,
|
||||
'===': (a, b) => a === b,
|
||||
'!=': (a, b) => a != b,
|
||||
'!==': (a, b) => a !== b,
|
||||
'>': (a, b) => a > b,
|
||||
'>=': (a, b) => a >= b,
|
||||
'<': (a, b) => a < b,
|
||||
'<=': (a, b) => a <= b,
|
||||
};
|
||||
|
||||
/**
|
||||
* Evaluates a condition object against the game state.
|
||||
* @param {Object} condition - The condition to evaluate
|
||||
* @param {Object} state - The current game state
|
||||
* @returns {boolean} - Whether the condition is satisfied
|
||||
*/
|
||||
export function evaluateCondition(condition, state) {
|
||||
if (!condition || typeof condition !== 'object') {
|
||||
return false;
|
||||
}
|
||||
|
||||
const { type } = condition;
|
||||
|
||||
switch (type) {
|
||||
case 'age': {
|
||||
const opFn = OPS[condition.op];
|
||||
if (!opFn) return false;
|
||||
return opFn(state.age ?? 0, condition.value);
|
||||
}
|
||||
|
||||
case 'stat': {
|
||||
const opFn = OPS[condition.op];
|
||||
if (!opFn) return false;
|
||||
const statValue = state.stats?.[condition.stat] ?? 0;
|
||||
return opFn(statValue, condition.value);
|
||||
}
|
||||
|
||||
case 'careerLevel': {
|
||||
const opFn = OPS[condition.op];
|
||||
if (!opFn) return false;
|
||||
const level = state.careers?.[condition.careerId]?.level ?? 0;
|
||||
return opFn(level, condition.value);
|
||||
}
|
||||
|
||||
case 'money': {
|
||||
const opFn = OPS[condition.op];
|
||||
if (!opFn) return false;
|
||||
return opFn(state.money ?? 0, condition.value);
|
||||
}
|
||||
|
||||
case 'identity': {
|
||||
return state.identity === condition.value;
|
||||
}
|
||||
|
||||
case 'worldFlag': {
|
||||
const flagValue = state.worldFlags?.[condition.flag];
|
||||
if (condition.value !== undefined) {
|
||||
return flagValue === condition.value;
|
||||
}
|
||||
return !!flagValue;
|
||||
}
|
||||
|
||||
case 'hasItem': {
|
||||
const itemCount = state.shopItems?.[condition.itemId] ?? 0;
|
||||
return itemCount > 0;
|
||||
}
|
||||
|
||||
case 'hasArtifact': {
|
||||
const artifactValue = state.artifacts?.[condition.artifactId] ?? 0;
|
||||
if (condition.op) {
|
||||
const opFn = OPS[condition.op];
|
||||
if (!opFn) return false;
|
||||
return opFn(artifactValue, condition.value);
|
||||
}
|
||||
return artifactValue > 0;
|
||||
}
|
||||
|
||||
case 'reincarnation': {
|
||||
const opFn = OPS[condition.op];
|
||||
if (!opFn) return false;
|
||||
return opFn(state.reincarnation ?? 0, condition.value);
|
||||
}
|
||||
|
||||
case 'and': {
|
||||
if (!Array.isArray(condition.conditions)) return false;
|
||||
return condition.conditions.every(sub => evaluateCondition(sub, state));
|
||||
}
|
||||
|
||||
case 'or': {
|
||||
if (!Array.isArray(condition.conditions)) return false;
|
||||
return condition.conditions.some(sub => evaluateCondition(sub, state));
|
||||
}
|
||||
|
||||
case 'not': {
|
||||
return !evaluateCondition(condition.condition, state);
|
||||
}
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user