Files
game/addons/yt_world/build_spec.py
T
2026-09-24 10:19:53 +08:00

80 lines
3.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
"""建筑产出规格的单一真源(Single Source of Truth)。
此前建筑产出写在 noupdate 的 XML 数据记录里,模块升级时 Odoo 不会重放
已存在记录的字段,导致改了产出必须手动补写 DB —— 这是行业里典型的
「可变平衡值被放进存档/活数据」反模式。
这里把产出参数全部收口到代码:
- stat_yield_tick : 每分钟产出的资源,如 {'food': 3}
- stat_yield_instant: 建造即给、拆除即收的即时属性,如 {'population': 4}
- effects : 非库存效果(治疗/饱食/仓储上限),供建筑交互使用,
不参与世界 stock 结算
改任何建筑的产出,只改这个字典 + 升级模块即可,全自动生效,永不再手动补写。
"""
BUILD_SPECS = {
# ===== 即时属性(建造 +,拆除 -)=====
'cottage': {'stat_yield_instant': {'population': 4}, 'stat_yield_tick': {}},
'village': {'stat_yield_instant': {'population': 6}, 'stat_yield_tick': {'food': 1}},
# ===== 每分钟资源(tick)=====
'farmland': {'stat_yield_instant': {}, 'stat_yield_tick': {'food': 3}},
'well': {'stat_yield_instant': {}, 'stat_yield_tick': {'water': 2}},
'windmill': {'stat_yield_instant': {}, 'stat_yield_tick': {'flour': 2}},
'blacksmith': {'stat_yield_instant': {}, 'stat_yield_tick': {'metal': 2}},
'grocery': {'stat_yield_instant': {}, 'stat_yield_tick': {'coin': 2}},
'temple': {'stat_yield_instant': {}, 'stat_yield_tick': {'prestige': 3}},
'pasture': {'stat_yield_instant': {}, 'stat_yield_tick': {'meat': 2, 'milk': 1}},
'school': {'stat_yield_instant': {}, 'stat_yield_tick': {'research': 3, 'prestige': 1}},
'library': {'stat_yield_instant': {}, 'stat_yield_tick': {'research': 4}},
'barracks': {'stat_yield_instant': {}, 'stat_yield_tick': {'military': 4}},
'guild': {'stat_yield_instant': {}, 'stat_yield_tick': {'prestige': 2, 'coin': 1}},
# ===== 效果类(非库存,供建筑交互)=====
'clinic': {'stat_yield_instant': {}, 'stat_yield_tick': {}, 'effects': {'heal': 2}},
'restaurant': {'stat_yield_instant': {}, 'stat_yield_tick': {}, 'effects': {'satiety': 3}},
'storage': {'stat_yield_instant': {}, 'stat_yield_tick': {}, 'effects': {'storage': 10}},
# ===== 无产出(功能性)=====
'fence': {'stat_yield_instant': {}, 'stat_yield_tick': {}},
'wall': {'stat_yield_instant': {}, 'stat_yield_tick': {}},
'blackmarket':{'stat_yield_instant': {}, 'stat_yield_tick': {}}, # 功能性建筑,无库存产出
}
def level_mult(level):
"""建筑等级产出倍率:L1=1倍、L2=2倍……(线性,升级即等比提升)。
所有结算/对账/速率计算都必须乘上此倍率,保证升级带来实际收益。"""
try:
lv = int(level or 1)
except (TypeError, ValueError):
lv = 1
return max(1, lv)
def scaled(d, level):
"""把基础产出字典按等级缩放:{k: v} → {k: v * level_mult(level)}。"""
if not d:
return {}
m = level_mult(level)
return {k: (v or 0) * m for k, v in d.items()}
def spec_defined(code):
"""某建筑编码是否在 BUILD_SPECS 中有明确定义。"""
return code in BUILD_SPECS
def get_spec(code):
"""取某建筑编码的规格;不存在返回空规格。"""
spec = BUILD_SPECS.get(code)
if not spec:
return {'stat_yield_instant': {}, 'stat_yield_tick': {}, 'effects': {}}
return {
'stat_yield_instant': spec.get('stat_yield_instant', {}) or {},
'stat_yield_tick': spec.get('stat_yield_tick', {}) or {},
'effects': spec.get('effects', {}) or {},
}