65 lines
2.5 KiB
Python
65 lines
2.5 KiB
Python
# -*- coding: utf-8 -*-
|
||
from odoo import api, fields, models
|
||
|
||
RELATION_STATUS_ORDER = [
|
||
'enemy', 'hostile', 'stranger', 'acquaintance', 'friend', 'close_friend', 'family',
|
||
]
|
||
RELATION_STATUS_LABELS = {
|
||
'enemy': '死敌', 'hostile': '敌对', 'stranger': '陌生人',
|
||
'acquaintance': '熟人', 'friend': '朋友', 'close_friend': '挚友', 'family': '至亲',
|
||
}
|
||
|
||
class GameNpcRelationship(models.Model):
|
||
_name = 'game.npc.relationship'
|
||
_description = 'NPC 关系'
|
||
_rec_name = 'display_name'
|
||
_order = 'affinity desc'
|
||
|
||
npc_id = fields.Many2one('game.npc', string='角色', required=True, ondelete='cascade', index=True)
|
||
target_npc_id = fields.Many2one('game.npc', string='对方', required=True, ondelete='cascade', index=True)
|
||
affinity = fields.Integer(string='好感度', default=0,
|
||
help='范围 -100(死敌)~ 100(至亲),0 = 陌生人')
|
||
status = fields.Selection([
|
||
('enemy', '死敌'), ('hostile', '敌对'), ('stranger', '陌生人'),
|
||
('acquaintance', '熟人'), ('friend', '朋友'),
|
||
('close_friend', '挚友'), ('family', '至亲'),
|
||
], string='关系层级', default='stranger', compute='_compute_status', store=True)
|
||
|
||
last_interaction = fields.Datetime(string='最近互动', default=fields.Datetime.now)
|
||
interaction_count = fields.Integer(string='互动次数', default=1)
|
||
notes = fields.Text(string='看法备注',
|
||
help='角色对对方的印象,未来可由 LLM 生成')
|
||
|
||
display_name = fields.Char(string='显示名称', compute='_compute_display_name')
|
||
|
||
_sql_constraints = [
|
||
('unique_npc_pair', 'UNIQUE(npc_id, target_npc_id)',
|
||
'同一对 NPC 只能有一条关系记录!'),
|
||
]
|
||
|
||
@api.depends('npc_id', 'target_npc_id')
|
||
def _compute_display_name(self):
|
||
for r in self:
|
||
source = r.npc_id.name or '?'
|
||
target = r.target_npc_id.name or '?'
|
||
r.display_name = f'{source} → {target}'
|
||
|
||
@api.depends('affinity')
|
||
def _compute_status(self):
|
||
for r in self:
|
||
r.status = r._calc_status(r.affinity)
|
||
|
||
def _calc_status(self, affinity):
|
||
if affinity <= -70: return 'enemy'
|
||
if affinity <= -30: return 'hostile'
|
||
if affinity <= 10: return 'stranger'
|
||
if affinity <= 30: return 'acquaintance'
|
||
if affinity <= 60: return 'friend'
|
||
if affinity <= 80: return 'close_friend'
|
||
return 'family'
|
||
|
||
def _update_status(self):
|
||
"""将当前好感度同步到关系层级。"""
|
||
for r in self:
|
||
r.status = r._calc_status(r.affinity)
|