图鉴
This commit is contained in:
@@ -1049,9 +1049,12 @@ class YtWorldApi(http.Controller):
|
||||
@http.route('/yt_world/api/equip/catalog', type='http', auth='public',
|
||||
methods=['GET', 'OPTIONS'], csrf=False)
|
||||
def equip_catalog(self, **kw):
|
||||
"""装备目录(单一事实来源)。"""
|
||||
items = request.env['yt.world.equip.item'].sudo().search([('active', '=', True)])
|
||||
return _json({'ok': True, 'items': [it.to_dict() for it in items]})
|
||||
"""装备目录(单一事实来源)。同时返回 slots 槽位真源列表,
|
||||
前端面板据此动态渲染(含尚无装备的空槽位)。"""
|
||||
Item = request.env['yt.world.equip.item'].sudo()
|
||||
items = Item.search([('active', '=', True)])
|
||||
slots = [{'value': v, 'label': l} for v, l in Item._fields['slot'].selection]
|
||||
return _json({'ok': True, 'items': [it.to_dict() for it in items], 'slots': slots})
|
||||
|
||||
def _creature_by_cid(self, world, cid):
|
||||
if not cid:
|
||||
@@ -1093,7 +1096,8 @@ class YtWorldApi(http.Controller):
|
||||
if action == 'equip':
|
||||
slot = body.get('slot')
|
||||
code = body.get('code')
|
||||
if slot not in ('weapon', 'armor', 'accessory', 'boots'):
|
||||
valid_slots = [s[0] for s in request.env['yt.world.equip.item']._fields['slot'].selection]
|
||||
if slot not in valid_slots:
|
||||
return _json({'ok': False, 'error': 'bad_slot'})
|
||||
item = request.env['yt.world.equip.item'].sudo().search([('code', '=', code)], limit=1)
|
||||
if not item:
|
||||
|
||||
@@ -125,4 +125,121 @@
|
||||
<field name="stats">{"hp_max": 25, "energy_max": 15}</field>
|
||||
<field name="desc">蕴含生命能量的护符,佩戴者精力更充沛。</field>
|
||||
</record>
|
||||
|
||||
<!-- ================= 帽子 (hat) ================= -->
|
||||
<record id="equip_straw_hat" model="yt.world.equip.item">
|
||||
<field name="code">straw_hat</field>
|
||||
<field name="name">草帽</field>
|
||||
<field name="icon">assets/icons/equips/straw_hat.png</field>
|
||||
<field name="slot">hat</field>
|
||||
<field name="rarity">common</field>
|
||||
<field name="stats">{"defense": 1}</field>
|
||||
<field name="desc">编织草帽,遮阳挡雨,略增防护。</field>
|
||||
</record>
|
||||
<record id="equip_iron_helm" model="yt.world.equip.item">
|
||||
<field name="code">iron_helm</field>
|
||||
<field name="name">铁盔</field>
|
||||
<field name="icon">assets/icons/equips/iron_helm.png</field>
|
||||
<field name="slot">hat</field>
|
||||
<field name="rarity">rare</field>
|
||||
<field name="stats">{"defense": 3, "hp_max": 8}</field>
|
||||
<field name="desc">冷锻铁盔,关键时刻护住头脸。</field>
|
||||
</record>
|
||||
<record id="equip_gold_crown" model="yt.world.equip.item">
|
||||
<field name="code">gold_crown</field>
|
||||
<field name="name">黄金王冠</field>
|
||||
<field name="icon">assets/icons/equips/gold_crown.png</field>
|
||||
<field name="slot">hat</field>
|
||||
<field name="rarity">legendary</field>
|
||||
<field name="stats">{"defense": 5, "hp_max": 20, "attack": 5}</field>
|
||||
<field name="desc">象征权柄的黄金王冠,威仪凛然。</field>
|
||||
</record>
|
||||
|
||||
<!-- ================= 裤子 (pants) ================= -->
|
||||
<record id="equip_cloth_pants" model="yt.world.equip.item">
|
||||
<field name="code">cloth_pants</field>
|
||||
<field name="name">布裤</field>
|
||||
<field name="icon">assets/icons/equips/cloth_pants.png</field>
|
||||
<field name="slot">pants</field>
|
||||
<field name="rarity">common</field>
|
||||
<field name="stats">{"defense": 1}</field>
|
||||
<field name="desc">轻便布裤,行动无碍。</field>
|
||||
</record>
|
||||
<record id="equip_iron_leggings" model="yt.world.equip.item">
|
||||
<field name="code">iron_leggings</field>
|
||||
<field name="name">铁护腿</field>
|
||||
<field name="icon">assets/icons/equips/iron_leggings.png</field>
|
||||
<field name="slot">pants</field>
|
||||
<field name="rarity">rare</field>
|
||||
<field name="stats">{"defense": 3, "hp_max": 10}</field>
|
||||
<field name="desc">裹住小腿的铁片护腿,稳健可靠。</field>
|
||||
</record>
|
||||
<record id="equip_dragon_pants" model="yt.world.equip.item">
|
||||
<field name="code">dragon_pants</field>
|
||||
<field name="name">龙鳞战裤</field>
|
||||
<field name="icon">assets/icons/equips/dragon_pants.png</field>
|
||||
<field name="slot">pants</field>
|
||||
<field name="rarity">legendary</field>
|
||||
<field name="stats">{"defense": 6, "hp_max": 25}</field>
|
||||
<field name="desc">龙鳞缀成的战裤,刀枪难入。</field>
|
||||
</record>
|
||||
|
||||
<!-- ================= 护臂 (bracelet) ================= -->
|
||||
<record id="equip_leather_bracer" model="yt.world.equip.item">
|
||||
<field name="code">leather_bracer</field>
|
||||
<field name="name">皮护腕</field>
|
||||
<field name="icon">assets/icons/equips/leather_bracer.png</field>
|
||||
<field name="slot">bracelet</field>
|
||||
<field name="rarity">common</field>
|
||||
<field name="stats">{"attack": 2}</field>
|
||||
<field name="desc">皮质护腕,挥击更稳。</field>
|
||||
</record>
|
||||
<!-- 银手镯/龙纹手镯 归属饰品槽 (accessory) -->
|
||||
<record id="equip_silver_bracer" model="yt.world.equip.item">
|
||||
<field name="code">silver_bracer</field>
|
||||
<field name="name">银手镯</field>
|
||||
<field name="icon">assets/icons/equips/silver_bracer.png</field>
|
||||
<field name="slot">accessory</field>
|
||||
<field name="rarity">rare</field>
|
||||
<field name="stats">{"attack": 4, "defense": 1}</field>
|
||||
<field name="desc">嵌银手镯,攻防兼修。</field>
|
||||
</record>
|
||||
<record id="equip_dragon_bracelet" model="yt.world.equip.item">
|
||||
<field name="code">dragon_bracelet</field>
|
||||
<field name="name">龙纹手镯</field>
|
||||
<field name="icon">assets/icons/equips/dragon_bracelet.png</field>
|
||||
<field name="slot">accessory</field>
|
||||
<field name="rarity">epic</field>
|
||||
<field name="stats">{"attack": 8, "hp_max": 10}</field>
|
||||
<field name="desc">刻龙纹的护腕,蓄力更猛。</field>
|
||||
</record>
|
||||
|
||||
<!-- ================= 腰带 (belt) ================= -->
|
||||
<record id="equip_rope_belt" model="yt.world.equip.item">
|
||||
<field name="code">rope_belt</field>
|
||||
<field name="name">麻绳腰带</field>
|
||||
<field name="icon">assets/icons/equips/rope_belt.png</field>
|
||||
<field name="slot">belt</field>
|
||||
<field name="rarity">common</field>
|
||||
<field name="stats">{"hp_max": 5}</field>
|
||||
<field name="desc">粗麻绳束腰,勉强管用。</field>
|
||||
</record>
|
||||
<record id="equip_iron_belt" model="yt.world.equip.item">
|
||||
<field name="code">iron_belt</field>
|
||||
<field name="name">铁腰封</field>
|
||||
<field name="icon">assets/icons/equips/iron_belt.png</field>
|
||||
<field name="slot">belt</field>
|
||||
<field name="rarity">rare</field>
|
||||
<field name="stats">{"hp_max": 12, "defense": 2}</field>
|
||||
<field name="desc">铁片腰封,护住躯干。</field>
|
||||
</record>
|
||||
<record id="equip_dragon_belt" model="yt.world.equip.item">
|
||||
<field name="code">dragon_belt</field>
|
||||
<field name="name">龙鳞腰带</field>
|
||||
<field name="icon">assets/icons/equips/dragon_belt.png</field>
|
||||
<field name="slot">belt</field>
|
||||
<field name="rarity">epic</field>
|
||||
<field name="stats">{"hp_max": 25, "defense": 4}</field>
|
||||
<field name="desc">龙鳞束腰,根骨更稳。</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
生物→世界→账号自动归属到对应玩家。
|
||||
"""
|
||||
from odoo import models, fields, api
|
||||
from odoo.addons.yt_world.models.yt_world_equip_item import YtWorldEquipItem
|
||||
|
||||
|
||||
class YtWorldEquipInstance(models.Model):
|
||||
@@ -23,10 +24,10 @@ class YtWorldEquipInstance(models.Model):
|
||||
required=True, ondelete='cascade', index=True)
|
||||
owner_creature_id = fields.Many2one('yt.world.creature', string='拥有者生物',
|
||||
ondelete='cascade', index=True)
|
||||
# 已装备的部位;空值(False)表示在背包中未装备
|
||||
# 已装备的部位;空值(False)表示在背包中未装备。
|
||||
# 与 yt.world.equip.item 的 SLOT_SELECTION 共用同一份常量,避免两处各写一份槽位列表。
|
||||
equipped_slot = fields.Selection(
|
||||
[('weapon', '武器'), ('armor', '护甲'), ('accessory', '饰品'), ('boots', '鞋子')],
|
||||
string='已装备部位', index=True)
|
||||
YtWorldEquipItem.SLOT_SELECTION, string='已装备部位', index=True)
|
||||
durability = fields.Integer(string='当前耐久', default=100)
|
||||
max_durability = fields.Integer(string='最大耐久', default=100)
|
||||
enhance_level = fields.Integer(string='强化等级', default=0)
|
||||
|
||||
@@ -21,9 +21,13 @@ class YtWorldEquipItem(models.Model):
|
||||
code = fields.Char(string='编码', required=True, index=True)
|
||||
name = fields.Char(string='名称', required=True)
|
||||
icon = fields.Char(string='图标', default='⚔️')
|
||||
slot = fields.Selection(
|
||||
[('weapon', '武器'), ('armor', '护甲'), ('accessory', '饰品'), ('boots', '鞋子')],
|
||||
string='部位', required=True)
|
||||
# 部位槽位:单一真源。前端面板 / 实例表 / catalog 接口均以本选择项为准,
|
||||
# 新增槽位只需在此追加(及 yt.world.equip.instance 的 equipped_slot),前端自动渲染。
|
||||
SLOT_SELECTION = [
|
||||
('weapon', '武器'), ('armor', '护甲'), ('accessory', '饰品'), ('boots', '鞋子'),
|
||||
('hat', '帽子'), ('pants', '裤子'), ('bracelet', '护臂'), ('belt', '腰带'),
|
||||
]
|
||||
slot = fields.Selection(SLOT_SELECTION, string='部位', required=True)
|
||||
rarity = fields.Selection(
|
||||
[('common', '普通'), ('rare', '稀有'), ('epic', '史诗'), ('legendary', '传说')],
|
||||
string='稀有度', default='common')
|
||||
|
||||
@@ -298,8 +298,10 @@ class YtWorldCreature(models.Model):
|
||||
catalog[it.code] = it.to_dict()
|
||||
# 从装备实例表反查"当前已装备"的装备(实例 -> 模板对象),
|
||||
# 保持前端 {slot: 对象} 结构不变,前端渲染零改动。
|
||||
# 槽位列表直接取自装备图鉴模型的 SLOT_SELECTION(单一真源),新增槽位无需改此处。
|
||||
equip_resolved = {}
|
||||
for slot in ('weapon', 'armor', 'accessory', 'boots'):
|
||||
equip_slots = [s[0] for s in self.env['yt.world.equip.item']._fields['slot'].selection]
|
||||
for slot in equip_slots:
|
||||
inst = self.env['yt.world.equip.instance'].sudo().search(
|
||||
[('owner_creature_id', '=', self.id), ('equipped_slot', '=', slot)], limit=1)
|
||||
if inst:
|
||||
|
||||
Reference in New Issue
Block a user