game/addons/game_base/models/game_achievement.py
2026-07-28 19:06:32 +08:00

86 lines
3.4 KiB
Python

# -*- coding: utf-8 -*-
from odoo import api, fields, models
class GameAchievementTemplate(models.Model):
"""全局成就模板:后台定义,所有玩家共用同一套成就定义。"""
_name = 'game.achievement.template'
_description = '成就模板'
_order = 'sequence, id'
_rec_name = 'name'
TIER = [
('bronze', ''),
('silver', ''),
('gold', ''),
('platinum', '铂金'),
('legend', '传奇'),
]
sequence = fields.Integer('排序', default=10, index=True)
code = fields.Char('标识', index=True,
help='唯一标识,用于代码引用,如 first_land')
name = fields.Char('成就名称', required=True, translate=True)
icon = fields.Char('图标', help='emoji 或符号,如 star / sprout / lock')
tier = fields.Selection(TIER, '品质', default='bronze', index=True)
desc = fields.Text('描述', help='解锁条件/说明')
target = fields.Integer('目标值', default=1,
help='解锁所需进度值,如 10 表示需完成 10 次')
points = fields.Integer('成就点数', default=10)
active = fields.Boolean('启用', default=True)
player_achievement_ids = fields.One2many(
'game.player.achievement', 'template_id', '玩家解锁记录')
class GamePlayerAchievement(models.Model):
"""玩家已解锁/进行中的成就,关联到 hr.employee。"""
_name = 'game.player.achievement'
_description = '玩家成就'
_order = 'template_id, id'
_rec_name = 'name'
template_id = fields.Many2one(
'game.achievement.template', '成就模板',
required=True, ondelete='cascade', index=True)
employee_id = fields.Many2one(
'hr.employee', '所属玩家',
required=True, ondelete='cascade', index=True)
name = fields.Char('名称', related='template_id.name', store=True)
icon = fields.Char('图标', related='template_id.icon')
tier = fields.Selection(
related='template_id.tier', store=True)
desc = fields.Text('描述', related='template_id.desc')
points = fields.Integer('点数', related='template_id.points')
progress = fields.Integer('进度', default=0)
target = fields.Integer('目标值', related='template_id.target')
unlocked = fields.Boolean('已解锁', default=False)
unlock_date = fields.Datetime('解锁时间')
@api.model
def _update_progress(self, employee_id, template_key, progress):
"""更新某玩家某成就的进度,达标自动解锁。"""
tmpl = self.env['game.achievement.template'].search(
[('id', '=', template_key)], limit=1)
if not tmpl:
return False
rec = self.search([
('employee_id', '=', employee_id),
('template_id', '=', tmpl.id),
], limit=1)
if not rec:
rec = self.create({
'employee_id': employee_id,
'template_id': tmpl.id,
'progress': min(progress, tmpl.target),
'unlocked': progress >= tmpl.target,
'unlock_date': fields.Datetime.now() if progress >= tmpl.target else False,
})
elif not rec.unlocked:
rec.write({
'progress': min(progress, tmpl.target),
'unlocked': progress >= tmpl.target,
})
if rec.unlocked:
rec.unlock_date = fields.Datetime.now()
return True