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.Status = fightinfo.BattleMode.FIGHT_WITH_NPC
|
||||||
p.Fightinfo.Mode = fightinfo.BattleMode.MULTI_MODE
|
p.Fightinfo.Mode = resolveMapNodeFightMode(mapNode)
|
||||||
|
|
||||||
ai := player.NewAI_player(monsterInfo)
|
ai := player.NewAI_player(monsterInfo)
|
||||||
ai.CanCapture = resolveBossCaptureRate(bossConfigs[0].IsCapture, leadMonsterID)
|
ai.CanCapture = resolveBossCaptureRate(bossConfigs[0].IsCapture, leadMonsterID)
|
||||||
@@ -76,12 +76,23 @@ func startMapBossFight(
|
|||||||
oppPets := ai.GetPetInfo(0)
|
oppPets := ai.GetPetInfo(0)
|
||||||
if mapNode != nil && mapNode.IsGroupBoss != 0 {
|
if mapNode != nil && mapNode.IsGroupBoss != 0 {
|
||||||
if len(ourPets) > 0 && len(oppPets) > 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)
|
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 战斗野怪
|
// OnPlayerFightNpcMonster 战斗野怪
|
||||||
func (Controller) OnPlayerFightNpcMonster(req *FightNpcMonsterInboundInfo, p *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
|
func (Controller) OnPlayerFightNpcMonster(req *FightNpcMonsterInboundInfo, p *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
|
||||||
if err = p.CanFight(); err != 0 {
|
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 {
|
// if service.NewTaskService().IsAcceptable(data1.TaskId) == nil {
|
||||||
// return nil, errorcode.ErrorCodes.ErrSystemError
|
// return nil, errorcode.ErrorCodes.ErrSystemError
|
||||||
// }
|
// }
|
||||||
c.Info.SetTask(int(data1.TaskId), model.Completed)
|
|
||||||
|
|
||||||
result = &task.CompleteTaskOutboundInfo{
|
result = &task.CompleteTaskOutboundInfo{
|
||||||
TaskId: data1.TaskId,
|
TaskId: data1.TaskId,
|
||||||
ItemList: make([]data.ItemInfo, 0),
|
ItemList: make([]data.ItemInfo, 0),
|
||||||
}
|
}
|
||||||
|
|
||||||
taskInfo := task.GetTaskInfo(int(data1.TaskId), int(data1.OutState))
|
if _, err = c.ApplyTaskCompletion(data1.TaskId, int(data1.OutState), result); err != 0 {
|
||||||
if taskInfo == nil {
|
return nil, err
|
||||||
return nil, errorcode.ErrorCodes.ErrNeedCompleteTaskForPrize
|
|
||||||
}
|
}
|
||||||
|
if taskErr := c.Info.SetTask(int(data1.TaskId), model.Completed); taskErr != nil {
|
||||||
if taskInfo.Pet != nil {
|
return nil, errorcode.ErrorCodes.ErrSystemError
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, 0 //通过PUB/SUB回包
|
return result, 0 //通过PUB/SUB回包
|
||||||
|
|||||||
@@ -1,23 +1,11 @@
|
|||||||
package player
|
package player
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"blazing/logic/service/fight/info"
|
|
||||||
"blazing/logic/service/task"
|
|
||||||
"blazing/modules/player/model"
|
"blazing/modules/player/model"
|
||||||
|
|
||||||
"github.com/pointernil/bitset32"
|
"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 完成任务(单分支)
|
// SptCompletedTask 完成任务(单分支)
|
||||||
// 优化点:仅当奖励存在时,才完成任务并发放奖励
|
// 优化点:仅当奖励存在时,才完成任务并发放奖励
|
||||||
func (p *Player) SptCompletedTask(taskID int, ot int) {
|
func (p *Player) SptCompletedTask(taskID int, ot int) {
|
||||||
@@ -29,15 +17,17 @@ func (p *Player) SptCompletedTask(taskID int, ot int) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 核心逻辑:先检查奖励是否存在,无奖励则直接返回(不完成任务)
|
if !p.canCompleteTaskReward(taskID, ot) {
|
||||||
gift := p.getTaskGift(taskID, ot)
|
return
|
||||||
if gift == nil {
|
}
|
||||||
|
|
||||||
|
granted, err := p.ApplyTaskCompletion(uint32(taskID), ot, nil)
|
||||||
|
if err != 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 奖励存在时,才标记任务完成 + 发放奖励
|
|
||||||
p.Info.SetTask(taskID, model.Completed)
|
p.Info.SetTask(taskID, model.Completed)
|
||||||
p.bossgive(taskID, ot)
|
p.SendTaskCompletionBonus(uint32(taskID), granted)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TawerCompletedTask 完成塔类任务(多分支)
|
// TawerCompletedTask 完成塔类任务(多分支)
|
||||||
@@ -48,10 +38,12 @@ func (p *Player) TawerCompletedTask(taskID int, ot int) {
|
|||||||
}
|
}
|
||||||
// 处理默认分支(ot=-1):仅奖励存在时才完成主任务
|
// 处理默认分支(ot=-1):仅奖励存在时才完成主任务
|
||||||
if p.Info.GetTask(taskID) != model.Completed {
|
if p.Info.GetTask(taskID) != model.Completed {
|
||||||
defaultGift := p.getTaskGift(taskID, -1)
|
if p.canCompleteTaskReward(taskID, -1) {
|
||||||
if defaultGift != nil { // 奖励存在才标记主任务完成
|
granted, err := p.ApplyTaskCompletion(uint32(taskID), -1, nil)
|
||||||
p.Info.SetTask(taskID, model.Completed)
|
if err == 0 {
|
||||||
p.bossgive(taskID, -1)
|
p.Info.SetTask(taskID, model.Completed)
|
||||||
|
p.SendTaskCompletionBonus(uint32(taskID), granted)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,53 +53,19 @@ func (p *Player) TawerCompletedTask(taskID int, ot int) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 核心检查:指定分支的奖励是否存在
|
if !p.canCompleteTaskReward(taskID, ot) {
|
||||||
branchGift := p.getTaskGift(taskID, ot)
|
|
||||||
if branchGift == nil {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
r := bitset32.From(taskData.Data)
|
r := bitset32.From(taskData.Data)
|
||||||
if !r.Test(uint(ot)) {
|
if !r.Test(uint(ot)) {
|
||||||
r.Set(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()
|
taskData.Data = r.Bytes()
|
||||||
_ = p.Service.Task.SetTask(taskData)
|
_ = 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 {
|
type TaskResult struct {
|
||||||
Pet *model.PetInfo `json:"petTypeId" description:"发放的精灵ID"` // 发放的精灵ID,
|
Pet *model.PetInfo `json:"petTypeId" description:"发放的精灵ID"` // 发放的精灵ID,
|
||||||
|
|
||||||
ItemList []data.ItemInfo `json:"itemList" description:"发放物品的数组"` // 发放物品的数组,
|
ItemList []data.ItemInfo `json:"itemList" description:"发放物品的数组"` // 发放物品的数组,
|
||||||
Title uint32 `json:"title" 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 {
|
func GetTaskInfo(id, ot int) *TaskResult {
|
||||||
@@ -26,6 +29,12 @@ func GetTaskInfo(id, ot int) *TaskResult {
|
|||||||
if pet != nil {
|
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.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 {
|
for _, itemID := range r.ItemRewardIds {
|
||||||
iteminfo := service.NewItemService().GetItemCount(itemID)
|
iteminfo := service.NewItemService().GetItemCount(itemID)
|
||||||
@@ -39,3 +48,59 @@ func GetTaskInfo(id, ot int) *TaskResult {
|
|||||||
|
|
||||||
return ret
|
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
|
||||||
|
}
|
||||||
|
|||||||
@@ -71,6 +71,10 @@ func roundFloat32(val float32, decimals int) float32 {
|
|||||||
return float32(math.Round(float64(val*shift))) / shift
|
return float32(math.Round(float64(val*shift))) / shift
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func randomFloat32Range(r *rand.Rand, min, max float32) float32 {
|
||||||
|
return min + float32(r.Float64())*(max-min)
|
||||||
|
}
|
||||||
|
|
||||||
// 预处理矩阵:自动修正越界参数,确保合规
|
// 预处理矩阵:自动修正越界参数,确保合规
|
||||||
func ProcessOffspringMatrix(mat [4][5]float32) [4][5]float32 {
|
func ProcessOffspringMatrix(mat [4][5]float32) [4][5]float32 {
|
||||||
var processedMat [4][5]float32
|
var processedMat [4][5]float32
|
||||||
@@ -118,71 +122,62 @@ func calculateMatrixHash(mm MonsterMatrix) string {
|
|||||||
return hex.EncodeToString(h.Sum(nil))
|
return hex.EncodeToString(h.Sum(nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenerateRandomParentMatrix 调整随机参数范围,解决暗色问题,贴合你的示例
|
// GenerateRandomParentMatrix 生成色域更大的父矩阵,同时抬高黑场避免整只精灵发黑
|
||||||
func GenerateRandomParentMatrix() MonsterMatrix {
|
func GenerateRandomParentMatrix() MonsterMatrix {
|
||||||
// 1. 保留高熵种子逻辑(确保唯一性,不变)
|
|
||||||
salt := "player-matrix-random-seed"
|
salt := "player-matrix-random-seed"
|
||||||
now := time.Now().UnixNano()
|
now := time.Now().UnixNano()
|
||||||
randomNum := rand.Int63()
|
randomNum := rand.Int63()
|
||||||
seed := now ^ randomNum ^ int64(hashString(salt))
|
seed := now ^ randomNum ^ int64(hashString(salt))
|
||||||
r := rand.New(rand.NewSource(seed))
|
r := rand.New(rand.NewSource(seed))
|
||||||
|
|
||||||
// 2. 调整随机参数范围(贴合你的示例,解决暗色问题)
|
matrix := newIdentityMatrix()
|
||||||
// 对比你的示例:亮度大多在[-30,30],对比度[0.7,1.7],饱和度[0.4,1.4],偏移[-10,10]
|
dominant := r.Intn(3)
|
||||||
params := struct {
|
accent := (dominant + 1 + r.Intn(2)) % 3
|
||||||
brightness float32 // 从[-125,125]调整为[-30,60],避免过低亮度
|
baseLift := randomFloat32Range(r, 10, 24)
|
||||||
contrast float32 // 从[0.4,2.2]调整为[0.7,1.7],贴合你的示例
|
|
||||||
saturation float32 // 从[0.1,2.0]调整为[0.4,1.4],避免低饱和度灰暗
|
for row := 0; row < 3; row++ {
|
||||||
hueRotate float32 // 从[-180,180]调整为[-50,50],减少极端色相导致的暗沉
|
for col := 0; col < 3; col++ {
|
||||||
rOffset float32 // 从[-50,50]调整为[-10,10],避免亮度偏移过大
|
value := randomFloat32Range(r, -0.22, 0.22)
|
||||||
gOffset float32 // 同上
|
if row == col {
|
||||||
bOffset float32 // 同上
|
value = randomFloat32Range(r, 0.8, 1.45)
|
||||||
}{
|
}
|
||||||
brightness: float32(r.Float64()*90 - 30), // [-30, 60](贴合示例亮度范围,减少暗色)
|
if row == dominant && col == dominant {
|
||||||
contrast: float32(r.Float64()*1.0 + 0.7), // [0.7, 1.7](与你的示例完全匹配)
|
value += randomFloat32Range(r, 0.35, 0.7)
|
||||||
saturation: float32(r.Float64()*1.0 + 0.4), // [0.4, 1.4](与你的示例完全匹配)
|
}
|
||||||
hueRotate: float32(r.Float64()*100 - 50), // [-50, 50](避免极端色相)
|
if row == accent && col == accent {
|
||||||
rOffset: float32(r.Float64()*20 - 10), // [-10, 10](小幅亮度偏移,贴合示例)
|
value += randomFloat32Range(r, 0.1, 0.3)
|
||||||
gOffset: float32(r.Float64()*20 - 10), // 同上
|
}
|
||||||
bOffset: float32(r.Float64()*20 - 10), // 同上
|
if row == dominant && col != row {
|
||||||
|
value += randomFloat32Range(r, -0.12, 0.28)
|
||||||
|
}
|
||||||
|
matrix[row][col] = clampFloat32(roundFloat32(value, FloatPrecision), MatrixMinVal, MatrixMaxVal)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 矩阵计算逻辑不变(确保与你的示例参数分布一致)
|
matrix[0][4] = baseLift + randomFloat32Range(r, -5, 10)
|
||||||
matrix := newIdentityMatrix()
|
matrix[1][4] = baseLift + randomFloat32Range(r, -5, 10)
|
||||||
contrast := params.contrast
|
matrix[2][4] = baseLift + randomFloat32Range(r, -5, 10)
|
||||||
matrix[0][0] *= contrast
|
matrix[dominant][4] += randomFloat32Range(r, 8, 18)
|
||||||
matrix[1][1] *= contrast
|
matrix[accent][4] += randomFloat32Range(r, 2, 8)
|
||||||
matrix[2][2] *= contrast
|
|
||||||
|
|
||||||
sat := params.saturation
|
avgBrightness := (matrix[0][4] + matrix[1][4] + matrix[2][4]) / 3
|
||||||
grayR, grayG, grayB := float32(0.299)*(1-sat), float32(0.587)*(1-sat), float32(0.114)*(1-sat)
|
if avgBrightness < 12 {
|
||||||
matrix[0][0] = grayR + sat*matrix[0][0]
|
lift := 12 - avgBrightness + randomFloat32Range(r, 0, 6)
|
||||||
matrix[0][1], matrix[0][2] = grayG, grayB
|
for row := 0; row < 3; row++ {
|
||||||
matrix[1][0] = grayR
|
matrix[row][4] += lift
|
||||||
matrix[1][1] = grayG + sat*matrix[1][1]
|
}
|
||||||
matrix[1][2] = grayB
|
}
|
||||||
matrix[2][0] = grayR
|
if matrix[dominant][4] < 16 {
|
||||||
matrix[2][1] = grayG
|
matrix[dominant][4] = 16 + randomFloat32Range(r, 0, 10)
|
||||||
matrix[2][2] = grayB + sat*matrix[2][2]
|
}
|
||||||
|
|
||||||
angle := params.hueRotate * float32(math.Pi) / 180
|
for row := 0; row < 3; row++ {
|
||||||
cos, sin := float32(math.Cos(float64(angle))), float32(math.Sin(float64(angle)))
|
for col := 0; col < 3; col++ {
|
||||||
r1, g1, b1 := matrix[0][0], matrix[0][1], matrix[0][2]
|
matrix[row][col] = clampFloat32(roundFloat32(matrix[row][col], FloatPrecision), MatrixMinVal, MatrixMaxVal)
|
||||||
r2, g2, b2 := matrix[1][0], matrix[1][1], matrix[1][2]
|
}
|
||||||
|
matrix[row][4] = clampFloat32(roundFloat32(matrix[row][4], FloatPrecision), BrightnessMinVal, BrightnessMaxVal)
|
||||||
|
}
|
||||||
|
|
||||||
matrix[0][0] = r1*cos - r2*sin
|
|
||||||
matrix[0][1] = r1*sin + r2*cos
|
|
||||||
matrix[1][0] = g1*cos - g2*sin
|
|
||||||
matrix[1][1] = g1*sin + g2*cos
|
|
||||||
matrix[2][0] = b1*cos - b2*sin
|
|
||||||
matrix[2][1] = b1*sin + b2*cos
|
|
||||||
|
|
||||||
// 亮度偏移:范围缩小后,避免过暗/过亮
|
|
||||||
matrix[0][4] = params.brightness + params.rOffset
|
|
||||||
matrix[1][4] = params.brightness + params.gOffset
|
|
||||||
matrix[2][4] = params.brightness + params.bOffset
|
|
||||||
|
|
||||||
// 4. 封装为MonsterMatrix(不变)
|
|
||||||
parent := MonsterMatrix{
|
parent := MonsterMatrix{
|
||||||
Matrix: matrix,
|
Matrix: matrix,
|
||||||
Hash: "",
|
Hash: "",
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ type MapNode struct {
|
|||||||
IsBroadcast uint32 `gorm:"type:int;default:0;comment:'广播模型ID(0表示不广播)'" json:"is_broadcast"`
|
IsBroadcast uint32 `gorm:"type:int;default:0;comment:'广播模型ID(0表示不广播)'" json:"is_broadcast"`
|
||||||
|
|
||||||
IsGroupBoss uint32 `gorm:"type:int;default:0;comment:'是否为组队Boss(0否1是)'" json:"is_group_boss" description:"是否为组队Boss"`
|
IsGroupBoss uint32 `gorm:"type:int;default:0;comment:'是否为组队Boss(0否1是)'" json:"is_group_boss" description:"是否为组队Boss"`
|
||||||
|
PkFlag uint32 `gorm:"type:int;default:0;comment:'是否单精灵对战(0否1是)'" json:"pk_flag" description:"是否单精灵对战"`
|
||||||
|
|
||||||
TriggerPlotID uint32 `gorm:"default:0;comment:'触发剧情ID(0表示无剧情)'" json:"trigger_plot_id" description:"触发剧情ID"`
|
TriggerPlotID uint32 `gorm:"default:0;comment:'触发剧情ID(0表示无剧情)'" json:"trigger_plot_id" description:"触发剧情ID"`
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,9 @@ type TaskConfig struct {
|
|||||||
// 奖励配置
|
// 奖励配置
|
||||||
ItemRewardIds []uint32 `gorm:"not null;type:jsonb;default:'[]';comment:'绑定奖励物品ID数组,关联item_gift表主键'" json:"item_reward_ids" description:"奖励物品数组"`
|
ItemRewardIds []uint32 `gorm:"not null;type:jsonb;default:'[]';comment:'绑定奖励物品ID数组,关联item_gift表主键'" json:"item_reward_ids" description:"奖励物品数组"`
|
||||||
ElfRewardIds uint32 `gorm:"not null;default:0;comment:'绑定奖励精灵ID,关联elf_gift表主键'" json:"elf_reward_ids" description:"绑定奖励精灵ID"`
|
ElfRewardIds uint32 `gorm:"not null;default:0;comment:'绑定奖励精灵ID,关联elf_gift表主键'" json:"elf_reward_ids" description:"绑定奖励精灵ID"`
|
||||||
|
RewardPetID uint32 `gorm:"not null;default:0;comment:'宠物相关奖励生效的目标精灵ID,0表示不对已有精灵发放'" json:"reward_pet_id" description:"目标精灵ID"`
|
||||||
|
TrainSkillIDs []uint32 `gorm:"not null;type:jsonb;default:'[]';comment:'任务奖励的特训技能ID数组'" json:"train_skill_ids" description:"特训技能奖励数组"`
|
||||||
|
SkinIDs []uint32 `gorm:"not null;type:jsonb;default:'[]';comment:'任务奖励的皮肤ID数组'" json:"skin_ids" description:"皮肤奖励数组"`
|
||||||
|
|
||||||
//绑定奖励
|
//绑定奖励
|
||||||
TitleRewardIds uint32 `gorm:"not null;default:0;comment:'绑定奖励称号'" json:"title_reward_ids" description:"绑定奖励称号"`
|
TitleRewardIds uint32 `gorm:"not null;default:0;comment:'绑定奖励称号'" json:"title_reward_ids" description:"绑定奖励称号"`
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package service
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"blazing/common/data"
|
"blazing/common/data"
|
||||||
"blazing/common/utils"
|
|
||||||
"blazing/cool"
|
"blazing/cool"
|
||||||
"blazing/modules/config/model"
|
"blazing/modules/config/model"
|
||||||
"context"
|
"context"
|
||||||
@@ -43,18 +42,52 @@ func (s *ShinyService) ModifyBefore(ctx context.Context, method string, param g.
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func (s *ShinyService) RandShiny(id uint32) *data.GlowFilter {
|
|
||||||
|
|
||||||
|
func (s *ShinyService) listByPetID(id uint32) []model.ColorfulSkin {
|
||||||
var ret []model.ColorfulSkin
|
var ret []model.ColorfulSkin
|
||||||
|
|
||||||
// 执行 Raw SQL 并扫描返回值
|
|
||||||
dbm_enable(s.Model).
|
dbm_enable(s.Model).
|
||||||
Wheref(`bind_elf_ids @> ?::jsonb`, id).
|
Wheref(`bind_elf_ids @> ?::jsonb`, id).
|
||||||
Wheref(`jsonb_typeof(bind_elf_ids) = ?`, "array").Scan(&ret)
|
Wheref(`jsonb_typeof(bind_elf_ids) = ?`, "array").
|
||||||
|
Scan(&ret)
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func pickColorfulSkinByWeight(items []model.ColorfulSkin) *model.ColorfulSkin {
|
||||||
|
if len(items) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
totalWeight := 0
|
||||||
|
for _, item := range items {
|
||||||
|
if item.ElfProbability > 0 {
|
||||||
|
totalWeight += int(item.ElfProbability)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if totalWeight <= 0 {
|
||||||
|
return &items[grand.Intn(len(items))]
|
||||||
|
}
|
||||||
|
|
||||||
|
randomValue := grand.Intn(totalWeight)
|
||||||
|
for i := range items {
|
||||||
|
weight := int(items[i].ElfProbability)
|
||||||
|
if weight <= 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if randomValue < weight {
|
||||||
|
return &items[i]
|
||||||
|
}
|
||||||
|
randomValue -= weight
|
||||||
|
}
|
||||||
|
|
||||||
|
return &items[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ShinyService) RandShiny(id uint32) *data.GlowFilter {
|
||||||
|
ret := s.listByPetID(id)
|
||||||
|
|
||||||
for _, v := range ret {
|
for _, v := range ret {
|
||||||
//print(v.ID)
|
|
||||||
|
|
||||||
id := v.ID
|
id := v.ID
|
||||||
|
|
||||||
if grand.Meet(int(v.ElfProbability), 1000) {
|
if grand.Meet(int(v.ElfProbability), 1000) {
|
||||||
@@ -74,32 +107,16 @@ func (s *ShinyService) RandShiny(id uint32) *data.GlowFilter {
|
|||||||
|
|
||||||
var t = data.GetDef()
|
var t = data.GetDef()
|
||||||
|
|
||||||
t.ColorMatrixFilter = model.GenerateRandomOffspringMatrix().Get()
|
t.ColorMatrixFilter = model.GenerateRandomParentMatrix().Get()
|
||||||
|
|
||||||
return &t
|
return &t
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ShinyService) RandomByWeightShiny(id uint32) *data.GlowFilter {
|
func (s *ShinyService) RandomByWeightShiny(id uint32) *data.GlowFilter {
|
||||||
|
r := pickColorfulSkinByWeight(s.listByPetID(id))
|
||||||
var ret []model.ColorfulSkin
|
if r == nil {
|
||||||
|
|
||||||
// 执行 Raw SQL 并扫描返回值
|
|
||||||
dbm_enable(s.Model).
|
|
||||||
Wheref(`bind_elf_ids @> ?::jsonb`, id).
|
|
||||||
Wheref(`jsonb_typeof(bind_elf_ids) = ?`, "array").Scan(&ret)
|
|
||||||
if len(ret) == 0 {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var rets []model.ColorfulSkin
|
|
||||||
var props []int
|
|
||||||
|
|
||||||
for _, v := range ret {
|
|
||||||
rets = append(rets, v)
|
|
||||||
props = append(props, int(v.ElfProbability))
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
r, _ := utils.RandomByWeight(rets, props)
|
|
||||||
if cool.Config.ServerInfo.IsVip == 0 {
|
if cool.Config.ServerInfo.IsVip == 0 {
|
||||||
m := cool.DBM(s.Model).Where("id", r.ID)
|
m := cool.DBM(s.Model).Where("id", r.ID)
|
||||||
m.Increment("refresh_count", 1)
|
m.Increment("refresh_count", 1)
|
||||||
|
|||||||
BIN
modules/model.test
Executable file
BIN
modules/model.test
Executable file
Binary file not shown.
@@ -3,6 +3,7 @@ package service
|
|||||||
import (
|
import (
|
||||||
"blazing/common/utils"
|
"blazing/common/utils"
|
||||||
"blazing/cool"
|
"blazing/cool"
|
||||||
|
configmodel "blazing/modules/config/model"
|
||||||
config "blazing/modules/config/service"
|
config "blazing/modules/config/service"
|
||||||
"blazing/modules/player/model"
|
"blazing/modules/player/model"
|
||||||
|
|
||||||
@@ -27,54 +28,58 @@ func (s *TalkService) reset(flag int) {
|
|||||||
s.dbm(s.Model).Where("talk_id", flag).Data("count", 0, "last_reset_time", gtime.Now()).Update()
|
s.dbm(s.Model).Where("talk_id", flag).Data("count", 0, "last_reset_time", gtime.Now()).Update()
|
||||||
}
|
}
|
||||||
|
|
||||||
//实现挖矿次数确认
|
func (s *TalkService) progress(flag int) (uint32, *model.Talk, *configmodel.MineralCollectionConfig, bool) {
|
||||||
|
|
||||||
func (s *TalkService) Cheak(mapid uint32, flag int) (int, bool) {
|
|
||||||
|
|
||||||
m1 := s.dbm(s.Model)
|
|
||||||
|
|
||||||
var talks *model.Talk
|
var talks *model.Talk
|
||||||
m1.Where("talk_id", flag).Scan(&talks)
|
s.dbm(s.Model).Where("talk_id", flag).Scan(&talks)
|
||||||
|
|
||||||
|
cfg := config.NewTalkConfigService().GetCache(flag)
|
||||||
|
if cfg == nil {
|
||||||
|
return 0, talks, nil, false
|
||||||
|
}
|
||||||
if talks == nil {
|
if talks == nil {
|
||||||
|
return 0, nil, cfg, true
|
||||||
return 0, true //如果表里没有记载数据,那么就可以直接挖矿
|
|
||||||
}
|
}
|
||||||
|
|
||||||
c := config.NewTalkConfigService().GetCache(flag)
|
switch cfg.Limit {
|
||||||
|
|
||||||
//因为这个是挖一次更新一次,而且是实时更新的,如果更新日期是今天,那么就可以确认不用再重置,否则就需要重置挖矿记录
|
|
||||||
if c == nil {
|
|
||||||
return 0, false //没在地图
|
|
||||||
}
|
|
||||||
switch c.Limit {
|
|
||||||
case 0:
|
case 0:
|
||||||
if !utils.IsToday(talks.LastResetTime) {
|
if !utils.IsToday(talks.LastResetTime) {
|
||||||
|
|
||||||
s.reset(flag)
|
s.reset(flag)
|
||||||
return int(0), true
|
return 0, talks, cfg, true
|
||||||
}
|
}
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
if !utils.IsWEEK(talks.LastResetTime) {
|
if !utils.IsWEEK(talks.LastResetTime) {
|
||||||
|
|
||||||
s.reset(flag)
|
s.reset(flag)
|
||||||
return int(0), true
|
return 0, talks, cfg, true
|
||||||
}
|
}
|
||||||
case 2:
|
case 2:
|
||||||
if !utils.IsMon(talks.LastResetTime) {
|
if !utils.IsMon(talks.LastResetTime) {
|
||||||
|
|
||||||
s.reset(flag)
|
s.reset(flag)
|
||||||
return int(0), true
|
return 0, talks, cfg, true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if uint32(mapid) != c.MapID {
|
return talks.Count, talks, cfg, true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *TalkService) Progress(flag int) (uint32, bool) {
|
||||||
|
count, _, _, ok := s.progress(flag)
|
||||||
|
return count, ok
|
||||||
|
}
|
||||||
|
|
||||||
|
//实现挖矿次数确认
|
||||||
|
|
||||||
|
func (s *TalkService) Cheak(mapid uint32, flag int) (int, bool) {
|
||||||
|
count, _, cfg, ok := s.progress(flag)
|
||||||
|
if !ok || cfg == nil {
|
||||||
return 0, false //没在地图
|
return 0, false //没在地图
|
||||||
}
|
}
|
||||||
if talks.Count >= c.DailyCollectCount {
|
if uint32(mapid) != cfg.MapID {
|
||||||
|
return 0, false //没在地图
|
||||||
|
}
|
||||||
|
if count >= cfg.DailyCollectCount {
|
||||||
return 0, false
|
return 0, false
|
||||||
}
|
}
|
||||||
return int(talks.Count), true //int(config.MaxDailyCnt - talks.Count)
|
return int(count), true //int(config.MaxDailyCnt - talks.Count)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
BIN
modules/service.test
Executable file
BIN
modules/service.test
Executable file
Binary file not shown.
Reference in New Issue
Block a user