diff --git a/logic/service/fight/effect/register.go b/logic/service/fight/effect/register.go index a70471aaa..4a480b978 100644 --- a/logic/service/fight/effect/register.go +++ b/logic/service/fight/effect/register.go @@ -5,3 +5,7 @@ import "blazing/logic/service/fight/input" func initskill(id int, e input.Effect) { input.InitEffect(input.EffectType.Skill, id, e) } + +func initskillFactory(id int, factory func() input.Effect) { + input.InitEffectFactory(input.EffectType.Skill, id, factory) +} diff --git a/logic/service/fight/effect/selfkill.go b/logic/service/fight/effect/selfkill.go index 5f29ac113..061f9df6a 100644 --- a/logic/service/fight/effect/selfkill.go +++ b/logic/service/fight/effect/selfkill.go @@ -158,7 +158,10 @@ func registerSelfDamageSkillHitEffects() { } for effectID, handler := range handlers { - initskill(effectID, newSkillHitRegistrarEffect(handler)) + currentHandler := handler + initskillFactory(effectID, func() input.Effect { + return newSkillHitRegistrarEffect(currentHandler) + }) } } @@ -223,7 +226,10 @@ func registerSelfDamageOnSkillEffects() { } for effectID, handler := range handlers { - initskill(effectID, newOnSkillRegistrarEffect(handler)) + currentHandler := handler + initskillFactory(effectID, func() input.Effect { + return newOnSkillRegistrarEffect(currentHandler) + }) } } @@ -305,7 +311,10 @@ func registerSelfDamageSkillUseEffects() { } for effectID, handler := range handlers { - initskill(effectID, newSkillUseRegistrarEffect(handler)) + currentHandler := handler + initskillFactory(effectID, func() input.Effect { + return newSkillUseRegistrarEffect(currentHandler) + }) } } @@ -339,7 +348,10 @@ func registerSelfDamageComparePreOnSkillEffects() { } for effectID, effect := range effects { - initskill(effectID, effect) + currentEffect := effect + initskillFactory(effectID, func() input.Effect { + return newComparePreOnSkillRegistrarEffect(currentEffect.comparePreHandler, currentEffect.onSkillHandler) + }) } } diff --git a/logic/service/fight/fightc.go b/logic/service/fight/fightc.go index e440a6c54..85d26dc08 100644 --- a/logic/service/fight/fightc.go +++ b/logic/service/fight/fightc.go @@ -198,6 +198,18 @@ func (f *FightC) buildNoteUseSkillOutboundInfo() info.NoteUseSkillOutboundInfo { return result } +func (f *FightC) roundOpponentInput(attacker *input.Input) *input.Input { + if attacker == nil { + return nil + } + for _, opponent := range attacker.OpponentSlots() { + if opponent != nil { + return opponent + } + } + return nil +} + // enterturn 处理战斗回合逻辑 // 回合有先手方和后手方,同时有攻击方和被攻击方 func (f *FightC) enterturn(firstAttack, secondAttack *action.SelectSkillAction) { @@ -245,9 +257,11 @@ func (f *FightC) enterturn(firstAttack, secondAttack *action.SelectSkillAction) f.First, _ = f.getSkillParticipants(firstAttack) f.Second, _ = f.getSkillParticipants(secondAttack) case firstAttack != nil: - f.First, f.Second = f.getSkillParticipants(firstAttack) + f.First, _ = f.getSkillParticipants(firstAttack) + f.Second = f.roundOpponentInput(f.First) case secondAttack != nil: - f.First, f.Second = f.getSkillParticipants(secondAttack) + f.First, _ = f.getSkillParticipants(secondAttack) + f.Second = f.roundOpponentInput(f.First) } if f.First == nil { f.First = f.primaryOur() @@ -332,7 +346,6 @@ func (f *FightC) enterturn(firstAttack, secondAttack *action.SelectSkillAction) } //先手权不一定出手 - } else { f.setActionAttackValue(currentAction) diff --git a/logic/service/fight/input/effect.go b/logic/service/fight/input/effect.go index 483abea97..df86927c6 100644 --- a/logic/service/fight/input/effect.go +++ b/logic/service/fight/input/effect.go @@ -32,6 +32,7 @@ var EffectType = enum.New[struct { }]() var NodeM = make(map[int64]Effect, 0) +var NodeFactoryM = make(map[int64]func() Effect, 0) func InitEffect(etype EnumEffectType, id int, t Effect) { pr := EffectIDCombiner{} @@ -41,6 +42,13 @@ func InitEffect(etype EnumEffectType, id int, t Effect) { NodeM[pr.EffectID()] = t } + +func InitEffectFactory(etype EnumEffectType, id int, factory func() Effect) { + pr := EffectIDCombiner{} + pr.Combine(etype, 0, gconv.Uint16(id)) + + NodeFactoryM[pr.EffectID()] = factory +} func GeteffectIDs(etype EnumEffectType) []uint32 { var ret []uint32 = make([]uint32, 0) @@ -60,6 +68,19 @@ func geteffect[T int | byte | uint16](etype EnumEffectType, id T) Effect { pr := EffectIDCombiner{} pr.Combine(etype, 0, gconv.Uint16(id)) + if factory, ok := NodeFactoryM[pr.EffectID()]; ok { + eff := factory() + if eff == nil { + return nil + } + eff.ID(pr) + if etype == EffectType.Status { + eff.CanStack(true) + eff.Duration(grand.N(1, 2)) + } + return eff + } + //todo 获取前GetEffect ret, ok := NodeM[pr.EffectID()] if ok { diff --git a/logic/service/player/task_completion.go b/logic/service/player/task_completion.go index 743da6192..6919bc802 100644 --- a/logic/service/player/task_completion.go +++ b/logic/service/player/task_completion.go @@ -11,6 +11,12 @@ import ( "sync" ) +// TaskCompletionContext 封装任务完成时的上下文。 +// 这里除了保留任务配置和默认奖励,也给自定义任务完成逻辑暴露了返回包与开关位, +// 用来兼容“固定发物品/精灵”之外的奖励场景。 +// 这套扩展最初是为任务发放特训技能、皮肤而补上的: +// 特训奖励不能完全按静态表直发,需要结合额外条件做特判, +// 例如通过挖矿/对话进度限制特训次数,满足条件后再允许完成任务。 type TaskCompletionContext struct { TaskID uint32 OutState int @@ -21,8 +27,12 @@ type TaskCompletionContext struct { SkipDefaultReward bool } +// TaskCompletionHandler 定义任务完成前的自定义处理器。 +// 处理器可用于补充校验、写入额外奖励,或在任务完全走自定义发奖时跳过默认奖励流程。 type TaskCompletionHandler func(*Player, *TaskCompletionContext) errorcode.ErrorCode +// taskCompletionRegistry 按任务 ID 维护自定义完成处理器。 +// 默认任务仍然走 task 配表里的固定奖励;只有存在特判需求的任务才在这里注册。 var taskCompletionRegistry = struct { sync.RWMutex handlers map[uint32]TaskCompletionHandler @@ -30,11 +40,16 @@ var taskCompletionRegistry = struct { handlers: make(map[uint32]TaskCompletionHandler), } +// taskRewardGrantResult 汇总本次任务实际发放的奖励, +// 便于后续统一推送给前端展示。 type taskRewardGrantResult struct { Pet *playermodel.PetInfo Items []data.ItemInfo } +// RegisterTaskCompletionHandler 注册任务完成时的自定义处理器。 +// 用于覆盖“任务奖励固定为物品和精灵”的旧模型,让指定任务在完成前后插入额外逻辑。 +// 当前这套机制主要服务于特训技能、皮肤等特殊奖励,以及需要额外次数/进度校验的任务。 func RegisterTaskCompletionHandler(taskID uint32, handler TaskCompletionHandler) { if taskID == 0 || handler == nil { return @@ -45,6 +60,9 @@ func RegisterTaskCompletionHandler(taskID uint32, handler TaskCompletionHandler) taskCompletionRegistry.Unlock() } +// RegisterTaskTalkLimitHandler 注册一个基于挖矿/采集对话进度的完成限制。 +// 历史上特训任务需要通过挖矿次数限制可领取次数,因此复用了 Talk 进度作为准入条件。 +// 当指定 talkID 的进度不足 needCount 时,任务不能完成也不能领奖。 func RegisterTaskTalkLimitHandler(taskID, talkID, needCount uint32) { RegisterTaskCompletionHandler(taskID, func(p *Player, _ *TaskCompletionContext) errorcode.ErrorCode { if p == nil || p.Service == nil || p.Service.Talk == nil { @@ -67,6 +85,7 @@ func (p *Player) getTaskGift(taskID int, outState int) *tasklogic.TaskResult { return tasklogic.GetTaskInfo(taskID, outState) } +// hasTaskCompletionHandler 判断任务是否存在自定义完成处理器。 func hasTaskCompletionHandler(taskID uint32) bool { taskCompletionRegistry.RLock() _, ok := taskCompletionRegistry.handlers[taskID] @@ -74,6 +93,7 @@ func hasTaskCompletionHandler(taskID uint32) bool { return ok } +// getTaskCompletionHandler 获取任务的自定义完成处理器。 func getTaskCompletionHandler(taskID uint32) TaskCompletionHandler { taskCompletionRegistry.RLock() handler := taskCompletionRegistry.handlers[taskID] @@ -81,6 +101,8 @@ func getTaskCompletionHandler(taskID uint32) TaskCompletionHandler { return handler } +// canCompleteTaskReward 判断任务是否具备可执行的奖励逻辑。 +// 只要存在默认奖励,或已注册自定义处理器,就允许进入完成流程。 func (p *Player) canCompleteTaskReward(taskID, outState int) bool { if taskID <= 0 { return false @@ -88,6 +110,10 @@ func (p *Player) canCompleteTaskReward(taskID, outState int) bool { return p.getTaskGift(taskID, outState) != nil || hasTaskCompletionHandler(uint32(taskID)) } +// ApplyTaskCompletion 执行任务完成时的奖励发放入口。 +// 流程分两层: +// 1. 先执行自定义处理器,处理特训/皮肤/额外次数校验等特殊逻辑; +// 2. 若未要求跳过默认奖励,再回落到原有的物品/精灵发奖逻辑。 func (p *Player) ApplyTaskCompletion(taskID uint32, outState int, result *tasklogic.CompleteTaskOutboundInfo) (*taskRewardGrantResult, errorcode.ErrorCode) { if p == nil { return nil, errorcode.ErrorCodes.ErrSystemError @@ -125,6 +151,8 @@ func (p *Player) ApplyTaskCompletion(taskID uint32, outState int, result *tasklo return p.grantTaskReward(ctx.Reward, result), 0 } +// grantTaskReward 发放 task 配表里的默认奖励。 +// 这里仍负责原有的固定奖励模型:物品、精灵、称号,以及配置里声明的任务宠奖励。 func (p *Player) grantTaskReward(reward *tasklogic.TaskResult, result *tasklogic.CompleteTaskOutboundInfo) *taskRewardGrantResult { granted := &taskRewardGrantResult{ Items: make([]data.ItemInfo, 0), @@ -169,6 +197,7 @@ func (p *Player) grantTaskReward(reward *tasklogic.TaskResult, result *tasklogic return granted } +// SendTaskCompletionBonus 将任务奖励转换为旧的奖励展示协议并推送给前端。 func (p *Player) SendTaskCompletionBonus(bonusID uint32, granted *taskRewardGrantResult) { if p == nil { return diff --git a/modules/config/model/server_list.go b/modules/config/model/server_list.go index 69c93ddff..5972464ea 100644 --- a/modules/config/model/server_list.go +++ b/modules/config/model/server_list.go @@ -12,7 +12,7 @@ const TableNameServerList = "server_list" type ServerList struct { *cool.Model coolconfig.ServerList - ServerShow *ServerShow `orm:"with:server_id=online_id" gorm:"-" json:"server_show,omitempty"` + ServerShow *ServerShow `orm:"with:server_id=online_id" gorm:"-" json:"servershow,omitempty"` // isonline IsOnline uint8 `gorm:"column:isonline;default:0;comment:'是否在线'" json:"isonline"` }