feat: 重构任务奖励系统并增加宠物技能和皮肤奖励
All checks were successful
ci/woodpecker/push/my-first-workflow Pipeline was successful
All checks were successful
ci/woodpecker/push/my-first-workflow Pipeline was successful
将任务奖励逻辑重构到单独的文件中,增加对宠物技能和皮肤奖励的支持,优化任务完成处理流程
This commit is contained in:
@@ -43,7 +43,7 @@ func (Controller) PlayerFightBoss(req *ChallengeBossInboundInfo, p *player.Playe
|
||||
}
|
||||
|
||||
p.Fightinfo.Status = fightinfo.BattleMode.FIGHT_WITH_NPC
|
||||
p.Fightinfo.Mode = fightinfo.BattleMode.MULTI_MODE
|
||||
p.Fightinfo.Mode = resolveMapNodeFightMode(mapNode)
|
||||
|
||||
ai := player.NewAI_player(monsterInfo)
|
||||
ai.CanCapture = resolveBossCaptureRate(bossConfigs[0].IsCapture, leadMonsterID)
|
||||
@@ -76,12 +76,23 @@ func startMapBossFight(
|
||||
oppPets := ai.GetPetInfo(0)
|
||||
if mapNode != nil && mapNode.IsGroupBoss != 0 {
|
||||
if len(ourPets) > 0 && len(oppPets) > 0 {
|
||||
return fight.NewLegacyGroupFightSingleController(p, ai, ourPets, oppPets, groupBossSlotLimit, fn)
|
||||
slotLimit := groupBossSlotLimit
|
||||
if mapNode.PkFlag != 0 {
|
||||
slotLimit = 1
|
||||
}
|
||||
return fight.NewLegacyGroupFightSingleController(p, ai, ourPets, oppPets, slotLimit, fn)
|
||||
}
|
||||
}
|
||||
return fight.NewFight(p, ai, ourPets, oppPets, fn)
|
||||
}
|
||||
|
||||
func resolveMapNodeFightMode(mapNode *configmodel.MapNode) uint32 {
|
||||
if mapNode != nil && mapNode.PkFlag != 0 {
|
||||
return fightinfo.BattleMode.SINGLE_MODE
|
||||
}
|
||||
return fightinfo.BattleMode.MULTI_MODE
|
||||
}
|
||||
|
||||
// OnPlayerFightNpcMonster 战斗野怪
|
||||
func (Controller) OnPlayerFightNpcMonster(req *FightNpcMonsterInboundInfo, p *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
|
||||
if err = p.CanFight(); err != 0 {
|
||||
|
||||
@@ -77,31 +77,16 @@ func (h Controller) CompleteTask(data1 *CompleteTaskInboundInfo, c *player.Playe
|
||||
// if service.NewTaskService().IsAcceptable(data1.TaskId) == nil {
|
||||
// return nil, errorcode.ErrorCodes.ErrSystemError
|
||||
// }
|
||||
c.Info.SetTask(int(data1.TaskId), model.Completed)
|
||||
|
||||
result = &task.CompleteTaskOutboundInfo{
|
||||
TaskId: data1.TaskId,
|
||||
ItemList: make([]data.ItemInfo, 0),
|
||||
}
|
||||
|
||||
taskInfo := task.GetTaskInfo(int(data1.TaskId), int(data1.OutState))
|
||||
if taskInfo == nil {
|
||||
return nil, errorcode.ErrorCodes.ErrNeedCompleteTaskForPrize
|
||||
if _, err = c.ApplyTaskCompletion(data1.TaskId, int(data1.OutState), result); err != 0 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if taskInfo.Pet != nil {
|
||||
|
||||
c.Service.Pet.PetAdd(taskInfo.Pet, 0)
|
||||
result.CaptureTime = taskInfo.Pet.CatchTime
|
||||
result.PetTypeId = taskInfo.Pet.ID
|
||||
}
|
||||
|
||||
for _, item := range taskInfo.ItemList {
|
||||
success := c.ItemAdd(item.ItemId, item.ItemCnt)
|
||||
if success {
|
||||
result.ItemList = append(result.ItemList, item)
|
||||
}
|
||||
|
||||
if taskErr := c.Info.SetTask(int(data1.TaskId), model.Completed); taskErr != nil {
|
||||
return nil, errorcode.ErrorCodes.ErrSystemError
|
||||
}
|
||||
|
||||
return result, 0 //通过PUB/SUB回包
|
||||
|
||||
@@ -1,23 +1,11 @@
|
||||
package player
|
||||
|
||||
import (
|
||||
"blazing/logic/service/fight/info"
|
||||
"blazing/logic/service/task"
|
||||
"blazing/modules/player/model"
|
||||
|
||||
"github.com/pointernil/bitset32"
|
||||
)
|
||||
|
||||
// 辅助函数:获取任务奖励,封装逻辑便于复用和统一检查
|
||||
// 返回nil表示无奖励
|
||||
func (p *Player) getTaskGift(taskID int, ot int) *task.TaskResult {
|
||||
// 防御性检查:taskID非法时直接返回nil
|
||||
if taskID <= 0 {
|
||||
return nil
|
||||
}
|
||||
return task.GetTaskInfo(taskID, ot)
|
||||
}
|
||||
|
||||
// SptCompletedTask 完成任务(单分支)
|
||||
// 优化点:仅当奖励存在时,才完成任务并发放奖励
|
||||
func (p *Player) SptCompletedTask(taskID int, ot int) {
|
||||
@@ -29,15 +17,17 @@ func (p *Player) SptCompletedTask(taskID int, ot int) {
|
||||
return
|
||||
}
|
||||
|
||||
// 2. 核心逻辑:先检查奖励是否存在,无奖励则直接返回(不完成任务)
|
||||
gift := p.getTaskGift(taskID, ot)
|
||||
if gift == nil {
|
||||
if !p.canCompleteTaskReward(taskID, ot) {
|
||||
return
|
||||
}
|
||||
|
||||
granted, err := p.ApplyTaskCompletion(uint32(taskID), ot, nil)
|
||||
if err != 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// 3. 奖励存在时,才标记任务完成 + 发放奖励
|
||||
p.Info.SetTask(taskID, model.Completed)
|
||||
p.bossgive(taskID, ot)
|
||||
p.SendTaskCompletionBonus(uint32(taskID), granted)
|
||||
}
|
||||
|
||||
// TawerCompletedTask 完成塔类任务(多分支)
|
||||
@@ -48,10 +38,12 @@ func (p *Player) TawerCompletedTask(taskID int, ot int) {
|
||||
}
|
||||
// 处理默认分支(ot=-1):仅奖励存在时才完成主任务
|
||||
if p.Info.GetTask(taskID) != model.Completed {
|
||||
defaultGift := p.getTaskGift(taskID, -1)
|
||||
if defaultGift != nil { // 奖励存在才标记主任务完成
|
||||
p.Info.SetTask(taskID, model.Completed)
|
||||
p.bossgive(taskID, -1)
|
||||
if p.canCompleteTaskReward(taskID, -1) {
|
||||
granted, err := p.ApplyTaskCompletion(uint32(taskID), -1, nil)
|
||||
if err == 0 {
|
||||
p.Info.SetTask(taskID, model.Completed)
|
||||
p.SendTaskCompletionBonus(uint32(taskID), granted)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,53 +53,19 @@ func (p *Player) TawerCompletedTask(taskID int, ot int) {
|
||||
return
|
||||
}
|
||||
|
||||
// 核心检查:指定分支的奖励是否存在
|
||||
branchGift := p.getTaskGift(taskID, ot)
|
||||
if branchGift == nil {
|
||||
if !p.canCompleteTaskReward(taskID, ot) {
|
||||
return
|
||||
}
|
||||
|
||||
r := bitset32.From(taskData.Data)
|
||||
if !r.Test(uint(ot)) {
|
||||
r.Set(uint(ot))
|
||||
p.bossgive(taskID, ot)
|
||||
granted, rewardErr := p.ApplyTaskCompletion(uint32(taskID), ot, nil)
|
||||
if rewardErr != 0 {
|
||||
return
|
||||
}
|
||||
p.SendTaskCompletionBonus(uint32(taskID), granted)
|
||||
taskData.Data = r.Bytes()
|
||||
_ = p.Service.Task.SetTask(taskData)
|
||||
}
|
||||
}
|
||||
|
||||
// bossgive 发放任务奖励(逻辑保持不变,仅补充注释)
|
||||
func (p *Player) bossgive(taskID int, ot int) {
|
||||
gift := p.getTaskGift(taskID, ot)
|
||||
if gift == nil {
|
||||
return
|
||||
}
|
||||
|
||||
res := &info.S2C_GET_BOSS_MONSTER{
|
||||
BonusID: uint32(taskID),
|
||||
}
|
||||
|
||||
// 发放宠物奖励
|
||||
if gift.Pet != nil {
|
||||
p.Service.Pet.PetAdd(gift.Pet, 0)
|
||||
res.PetID = gift.Pet.ID
|
||||
res.CaptureTm = gift.Pet.CatchTime
|
||||
}
|
||||
|
||||
// 发放道具奖励(仅成功添加的道具才返回给前端)
|
||||
for _, item := range gift.ItemList {
|
||||
if success := p.ItemAdd(item.ItemId, item.ItemCnt); success {
|
||||
res.AddItemInfo(item)
|
||||
}
|
||||
}
|
||||
|
||||
// 发放称号奖励
|
||||
if gift.Title != 0 {
|
||||
p.GiveTitle(gift.Title)
|
||||
}
|
||||
|
||||
// 发送奖励通知给前端
|
||||
if res.HasReward() {
|
||||
p.SendPackCmd(8004, res)
|
||||
}
|
||||
}
|
||||
|
||||
193
logic/service/player/task_completion.go
Normal file
193
logic/service/player/task_completion.go
Normal file
@@ -0,0 +1,193 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
115
logic/service/player/task_reward.go
Normal file
115
logic/service/player/task_reward.go
Normal file
@@ -0,0 +1,115 @@
|
||||
package player
|
||||
|
||||
import "blazing/modules/player/model"
|
||||
|
||||
func applyTaskRewardToPetInfo(pet *model.PetInfo, trainSkillIDs, skinIDs []uint32) bool {
|
||||
if pet == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
changed := false
|
||||
|
||||
mergedSkills := mergeTaskRewardIDs(pet.ExtSKill, trainSkillIDs)
|
||||
if len(mergedSkills) != len(pet.ExtSKill) {
|
||||
pet.ExtSKill = mergedSkills
|
||||
changed = true
|
||||
}
|
||||
|
||||
mergedSkins := mergeTaskRewardIDs(pet.ExtSkin, skinIDs)
|
||||
if len(mergedSkins) != len(pet.ExtSkin) {
|
||||
pet.ExtSkin = mergedSkins
|
||||
changed = true
|
||||
}
|
||||
|
||||
if pet.SkinID == 0 {
|
||||
for _, skinID := range mergedSkins {
|
||||
if skinID == 0 {
|
||||
continue
|
||||
}
|
||||
pet.SkinID = skinID
|
||||
changed = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return changed
|
||||
}
|
||||
|
||||
func mergeTaskRewardIDs(dst []uint32, src []uint32) []uint32 {
|
||||
if len(src) == 0 {
|
||||
return dst
|
||||
}
|
||||
|
||||
seen := make(map[uint32]struct{}, len(dst)+len(src))
|
||||
result := make([]uint32, 0, len(dst)+len(src))
|
||||
|
||||
for _, id := range dst {
|
||||
if id == 0 {
|
||||
continue
|
||||
}
|
||||
if _, ok := seen[id]; ok {
|
||||
continue
|
||||
}
|
||||
seen[id] = struct{}{}
|
||||
result = append(result, id)
|
||||
}
|
||||
|
||||
for _, id := range src {
|
||||
if id == 0 {
|
||||
continue
|
||||
}
|
||||
if _, ok := seen[id]; ok {
|
||||
continue
|
||||
}
|
||||
seen[id] = struct{}{}
|
||||
result = append(result, id)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func (p *Player) GrantTaskPetRewards(targetPetID uint32, trainSkillIDs, skinIDs []uint32) bool {
|
||||
if p == nil || targetPetID == 0 || (len(trainSkillIDs) == 0 && len(skinIDs) == 0) {
|
||||
return false
|
||||
}
|
||||
|
||||
changed := false
|
||||
|
||||
for i := range p.Info.PetList {
|
||||
if p.Info.PetList[i].ID != targetPetID {
|
||||
continue
|
||||
}
|
||||
if applyTaskRewardToPetInfo(&p.Info.PetList[i], trainSkillIDs, skinIDs) {
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
|
||||
for i := range p.Info.BackupPetList {
|
||||
if p.Info.BackupPetList[i].ID != targetPetID {
|
||||
continue
|
||||
}
|
||||
if applyTaskRewardToPetInfo(&p.Info.BackupPetList[i], trainSkillIDs, skinIDs) {
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
|
||||
if p.Service == nil || p.Service.Pet == nil {
|
||||
return changed
|
||||
}
|
||||
|
||||
allPets := p.Service.Pet.PetInfo(0)
|
||||
for i := range allPets {
|
||||
if allPets[i].Data.ID != targetPetID {
|
||||
continue
|
||||
}
|
||||
if !applyTaskRewardToPetInfo(&allPets[i].Data, trainSkillIDs, skinIDs) {
|
||||
continue
|
||||
}
|
||||
allPets[i].Data.CatchTime = allPets[i].CatchTime
|
||||
if p.Service.Pet.Update(allPets[i].Data) {
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
|
||||
return changed
|
||||
}
|
||||
@@ -10,8 +10,11 @@ import (
|
||||
type TaskResult struct {
|
||||
Pet *model.PetInfo `json:"petTypeId" description:"发放的精灵ID"` // 发放的精灵ID,
|
||||
|
||||
ItemList []data.ItemInfo `json:"itemList" description:"发放物品的数组"` // 发放物品的数组,
|
||||
Title uint32 `json:"title" description:"称号奖励"`
|
||||
ItemList []data.ItemInfo `json:"itemList" description:"发放物品的数组"` // 发放物品的数组,
|
||||
Title uint32 `json:"title" description:"称号奖励"`
|
||||
RewardPetID uint32 `json:"rewardPetId" description:"宠物相关奖励目标精灵ID"`
|
||||
TrainSkillIDs []uint32 `json:"trainSkillIds" description:"特训技能奖励"`
|
||||
SkinIDs []uint32 `json:"skinIds" description:"皮肤奖励"`
|
||||
}
|
||||
|
||||
func GetTaskInfo(id, ot int) *TaskResult {
|
||||
@@ -26,6 +29,12 @@ func GetTaskInfo(id, ot int) *TaskResult {
|
||||
if pet != nil {
|
||||
ret.Pet = model.GenPetInfo(int(pet.MonID), int(pet.DV), int(pet.Nature), int(pet.Effect), int(pet.Lv), nil, 0)
|
||||
}
|
||||
ret.RewardPetID = r.RewardPetID
|
||||
ret.TrainSkillIDs = append(ret.TrainSkillIDs, r.TrainSkillIDs...)
|
||||
ret.SkinIDs = append(ret.SkinIDs, r.SkinIDs...)
|
||||
if ret.Pet != nil {
|
||||
applyTaskRewardPetExtras(ret.Pet, ret.TrainSkillIDs, ret.SkinIDs)
|
||||
}
|
||||
|
||||
for _, itemID := range r.ItemRewardIds {
|
||||
iteminfo := service.NewItemService().GetItemCount(itemID)
|
||||
@@ -39,3 +48,59 @@ func GetTaskInfo(id, ot int) *TaskResult {
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func applyTaskRewardPetExtras(pet *model.PetInfo, trainSkillIDs, skinIDs []uint32) {
|
||||
if pet == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if merged := mergeTaskRewardIDs(pet.ExtSKill, trainSkillIDs); len(merged) != len(pet.ExtSKill) {
|
||||
pet.ExtSKill = merged
|
||||
}
|
||||
|
||||
mergedSkins := mergeTaskRewardIDs(pet.ExtSkin, skinIDs)
|
||||
if len(mergedSkins) != len(pet.ExtSkin) {
|
||||
pet.ExtSkin = mergedSkins
|
||||
}
|
||||
if pet.SkinID == 0 {
|
||||
for _, skinID := range mergedSkins {
|
||||
if skinID != 0 {
|
||||
pet.SkinID = skinID
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func mergeTaskRewardIDs(dst []uint32, src []uint32) []uint32 {
|
||||
if len(src) == 0 {
|
||||
return dst
|
||||
}
|
||||
|
||||
seen := make(map[uint32]struct{}, len(dst)+len(src))
|
||||
result := make([]uint32, 0, len(dst)+len(src))
|
||||
|
||||
for _, id := range dst {
|
||||
if id == 0 {
|
||||
continue
|
||||
}
|
||||
if _, ok := seen[id]; ok {
|
||||
continue
|
||||
}
|
||||
seen[id] = struct{}{}
|
||||
result = append(result, id)
|
||||
}
|
||||
|
||||
for _, id := range src {
|
||||
if id == 0 {
|
||||
continue
|
||||
}
|
||||
if _, ok := seen[id]; ok {
|
||||
continue
|
||||
}
|
||||
seen[id] = struct{}{}
|
||||
result = append(result, id)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user