All checks were successful
ci/woodpecker/push/my-first-workflow Pipeline was successful
将任务奖励逻辑重构到单独的文件中,增加对宠物技能和皮肤奖励的支持,优化任务完成处理流程
194 lines
4.7 KiB
Go
194 lines
4.7 KiB
Go
package player
|
|
|
|
import (
|
|
"blazing/common/data"
|
|
"blazing/common/socket/errorcode"
|
|
fightinfo "blazing/logic/service/fight/info"
|
|
tasklogic "blazing/logic/service/task"
|
|
configmodel "blazing/modules/config/model"
|
|
configservice "blazing/modules/config/service"
|
|
playermodel "blazing/modules/player/model"
|
|
"sync"
|
|
)
|
|
|
|
type TaskCompletionContext struct {
|
|
TaskID uint32
|
|
OutState int
|
|
Config *configmodel.TaskConfig
|
|
Reward *tasklogic.TaskResult
|
|
Result *tasklogic.CompleteTaskOutboundInfo
|
|
|
|
SkipDefaultReward bool
|
|
}
|
|
|
|
type TaskCompletionHandler func(*Player, *TaskCompletionContext) errorcode.ErrorCode
|
|
|
|
var taskCompletionRegistry = struct {
|
|
sync.RWMutex
|
|
handlers map[uint32]TaskCompletionHandler
|
|
}{
|
|
handlers: make(map[uint32]TaskCompletionHandler),
|
|
}
|
|
|
|
type taskRewardGrantResult struct {
|
|
Pet *playermodel.PetInfo
|
|
Items []data.ItemInfo
|
|
}
|
|
|
|
func RegisterTaskCompletionHandler(taskID uint32, handler TaskCompletionHandler) {
|
|
if taskID == 0 || handler == nil {
|
|
return
|
|
}
|
|
|
|
taskCompletionRegistry.Lock()
|
|
taskCompletionRegistry.handlers[taskID] = handler
|
|
taskCompletionRegistry.Unlock()
|
|
}
|
|
|
|
func RegisterTaskTalkLimitHandler(taskID, talkID, needCount uint32) {
|
|
RegisterTaskCompletionHandler(taskID, func(p *Player, _ *TaskCompletionContext) errorcode.ErrorCode {
|
|
if p == nil || p.Service == nil || p.Service.Talk == nil {
|
|
return errorcode.ErrorCodes.ErrSystemError
|
|
}
|
|
|
|
currentCount, ok := p.Service.Talk.Progress(int(talkID))
|
|
if !ok || currentCount < needCount {
|
|
return errorcode.ErrorCodes.ErrNeedCompleteTaskForPrize
|
|
}
|
|
|
|
return 0
|
|
})
|
|
}
|
|
|
|
func (p *Player) getTaskGift(taskID int, outState int) *tasklogic.TaskResult {
|
|
if taskID <= 0 {
|
|
return nil
|
|
}
|
|
return tasklogic.GetTaskInfo(taskID, outState)
|
|
}
|
|
|
|
func hasTaskCompletionHandler(taskID uint32) bool {
|
|
taskCompletionRegistry.RLock()
|
|
_, ok := taskCompletionRegistry.handlers[taskID]
|
|
taskCompletionRegistry.RUnlock()
|
|
return ok
|
|
}
|
|
|
|
func getTaskCompletionHandler(taskID uint32) TaskCompletionHandler {
|
|
taskCompletionRegistry.RLock()
|
|
handler := taskCompletionRegistry.handlers[taskID]
|
|
taskCompletionRegistry.RUnlock()
|
|
return handler
|
|
}
|
|
|
|
func (p *Player) canCompleteTaskReward(taskID, outState int) bool {
|
|
if taskID <= 0 {
|
|
return false
|
|
}
|
|
return p.getTaskGift(taskID, outState) != nil || hasTaskCompletionHandler(uint32(taskID))
|
|
}
|
|
|
|
func (p *Player) ApplyTaskCompletion(taskID uint32, outState int, result *tasklogic.CompleteTaskOutboundInfo) (*taskRewardGrantResult, errorcode.ErrorCode) {
|
|
if p == nil {
|
|
return nil, errorcode.ErrorCodes.ErrSystemError
|
|
}
|
|
|
|
ctx := &TaskCompletionContext{
|
|
TaskID: taskID,
|
|
OutState: outState,
|
|
Config: configservice.NewTaskService().Get(int(taskID), outState),
|
|
Reward: tasklogic.GetTaskInfo(int(taskID), outState),
|
|
Result: result,
|
|
}
|
|
|
|
if ctx.Reward == nil && !hasTaskCompletionHandler(taskID) {
|
|
return nil, errorcode.ErrorCodes.ErrNeedCompleteTaskForPrize
|
|
}
|
|
|
|
if handler := getTaskCompletionHandler(taskID); handler != nil {
|
|
if err := handler(p, ctx); err != 0 {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
if ctx.SkipDefaultReward {
|
|
if result != nil {
|
|
result.ItemLen = uint32(len(result.ItemList))
|
|
}
|
|
return &taskRewardGrantResult{Items: make([]data.ItemInfo, 0)}, 0
|
|
}
|
|
|
|
if ctx.Reward == nil {
|
|
return nil, errorcode.ErrorCodes.ErrNeedCompleteTaskForPrize
|
|
}
|
|
|
|
return p.grantTaskReward(ctx.Reward, result), 0
|
|
}
|
|
|
|
func (p *Player) grantTaskReward(reward *tasklogic.TaskResult, result *tasklogic.CompleteTaskOutboundInfo) *taskRewardGrantResult {
|
|
granted := &taskRewardGrantResult{
|
|
Items: make([]data.ItemInfo, 0),
|
|
}
|
|
|
|
if reward == nil {
|
|
if result != nil {
|
|
result.ItemLen = uint32(len(result.ItemList))
|
|
}
|
|
return granted
|
|
}
|
|
|
|
if reward.Pet != nil {
|
|
p.Service.Pet.PetAdd(reward.Pet, 0)
|
|
granted.Pet = reward.Pet
|
|
if result != nil {
|
|
result.CaptureTime = reward.Pet.CatchTime
|
|
result.PetTypeId = reward.Pet.ID
|
|
}
|
|
}
|
|
|
|
for _, item := range reward.ItemList {
|
|
if !p.ItemAdd(item.ItemId, item.ItemCnt) {
|
|
continue
|
|
}
|
|
granted.Items = append(granted.Items, item)
|
|
if result != nil {
|
|
result.ItemList = append(result.ItemList, item)
|
|
}
|
|
}
|
|
|
|
if reward.Title != 0 {
|
|
p.GiveTitle(reward.Title)
|
|
}
|
|
if reward.RewardPetID != 0 {
|
|
p.GrantTaskPetRewards(reward.RewardPetID, reward.TrainSkillIDs, reward.SkinIDs)
|
|
}
|
|
|
|
if result != nil {
|
|
result.ItemLen = uint32(len(result.ItemList))
|
|
}
|
|
return granted
|
|
}
|
|
|
|
func (p *Player) SendTaskCompletionBonus(bonusID uint32, granted *taskRewardGrantResult) {
|
|
if p == nil {
|
|
return
|
|
}
|
|
|
|
res := &fightinfo.S2C_GET_BOSS_MONSTER{
|
|
BonusID: bonusID,
|
|
}
|
|
if granted != nil && granted.Pet != nil {
|
|
res.PetID = granted.Pet.ID
|
|
res.CaptureTm = granted.Pet.CatchTime
|
|
}
|
|
if granted != nil {
|
|
for _, item := range granted.Items {
|
|
res.AddItemInfo(item)
|
|
}
|
|
}
|
|
|
|
if res.HasReward() {
|
|
p.SendPackCmd(8004, res)
|
|
}
|
|
}
|