```
All checks were successful
ci/woodpecker/push/my-first-workflow Pipeline was successful

feat(fight): 新增疲惫状态并优化睡眠状态机制

- 实现疲惫状态(StatusTired),仅限制攻击技能,允许属性技能正常使用
- 重构睡眠状态,改为在被攻击且未miss时立即解除,而非技能使用后
- 修复寄生种子效果触发时机,改为回合开始时触发
- 调整寄生效果的目标为技能施放者而非对手

fix(fight): 修正战斗回合逻辑和技能持续时间处理

- 修复Effect2194中状态添加函数调用,使用带时间参数的版本
- 修正Effect13中技能持续时间计算,避免额外减1的问题
- 优化回合处理逻辑,当双方都未出手时跳过动作阶段

refactor(cdk): 重构CDK配置结构和服务器冠名功能

- 将CDKConfig中的CDKType字段重命名为Type以符合GORM映射
- 优化UseServerNamingCDK方法的上下文处理逻辑
- 修复服务器冠名CDK使用时的类型检查条件

feat(player): 完善宠物经验系统和CDK兑换功能

- 增强AddPetExp方法,处理宠物等级达到100级的情况
- 添加查询当前账号有效期内服务器冠名信息的API接口
- 实现服务器服务相关的数据模型和查询方法

fix(task): 任务查询支持启用和未启用状态

- 修改任务服务中的Get、GetDaily、GetWeek方法
- 当启用状态下无结果时,自动查询未启用状态的任务配置
```
This commit is contained in:
昔念
2026-04-13 22:27:27 +08:00
parent f95fd49efd
commit 7dfa9c297e
4 changed files with 184 additions and 78 deletions

View File

