生物面板
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user