game/addons/game_ai_npc/models/npc_relationship.py

65 lines
2.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- 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)