Files
bl/logic/service/fight/input.go

292 lines
6.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package fight
import (
"blazing/common/data"
"blazing/common/socket/errorcode"
"blazing/common/utils"
"blazing/modules/config/service"
"blazing/modules/player/model"
"encoding/json"
"blazing/logic/service/common"
"blazing/logic/service/fight/action"
"blazing/logic/service/fight/info"
"blazing/logic/service/fight/input"
"blazing/logic/service/user"
"math/rand"
"sync"
"time"
"github.com/gogf/gf/v2/util/grand"
"github.com/jinzhu/copier"
)
type FightC struct {
//准备战斗信息
ReadyInfo info.NoteReadyToFightInfo
//开始战斗信息
info.FightStartOutboundInfo
Info info.Fightinfo
IsReady bool
ownerID uint32 // 战斗发起者ID
Our *input.Input //始终等于房主ID
Opp *input.Input //对手ID
Switch map[uint32]*action.ActiveSwitchAction
startl sync.Once
rand *rand.Rand
StartTime time.Time
actionChan chan action.BattleActionI // 所有操作统一从这里进入
quit chan struct{}
over chan struct{}
First *input.Input
TrueFirst *input.Input
Second *input.Input
closefight bool
overl sync.Once
waittime int
info.FightOverInfo
//战斗结束的插装
callback func(info.FightOverInfo)
}
func (f *FightC) Ownerid() uint32 {
return f.ownerID
}
func (f *FightC) GetInputByPlayer(c common.PlayerI, isOpposite bool) *input.Input {
// 判断当前玩家是否为我方玩家
isOurPlayer := c.GetInfo().UserID == f.ownerID
// 当isOurPlayer与isOpposite值不同时返回我方相同时返回对方
if isOurPlayer != isOpposite {
return f.Our
}
return f.Opp
}
func (f *FightC) GetInputByAction(c action.BattleActionI, isOpposite bool) *input.Input {
// 判断动作所属玩家是否为我方
isOurAction := c.GetPlayerID() == f.Our.Player.GetInfo().UserID
// 根据isOpposite决定是否返回相反方向的输入
if isOurAction == !isOpposite {
return f.Our
}
return f.Opp
}
// 玩家使用技能
func (f *FightC) GetCurrPET(c common.PlayerI) *info.BattlePetEntity {
if f.Our.Player.GetInfo().UserID == c.GetInfo().UserID {
return f.Our.CurrentPet
} else {
return f.Opp.CurrentPet
}
}
func (f *FightC) GetOpp(c common.PlayerI) *input.Input {
return f.GetInputByPlayer(c, true)
}
// 获取随机数
func (f *FightC) GetRand() *rand.Rand {
return f.rand
}
// 获取随机数
func (f *FightC) IsFirst(play common.PlayerI) bool {
return f.TrueFirst.Player == play
}
func (f *FightC) Chat(c common.PlayerI, msg string) {
f.GetInputByPlayer(c, true).Player.SendPackCmd(50002, &user.ChatOutboundInfo{
SenderId: c.GetInfo().UserID,
SenderNickname: c.GetInfo().Nick,
Message: utils.RemoveLast(msg),
})
}
// 加载进度
func (f *FightC) LoadPercent(c common.PlayerI, percent int32) {
if f.Info.Mode == info.BattleMode.PET_MELEE {
return
}
if f.Info.Status == info.BattleMode.FIGHT_WITH_NPC {
return
}
f.GetInputByPlayer(c, true).Player.SendPackCmd(2441, &info.LoadPercentOutboundInfo{
Id: c.GetInfo().UserID,
Percent: uint32(percent),
})
}
var meetpet = make(map[int]model.PetInfo)
func (f *FightC) initplayer(c common.PlayerI) (*input.Input, errorcode.ErrorCode) {
if !c.CanFight() {
return nil, errorcode.ErrorCodes.ErrNoEligiblePokemon
}
in := input.NewInput(f, c)
in.AllPet = make([]*info.BattlePetEntity, 0)
in.InitAttackValue()
for i := 0; i < len(c.GetInfo().PetList); i++ {
in.AllPet = append(in.AllPet, info.CreateBattlePetEntity(c.GetInfo().PetList[i], f.rand))
}
in.SortPet()
if len(in.AllPet) == 0 {
return nil, errorcode.ErrorCodes.ErrNoEligiblePokemon
}
switch f.Info.Mode {
case info.BattleMode.SINGLE_MODE:
in.AllPet = in.AllPet[:1]
case info.BattleMode.PET_MELEE:
in.AllPet = make([]*info.BattlePetEntity, 0)
// if len(meetpet) == 0 {
// initmeetpet()
// }
r := service.NewMELEEService().Def()
if len(r) == 0 {
return nil, errorcode.ErrorCodes.ErrNoEligiblePokemon
}
for i, v := range r {
if v.Lv == 0 {
v.Lv = 100
}
// var effect int
// if len(v.Effect) > 0 {
// effect = int(v.Effect[0])
// }
pet := model.GenPetInfo(int(v.MonID), 24, int(v.Nature), int(v.Effect[0]), int(v.Lv), nil)
var color data.GlowFilter
err := json.Unmarshal([]byte(v.Color), &color)
if err == nil {
pet.ShinyInfo = append(pet.ShinyInfo, color)
}
if len(v.Prop) == 5 {
pet.Prop = [5]uint32(v.Prop)
}
if v.Hp != 0 {
pet.MaxHp = uint32(v.Hp)
}
if len(v.SKill) != 0 {
for i := 0; i < 4; i++ {
if v.SKill[i] != 0 {
pet.SkillList[i].ID = v.SKill[i]
}
}
}
pet.CatchTime = c.GetInfo().UserID + uint32(i)*1000000
pet.Cure()
in.AllPet = append(in.AllPet, info.CreateBattlePetEntity(*pet, f.rand))
}
// for i, v := range meetpet {
// v1 := v
// if len(in.AllPet) > 2 {
// break
// }
// v1.CatchTime = c.GetInfo().UserID + uint32(i)*1000000
// v1.Cure()
// in.AllPet = append(in.AllPet, info.CreateBattlePetEntity(v1, f.rand))
// }
//in.AllPet = in.AllPet[:3]
default:
}
in.CurrentPet = in.AllPet[0]
return in, 0
}
// RandomElfIDs 从1-2000中随机抽取n个不重复的精灵ID
func RandomElfIDs(n int) []int {
if n <= 0 || n > 2000 {
return nil
}
// 用map记录已抽取的ID避免重复
used := make(map[int]struct{}, n)
ids := make([]int, 0, n)
for len(ids) < n {
// 生成1-2000的随机数
id := grand.Intn(2000) + 1 // rand.Intn(2000)生成0-1999+1后为1-2000
// 检查是否已抽取
if _, exists := used[id]; !exists {
used[id] = struct{}{}
ids = append(ids, id)
}
}
return ids
}
func initfightready(in *input.Input) (info.FightUserInfo, []info.ReadyFightPetInfo) {
t := make([]info.ReadyFightPetInfo, len(in.AllPet))
userindo := info.FightUserInfo{
UserID: in.UserID,
Nick: in.Player.GetInfo().Nick,
}
for i := 0; i < len(in.AllPet); i++ {
err := copier.CopyWithOption(&t[i], &in.AllPet[i].Info, copier.Option{IgnoreEmpty: true, DeepCopy: true})
if err != nil {
panic(err)
}
}
return userindo, t
}
// 被击败的ID
func (f *FightC) IsWin(c *input.Input) bool {
for _, v := range f.GetInputByPlayer(c.Player, true).AllPet {
if !v.NotAlive { //如果存活
return false
}
}
return true
}
// 广播,并是否结束回合
func (f *FightC) Broadcast(t func(ff *input.Input)) {
t(f.Our)
t(f.Opp)
}
func (f *FightC) GetOverChan() chan struct{} {
return f.over
}
func (f *FightC) GetOverInfo() info.FightOverInfo {
return f.FightOverInfo
}