259 lines
7.6 KiB
Go
259 lines
7.6 KiB
Go
package controller
|
|
|
|
import (
|
|
"blazing/common/socket/errorcode"
|
|
"blazing/common/utils"
|
|
"blazing/logic/service/fight"
|
|
fightinfo "blazing/logic/service/fight/info"
|
|
"blazing/logic/service/player"
|
|
"blazing/logic/service/space/info"
|
|
configmodel "blazing/modules/config/model"
|
|
"blazing/modules/config/service"
|
|
"blazing/modules/player/model"
|
|
|
|
"sync/atomic"
|
|
|
|
"github.com/gogf/gf/v2/util/gconv"
|
|
"github.com/jinzhu/copier"
|
|
)
|
|
|
|
const (
|
|
towerCmdChoiceTrial uint32 = 2428
|
|
towerCmdChoiceBrave uint32 = 2414
|
|
towerCmdFightTrial uint32 = 2429
|
|
towerCmdFightBrave uint32 = 2415
|
|
towerCmdFightDark uint32 = 2425
|
|
|
|
towerTaskDark int = 110
|
|
towerTaskBrave int = 500
|
|
towerTaskTrial int = 600
|
|
)
|
|
|
|
type towerChoiceState struct {
|
|
currentLevel *uint32
|
|
maxLevel *uint32
|
|
service *service.TowerService
|
|
}
|
|
|
|
// 暗黑门进入boss
|
|
func (h Controller) FreshOpen(data *C2S_OPEN_DARKPORTAL, c *player.Player) (result *fight.S2C_OPEN_DARKPORTAL, err errorcode.ErrorCode) {
|
|
result = &fight.S2C_OPEN_DARKPORTAL{}
|
|
|
|
towerBosses := service.NewTower110Service().Boss(uint32(data.Level))
|
|
bossConfig, ok := firstTowerBossConfig(towerBosses)
|
|
if !ok {
|
|
return nil, errorcode.ErrorCodes.ErrPokemonNotExists
|
|
}
|
|
|
|
bosses := service.NewBossService().Get(bossConfig.BossIds[0])
|
|
if len(bosses) == 0 {
|
|
return nil, errorcode.ErrorCodes.ErrPokemonNotExists
|
|
}
|
|
|
|
result.CurBossID = uint32(bosses[0].MonID)
|
|
c.CurDark = uint32(data.Level)
|
|
defer c.GetSpace().LeaveMap(c)
|
|
return result, 0
|
|
}
|
|
|
|
// FreshChoiceFightLevel 处理玩家选择挑战模式(试炼之塔或勇者之塔)
|
|
func (h Controller) FreshChoiceFightLevel(data *C2S_FRESH_CHOICE_FIGHT_LEVEL, c *player.Player) (result *fight.S2C_FreshChoiceLevelRequestInfo, err errorcode.ErrorCode) {
|
|
result = &fight.S2C_FreshChoiceLevelRequestInfo{}
|
|
c.Info.CurrentFreshStage = utils.Max(c.Info.CurrentFreshStage, 1)
|
|
c.Info.CurrentStage = utils.Max(c.Info.CurrentStage, 1)
|
|
|
|
choiceState, ok := towerChoiceRuntime(c, data.Head.CMD)
|
|
if !ok {
|
|
return nil, errorcode.ErrorCodes.ErrSystemError
|
|
}
|
|
|
|
if data.Level > 0 {
|
|
if !canSelectTowerLevel(data.Level, *choiceState.maxLevel) {
|
|
return nil, errorcode.ErrorCodes.ErrPokemonNotExists
|
|
}
|
|
*choiceState.currentLevel = uint32(data.Level)
|
|
}
|
|
|
|
result.CurFightLevel = *choiceState.currentLevel
|
|
appendTowerBossPreview(&result.BossId, choiceState.service.Boss(*choiceState.currentLevel))
|
|
|
|
atomic.StoreUint32(&c.Canmon, 0)
|
|
defer c.GetSpace().LeaveMap(c)
|
|
return result, 0
|
|
}
|
|
|
|
// FreshLeaveFightLevel 处理控制器请求。
|
|
func (h Controller) FreshLeaveFightLevel(data *FRESH_LEAVE_FIGHT_LEVEL, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
|
|
_ = data
|
|
defer c.GetSpace().EnterMap(c)
|
|
|
|
out := info.NewOutInfo()
|
|
copier.CopyWithOption(out, c.GetInfo(), copier.Option{DeepCopy: true})
|
|
|
|
return result, 0
|
|
}
|
|
|
|
// PetTawor 处理控制器请求。
|
|
func (h Controller) PetTawor(data *StartTwarInboundInfo, c *player.Player) (result *fight.S2C_ChoiceLevelRequestInfo, err errorcode.ErrorCode) {
|
|
if err = c.CanFight(); err != 0 {
|
|
return nil, err
|
|
}
|
|
|
|
bossList, currentLevel, taskID, ok := towerFightBosses(c, data.Head.CMD)
|
|
if !ok {
|
|
return nil, errorcode.ErrorCodes.ErrSystemError
|
|
}
|
|
|
|
currentBoss, ok := firstTowerBossConfig(bossList)
|
|
if !ok {
|
|
return nil, errorcode.ErrorCodes.ErrPokemonNotExists
|
|
}
|
|
|
|
result = &fight.S2C_ChoiceLevelRequestInfo{CurFightLevel: currentLevel}
|
|
appendTowerNextBossPreview(&result.BossID, bossList)
|
|
|
|
monsterInfo, bossScript, ok := buildTowerMonsterInfo(currentBoss)
|
|
if !ok {
|
|
return nil, errorcode.ErrorCodes.ErrPokemonNotExists
|
|
}
|
|
|
|
c.Fightinfo.Mode = fightinfo.BattleMode.MULTI_MODE
|
|
c.Fightinfo.Status = fightinfo.BattleMode.FIGHT_WITH_NPC
|
|
|
|
ai := player.NewAI_player(monsterInfo)
|
|
ai.BossScript = bossScript
|
|
_, err = fight.NewFight(c, ai, c.GetPetInfo(100), ai.GetPetInfo(0), func(foi model.FightOverInfo) {
|
|
if foi.Reason != 0 || foi.WinnerId != c.Info.UserID {
|
|
return
|
|
}
|
|
handleTowerFightWin(c, data.Head.CMD, taskID, currentLevel)
|
|
})
|
|
|
|
return
|
|
}
|
|
|
|
func towerChoiceRuntime(c *player.Player, cmd uint32) (towerChoiceState, bool) {
|
|
switch cmd {
|
|
case towerCmdChoiceTrial:
|
|
return towerChoiceState{
|
|
currentLevel: &c.Info.CurrentFreshStage,
|
|
maxLevel: &c.Info.MaxFreshStage,
|
|
service: service.NewTower600Service(),
|
|
}, true
|
|
case towerCmdChoiceBrave:
|
|
return towerChoiceState{
|
|
currentLevel: &c.Info.CurrentStage,
|
|
maxLevel: &c.Info.MaxStage,
|
|
service: service.NewTower500Service(),
|
|
}, true
|
|
default:
|
|
return towerChoiceState{}, false
|
|
}
|
|
}
|
|
|
|
func towerFightBosses(c *player.Player, cmd uint32) ([]configmodel.BaseTowerConfig, uint32, int, bool) {
|
|
switch cmd {
|
|
case towerCmdFightTrial:
|
|
return service.NewTower600Service().Boss(c.Info.CurrentFreshStage, c.Info.CurrentFreshStage+1), c.Info.CurrentFreshStage, towerTaskTrial, true
|
|
case towerCmdFightBrave:
|
|
return service.NewTower500Service().Boss(c.Info.CurrentStage, c.Info.CurrentStage+1), c.Info.CurrentStage, towerTaskBrave, true
|
|
case towerCmdFightDark:
|
|
return service.NewTower110Service().Boss(c.CurDark), c.CurDark, towerTaskDark, true
|
|
default:
|
|
return nil, 0, 0, false
|
|
}
|
|
}
|
|
|
|
func canSelectTowerLevel(targetLevel uint, maxLevel uint32) bool {
|
|
return targetLevel == 1 || targetLevel <= uint(maxLevel)
|
|
}
|
|
|
|
func firstTowerBossConfig(bossList []configmodel.BaseTowerConfig) (configmodel.BaseTowerConfig, bool) {
|
|
if len(bossList) == 0 || len(bossList[0].BossIds) == 0 {
|
|
return configmodel.BaseTowerConfig{}, false
|
|
}
|
|
return bossList[0], true
|
|
}
|
|
|
|
func appendTowerBossPreview(dst *[]uint32, bossList []configmodel.BaseTowerConfig) {
|
|
bossConfig, ok := firstTowerBossConfig(bossList)
|
|
if !ok {
|
|
return
|
|
}
|
|
|
|
bosses := service.NewBossService().Get(bossConfig.BossIds[0])
|
|
for _, boss := range bosses {
|
|
*dst = append(*dst, uint32(boss.MonID))
|
|
}
|
|
}
|
|
|
|
func appendTowerNextBossPreview(dst *[]uint32, bossList []configmodel.BaseTowerConfig) {
|
|
if len(bossList) < 2 || len(bossList[1].BossIds) == 0 {
|
|
return
|
|
}
|
|
|
|
bosses := service.NewBossService().Get(bossList[1].BossIds[0])
|
|
for _, boss := range bosses {
|
|
*dst = append(*dst, uint32(boss.MonID))
|
|
}
|
|
}
|
|
|
|
func buildTowerMonsterInfo(towerBoss configmodel.BaseTowerConfig) (*model.PlayerInfo, string, bool) {
|
|
bosses := service.NewBossService().Get(towerBoss.BossIds[0])
|
|
if len(bosses) == 0 {
|
|
return nil, "", false
|
|
}
|
|
|
|
monsterInfo := &model.PlayerInfo{Nick: towerBoss.Name}
|
|
for i, boss := range bosses {
|
|
monster := model.GenPetInfo(int(boss.MonID), 24, int(boss.Nature), 0, int(boss.Lv), nil, 0)
|
|
if boss.Hp != 0 {
|
|
monster.Hp = uint32(boss.Hp)
|
|
monster.MaxHp = uint32(boss.Hp)
|
|
}
|
|
|
|
for statIdx, prop := range boss.Prop {
|
|
if prop != 0 {
|
|
monster.Prop[statIdx] = prop
|
|
}
|
|
}
|
|
|
|
for skillIdx := 0; skillIdx < len(monster.SkillList) && skillIdx < len(boss.SKill); skillIdx++ {
|
|
if boss.SKill[skillIdx] != 0 {
|
|
monster.SkillList[skillIdx].ID = boss.SKill[skillIdx]
|
|
}
|
|
}
|
|
|
|
effects := service.NewEffectService().Args(boss.Effect)
|
|
for _, effect := range effects {
|
|
monster.EffectInfo = append(monster.EffectInfo, model.PetEffectInfo{
|
|
Idx: uint16(effect.ID),
|
|
EID: gconv.Uint16(effect.Eid),
|
|
Args: gconv.Ints(effect.Args),
|
|
})
|
|
}
|
|
|
|
monster.CatchTime = uint32(i)
|
|
monsterInfo.PetList = append(monsterInfo.PetList, *monster)
|
|
}
|
|
|
|
return monsterInfo, bosses[0].Script, true
|
|
}
|
|
|
|
func handleTowerFightWin(c *player.Player, cmd uint32, taskID int, currentLevel uint32) {
|
|
c.TawerCompletedTask(taskID, int(currentLevel))
|
|
|
|
switch cmd {
|
|
case towerCmdFightTrial:
|
|
c.Info.CurrentFreshStage++
|
|
if c.Info.CurrentFreshStage >= c.Info.MaxFreshStage {
|
|
c.Info.MaxFreshStage = c.Info.CurrentFreshStage
|
|
}
|
|
case towerCmdFightBrave:
|
|
c.Info.CurrentStage++
|
|
if c.Info.CurrentStage >= c.Info.MaxStage {
|
|
c.Info.MaxStage = c.Info.CurrentStage
|
|
}
|
|
}
|
|
}
|