Package:BattleServer
1.AI:
AI 结构:
type AI struct { Owner *Unit //拥有的单元 pause bool //是否暂停 ppSkillCDOnly bool notUsePPSkill bool currentAction AIActionInterface notUseAnySkill bool }
AIInterface结构:
type AIInterface interface { Update() //更新 Pause() //暂停 Resume() //重新启动 SetForceTarget(target *Target) SetAttackTarget(*Target) //设置攻击目标 GetAttackTarget() *Target //获取攻击目标 ManualCastSkill(skill *Skill) FinishCurrentAction() //NotUseAnySkill(v bool) }
AIAtction结构:
type AIAction struct { Owner *Unit finished bool }
AIActionInterface结构:
type AIActionInterface interface { Update() (end bool) //更新 IsFinished() bool //是否结束 }
AIActionSkill结构:
type AIActionSkill struct { AIAction nowChooseSkill *Skill attackTarget *Target }
AISimpleBattle结构:
type AISimpleBattle struct { AI nowChooseSkill *Skill attackTarget *Target forceTarget *Target }
2.BattleGround:
BattleGround结构:
type BattleGround struct { Id int64 Type BattleType ConfigId int32 //根据type不同,fb是明雷id haveTrigger bool Now int64 DeltaTime int64 startTime int64 allLoadedTime int64 serial int64 //stoped bool bgState BGState pause bool powerpoint float64 teamPlayerCount int32 skills []*Skill MutexPacks sync.Mutex SessionPackets []*ClientPacket SessionPacketsProcessing []*ClientPacket ClientPacketHandlers map[pbID.Message]FightRolePacketHandler Clients map[int64]*Session FightRoles map[int64]*FightRole //id就是userid Units []*Unit UnitsById map[int64]*Unit Missiles []*Missile BUFFs []BUFFInterface BUFFsForTrigger map[BUFF_Occation][]BUFFInterface ch_Packet chan *ClientPacket currentWave int32 maxTeam int32 mapRefId int64 mapRefProtoId int32 captureTimeout <-chan time.Time captureCourse *PetCaptureCourse killMonsters map[int32]int32 loser int32 finishTimeout <-chan time.Time leaderLv int32 center Vector3 isLeaderFieldCaped bool //队长是否曾在该field抓过宠 hasTriggedCap bool ChangedAttrs map[int64]map[int32]float64 //记录每一帧单位的属性变化 广播给前端 }
BattleGroundApI:
1.特效API
//从单位到单位的特效 func (self *BattleGround) EffectFromUnitToUnit(effectid int32, source *Unit, target *Unit, movetime int64) int64 { newpbmsg := &pb.Fight_PlayEffect{ Time: self.Now, Id: self.GetNextSerial(), Effid: int64(effectid), Duration: movetime + 50, HangPos: source.Pos.ToPB(), HangId: source.Id, TriggerType: 1, //MoveSpeed:speed.ToPB(), MoveTime: movetime, MoveTarget: &pb.Fight_Target{ Type: TARTGET_UNIT, Poses: []*pb.Vector3{target.Pos.ToPB()}, UnitIds: []int64{target.Id}, }, } self.BroadCast(pbID.Message_Battle_PlayEffect, 0, newpbmsg) return newpbmsg.Id } //从单位到位置的特效 func (self *BattleGround) EffectFromUnitToPos(effectid int32, source *Unit, target Vector3, movetime int64) int64 { newpbmsg := &pb.Fight_PlayEffect{ Time: self.Now, Id: self.GetNextSerial(), Effid: int64(effectid), Duration: movetime + 50, HangPos: source.Pos.ToPB(), HangId: source.Id, TriggerType: 1, //MoveSpeed:speed.ToPB(), MoveTime: movetime, MoveTarget: &pb.Fight_Target{ Type: TARTGET_POINT, Poses: []*pb.Vector3{target.ToPB()}, }, } self.BroadCast(pbID.Message_Battle_PlayEffect, 0, newpbmsg) return newpbmsg.Id } //从位置到位置的特效 func (self *BattleGround) EffectFromPosToPos(effectid int32, source Vector3, target Vector3, movetime int64) int64 { newpbmsg := &pb.Fight_PlayEffect{ Time: self.Now, Id: self.GetNextSerial(), Effid: int64(effectid), Duration: movetime + 50, HangPos: source.ToPB(), HangId: 0, TriggerType: 1, //MoveSpeed:speed.ToPB(), MoveTime: movetime, MoveTarget: &pb.Fight_Target{ Type: TARTGET_POINT, Poses: []*pb.Vector3{target.ToPB()}, }, } self.BroadCast(pbID.Message_Battle_PlayEffect, 0, newpbmsg) return newpbmsg.Id } //作用在单位上的特效 func (self *BattleGround) EffectOnUnit(effectid int32, target *Unit, duration int64) int64 { newpbmsg := &pb.Fight_PlayEffect{ Time: self.Now, Id: self.GetNextSerial(), Effid: int64(effectid), Duration: duration, HangPos: target.Pos.ToPB(), HangId: target.Id, TriggerType: 1, } self.BroadCast(pbID.Message_Battle_PlayEffect, 0, newpbmsg) return newpbmsg.Id } //作用在位置上的特效 func (self *BattleGround) EffectOnPos(effectid int32, target Vector3, duration int64, rotation Vector3) int64 { newpbmsg := &pb.Fight_PlayEffect{ Time: self.Now, Id: self.GetNextSerial(), Effid: int64(effectid), Duration: duration, HangPos: target.ToPB(), TriggerType: 1, Rotation: rotation.ToPB(), } self.BroadCast(pbID.Message_Battle_PlayEffect, 0, newpbmsg) return newpbmsg.Id } //在特效上的特效 func (self *BattleGround) EffectOnEffect(effectid int32, hangeffectid int64, hangpos Vector3) int64 { newpbmsg := &pb.Fight_PlayEffect{ Time: self.Now, Id: self.GetNextSerial(), Effid: int64(effectid), HangPos: hangpos.ToPB(), HangId: hangeffectid, TriggerType: 1, } self.BroadCast(pbID.Message_Battle_PlayEffect, 0, newpbmsg) return newpbmsg.Id }
2.获取单位API
//获取前方90度范围内的目标 func (self *BattleGround) GetUnitsInfront90(center *Unit, len float32) []*Unit { lenpower2 := len * len units := make([]*Unit, 0) for _, unit := range self.Units { if unit.Dead || unit.GetAttr(ATTR_Invincibility) > 0 || unit.Team == 0 { continue } if center.Dir.IsFront90(unit.Pos.Sub(center.Pos)) && center.Pos.Distance2DSqr(unit.Pos) < lenpower2 { units = append(units, unit) } } return units } //获取最近的目标 func (self *BattleGround) GetClosestEnemy(me *Unit) (*Unit, float32) { var choosed *Unit = nil var mindist float32 = 999999999 var dist float32 = 0 for _, unit := range self.Units { if unit.Dead || unit.GetAttr(ATTR_Invincibility) > 0 || unit.GetAttr(ATTR_Invisible) > 0 { continue } if unit.Team == me.Team || unit.Team == 0 { continue } dist = me.Pos.Distance2DSqr(unit.Pos) if dist < mindist { mindist = dist choosed = unit } } return choosed, mindist } //获取某个位置范围内的单位 func (self *BattleGround) GetCicleMulEnemyAtPos(me *Unit, distance float32, pos Vector3) []*Unit { units := make([]*Unit, 0) for _, unit := range self.Units { if unit.Dead || unit.GetAttr(ATTR_Invincibility) > 0 || unit.Team == me.Team || unit.Team == 0 { continue } var dist float32 = pos.Distance2DSqr(unit.Pos) if dist < distance*distance { units = append(units, unit) } } return units } //获取最近的多个单位 func (self *BattleGround) GetCloseMulEnemy(me *Unit, count int) []*Unit { units := make([]*Unit, 0) var maxDisUnit *Unit = nil var maxDist float32 = 0 for _, unit := range self.Units { if unit.Dead || unit.GetAttr(ATTR_Invincibility) > 0 || unit.Team == me.Team || unit.Team == 0 { continue } if len(units) < count { units = append(units, unit) var dist float32 = me.Pos.Distance2DSqr(unit.Pos) if dist > maxDist { maxDist = dist maxDisUnit = unit } } else { var dist float32 = me.Pos.Distance2DSqr(unit.Pos) var tmpUnit *Unit = nil maxDist = 0 if dist < maxDist { for i, tmpunit := range units { if tmpunit.Id == maxDisUnit.Id { units[i] = unit } var dis float32 = me.Pos.Distance2DSqr(tmpunit.Pos) if dis > maxDist { maxDist = dis tmpUnit = tmpunit } } maxDisUnit = tmpUnit } } } return units } //获取最近的多个友方单位 func (self *BattleGround) GetCloseMulTeammate(me *Unit, count int) []*Unit { units := make([]*Unit, 0) var maxDisUnit *Unit = nil var maxDist float32 = 0 for _, unit := range self.Units { if unit.Dead || unit.GetAttr(ATTR_Invincibility) > 0 || unit.Team != me.Team || unit.Team == 0 { continue } if len(units) < count { units = append(units, unit) var dist float32 = me.Pos.Distance2DSqr(unit.Pos) if dist > maxDist { maxDist = dist maxDisUnit = unit } } else { var dist float32 = me.Pos.Distance2DSqr(unit.Pos) var tmpUnit *Unit = nil maxDist = 0 if dist < maxDist { for i, tmpunit := range units { if tmpunit.Id == maxDisUnit.Id { units[i] = unit } var dis float32 = me.Pos.Distance2DSqr(tmpunit.Pos) if dis > maxDist { maxDist = dis tmpUnit = tmpunit } } maxDisUnit = tmpUnit } } } return units } //获取某个位置的最近范围里的多个敌方单位 func (self *BattleGround) GetCloseMulEnemyAtPos(Pos Vector3, me *Unit, count int) []*Unit { units := make([]*Unit, 0) var maxDisUnit *Unit = nil var maxDist float32 = 0 for _, unit := range self.Units { if unit.Dead || unit.GetAttr(ATTR_Invincibility) > 0 || unit.Team == me.Team || unit.Team == 0 { continue } if len(units) < count { units = append(units, unit) var dist float32 = Pos.Distance2DSqr(unit.Pos) if dist > maxDist { maxDist = dist maxDisUnit = unit } } else { var dist float32 = Pos.Distance2DSqr(unit.Pos) var tmpUnit *Unit = nil maxDist = 0 if dist < maxDist { for i, tmpunit := range units { if tmpunit.Id == maxDisUnit.Id { units[i] = unit } var dis float32 = Pos.Distance2DSqr(tmpunit.Pos) if dis > maxDist { maxDist = dis tmpUnit = tmpunit } } maxDisUnit = tmpUnit } } } return units } //获取半径范围内的所有敌方目标 func (self *BattleGround) GetCicleMulEnemy(me *Unit, distance float32, pos Vector3) []*Unit { units := make([]*Unit, 0) for _, unit := range self.Units { if unit.Dead || unit.GetAttr(ATTR_Invincibility) > 0 || unit.Team == me.Team || unit.Team == 0 { continue } var dist float32 = pos.Distance2DSqr(unit.Pos) if dist < distance*distance { units = append(units, unit) } } return units } //根据技能中规定的目标数量,随机攻击他们 //huhao func (self *BattleGround) GetCicleMulEnemyRand(me *Unit, distance float32, pos Vector3, attckNum int32) []*Unit { units := make([]*Unit, 0) resultUnits := make([]*Unit, 0) for _, unit := range self.Units { if unit.Dead || unit.GetAttr(ATTR_Invincibility) > 0 || unit.Team == me.Team || unit.Team == 0 { continue } var dist float32 = pos.Distance2DSqr(unit.Pos) if dist < distance*distance { units = append(units, unit) } } if int(attckNum) < len(units) { for i := 0; i < int(attckNum); { var count = 0 var tag bool //r := rand.New(rand.NewSource(time.Now().UnixNano())) targetIndex := rand.Intn(int(len(units) - 1)) if len(resultUnits) != 0 { for _, ele := range resultUnits { if ele.Id == units[targetIndex].Id { count++ } } if int(count) >= 1 { tag = true } if !tag { //fmt.Println("--------------%v",+targetIndex) resultUnits = append(resultUnits, units[targetIndex]) i++ } } else { //fmt.Println("--------------%v",+targetIndex) resultUnits = append(resultUnits, units[targetIndex]) i++ } } return resultUnits } return units } //获取最远的目标 func (self *BattleGround) FindFarestUnit(team int32, findEnemy bool, pos Vector3) *Unit { var choosed *Unit = nil var maxdist float32 = 0 var dist float32 = 0 for _, unit := range self.Units { if unit.Dead || unit.GetAttr(ATTR_Invincibility) > 0 { continue } if unit.Team == team && findEnemy || unit.Team != team && !findEnemy || unit.Team == 0 || unit.GetAttr(ATTR_Invisible) > 0 && findEnemy { continue } dist = pos.Distance2DSqr(unit.Pos) if dist > maxdist { maxdist = dist choosed = unit } } return choosed } //获取 unit.hp / unit.hpMax 最大的 func (self *BattleGround) FindHpRatioMaxUnit(me *Unit, findEnemy bool) *Unit { var choosed *Unit = nil var maxHpRatio float64 = 0 var dist float64 = 0 for _, unit := range self.Units { if unit.Dead || unit.GetAttr(ATTR_Invincibility) > 0 { continue } if unit.Team == me.Team && findEnemy || unit.Team != me.Team && !findEnemy || unit.Team == 0 || unit.GetAttr(ATTR_Invisible) > 0 && findEnemy { continue } dist = unit.hp / unit.hpMax if dist > maxHpRatio { maxHpRatio = dist choosed = unit } } return choosed } //获取 unit.hp / unit.hpMax最小的 func (self *BattleGround) FindHpRatioMinUnit(me *Unit, findEnemy bool) *Unit { var choosed *Unit = nil var mixHpRatio float64 = 9999999 var dist float64 = 0 for _, unit := range self.Units { if unit.Dead || unit.GetAttr(ATTR_Invincibility) > 0 { continue } if unit.Team == me.Team && findEnemy || unit.Team != me.Team && !findEnemy || unit.Team == 0 || unit.GetAttr(ATTR_Invisible) > 0 && findEnemy { continue } dist = unit.hp / unit.hpMax if dist < mixHpRatio { mixHpRatio = dist choosed = unit } } return choosed } //获取血量最大的目标 func (self *BattleGround) FindHpMaxUnit(me *Unit, findEnemy bool) *Unit { var choosed *Unit = nil var maxHp float64 = 0 var dist float64 = 0 for _, unit := range self.Units { if unit.Dead || unit.GetAttr(ATTR_Invincibility) > 0 { continue } if unit.Team == me.Team && findEnemy || unit.Team != me.Team && !findEnemy || unit.Team == 0 || unit.GetAttr(ATTR_Invisible) > 0 && findEnemy { continue } dist = unit.hp if dist > maxHp { maxHp = dist choosed = unit } } return choosed } //获取血量最小的 func (self *BattleGround) FindHpMinUnit(me *Unit, findEnemy bool) *Unit { var choosed *Unit = nil var minHp float64 = 999999999 var dist float64 = 0 for _, unit := range self.Units { if unit.Dead || unit.GetAttr(ATTR_Invincibility) > 0 { continue } if unit.Team == me.Team && findEnemy || unit.Team != me.Team && !findEnemy || unit.Team == 0 || unit.GetAttr(ATTR_Invisible) > 0 && findEnemy { continue } dist = unit.hp if dist < minHp { minHp = dist choosed = unit } } return choosed } //获取物理攻击力(ATTR_PhysicsAttack)最大的 func (self *BattleGround) FindPhysicsAttackMaxUnit(me *Unit, findEnemy bool) *Unit { var choosed *Unit = nil var maxPhysics float64 = 0 var dist float64 = 0 for _, unit := range self.Units { if unit.Dead || unit.GetAttr(ATTR_Invincibility) > 0 { continue } if unit.Team == me.Team && findEnemy || unit.Team != me.Team && !findEnemy || unit.Team == 0 || unit.GetAttr(ATTR_Invisible) > 0 && findEnemy { continue } dist = unit.GetAttr(ATTR_PhysicsAttack) if dist > maxPhysics { maxPhysics = dist choosed = unit } } return choosed } //获取物理攻击力(ATTR_PhysicsAttack)最小的 func (self *BattleGround) FindPhysicsAttackMinUnit(me *Unit, findEnemy bool) *Unit { var choosed *Unit = nil var minPhysics float64 = 999999999 var dist float64 = 0 for _, unit := range self.Units { if unit.Dead || unit.GetAttr(ATTR_Invincibility) > 0 { continue } if unit.Team == me.Team && findEnemy || unit.Team != me.Team && !findEnemy || unit.Team == 0 || unit.GetAttr(ATTR_Invisible) > 0 && findEnemy { continue } dist = unit.GetAttr(ATTR_PhysicsAttack) if dist < minPhysics { minPhysics = dist choosed = unit } } return choosed } //获取魔攻击力(ATTR_MagicAttack)最大的 func (self *BattleGround) FindMagicAttackMaxUnit(me *Unit, findEnemy bool) *Unit { var choosed *Unit = nil var maxMagic float64 = 0 var dist float64 = 0 for _, unit := range self.Units { if unit.Dead || unit.GetAttr(ATTR_Invincibility) > 0 { continue } if unit.Team == me.Team && findEnemy || unit.Team != me.Team && !findEnemy || unit.Team == 0 || unit.GetAttr(ATTR_Invisible) > 0 && findEnemy { continue } dist = unit.GetAttr(ATTR_MagicAttack) if dist > maxMagic { maxMagic = dist choosed = unit } } return choosed } //获取魔攻击力(ATTR_MagicAttack)最小的 func (self *BattleGround) FindMagicAttackMinUnit(me *Unit, findEnemy bool) *Unit { var choosed *Unit = nil var minMagic float64 = 999999999 var dist float64 = 0 for _, unit := range self.Units { if unit.Dead || unit.GetAttr(ATTR_Invincibility) > 0 { continue } if unit.Team == me.Team && findEnemy || unit.Team != me.Team && !findEnemy || unit.Team == 0 || unit.GetAttr(ATTR_Invisible) > 0 && findEnemy { continue } dist = unit.GetAttr(ATTR_MagicAttack) if dist < minMagic { minMagic = dist choosed = unit } } return choosed } //获取防御力(ATTR_PhysicsDefense)最大的 func (self *BattleGround) FindPhysicsDefenseMaxUnit(me *Unit, findEnemy bool) *Unit { var choosed *Unit = nil var maxPhysics float64 = 0 var dist float64 = 0 for _, unit := range self.Units { if unit.Dead || unit.GetAttr(ATTR_Invincibility) > 0 { continue } if unit.Team == me.Team && findEnemy || unit.Team != me.Team && !findEnemy || unit.Team == 0 || unit.GetAttr(ATTR_Invisible) > 0 && findEnemy { continue } dist = unit.GetAttr(ATTR_PhysicsDefense) if dist > maxPhysics { maxPhysics = dist choosed = unit } } return choosed } //获取物理防御力(ATTR_PhysicsDefense)最小的 func (self *BattleGround) FindPhysicsDefenseMinUnit(me *Unit, findEnemy bool) *Unit { var choosed *Unit = nil var minPhysics float64 = 999999999 var dist float64 = 0 for _, unit := range self.Units { if unit.Dead || unit.GetAttr(ATTR_Invincibility) > 0 { continue } if unit.Team == me.Team && findEnemy || unit.Team != me.Team && !findEnemy || unit.Team == 0 || unit.GetAttr(ATTR_Invisible) > 0 && findEnemy { continue } dist = unit.GetAttr(ATTR_PhysicsDefense) if dist < minPhysics { minPhysics = dist choosed = unit } } return choosed } //获取魔攻防御力(ATTR_MagicDefense)最大的 func (self *BattleGround) FindMagicDefenseMaxUnit(me *Unit, findEnemy bool) *Unit { var choosed *Unit = nil var maxMagic float64 = 0 var dist float64 = 0 for _, unit := range self.Units { if unit.Dead || unit.GetAttr(ATTR_Invincibility) > 0 { continue } if unit.Team == me.Team && findEnemy || unit.Team != me.Team && !findEnemy || unit.Team == 0 || unit.GetAttr(ATTR_Invisible) > 0 && findEnemy { continue } dist = unit.GetAttr(ATTR_MagicDefense) if dist > maxMagic { maxMagic = dist choosed = unit } } return choosed } //获取魔攻防御力(ATTR_MagicDefense)最小的 func (self *BattleGround) FindMagicDefenseMinUnit(me *Unit, findEnemy bool) *Unit { var choosed *Unit = nil var minMagic float64 = 999999999 var dist float64 = 0 for _, unit := range self.Units { if unit.Dead || unit.GetAttr(ATTR_Invincibility) > 0 { continue } if unit.Team == me.Team && findEnemy || unit.Team != me.Team && !findEnemy || unit.Team == 0 || unit.GetAttr(ATTR_Invisible) > 0 && findEnemy { continue } dist = unit.GetAttr(ATTR_MagicDefense) if dist < minMagic { minMagic = dist choosed = unit } } return choosed } //获取活着的目标 func (self *BattleGround) FindLiveUnits(me *Unit, findEnemy bool, includeSelf bool) []*Unit { units := make([]*Unit, 0) for _, unit := range self.Units { if unit.Dead || unit.GetAttr(ATTR_Invincibility) > 0 { continue } if unit.Team == me.Team && findEnemy || unit.Team != me.Team && !findEnemy || unit.Team == 0 || unit.GetAttr(ATTR_Invisible) > 0 && findEnemy { continue } if !includeSelf && me.Id == unit.Id { continue } units = append(units, unit) } return units } //获取死亡的目标 func (self *BattleGround) FindDeadUnits(me *Unit, findEnemy bool, includeSelf bool) []*Unit { units := make([]*Unit, 0) for _, unit := range self.Units { if !unit.Dead { continue } if unit.Team == me.Team && findEnemy || unit.Team != me.Team && !findEnemy || unit.Team == 0 { continue } if !includeSelf && me.Id == unit.Id { continue } units = append(units, unit) } return units }
BattleGroundHandler:
3.BattleServer:
BattleServer结构:
type BattleServer struct { listenServer *Server handlers map[pbID.Message]ClientPacketHandler battlegrounds sync.Map userId2battleGrounds sync.Map ch_WorldPacket chan *ClientPacket wg *sync.WaitGroup }
MapBattleServer结构:
type _MapBattleServer struct { mapSever *MapServer battleServer *BattleServer client2World *Client clientListening bool openServerTime int64 }
MapServer结构:
type MapServer struct { wg *sync.WaitGroup listenServer *Server ch_WorldPacket chan *ClientPacket serverHandlers map[pbID.Message]ClientPacketHandler gridMaps map[int64]*GridMap usersInMap map[int64]*GridMap ch_DeleteMap chan *GridMap }
GridMap结构:
type GridMap struct { id int64 mapType MapType mapId int32 refProtoId int32 refId int64 relatedConfig interface{} //根据mapType不同而不同。副本是副本配置 handlers map[pbID.Message]ClientPacketHandler serverHandlers map[pbID.Message]ClientPacketHandler time int64 timeVirtual time.Time spwanMap *MonsterSpawnMap users map[int64]*MapUser Grids [][]*Grid //使用顶点是0,0的算法 //中心点是0,0的算法用map[int32]map[int32]*Grid,因为有负数 ch_Packet chan *ClientPacket ch_logOut chan *LogoutData ch_WorldServerPacket chan *ClientPacket size int32 enableGrid bool noGridLoadUsers map[int64]*MapUser fbMap *FBMap state int32 closeTimer <-chan time.Time }
LogoutData结构:
type LogoutData struct { user *MapUser isCurUserGridMap bool }
MapUser结构:
type MapUser struct { gridMap *GridMap id int64 token string session *Session pos Vector3 speed float32 name string sex int32 dress []int32 horse int32 //默认坐骑 horseSpeed float32 mountOwnerId int64 //骑在谁的马上 mountPos int32 //骑在哪个位置 passengers []int64 //自己坐骑上的乘客列表,含自己(含自己方便调整位置) pet int32 level int32 vip int32 decorate map[int32]int32 guildId int64 guildName string guildTitle int32 title int32 monsterProtectEndTime int64 inBattle bool followState MapUserFollowState followUserId int64 followedMems []int64 horseConfig *MountConfig rideInvited map[int64]struct{} //邀请列表 rideApplied map[int64]struct{} //(向别人)申请列表 canBattle bool fightData *MapUserFightData moveType int32 //当前移动方式 }
MountConfig结构:
type MountConfig struct { Mounts_id int32 Clothes int32 }
MapUserFightData结构:
type MapUserFightData struct { fightState int32 fightTime int64 fightType int32 fbId int32 //剧情战斗:剧情id 副本:副本明雷id simle:battleField id battleGround int64 }
MonsterSpawnMap结构:
type MonsterSpawnMap struct{ sceneName string //color2SpwanInfo map[int32]*MonsterSpawnConfigInfo spawnMaskImage image.Image scale float32 fullsize int32 }
MonsterSpawnConfigInfo结构:
type MonsterSpawnConfigInfo struct { Battle_id int32 Battle_name string Battle_lv int32 Battle_lv_type int32 Monsters [][]int32 Battle_areacenter [][]float32 Center []Vector3 Min_level int32 // 捕捉宠物 Probability int32 Capture_pet [][]int32 Capture_level int32 Core_pet int32 }
FBMap结构:
type FBMap struct { gridMap *GridMap wave int32 config *CopyConfig mines map[int32]*FBMine finishStar int32 }
FBMine结构:
type FBMine struct { fbMap *FBMap config *CopyUnitConfig pos Vector3 fighting bool }
4.BUFF:
BUFFTriggerEvent结构:
type BUFFTriggerEvent struct { occation BUFF_Occation skill SkillInstInterface releatedUnit *Unit releatedUnit2 *Unit doublevalue float64 intvalue int64 doublevalue2 float64 intvalue2 int64 anyvalue interface{} anyvalue2 interface{} }
BUFFConfig结构:
type BUFFConfig struct { Id int32 Name string Goodorbad int32 //1--增益 2--减益 Triggerway int32 //BUFF生效方式 1=获得时立即生效,2=逐帧触发 StateType int32 //buff类型 }
BUFFInterface结构:
type BUFFInterface interface { Trigger(event *BUFFTriggerEvent) (end bool) AddStack(newbuff *BUFF) GetID() int64 GetConfig() *BUFFConfig GetSourceSkill() SkillInstInterface GetType() int64 IsEnd() bool End() OnBeforeEnd() GetBUFF()*UnitBUFF GetEventType() int32 GetBuffType()string }
BUFF结构:
type BUFF struct { Id int64 battleGround *BattleGround Config *BUFFConfig Stack int32 StackMax int32 StartTime int64 source *Unit sourceSkill SkillInstInterface end bool EffectType int64 //效果类型 //沉默 眩晕。。。。等 thisInterface BUFFInterface eventType int32 bufftype string }
UnitBUFF结构:
BUFFInterface结构:
BUFFTriggerEvent结构:
5.Unit
Unit结构:
type Unit struct { Id int64 idForTrigger int32 Type int32 Name string BattleGround *BattleGround AttackSkill *Skill Skills map[string]*Skill SkillInstances []SkillInstInterface BUFFs []BUFFInterface BUFFMaps map[string]BUFFInterface BUFFsForTrigger map[BUFF_Occation][]BUFFInterface Pos Vector3 hp float64 hpMax float64 speed float64 Attrs []float64 Role *FightRole ProtoId int32 Dir Vector3 StandPlace int32 Team int32 Dead bool BornPos Vector3 AI AIInterface Moving bool movetarget Vector3 NavReq *NavRequest lastnavtime int64 lastmovesendtime int64 PlayerControling bool skillusingend int64 navPath NavPath reviveTime int64 attSpeed float64 nowUsedSkill SkillInstInterface ExHarm map[int32]*Seriesharm //其他单位额外增加的技能伤害Key技能属性类型,额外增加的技能伤害数量 ExSkillHarm map[int32]float64 //技能攻击力加成 ImmuneBuff int32 //免疫buff类型 changedAttrs map[int32]float64 //每一帧变化的属性 config interface{} }
PetConfig结构:
type PetConfig struct { Pet_id int32 Pet_name string Pet_model int64 UnitConfig *UnitConfig Hp float64 Att_1 float64 Att_2 float64 Def_1 float64 Def_2 float64 Run_speed float64 Hit_rate float64 Dodge_rate float64 Crit_rate float64 Uncrit_rate float64 Hurt_up float64 Hurt_down float64 Att_speed float64 Ball1_probability int32 Ball2_probability int32 Ball3_probability int32 Pet_depa_1 int32 Pet_depa_2 int32 Capture_Initialization [][]int32 //抓捕时,生成的随机类型 genCapQualityTotalRate int32 }
MonsterConfig结构:
type MonsterConfig struct { Monster_id int32 Monster_name string Monster_type int32 Prop_model int64 UnitConfig *UnitConfig Pet_depa_1 int32 Pet_depa_2 int32 Run_speed float64 Attack_id string Skill_id []string Att_speed float64 Deviation []int32 }
6.Skill
Skill结构:
type Skill struct { Owner *Unit Id string Cd int64 SkillTime int64 CdStart int64 Config *SkillConfig Level int32 }
SkillInstInterface结构:
type SkillInstInterface interface{ Start() (end bool) Update() (end bool) CheckTimeAndUpdate() (end bool) Interrupt(force bool) (end bool) //force强制打断,用于单位死亡,剧情切换等情况 GetSkill() *Skill GetId() int64 SetInst(inst SkillInstInterface) GetSkillConfig()*SkillConfig StageEnd(duration int64)(end bool) }
SkillInst结构:
SkillConfig结构:
type SkillConfig struct { Id string Name string Script string Pp float64 Cd float64 Skill_type int32 Dis_min float32 Dis_max float32 Weight int32 Skill_time float64 Start_cd float64 //Interruptable bool Skill_depa int32 Search_Type int32 Effectsid []int32 Skill_buff []int32 Growth float64 Skill_power float64 DamageType DamageType StringParams []string IntParams []int64 DoubleParams []float64 Hit_time []int64 Effect_time []int64 Floatparams []float32 }
7.FightRole结构:
type FightRole struct { Id int64 lv int32 token string BattleGround *BattleGround Session *Session team int32 Units map[int64]*Unit AttackSkill *Skill Skills []*Skill //当前可用技能 NextSkill *Skill //下次刷新技能 SkillStorehouse []*Skill //技能池 SingleFight bool //单人战斗 FixedSlotInMulFight int32 //多人战斗中的固定槽位 }
7.Target:
Target结构:
8.TriggerManager:
TriggerManager_结构:
type TriggerManager_ struct { dramaBattleTriggers map[int32][]*TriggerConfig fbBattleTriggers map[int32][]*TriggerConfig dramaEndTriggers map[int32][]*TriggerConfig battleOnceTriggers map[int64][]int32 }
TriggerConfig结构:
9.FightRole
type FightRole struct { Id int64 lv int32 token string BattleGround *BattleGround Session *Session team int32 Units map[int64]*Unit AttackSkill *Skill Skills []*Skill //当前可用技能 NextSkill *Skill //下次刷新技能 SkillStorehouse []*Skill //技能池 SingleFight bool //单人战斗 FixedSlotInMulFight int32 //多人战斗中的固定槽位 }
Package:Network
1.Sever
Server结构:
ServerOptions结构:
type ServerOptions struct{ WriteBufferLen int ReadBufferLen int StreamMode bool Timeout int }
2.Client
Client 结构:
type Client struct { id string server string Session *Session protocol ProtocolType //type ProtocolType string AutoReconnect bool Chan_Packet chan *ClientPacket Chan_Close chan *Session Chan_Connection chan *Session connected bool chan_nextconnect <-chan time.Time chan_nextheartbeat <-chan time.Time }
3.Packet
Packet结构:
type Packet struct { msgLength int version uint16 //暂时尚未使用。首位征用,用于表示是否有ReqId MessageId uint32 ErrCode uint32 data []byte hasReqId bool ReqId uint32 //在包尾 }
4.Session
Session结构:
type Session struct { Conn net.Conn Userid int64 User interface{} State int32 Account string packet *Packet HandleConnected func() ProcessPacket func(session *Session, packet *Packet) HandleClose func(session *Session) chan_packet *chan *ClientPacket IsClient bool connected bool syncRequests sync.Map cipher *rc4.Cipher reqIdNext uint32 }
Package:kcp