生物面板

This commit is contained in:
李鹏宇
2026-09-04 16:11:02 +08:00
parent 692f95a282
commit 50c03839da
3 changed files with 275 additions and 41 deletions
+32 -3
View File
@@ -832,7 +832,7 @@ class YtWorldApi(http.Controller):
if 'inventory' in body and body['inventory'] is not None:
vals['inventory'] = body['inventory']
if 'equip' in body and body['equip'] is not None:
vals['equip'] = body['equip']
vals['equip'] = self._normalize_equip(body['equip'])
char.sudo().write(vals)
return _json({'ok': True, 'char': {
'name': char.name, 'level': char.level, 'exp': char.exp,
@@ -841,6 +841,19 @@ class YtWorldApi(http.Controller):
'equip': char.equip or {},
}})
@staticmethod
def _normalize_equip(equip):
"""equip 的值统一规范为装备 code 字符串。
读取接口返回的是解析后的装备对象(含 code/name/desc…),前端原样回存
会把它写成字典,导致后续序列化异常。这里统一压回 code。"""
if not isinstance(equip, dict):
return {}
out = {}
for slot, raw in equip.items():
out[slot] = (raw.get('code') if isinstance(raw, dict) else raw)
return out
@http.route('/yt_world/api/creatures', type='http', auth='public',
methods=['GET', 'OPTIONS'], csrf=False)
def get_creatures(self, **kw):
@@ -853,7 +866,23 @@ class YtWorldApi(http.Controller):
return _json({'ok': False, 'error': 'no_world'})
recs = request.env['yt.world.creature'].sudo().search(
[('world_id', '=', world.id)], order='id')
out = [r.to_panel_dict() for r in recs]
out = []
for r in recs:
try:
out.append(r.to_panel_dict())
except Exception:
# 单条脏数据不得拖垮整个接口,否则玩家所有生物都读不出来
_logger.exception('[yt_world] 生物 %s 序列化失败,已降级返回', r.cid)
out.append({
'oid': r.id, 'cid': r.cid, 'race': r.race, 'name': r.name,
'level': r.level, 'exp': r.exp, 'exp_max': r.exp_max,
'hp': r.hp, 'hp_max': r.hp_max,
'energy': r.energy, 'energy_max': r.energy_max,
'attack': r.attack, 'defense': r.defense, 'speed': r.speed,
'mood': r.mood, 'job': r.job, 'status': r.status, 'state': r.state,
'x': r.x, 'y': r.y, 'facing': r.facing,
'tile_ref': r.tile_ref or {}, 'equip': {},
})
return _json({'ok': True, 'creatures': out})
@http.route('/yt_world/api/creatures/save', type='http', auth='public',
@@ -887,7 +916,7 @@ class YtWorldApi(http.Controller):
'status': c.get('status') or 'idle',
'state': c.get('state') or 'idle',
'mood': c.get('mood', '😊'), 'job': c.get('job', 'none'),
'equip': c.get('equip') or {},
'equip': self._normalize_equip(c.get('equip')),
'tile_ref': c.get('tile_ref') or {},
}
rec = model.search([('world_id', '=', world.id), ('cid', '=', cid)], limit=1) if cid else None
+3 -1
View File
@@ -277,7 +277,9 @@ class YtWorldCreature(models.Model):
for it in self.env['yt.world.equip.item'].sudo().search([]):
catalog[it.code] = it.to_dict()
equip_resolved = {}
for slot, code in equip.items():
for slot, raw in (equip or {}).items():
# 容错:equip 的值可能是装备 code 字符串,也可能是历史遗留的整件装备字典
code = raw.get('code') if isinstance(raw, dict) else raw
if code and code in catalog:
equip_resolved[slot] = catalog[code]
return {