feat: add event engine with age trigger, random pool, choice filtering
This commit is contained in:
@@ -0,0 +1,222 @@
|
||||
{
|
||||
"events": [
|
||||
{
|
||||
"id": "daily_training",
|
||||
"name": "日常修炼",
|
||||
"description": "你坚持日常修炼,体质有所提升。",
|
||||
"trigger": {
|
||||
"type": "random",
|
||||
"pool": "normal"
|
||||
},
|
||||
"weight": 50,
|
||||
"effects": [
|
||||
{
|
||||
"type": "addStat",
|
||||
"stat": "体质",
|
||||
"value": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "study_hard",
|
||||
"name": "刻苦学习",
|
||||
"description": "你发奋读书,悟性有所提升。",
|
||||
"trigger": {
|
||||
"type": "random",
|
||||
"pool": "normal"
|
||||
},
|
||||
"weight": 50,
|
||||
"effects": [
|
||||
{
|
||||
"type": "addStat",
|
||||
"stat": "悟性",
|
||||
"value": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "invasion_military_40",
|
||||
"name": "蛮族入侵",
|
||||
"description": "北方蛮族大举入侵,边境告急!",
|
||||
"trigger": {
|
||||
"type": "age",
|
||||
"value": 40
|
||||
},
|
||||
"isChoice": true,
|
||||
"choices": [
|
||||
{
|
||||
"id": "resist",
|
||||
"text": "率军抵抗",
|
||||
"requirements": {
|
||||
"type": "careerLevel",
|
||||
"careerId": "soldier",
|
||||
"op": ">=",
|
||||
"value": 50
|
||||
},
|
||||
"effects": [
|
||||
{
|
||||
"type": "addLog",
|
||||
"text": "你率领大军击退了蛮族入侵,威震四方!"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "flee",
|
||||
"text": "弃城逃跑",
|
||||
"effects": [
|
||||
{
|
||||
"type": "addLog",
|
||||
"text": "你选择了弃城逃跑,虽然保住了性命,但名声扫地。"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "invasion_spiritual_45",
|
||||
"name": "天魔降世",
|
||||
"description": "天魔降世,人间陷入混乱,你该如何应对?",
|
||||
"trigger": {
|
||||
"type": "age",
|
||||
"value": 45
|
||||
},
|
||||
"isChoice": true,
|
||||
"choices": [
|
||||
{
|
||||
"id": "suppress",
|
||||
"text": "出手镇压",
|
||||
"requirements": {
|
||||
"type": "careerLevel",
|
||||
"careerId": "taoist",
|
||||
"op": ">=",
|
||||
"value": 50
|
||||
},
|
||||
"effects": [
|
||||
{
|
||||
"type": "addLog",
|
||||
"text": "你以无上道法镇压天魔,拯救了苍生!"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "hide",
|
||||
"text": "躲藏起来",
|
||||
"effects": [
|
||||
{
|
||||
"type": "addLog",
|
||||
"text": "你选择了躲藏起来,避开了这场浩劫。"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "invasion_political_50",
|
||||
"name": "王朝崩坏",
|
||||
"description": "王朝内部腐败,民不聊生,天下大乱。",
|
||||
"trigger": {
|
||||
"type": "age",
|
||||
"value": 50
|
||||
},
|
||||
"isChoice": true,
|
||||
"choices": [
|
||||
{
|
||||
"id": "assist",
|
||||
"text": "辅佐明君",
|
||||
"requirements": {
|
||||
"type": "stat",
|
||||
"stat": "智力",
|
||||
"op": ">=",
|
||||
"value": 50
|
||||
},
|
||||
"effects": [
|
||||
{
|
||||
"type": "addLog",
|
||||
"text": "你以智谋辅佐明君,力挽狂澜,拯救了王朝。"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "selfish",
|
||||
"text": "独善其身",
|
||||
"effects": [
|
||||
{
|
||||
"type": "addLog",
|
||||
"text": "你选择了独善其身,在乱世中保全了自己。"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "final_crisis_60",
|
||||
"name": "最终危机",
|
||||
"description": "世界面临最终危机,这是你最后的选择。",
|
||||
"trigger": {
|
||||
"type": "age",
|
||||
"value": 60
|
||||
},
|
||||
"isChoice": true,
|
||||
"choices": [
|
||||
{
|
||||
"id": "general",
|
||||
"text": "以将军之力平定天下",
|
||||
"requirements": {
|
||||
"type": "careerLevel",
|
||||
"careerId": "soldier",
|
||||
"op": ">=",
|
||||
"value": 50
|
||||
},
|
||||
"effects": [
|
||||
{
|
||||
"type": "addLog",
|
||||
"text": "你以将军之力平定天下,成为一代名将!"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "chancellor",
|
||||
"text": "以宰相之智治理国家",
|
||||
"requirements": {
|
||||
"type": "stat",
|
||||
"stat": "智力",
|
||||
"op": ">=",
|
||||
"value": 50
|
||||
},
|
||||
"effects": [
|
||||
{
|
||||
"type": "addLog",
|
||||
"text": "你以宰相之智治理国家,名垂青史!"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "cultivator",
|
||||
"text": "以修仙之道超脱轮回",
|
||||
"requirements": {
|
||||
"type": "careerLevel",
|
||||
"careerId": "taoist",
|
||||
"op": ">=",
|
||||
"value": 50
|
||||
},
|
||||
"effects": [
|
||||
{
|
||||
"type": "addLog",
|
||||
"text": "你以修仙之道超脱轮回,飞升成仙!"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "powerless",
|
||||
"text": "无力回天",
|
||||
"effects": [
|
||||
{
|
||||
"type": "addLog",
|
||||
"text": "你感到无力回天,只能接受命运的安排。"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
// ==================== 事件引擎 ====================
|
||||
|
||||
import { evaluateCondition } from './conditionEvaluator.js';
|
||||
|
||||
let _eventConfig = null;
|
||||
|
||||
export function setEventConfig(config) {
|
||||
_eventConfig = config;
|
||||
}
|
||||
|
||||
export function getEventConfig() {
|
||||
return _eventConfig;
|
||||
}
|
||||
|
||||
export function checkAgeEvents(config, state) {
|
||||
const triggered = [];
|
||||
if (!config || !config.events) return triggered;
|
||||
if (!state.triggeredEvents) state.triggeredEvents = new Set();
|
||||
|
||||
for (const event of config.events) {
|
||||
if (event.trigger?.type !== 'age') continue;
|
||||
if (state.triggeredEvents.has(event.id)) continue;
|
||||
if (state.age === event.trigger.value) {
|
||||
triggered.push(event);
|
||||
state.triggeredEvents.add(event.id);
|
||||
}
|
||||
}
|
||||
return triggered;
|
||||
}
|
||||
|
||||
export function pickRandomEvent(config, state, pool) {
|
||||
if (!config || !config.events) return null;
|
||||
if (!state.triggeredEvents) state.triggeredEvents = new Set();
|
||||
|
||||
const candidates = config.events.filter(event => {
|
||||
if (event.trigger?.type !== 'random') return false;
|
||||
if (event.trigger.pool !== pool) return false;
|
||||
if (state.triggeredEvents.has(event.id)) return false;
|
||||
return true;
|
||||
});
|
||||
|
||||
if (candidates.length === 0) return null;
|
||||
|
||||
const totalWeight = candidates.reduce((sum, e) => sum + (e.weight || 0), 0);
|
||||
if (totalWeight <= 0) return null;
|
||||
|
||||
let roll = Math.random() * totalWeight;
|
||||
for (const event of candidates) {
|
||||
roll -= (event.weight || 0);
|
||||
if (roll <= 0) return event;
|
||||
}
|
||||
return candidates[candidates.length - 1];
|
||||
}
|
||||
|
||||
export function getAvailableChoices(event, state) {
|
||||
if (!event || !event.choices) return [];
|
||||
return event.choices.filter(choice => {
|
||||
if (!choice.requirements) return true;
|
||||
return evaluateCondition(choice.requirements, state);
|
||||
});
|
||||
}
|
||||
|
||||
export function executeEvent(event, state, applyEffectFn) {
|
||||
if (!event || !event.effects) return;
|
||||
if (!state.triggeredEvents) state.triggeredEvents = new Set();
|
||||
|
||||
for (const effect of event.effects) {
|
||||
applyEffectFn(effect, state);
|
||||
}
|
||||
state.triggeredEvents.add(event.id);
|
||||
}
|
||||
Reference in New Issue
Block a user