| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447 |
- package mapLogic
- import (
- "f1-game/internal/constant"
- "f1-game/internal/data"
- "f1-game/internal/enum"
- "f1-game/internal/extend/times"
- "f1-game/internal/pb"
- mapCall "f1-game/nodes/map/internal/call"
- "f1-game/nodes/map/internal/db"
- dbLogic "f1-game/nodes/map/internal/db/data/logic"
- clog "github.com/cherry-game/cherry/logger"
- )
- func (p *actor) legionTicker(legionTable *db.LogicLegionTable) {
- // 集结等待中
- if legionTable.LegionState == enum.LegionState_AssembleWait {
- p.legionAssembleWait(legionTable)
- return
- }
- // 集结完成
- if legionTable.LegionState == enum.LegionState_AssembleFinish {
- p.legionAssembleFinish(legionTable)
- return
- }
- // 集结行军
- if legionTable.LegionState == enum.LegionState_AssembleMarch {
- p.legionAssembleMove(legionTable)
- return
- }
- }
- // 军团集结等待
- func (p *actor) legionAssembleWait(legionTable *db.LogicLegionTable) {
- // 如果集结时间到了,就立即出发
- if p.nowMillis >= legionTable.AssembleEndTime {
- clog.Debugf("assemble timeout: LegionObjectID = %d, Target = (%d %v)",
- legionTable.ObjectID, legionTable.TargetObjectID, legionTable.TargetPoint)
- p.updateLegionState(legionTable, enum.LegionState_AssembleFinish, 0)
- return
- }
- // 检查成员是否已满,如果没满,就继续等待
- if len(legionTable.Members) < data.Const.MapAssembleMemberNum {
- return
- }
- // 检查所有成员是否都到达了
- for _, member := range legionTable.Members {
- if !member.Value {
- return
- }
- }
- clog.Debugf("assemble all ready: LegionObjectID = %d, Target = (%d %v)",
- legionTable.ObjectID, legionTable.TargetObjectID, legionTable.TargetPoint)
- // 成员满了,且都到达了,就出发
- p.updateLegionState(legionTable, enum.LegionState_AssembleFinish, 0)
- }
- // 军团集结完成
- func (p *actor) legionAssembleFinish(legionTable *db.LogicLegionTable) {
- clog.Debugf("assemble finish, LegionObjectID = %d, MemberSize = %d", legionTable.ObjectID, len(legionTable.Members))
- // 集结时间结束,只有一个成员,就解散
- if len(legionTable.Members) == 1 {
- p.legionDisband(legionTable, enum.RetreatType_Retreat, true)
- return
- }
- for _, member := range legionTable.Members {
- if !member.Value {
- marchTable := p.MarchTables.GetValue(member.Key)
- // 可能发生了碰撞
- if marchTable.State != enum.MarchState_MarchAssemble {
- return
- }
- // 如果是行军集结状态,就直接到达
- p.marchMoveToPoint(marchTable, legionTable.Point)
- // 集结逻辑
- p.marchAssemble(marchTable)
- }
- }
- // 更新状态
- stateEndTime := p.nowMillis + int64(len(legionTable.Path)-1)*legionTable.Speed + constant.TickOffset_March
- p.updateLegionState(legionTable, enum.LegionState_AssembleMarch, stateEndTime)
- // 同时更新行军对象的状态
- for _, member := range legionTable.Members {
- marchTable := p.MarchTables.GetValue(member.Key)
- marchTable.Start(legionTable.MarchType, enum.MarchState_Assemble, legionTable.Path, legionTable.Speed, p.nowMillis, marchTable.IsAutoRetreat)
- }
- // 通知联盟
- mapCall.League.AssembleUpdate(legionTable.LeagueID, &pb.AssembleUpdate{
- LegionObjectID: legionTable.ObjectID,
- IsDepart: true,
- })
- }
- // 军团集结行军
- func (p *actor) legionAssembleMove(legionTable *db.LogicLegionTable) {
- if legionTable.IsMoving() {
- p.legionAssembleMoving(legionTable)
- }
- if legionTable.IsArrived {
- p.legionArrive(legionTable)
- }
- }
- func (p *actor) legionAssembleMoving(legionTable *db.LogicLegionTable) {
- // 到达了
- if legionTable.IsMoveArrive() {
- p.legionMarkArrive(legionTable)
- return
- }
- if !legionTable.CanMove(p.nowMillis) {
- return
- }
- // 移动军团
- p.legionMove(legionTable)
- // TODO: 暂时屏蔽军团碰撞功能
- // tileTable := p.TileTables.GetValue(legionTable.GetTileID())
- // // 检查是否发生碰撞
- // isMet, isAttack := p.isLegionMarchMeet(legionTable, tileTable)
- // if isMet {
- // p.legionMeet(legionTable, tileTable, isAttack)
- // return
- // }
- // if legionTable.IsMoveArrive() {
- // p.legionMarkArrive(legionTable)
- // } else {
- // p.addLegionToTileMarch(legionTable, tileTable)
- // }
- }
- // isLegionMarchMeet 检查是否发生碰撞
- func (p *actor) isLegionMarchMeet(legionTable *db.LogicLegionTable, tileTable *db.LogicTileTable) (isMet bool, isAttack bool) {
- // 如果有碰撞,则加入进攻列表,否则加入行军列表
- isMet, isAttack = p.isTileMeet(tileTable, 0, legionTable.LeagueID)
- if isMet {
- clog.Debugf("legion march tile meet result: objectID = %d, meet = %v, attack = %v", legionTable.ObjectID, isMet, isAttack)
- }
- return
- }
- func (p *actor) legionArrive(legionTable *db.LogicLegionTable) {
- clog.Debugf("[legionArrive]: legionObjectID = %d, marchType = %v, point = %v",
- legionTable.ObjectID, enum.GetMarchTypeName(legionTable.MarchType), legionTable.Point)
- // 防止在还是移动状态的情况下,tile 还没来得及处理就又一次进入 isArrived 逻辑
- legionTable.ClearPath()
- legionTable.IsArrived = false
- for _, member := range legionTable.Members {
- marchTable := p.MarchTables.GetValue(member.Key)
- marchTable.ClearPath()
- marchTable.IsArrived = false
- }
- // 处理集结到达后的逻辑
- switch legionTable.MarchType {
- case enum.MarchType_Crucade:
- // 讨伐
- p.legionCrucade(legionTable)
- case enum.MarchType_Siege:
- // 攻城
- p.legionSiege(legionTable)
- default:
- // 否则解散
- p.legionDisband(legionTable, enum.RetreatType_Retreat, true)
- }
- }
- func (p *actor) legionCrucade(legionTable *db.LogicLegionTable) {
- clog.Debugf("legion crucade: LegionObjectID = %d, Target = (%d %v)",
- legionTable.ObjectID, legionTable.TargetObjectID, legionTable.TargetPoint)
- tileTable := p.TileTables.GetValue(legionTable.GetTileID())
- monsterTable, ok := p.getMonsterTableInTile(tileTable)
- if !ok {
- clog.Debugf("[legionCrucade] Monster not found: MarchObjectID = %d, Point = %v", legionTable.ObjectID, tileTable.Point)
- p.legionDisband(legionTable, enum.RetreatType_Retreat, true)
- return
- }
- // 刷了新的怪物
- if monsterTable.ObjectID != legionTable.TargetObjectID {
- clog.Debugf("[legionCrucade] Monster not match: MarchObjectID = %d, Point = %v, Target = %d, Found = %d",
- legionTable.ObjectID, tileTable.Point, legionTable.TargetObjectID, monsterTable.ObjectID)
- p.legionDisband(legionTable, enum.RetreatType_Retreat, true)
- return
- }
- // 加入讨伐列表
- tileTable.AddCrusade(legionTable.ObjectID, dbLogic.NewTileLegionInfo(
- tileTable.TileID,
- legionTable.ObjectID,
- p.nowMillis,
- legionTable.MemberIDList(),
- ))
- // 设置为战斗状态
- p.updateLegionState(legionTable, enum.LegionState_BattleWait, 0)
- p.addTileProcess(tileTable)
- }
- func (p *actor) legionSiege(legionTable *db.LogicLegionTable) {
- clog.Debugf("legion siege: LegionObjectID = %d, Target = (%d %v)",
- legionTable.ObjectID, legionTable.TargetObjectID, legionTable.TargetPoint)
- tileTable := p.TileTables.GetValue(legionTable.GetTileID())
- mapSiegeObject, ok := p.getSiegeTable(tileTable)
- if !ok {
- clog.Debugf("[legionSiege]: siege not found, MarchObjectID = %v, Point = %v", legionTable.ObjectID, legionTable.Point)
- p.legionDisband(legionTable, enum.RetreatType_Retreat, true)
- return
- }
- // 不可以攻城
- if !p.canLegionSiege(legionTable, mapSiegeObject) {
- clog.Debugf("[legionSiege]: not siegeable, MarchObjectID = %v, LeagueID = %v, SiegeObject = %v",
- legionTable.ObjectID, legionTable.LeagueID, mapSiegeObject)
- p.legionDisband(legionTable, enum.RetreatType_Retreat, true)
- return
- }
- // 更新为攻城状态
- p.updateLegionState(legionTable, enum.LegionState_Siege, 0)
- tileLegionInfo := dbLogic.NewTileLegionInfo(
- tileTable.TileID,
- legionTable.ObjectID,
- p.nowMillis,
- legionTable.MemberIDList(),
- )
- // 设置为首次攻城
- tileLegionInfo.IsFirstSiege = true
- // 等待一个 ticker
- tileLegionInfo.LogicEndTime = p.nowMillis + 1000
- // 加入攻城列表
- tileTable.AddSiege(legionTable.ObjectID, tileLegionInfo)
- p.addTileProcess(tileTable)
- }
- // TODO 先不支持集结攻城
- func (p *actor) canLegionSiege(legionTable *db.LogicLegionTable, siegeTable *db.LogicSiegeTable) bool {
- // // 判断建筑是否可以攻打
- // if buildTable, ok := siegeObject.(*db.MapBuildTable); ok {
- // return buildTable.LeagueID != legionTable.LeagueID
- // }
- // // 判断城池是否可以攻打
- // if castleTable, ok := siegeObject.(*db.MapCastleTable); ok {
- // // 己方城池不可攻打
- // if castleTable.LeagueID == legionTable.LeagueID {
- // return false
- // }
- // // 没有占领攻城大营不可攻打
- // siegeInfo, ok := castleTable.SiegeInfo.Get(legionTable.LeagueID)
- // if !ok {
- // return false
- // }
- // // 不在攻城时间内不可攻打
- // return siegeInfo.Stage == enum.SiegeStage_Battle
- // }
- return false
- }
- func (p *actor) legionSiegeFail(legionTable *db.LogicLegionTable, tileTable *db.LogicTileTable) {
- // 移除攻城列表
- tileTable.RemoveSiege(legionTable.ObjectID)
- // 解散
- p.legionDisband(legionTable, enum.RetreatType_Rout, true)
- }
- func (p *actor) addLegionToTileMarch(legionTable *db.LogicLegionTable, tileTable *db.LogicTileTable) {
- for _, member := range legionTable.Members {
- marchTable := p.MarchTables.GetValue(member.Key)
- p.addToTileMarch(marchTable, tileTable)
- }
- }
- func (p *actor) legionMeet(legionTable *db.LogicLegionTable, tileTable *db.LogicTileTable, isAttack bool) {
- clog.Debugf("legion meet: LegionObjectID = %d, Target = (%d %v)",
- legionTable.ObjectID, legionTable.TargetObjectID, legionTable.TargetPoint)
- if isAttack {
- tileTable.AddAttackList(legionTable.ObjectID, dbLogic.NewTileLegionInfo(
- tileTable.TileID,
- legionTable.ObjectID,
- p.nowMillis,
- legionTable.MemberIDList(),
- ))
- // 保存当前状态
- legionTable.SaveState(p.nowMillis)
- // 设为战斗等待状态
- p.updateLegionState(legionTable, enum.LegionState_BattleWait, 0)
- } else {
- tileTable.AddMarch(legionTable.ObjectID, dbLogic.NewTileLegionInfo(
- tileTable.TileID,
- legionTable.ObjectID,
- p.nowMillis,
- legionTable.MemberIDList(),
- ))
- }
- }
- func (p *actor) legionMove(legionTable *db.LogicLegionTable) {
- legionTable.MoveNextTile(p.nowMillis)
- for _, member := range legionTable.Members {
- marchTable := p.MarchTables.GetValue(member.Key)
- marchTable.MoveNextTile(p.nowMillis)
- }
- mapCall.AOI.Move(legionTable.ToAOIMarker())
- // 从上一个格子的行军列表移除
- if prevTileID, ok := data.PointToTileID(legionTable.PrevPoint.X, legionTable.PrevPoint.Y); ok {
- prevTileTable := p.TileTables.GetValue(prevTileID)
- prevTileTable.RemoveMarch(legionTable.ObjectID)
- p.addTileProcess(prevTileTable)
- }
- clog.Debugf("Legion move: LegionObjectID = %d, Point = %v", legionTable.ObjectID, legionTable.Point)
- }
- func (p *actor) legionMarkArrive(legionTable *db.LogicLegionTable) {
- clog.Debugf("legion move arrive: LegionObjectID = %d, Target = (%d %v)",
- legionTable.ObjectID, legionTable.TargetObjectID, legionTable.TargetPoint)
- for _, member := range legionTable.Members {
- marchTable := p.MarchTables.GetValue(member.Key)
- marchTable.MarkArrive(true)
- }
- legionTable.IsArrived = true
- legionTable.IsDataChanged = true
- }
- func (p *actor) legionSave(legionTable *db.LogicLegionTable) {
- legionTable.IsDataChanged = false
- legionTable.Save2Queue()
- }
- // 军团解散
- func (p *actor) legionDisband(legionTable *db.LogicLegionTable, restreatType enum.RetreatType, notice bool) {
- clog.Debugf("[legionDisband] LegionObjectID = %d", legionTable.ObjectID)
- for _, member := range legionTable.Members {
- marchTable := p.MarchTables.GetValue(member.Key)
- marchTable.SetLegionObjectID(0)
- // 到达的成员撤退
- if member.Value {
- p.markMarchRetreat(marchTable, restreatType, false)
- }
- }
- legionTable.IsDelete = true
- legionTable.IsDataChanged = true
- // 离开aoi
- p.legionLeaveAOI(legionTable)
- // 通知联盟
- if notice {
- mapCall.League.AssembleUpdate(legionTable.LeagueID, &pb.AssembleUpdate{
- LegionObjectID: legionTable.ObjectID,
- IsDisband: true,
- })
- }
- }
- func (p *actor) updateLegionState(legionTable *db.LogicLegionTable, newState enum.LegionState, endTime int64) {
- if endTime > 0 {
- clog.Debugf("[updateLegionState] objectID = %d, state = %s -> %s, endTime = %s",
- legionTable.ObjectID,
- enum.GetLegionStateName(legionTable.LegionState),
- enum.GetLegionStateName(newState),
- times.MillisToDatetimeFormat(endTime),
- )
- } else {
- clog.Debugf("[updateLegionState] objectID = %d, state = %s -> %s",
- legionTable.ObjectID,
- enum.GetLegionStateName(legionTable.LegionState), enum.GetLegionStateName(newState))
- }
- legionTable.UpdateLegionState(newState)
- legionTable.UpdateMarchState(enum.GetMarchStateByLegionState(newState), p.nowMillis, endTime)
- p.UpdateObjectFull(legionTable.ObjectID, legionTable.Type)
- }
- // func (p *actor) restoreLegionState(legionTable *db.MapLegionTable) {
- // clog.Debugf("[restoreLegionState] state = %s -> %s, time offset = %v",
- // enum.GetLegionStateName(legionTable.LegionState),
- // enum.GetLegionStateName(legionTable.PrevState),
- // p.nowMillis-legionTable.PrevStateSaveTime)
- // legionTable.RestoreState(p.nowMillis)
- // // 推送march状态给客户端
- // // mapCall.Pusher.MapMarchStateWatcherPush(marchTable.ObjectID)
- // }
- func (p *actor) addLegionAOI(legionTable *db.LogicLegionTable) {
- marker := legionTable.ToAOIMarker()
- mapCall.AOI.Enter(marker)
- }
- func (p *actor) legionLeaveAOI(legionTable *db.LogicLegionTable) {
- mapCall.AOI.Leave(legionTable.ObjectID, legionTable.Type)
- }
- func (p *actor) legionMemberQuit(legionTable *db.LogicLegionTable, marchObjectID int64) {
- legionTable.RemoveMember(marchObjectID)
- if legionTable.LeadObjectID == marchObjectID && legionTable.LegionState == enum.LegionState_AssembleWait || len(legionTable.Members) == 0 {
- p.legionDisband(legionTable, enum.RetreatType_Must, true)
- } else {
- mapCall.League.AssembleUpdate(legionTable.LeagueID, &pb.AssembleUpdate{
- LegionObjectID: legionTable.ObjectID,
- QuitMember: marchObjectID,
- })
- }
- legionTable.IsDataChanged = true
- }
|