@@ -41,6 +41,7 @@ func (Controller) PlayerFightBoss(req *ChallengeBossInboundInfo, p *player.Playe
if err != 0 {
return nil, err
}
leadMonster := &monsterInfo.PetList[0]
p.Fightinfo.Status = fightinfo.BattleMode.FIGHT_WITH_NPC
p.Fightinfo.Mode = resolveMapNodeFightMode(mapNode)
@@ -52,12 +53,7 @@ func (Controller) PlayerFightBoss(req *ChallengeBossInboundInfo, p *player.Playe
var fightC *fight.FightC
fightC, err = startMapBossFight(mapNode, p, ai, func(foi model.FightOverInfo) {
if mapNode.WinBonusID == 0 {
return
}
if shouldGrantBossWinBonus(fightC, p.Info.UserID, bossConfigs[0], foi) {
p.SptCompletedTask(mapNode.WinBonusID, 1)
}
handleMapBossFightRewards(p, fightC, foi, mapNode, bossConfigs[0], leadMonster)
})
if err != 0 {
return nil, err
@@ -234,6 +230,95 @@ func shouldGrantBossWinBonus(fightC *fight.FightC, playerID uint32, bossConfig c
return true
}
func handleMapBossFightRewards(
p *player.Player,
fightC *fight.FightC,
foi model.FightOverInfo,
mapNode *configmodel.MapNode,
bossConfig configmodel.BossConfig,
leadMonster *model.PetInfo,
) {
rewards := grantMonsterFightRewards(p, foi, leadMonster)
if mapNode != nil && mapNode.WinBonusID != 0 && shouldGrantBossWinBonus(fightC, p.Info.UserID, bossConfig, foi) {
appendBossTaskReward(p, mapNode.WinBonusID, 1, rewards)
}
if rewards != nil && rewards.HasReward() {
p.SendPackCmd(8004, rewards)
}
}
func grantMonsterFightRewards(p *player.Player, foi model.FightOverInfo, monster *model.PetInfo) *fightinfo.S2C_GET_BOSS_MONSTER {
rewards := &fightinfo.S2C_GET_BOSS_MONSTER{}
if p == nil || monster == nil || foi.Reason != 0 || foi.WinnerId != p.Info.UserID || !p.CanGet() {
return rewards
}
petCfg, ok := xmlres.PetMAP[int(monster.ID)]
if !ok {
return rewards
}
exp := uint32(petCfg.YieldingExp) * monster.Level / 7
addlevel, poolevel := p.CanGetExp()
addexp := gconv.Float32(addlevel * gconv.Float32(exp))
poolexp := gconv.Float32(poolevel) * gconv.Float32(exp)
p.ItemAdd(3, int64(poolexp+addexp))
rewards.AddItem(rewardItemExpPool, uint32(poolexp))
p.AddPetExp(foi.Winpet, int64(addexp))
if p.CanGetItem() {
itemID := p.GetSpace().GetDrop()
if itemID != 0 {
count := uint32(grand.N(1, 2))
if p.ItemAdd(itemID, int64(count)) {
rewards.AddItem(uint32(itemID), count)
}
}
}
petType := int64(petCfg.Type)
if monster.IsShiny() && p.CanGetXUAN() && petType < 16 {
xuanID := uint32(400686 + petType)
count := uint32(grand.N(1, 2))
if p.ItemAdd(int64(xuanID), int64(count)) {
rewards.AddItem(xuanID, count)
}
}
if foi.Winpet != nil {
foi.Winpet.AddEV(petCfg.YieldingEVValues)
}
return rewards
}
func appendBossTaskReward(p *player.Player, taskID int, outState int, rewards *fightinfo.S2C_GET_BOSS_MONSTER) {
if p == nil || rewards == nil || !p.IsLogin || taskID <= 0 {
return
}
if p.Info.GetTask(taskID) == model.Completed {
return
}
granted, err := p.ApplyTaskCompletion(uint32(taskID), outState, nil)
if err != 0 {
return
}
p.Info.SetTask(taskID, model.Completed)
rewards.BonusID = uint32(taskID)
if granted == nil {
return
}
if granted.Pet != nil {
rewards.PetID = granted.Pet.ID
rewards.CaptureTm = granted.Pet.CatchTime
}
for _, item := range granted.Items {
rewards.AddItemInfo(item)
}
}
func buildNpcMonsterInfo(refPet player.OgrePetInfo, mapID uint32) (*model.PetInfo, *model.PlayerInfo, errorcode.ErrorCode) {
if refPet.ID == 0 {
return nil, nil, errorcode.ErrorCodes.ErrPokemonNotExists
@@ -269,46 +354,8 @@ func buildNpcMonsterInfo(refPet player.OgrePetInfo, mapID uint32) (*model.PetInf
}
func handleNpcFightRewards(p *player.Player, foi model.FightOverInfo, monster *model.PetInfo) {
if foi.Reason != 0 || foi.WinnerId != p.Info.UserID || !p.CanGet() {
return
}
petCfg, ok := xmlres.PetMAP[int(monster.ID)]
if !ok {
return
}
exp := uint32(petCfg.YieldingExp) * monster.Level / 7
addlevel, poolevel := p.CanGetExp()
addexp := gconv.Float32(addlevel * gconv.Float32(exp))
poolexp := gconv.Float32(poolevel) * gconv.Float32(exp)
rewards := &fightinfo.S2C_GET_BOSS_MONSTER{}
p.ItemAdd(3, int64(poolexp+addexp))
rewards.AddItem(rewardItemExpPool, uint32(poolexp))
p.AddPetExp(foi.Winpet, int64(addexp))
if p.CanGetItem() {
itemID := p.GetSpace().GetDrop()
if itemID != 0 {
count := uint32(grand.N(1, 2))
if p.ItemAdd(itemID, int64(count)) {
rewards.AddItem(uint32(itemID), count)
}
}
}
petType := int64(petCfg.Type)
if monster.IsShiny() && p.CanGetXUAN() && petType < 16 {
xuanID := uint32(400686 + petType)
count := uint32(grand.N(1, 2))
if p.ItemAdd(int64(xuanID), int64(count)) {
rewards.AddItem(xuanID, count)
}
}
rewards := grantMonsterFightRewards(p, foi, monster)
if rewards.HasReward() {
p.SendPackCmd(8004, rewards)
}
foi.Winpet.AddEV(petCfg.YieldingEVValues)
}