94 lines
3.1 KiB
Python
94 lines
3.1 KiB
Python
# -*- coding: utf-8 -*-
|
||
"""语义词典:condition/grant kind -> 真实 ID/形态。外置 ir_dictionary.json,
|
||
编译器与(M5)Web 后端共读。新增查表类 kind 只改 JSON,零代码改动。
|
||
|
||
form 决定 grant 编译串形态:
|
||
money -> "{id},{value}" (银两;正给负扣)
|
||
item -> "{item},{value}" (道具,item 由 grant 指定 drop_item_data ID)
|
||
friend -> "{target},{id},{value}" (友好度,需 target NPC slot)
|
||
join -> roleActionCode "{code}={target}"(入门,需 target)
|
||
"""
|
||
import json
|
||
import os
|
||
|
||
_DICT_PATH = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
|
||
"ir_dictionary.json")
|
||
|
||
|
||
class CompileError(Exception):
|
||
pass
|
||
|
||
|
||
class Dictionary(object):
|
||
def __init__(self, data):
|
||
self.conditions = data.get("conditions", {})
|
||
self.grants = data.get("grants", {})
|
||
|
||
# ---- 查询 ----
|
||
def is_known_cond(self, kind):
|
||
return kind in self.conditions
|
||
|
||
def is_known_grant(self, kind):
|
||
return kind in self.grants
|
||
|
||
def cond_spec(self, kind):
|
||
return self.conditions.get(kind)
|
||
|
||
def grant_spec(self, kind):
|
||
return self.grants.get(kind)
|
||
|
||
def grant_needs_target(self, kind):
|
||
spec = self.grants.get(kind) or {}
|
||
return bool(spec.get("needs_target"))
|
||
|
||
# ---- 编译 ----
|
||
def compile_cond(self, c):
|
||
"""condition -> condition 字段字符串。"""
|
||
if not c:
|
||
return ""
|
||
kind = c.get("kind")
|
||
spec = self.conditions.get(kind)
|
||
if not spec:
|
||
raise CompileError("不支持的 condition kind: %r" % kind)
|
||
op = c.get("op")
|
||
ops = spec.get("ops", {})
|
||
if op not in ops:
|
||
raise CompileError("condition %r 不支持比较符 %r" % (kind, op))
|
||
return "%s,%s,%s" % (spec["id"], ops[op], c["value"])
|
||
|
||
def compile_grants(self, grants):
|
||
"""grants -> (resultRewardIds 串, roleActionCode 串)。"""
|
||
rewards, rac = [], ""
|
||
for g in grants or []:
|
||
k = g.get("kind")
|
||
spec = self.grants.get(k)
|
||
if not spec:
|
||
raise CompileError("不支持的 grant kind: %r" % k)
|
||
form = spec.get("form")
|
||
if form == "money":
|
||
rewards.append("%s,%s" % (spec["id"], g["value"]))
|
||
elif form == "item":
|
||
rewards.append("%s,%s" % (g["item"], g["value"]))
|
||
elif form == "friend":
|
||
rewards.append("%s,%s,%s" % (g["target"], spec["id"], g["value"]))
|
||
elif form == "join":
|
||
rac = "%s=%s" % (spec["code"], g["target"])
|
||
else:
|
||
raise CompileError("grant kind %r 的 form %r 未实现" % (k, form))
|
||
return ";".join(rewards), rac
|
||
|
||
|
||
_cached = None
|
||
|
||
|
||
def load_dictionary(path=None):
|
||
"""加载词典(默认缓存同目录 ir_dictionary.json)。"""
|
||
global _cached
|
||
if path is None:
|
||
if _cached is None:
|
||
with open(_DICT_PATH, encoding="utf-8") as f:
|
||
_cached = Dictionary(json.load(f))
|
||
return _cached
|
||
with open(path, encoding="utf-8") as f:
|
||
return Dictionary(json.load(f))
|