| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602 |
- package mapPlayer
- import (
- capp "f1-game/internal/cherry_app"
- "f1-game/internal/code"
- "f1-game/internal/component/redis"
- "f1-game/internal/constant"
- "f1-game/internal/data"
- "f1-game/internal/enum"
- "f1-game/internal/event"
- nameActor "f1-game/internal/name/actor"
- nameLocal "f1-game/internal/name/local"
- nameRedis "f1-game/internal/name/redis"
- nameRemote "f1-game/internal/name/remote"
- nameRoute "f1-game/internal/name/route"
- "f1-game/internal/pb"
- "f1-game/internal/sessions"
- "f1-game/internal/types"
- ao "f1-game/nodes/game/player/asset/origin"
- mapCall "f1-game/nodes/map/internal/call"
- "f1-game/nodes/map/internal/db"
- dbMapPlayer "f1-game/nodes/map/internal/db/data/player"
- mapFacade "f1-game/nodes/map/internal/facade"
- mapTypes "f1-game/nodes/map/internal/types"
- "f1-game/nodes/map/player/battle"
- "f1-game/nodes/map/player/facility"
- sandMap "f1-game/nodes/map/player/map"
- "f1-game/nodes/map/player/player"
- "f1-game/nodes/map/player/scout"
- "f1-game/nodes/map/player/storage"
- "f1-game/nodes/map/player/team"
- "time"
- ctime "github.com/cherry-game/cherry/extend/time"
- cfacade "github.com/cherry-game/cherry/facade"
- cproto "github.com/cherry-game/cherry/net/proto"
- )
- func (p *actorPlayer) initMap() {
- p.Local().Register(nameLocal.MapPlayer_Login, p.login)
- p.Local().Register(nameLocal.MapPlayer_Enter, p.enter)
- p.Local().Register(nameLocal.MapPlayer_SelectState, p.selectState)
- p.Local().Register(nameLocal.MapPlayer_BornStateInfo, p.bornStateInfo)
- p.Local().Register(nameLocal.MapPlayer_Join, p.join)
- p.Local().Register(nameLocal.MapPlayer_Quit, p.quit)
- p.Local().Register(nameLocal.MapPlayer_Slide, p.slide)
- p.Local().Register(nameLocal.MapPlayer_March, p.march)
- p.Local().Register(nameLocal.MapPlayer_Retreat, p.retreat)
- p.Local().Register(nameLocal.MapPlayer_MarchStop, p.marchStop)
- p.Local().Register(nameLocal.MapPlayer_Discard, p.discard)
- p.Local().Register(nameLocal.MapPlayer_DiscardCancel, p.discardCancel)
- p.Local().Register(nameLocal.MapPlayer_Build, p.build)
- p.Local().Register(nameLocal.MapPlayer_BuildUpgrade, p.buildUpgrade)
- p.Local().Register(nameLocal.MapPlayer_Relocate, p.relocate)
- p.Local().Register(nameLocal.MapPlayer_Comeback, p.comeback)
- p.Local().Register(nameLocal.MapPlayer_Reborn, p.reborn)
- p.Local().Register(nameLocal.MapPlayer_MapMark, p.mapMark)
- p.Local().Register(nameLocal.MapPlayer_MapMarkDelete, p.mapMarkDelete)
- p.Local().Register(nameLocal.MapPlayer_SiegeAssemble, p.siegeAssemble)
- p.Local().Register(nameLocal.MapPlayer_SiegeRank, p.siegeRank)
- p.Local().Register(nameLocal.MapPlayer_FindPath, p.findPath)
- p.Local().Register(nameLocal.MapPlayer_OccupyCastleList, p.occupyCastleList)
- p.Local().Register(nameLocal.MapPlayer_ScoutRequest, p.scoutRequest)
- p.Local().Register(nameLocal.MapPlayer_Reinforce, p.reinforce)
- p.Local().Register(nameLocal.MapPlayer_ReinforceCancel, p.reinforceCancel)
- p.Local().Register(nameLocal.MapPlayer_ResArmies, p.resArmies)
- p.Local().Register(nameLocal.MapPlayer_MapObjectPosition, p.mapObjectPosition)
- p.Remote().Register(nameRemote.MapPlayer_AutoRetreat, p.autoRetreat)
- p.Remote().Register(nameRemote.MapPlayer_AutoReborn, p.autoReborn)
- p.Remote().Register(nameRemote.MapPlayer_UpdatePrestige, p.updatePrestige)
- p.Remote().Register(nameRemote.MapPlayer_MainCitySiege, p.mainCitySiege)
- p.Remote().Register(nameRemote.MapPlayer_UpdateWatcherPoint, p.updateWatcherPoint)
- p.Remote().Register(nameRemote.MapPlayer_AutoDefendQuit, p.autoDefendQuit)
- p.Remote().Register(nameRemote.MapPlayer_AutoDefendRequest, p.autoDefendRequest)
- p.Remote().Register(nameRemote.MapPlayer_ResOccupy, p.resOccupy)
- p.Remote().Register(nameRemote.MapPlayer_ResUpdate, p.resUpdate)
- p.Remote().Register(nameRemote.MapPlayer_UpdateCastleResYield, p.updateCastleResYield)
- p.Remote().Register(nameRemote.MapScout_UpdateNotice, p.scoutUpdateNotice)
- p.Remote().Register(nameRemote.MapScout_Seach, p.scoutSearch)
- p.Remote().Register(nameRemote.MapScout_SeachResult, p.scoutSearchResult)
- p.Remote().Register(nameRemote.MapPlayer_NotifyRebornPush, p.notifyRebornPush)
- p.Remote().Register(nameRemote.MapPlayer_AutoMarchRequest, p.autoMarch)
- p.Remote().Register(nameRemote.Game_UpdateTimeOffset, p.updateTimeOffset)
- }
- // login 玩家登录地图
- func (p *actorPlayer) login(session *cproto.Session, _ *pb.None) {
- p.Debug("player login map")
- if p.isOnline {
- p.ResponseCode(session, code.OK)
- return
- }
- p.updateNowTime()
- // 检查玩家表是否存在,没有则创建
- playerTable, isNewPlayer := db.CheckMapPlayerTable(p.playerID)
- if isNewPlayer {
- session.Add(sessions.IsNewPlayer, isNewPlayer)
- }
- p.Debug("Player login map success")
- p.onReset(playerTable, true)
- // 登录前事件处理
- ServiceOnLogin(playerTable, session)
- // 推送各个模块数据
- ServicePush(playerTable, session)
- // 设置actor为登录状态
- p.isOnline = true
- // 返回玩家地图的信息
- p.Response(session, playerTable.ToMapLoginResponse())
- // 在线状态设置后,再启动定时器
- p.startTimer()
- // 登录后事件处理
- ServiceOnLogined(playerTable, session)
- }
- // enter 玩家进入地图
- func (p *actorPlayer) enter(session *cproto.Session, _ *pb.None) {
- p.Debug("player enter map")
- if !p.isOnline {
- p.ResponseCode(session, code.PlayerNotLogin)
- return
- }
- playerTable := db.GetMapPlayerTable(p.playerID)
- // 未选择出生州
- if !playerTable.IsSelectBornState() {
- p.ResponseCode(session, code.Map_NotSelectState)
- return
- }
- rsp, errCode := mapCall.Logic.Enter(p.playerID)
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- p.Debug("Player enter map success")
- // TODO: 这些分散的信息后序根据业务看看是否可以放在一起,比如 warcher 中
- rsp.CityBaseEndTime = playerTable.Builds.CityBaseEndTime
- rsp.ComebackEndTime = playerTable.ComebackEndTime
- rsp.RechooseComebackEndTime = playerTable.RechooseComebackEndTime
- rsp.RelocateEndTime = playerTable.Builds.RelocateEndTime
- rsp.ResDefends = playerTable.Defends.ToProto()
- p.Response(session, rsp)
- }
- // selectState 选择出生州,只在玩家首次进入地图时调用
- // 后序跨逻辑调选州再起
- func (p *actorPlayer) selectState(session *cproto.Session, req *pb.I32) {
- playerTable := db.GetMapPlayerTable(p.playerID)
- if playerTable.IsSelectBornState() {
- p.ResponseCode(session, code.Map_AlreadySelectState)
- return
- }
- arg := &pb.SelectStateRequest{
- StateID: req.Value,
- PlayerID: p.playerID,
- LeagueID: playerTable.LeagueID,
- }
- // 新玩家从 redis 获取一次数据
- playerData := redis.Game.GetPlayerData(p.playerID, nameRedis.PlayerInfoFields...)
- if playerData != nil {
- arg.PlayerName = playerData.PlayerName
- arg.IconID = playerData.IconID
- arg.FrameID = playerData.FrameID
- }
- // 调用 logic 选择出生州
- rsp, errCode := mapCall.Logic.SelectState(arg)
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- // 更新出生州ID
- playerTable.ObjectID = rsp.ObjectID
- playerTable.SetPoint(rsp.Point.X, rsp.Point.Y)
- playerTable.BornStateID = req.Value
- playerTable.Save2Queue()
- // 同步城建属性给logic watcher
- capp.PostEvent(event.NewMapWatcherSync(playerTable.PlayerID, &event.MapWatcherData{
- PlayerID: playerTable.PlayerID,
- IsFacilitySync: true,
- FacilityAttrs: playerTable.Facilities.Attrs,
- }))
- p.ResponseCode(session, code.OK)
- }
- // bornStateInfo 获取出生州信息
- func (p *actorPlayer) bornStateInfo(session *cproto.Session, _ *pb.None) {
- rsp, errCode := mapCall.Logic.BornStateInfo()
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- p.Response(session, rsp)
- }
- // join 以观察者进入地图
- func (p *actorPlayer) join(session *cproto.Session, _ *pb.None) {
- p.Debug("player join map")
- playerTable := db.GetMapPlayerTable(p.playerID)
- mapCall.AOI.Enter(playerTable.ToAOIWatcher())
- }
- // quit 以观察者退出地图
- func (p *actorPlayer) quit(session *cproto.Session, _ *pb.None) {
- p.Debug("player quit map")
- playerTable := db.GetMapPlayerTable(p.playerID)
- mapCall.AOI.Leave(playerTable.ObjectID, enum.ObjectType_Player)
- mapCall.Logic.Quit(p.playerID)
- }
- // slide 滑动屏幕
- func (p *actorPlayer) slide(session *cproto.Session, req *pb.Point) {
- p.Debug("player slide: %v", req)
- playerTable := db.GetMapPlayerTable(p.playerID)
- aoiRequest := mapTypes.NewAOIRequest(p.playerID, playerTable.ObjectID, enum.ObjectType_Player, req.X, req.Y, true)
- mapCall.AOI.Move(aoiRequest)
- }
- // march 行军
- func (p *actorPlayer) march(session *cproto.Session, req *pb.MapMarchRequest) {
- marchType := enum.MarchType(req.MarchType)
- // 检查是否为不支持的行军类型
- if enum.IsNotAllowMarchType(marchType) {
- p.ResponseCode(session, code.MapUnsupportMarchType)
- return
- }
- playerTable := db.GetMapPlayerTable(p.playerID)
- dbTeam, ok := playerTable.Teams.GetTeam(req.TeamID)
- if !ok {
- p.ResponseCode(session, code.MapTeamNotFound)
- return
- }
- if errCode := dbTeam.IsBusy(); code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- var startPoint types.Point
- if dbTeam.IsNeedSync() {
- startPoint.Set(&playerTable.Point)
- } else {
- // 获取行军对象坐标
- errCode := mapCall.Logic.GetObject1Point(dbTeam.MarchObjectID, enum.ObjectType_March, &startPoint)
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- }
- // 寻路
- path, errCode := p.findMarchPath(playerTable, startPoint.X, startPoint.Y, req.Point.X, req.Point.Y, req.TargetObjectID, marchType)
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- // 检查消耗
- errCode = team.Service().CheckMarchCost(p.playerID, req.TeamID, marchType, len(path))
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- // 调用地图行军
- arg := &pb.MarchRequest{
- TeamID: dbTeam.TeamID,
- ObjectID: dbTeam.MarchObjectID,
- MarchType: req.MarchType,
- Point: req.Point,
- Path: path,
- IsAutoRetreat: req.IsAutoRetreat,
- TargetObjectID: req.TargetObjectID,
- }
- if dbTeam.IsNeedSync() {
- arg.MarchSync = team.Service().GetTeamMarchSyncProto(playerTable, dbTeam)
- }
- // 取消城外自动征兵
- p.marchOutsideTroopsCancel(playerTable, dbTeam)
- rsp, errCode := mapCall.Logic.March(arg)
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- // 保存行军对象ID
- if dbTeam.MarchObjectID == 0 {
- dbTeam.MarchObjectID = rsp.Key
- }
- // 设置自动征兵
- dbTeam.IsAutoTroops = req.IsAutoConscript
- playerTable.Save2Queue()
- // 扣除资源
- team.Service().MarchCost(p.playerID, req.TeamID, marchType, len(path))
- // 更新队伍状态
- team.Service().UpdateTeamStateByMarchState(playerTable, dbTeam, enum.MarchState(rsp.Value))
- p.ResponseCode(session, code.OK)
- }
- func (p *actorPlayer) findMarchPath(playerTable *db.MapPlayerTable, sx, sy, ex, ey int32, targetObjectID int64, marchType enum.MarchType) ([]*pb.Point, int32) {
- path, errCode := mapCall.PathFind.Find(sx, sy, ex, ey, p.playerID, playerTable.LeagueID, marchType)
- if code.IsFail(errCode) {
- return nil, errCode
- }
- // 如果不是攻城类型,寻路到请求的坐标点
- if marchType != enum.MarchType_Siege && marchType != enum.MarchType_Snatch {
- return path, code.OK
- }
- siegePoints, errCode := mapCall.Logic.GetSiegePoints(targetObjectID)
- if code.IsFail(errCode) {
- return nil, errCode
- }
- p.Debug("[findMarchPath] get siege points: %+v", siegePoints)
- if len(siegePoints.Points) == 0 {
- return path, code.OK
- }
- // 从最小距离到最大距离,对路点列表进行比较
- pathLen := len(path)
- i := siegePoints.MinDistance
- outer:
- for ; i <= siegePoints.MaxDistance; i++ {
- point := path[pathLen-int(i)]
- for _, siegePoint := range siegePoints.Points {
- if siegePoint.X == point.X && siegePoint.Y == point.Y {
- break outer // found
- }
- }
- }
- return path[:pathLen-int(i)+1], code.OK
- }
- // retreat 主动回城
- func (p *actorPlayer) retreat(session *cproto.Session, req *pb.I32I64) {
- var (
- teamID = req.Key
- redeployObjectID = req.Value
- )
- playerTable := db.GetMapPlayerTable(p.playerID)
- dbTeam, ok := playerTable.Teams.GetTeam(teamID)
- if !ok {
- p.ResponseCode(session, code.MapTeamNotFound)
- return
- }
- if dbTeam.IsStandby() {
- p.ResponseCode(session, code.OK)
- return
- }
- var (
- startPoint types.Point
- endPoint types.Point
- )
- // 没有传入调动对象ID,就回主城
- // 撤退回主城是不是就要把调动值清除了?
- if redeployObjectID == 0 {
- // 默认回主城,只拿部队的坐标
- endPoint.Set(&playerTable.Point)
- errCode := mapCall.Logic.GetObject1Point(dbTeam.MarchObjectID, enum.ObjectType_March, &startPoint)
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- // 把部队的调动信息删除
- dbTeam.RedeployObject.Set(0, 0)
- playerTable.Save2Queue()
- } else {
- // 回调动点
- if redeployObjectID != dbTeam.RedeployObject.Key {
- p.ResponseCode(session, code.MapRetreat_NotRedeploy)
- return
- }
- // 获取行军对象和调动点的坐标
- var (
- marchObject = enum.NewObject(dbTeam.MarchObjectID, enum.ObjectType_March)
- redeployObject = enum.NewObject(redeployObjectID, dbTeam.RedeployObject.Value)
- errCode = mapCall.Logic.GetObject2Point(marchObject, redeployObject, &startPoint, &endPoint)
- )
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- }
- // 取消城外自动征兵
- p.marchOutsideTroopsCancel(playerTable, dbTeam)
- // 寻路
- path, errCode := mapCall.PathFind.Find(startPoint.X, startPoint.Y, endPoint.X, endPoint.Y, p.playerID, playerTable.LeagueID, enum.MarchType_Retreat)
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- // 调用地图行军
- arg := &pb.MarchRequest{
- TeamID: dbTeam.TeamID,
- ObjectID: dbTeam.MarchObjectID,
- MarchType: int32(enum.MarchType_Retreat),
- Point: endPoint.ToProto(),
- Path: path,
- RetreatState: int32(enum.MarchState_Retreat),
- TargetObjectID: redeployObjectID, // 如果是0,要在 logic 判断撤退的目标
- }
- rsp, errCode := mapCall.Logic.Retreat(arg)
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- // 更新队伍状态
- team.Service().UpdateTeamStateByMarchState(playerTable, dbTeam, enum.MarchState(rsp.Value))
- p.ResponseCode(session, code.OK)
- }
- // 行军中止
- func (p *actorPlayer) marchStop(session *cproto.Session, req *pb.I32) {
- playerTable := db.GetMapPlayerTable(p.playerID)
- march, ok := playerTable.Teams.GetTeam(req.Value)
- if !ok {
- p.ResponseCode(session, code.MapTeamNotFound)
- return
- }
- errCode := mapCall.Logic.MarchStop(march.MarchObjectID)
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- p.ResponseCode(session, code.OK)
- }
- // discard 放弃地图上的对象
- func (p *actorPlayer) discard(session *cproto.Session, req *pb.I64I32) {
- var (
- objectID = req.Key
- objectType = enum.ObjectType(req.Value)
- )
- // 放弃资源
- if objectType == enum.ObjectType_Res {
- errCode := mapCall.Logic.ResDiscard(p.playerID, objectID)
- p.ResponseCode(session, errCode)
- return
- }
- // 放弃建筑
- if objectType == enum.ObjectType_Build {
- _, errCode := mapCall.Logic.BuildDiscard(p.playerID, objectID)
- p.ResponseCode(session, errCode)
- return
- }
- p.ResponseCode(session, code.MapObjectTypeUnkown)
- }
- // discardCancel 取消放弃对象
- func (p *actorPlayer) discardCancel(session *cproto.Session, req *pb.I64I32) {
- var (
- objectID = req.Key
- objectType = req.Value
- )
- p.Debug("discardCancel playerID: %d, objectID: %d, objectType: %s", p.playerID, objectID, enum.GetObjectTypeName(enum.ObjectType(objectType)))
- errCode := mapCall.Logic.DiscardCancelPlayer(p.playerID, objectID, objectType)
- p.ResponseCode(session, errCode)
- }
- func (p *actorPlayer) build(session *cproto.Session, req *pb.MapBuildRequest) {
- row, ok := data.MapBuild.GetByConfigID(req.ConfigID)
- if !ok {
- p.ResponseCode(session, code.ConfigNotFound_MapBuild)
- return
- }
- if row.BuildType != enum.BuildType_Player {
- p.ResponseCode(session, code.MapBuild_NotPlayerBuild)
- return
- }
- playerTable := db.GetMapPlayerTable(p.playerID)
- // 如果当前建造的是玩家地基 需要判断是否在冷却时间内
- if req.ConfigID == constant.MapBuild_CityBase && playerTable.Builds.IsCityBaseCooldowning() {
- p.ResponseCode(session, code.MapBuild_FoundateCooldown)
- return
- }
- if !mapFacade.Storage.IsAllEnough(p.playerID, row.BuildCost) {
- p.ResponseCode(session, code.ItemNotEnough)
- return
- }
- var (
- buildCount = playerTable.Builds.GetBuildCount(req.ConfigID)
- buildCountLimit = facility.Service().GetBuildCountLimit(playerTable, row)
- )
- // 计算建造时间
- buildTime := row.BuildTime
- // 首次建造
- if buildCount == 0 {
- if time, ok := data.Const.MapBuildFirstTimeElapsed[req.ConfigID]; ok {
- buildTime = time
- }
- }
- arg := pb.BuildRequest{
- ConfigID: req.ConfigID,
- PlayerID: p.playerID,
- LeagueID: playerTable.LeagueID,
- X: req.Point.X,
- Y: req.Point.Y,
- BuildEndTime: ctime.Now().ToMillisecond() + buildTime*ctime.MillisecondsPerSecond,
- BuildLimit: buildCountLimit,
- }
- _, errCode := mapCall.Logic.Build(&arg)
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- // 扣除道具
- mapFacade.Storage.AssetSubs(p.playerID, row.BuildCost, ao.None, true)
- // 增加建筑数量
- playerTable.Builds.AddBuildCount(req.ConfigID)
- resp := &pb.I64{}
- // 记录地基建造冷却时间戳
- if req.ConfigID == constant.MapBuild_CityBase {
- playerTable.Builds.CityBaseEndTime = ctime.Now().ToMillisecond() + data.Const.GetMapCityBaseCooldown()
- resp.Value = playerTable.Builds.CityBaseEndTime
- }
- playerTable.Save2Queue()
- p.Response(session, resp)
- }
- // 玩家建筑升级
- func (p *actorPlayer) buildUpgrade(session *cproto.Session, req *pb.MapBuildUpgradeRequest) {
- var (
- objectID = req.ObjectID
- configID = req.ConfigID
- level = req.Level
- )
- mapBuildRow, found := data.MapBuild.GetByConfigID(configID)
- if !found {
- p.ResponseCode(session, code.ConfigNotFound_MapBuild)
- return
- }
- // 不是玩家建筑
- if mapBuildRow.BuildType != enum.BuildType_Player {
- p.ResponseCode(session, code.MapBuild_NotPlayerBuild)
- return
- }
- mapBuildUpgradeRow, found := data.MapBuildUpgrade.GetByConfigIDLevel(configID, level)
- if !found {
- p.ResponseCode(session, code.ConfigNotFound_MapBuildUpgrade)
- return
- }
- if !mapFacade.Storage.IsAllEnough(p.playerID, mapBuildUpgradeRow.UpgradeCost) {
- p.ResponseCode(session, code.ItemNotEnough)
- return
- }
- arg := &pb.BuildUpgradeRequest{
- ObjectID: objectID,
- ConfigID: configID,
- PlayerID: p.playerID,
- Level: level,
- UpgradeEndTime: ctime.Now().ToMillisecond() + mapBuildUpgradeRow.UpgradeTime*ctime.MillisecondsPerSecond,
- }
- errCode := mapCall.Logic.BuildUpgrade(arg)
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- mapFacade.Storage.AssetSubs(p.playerID, mapBuildUpgradeRow.UpgradeCost, ao.None, true)
- p.ResponseCode(session, code.OK)
- }
- // relocate 玩家迁城
- func (p *actorPlayer) relocate(session *cproto.Session, req *pb.I64) {
- // 判断是否可以迁城
- if errCode := p.relocatable(); code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- cityBaseObjectID := req.Value
- point, errCode := mapCall.Logic.Relocate(p.playerID, cityBaseObjectID)
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- playerTable := db.GetMapPlayerTable(p.playerID)
- // 如果玩家存在联盟 删除驻地信息
- if playerTable.LeagueID > 0 {
- removeReq := &pb.I64{Value: p.playerID}
- target := cfacade.NewChildPath("", nameActor.Map_League, playerTable.LeagueID)
- capp.Call(target, nameRemote.MapLeague_ResidenceRemove, removeReq)
- }
- // 更新迁城冷却时间
- playerTable.Builds.RelocateEndTime = p.now.ToMillisecond() + data.Const.GetMapRelocateCooldown()
- playerTable.SetPoint(point.X, point.Y)
- playerTable.Save2Queue()
- resp := &pb.I64{
- Value: playerTable.Builds.RelocateEndTime,
- }
- p.Response(session, resp)
- }
- func (p *actorPlayer) relocatable() int32 {
- p.updateNowTime()
- playerTable := db.GetMapPlayerTable(p.playerID)
- // 迁城冷却中
- if playerTable.Builds.RelocateEndTime > p.now.ToMillisecond() {
- return code.MapRelocate_Cooldown
- }
- // 没有加入联盟,不能迁城
- if playerTable.LeagueID == 0 {
- return code.MapRelocate_NoLeague
- }
- // TODO 其它限制,比如:主城被攻击,攻城时间
- return code.OK
- }
- // comeback 玩家再起
- func (p *actorPlayer) comeback(session *cproto.Session, req *pb.I32Bool) {
- var (
- stateID = req.Key // 州ID
- rechoose = req.Value // 是否重新选州
- )
- p.Debug("[comeback] stateID = %d, rechoose = %v", stateID, rechoose)
- // 再起冷却中
- playerTable := db.GetMapPlayerTable(p.playerID)
- p.updateNowTime()
- if rechoose {
- if playerTable.RechooseComebackEndTime > p.now.ToMillisecond() {
- p.ResponseCode(session, code.MapComeback_Cooldown)
- return
- }
- // 不能重选当前州
- if stateID == playerTable.BornStateID {
- p.ResponseCode(session, code.MapComeback_SameState)
- return
- }
- // 需要退联盟
- if playerTable.LeagueID != 0 {
- p.ResponseCode(session, code.MapComeback_NeedLeagueQuit)
- return
- }
- } else {
- if playerTable.ComebackEndTime > p.now.ToMillisecond() {
- p.ResponseCode(session, code.MapComeback_Cooldown)
- return
- }
- // 非重新选州,使用当前出生州
- stateID = playerTable.BornStateID
- }
- point, errCode := mapCall.Logic.Comeback(p.playerID, rechoose, stateID)
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- if rechoose {
- playerTable.BornStateID = stateID
- playerTable.RechooseComebackEndTime = p.now.ToMillisecond() + data.Const.GetMapRechooseComebackCoolDown()
- } else {
- playerTable.ComebackEndTime = p.now.ToMillisecond() + data.Const.GetMapComebackCoolDown()
- }
- player.Service().UpdateWatcherPoint(playerTable, point.X, point.Y)
- // 如果玩家存在联盟 删除驻地信息
- if playerTable.LeagueID > 0 {
- removeReq := &pb.I64{Value: p.playerID}
- target := cfacade.NewChildPath("", nameActor.Map_League, playerTable.LeagueID)
- capp.Call(target, nameRemote.MapLeague_ResidenceRemove, removeReq)
- }
- rsp := pb.ComebackResponse{
- Point: point,
- ComebackEndTime: playerTable.ComebackEndTime,
- RechooseComebackEndTime: playerTable.RechooseComebackEndTime,
- }
- p.Response(session, &rsp)
- }
- // autoReborn 玩家自动重新出生
- func (p *actorPlayer) autoReborn() {
- p.Debug("[autoReborn]")
- playerTable := db.GetMapPlayerTable(p.playerID)
- if playerTable.BornStateID == 0 {
- p.Warn("[autoReborn] player not select state")
- return
- }
- point, errCode := mapCall.Logic.Reborn(p.playerID, playerTable.BornStateID)
- if code.IsFail(errCode) {
- p.Debug("[autoReborn] errCode = %d", errCode)
- // 重新出生失败,保存失败信息,以待重试
- playerTable.RebornInfo.IsFailed = true
- playerTable.Save2Queue()
- // 推送通知
- if p.isOnline {
- sessions.PushPlayer(p.playerID, nameRoute.PushMapPlayer_Reborn, playerTable.ToRebornPush())
- }
- return
- }
- playerTable.RebornInfo.IsFailed = false
- // 更新坐标
- player.Service().UpdateWatcherPoint(playerTable, point.X, point.Y)
- // 推送重生
- if p.isOnline {
- sessions.PushPlayer(p.playerID, nameRoute.PushMapPlayer_Reborn, &pb.RebornPush{
- Point: point,
- })
- } else {
- // 保存以登录时推送
- playerTable.RebornInfo.Point.SetValue(point.X, point.Y)
- playerTable.RebornInfo.NeedPush = true
- playerTable.Save2Queue()
- }
- }
- // reborn 重新随机出生点
- func (p *actorPlayer) reborn(session *cproto.Session, _ *pb.None) {
- playerTable := db.GetMapPlayerTable(p.playerID)
- if !playerTable.RebornInfo.IsFailed {
- p.ResponseCode(session, code.OperationNotSupportYet)
- return
- }
- // 还有选过州,不能重新随机出生点
- if playerTable.BornStateID == 0 {
- p.ResponseCode(session, code.Map_NotSelectState)
- return
- }
- // 重新随机出生点
- point, errCode := mapCall.Logic.Reborn(p.playerID, playerTable.BornStateID)
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- playerTable.RebornInfo.IsFailed = false
- playerTable.RebornInfo.NeedPush = false
- playerTable.Save2Queue()
- player.Service().UpdateWatcherPoint(playerTable, point.X, point.Y)
- p.Response(session, point)
- }
- // autoRetreat 自动撤退
- // TODO 自动撤退的流程可以改一下,因为是地图上发过来的消息,所以应该是有部队的坐标和调动点的坐标的,
- // 应该带过来,这里就只做寻路就OK了
- func (p *actorPlayer) autoRetreat(req *pb.AutoRetreat) {
- var (
- teamID = req.TeamID
- marchState = enum.MarchState(req.MarchState)
- isRemoveRedeploy = req.IsRemoveRedeploy
- )
- playerTable := db.GetMapPlayerTable(p.playerID)
- dbTeam, ok := playerTable.Teams.GetTeam(teamID)
- if !ok {
- p.Warn("auto retreat team not found, teamID = %d", teamID)
- return
- }
- // 移除调动点
- if isRemoveRedeploy {
- dbTeam.RedeployObject.Set(0, 0)
- playerTable.Save2Queue()
- }
- var (
- startPoint types.Point
- endPoint types.Point
- )
- // 如果有调动点,就撤退回调动点,否则就撤退回主城
- if dbTeam.RedeployObject.Key == 0 {
- // 默认回主城,只拿部队的坐标
- endPoint.Set(&playerTable.Point)
- errCode := mapCall.Logic.GetObject1Point(dbTeam.MarchObjectID, enum.ObjectType_March, &startPoint)
- if code.IsFail(errCode) {
- p.Warn("[autoRetreat] get march point failed. teamID = %d, errCode = %d", teamID, errCode)
- return
- }
- } else {
- // 回调动点
- // 获取行军对象和调动点的坐标
- var (
- marchObject = enum.NewObject(dbTeam.MarchObjectID, enum.ObjectType_March)
- deployObject = enum.NewObject(dbTeam.RedeployObject.Key, dbTeam.RedeployObject.Value)
- errCode = mapCall.Logic.GetObject2Point(marchObject, deployObject, &startPoint, &endPoint)
- )
- if code.IsFail(errCode) {
- p.Warn("[autoRetreat] get object points failed. teamID = %d, RedeployObject = (%d, %s), errCode = %d",
- teamID, dbTeam.RedeployObject.Key, enum.GetObjectTypeName(dbTeam.RedeployObject.Value), errCode)
- return
- }
- }
- path, errCode := mapCall.PathFind.Find(startPoint.X, startPoint.Y, endPoint.X, endPoint.Y, p.playerID, playerTable.LeagueID, enum.MarchType_Retreat)
- if code.IsFail(errCode) {
- p.Warn("auto retreat find path failed. teamID = %d, errCode = %d", teamID, errCode)
- return
- }
- // 调用地图行军
- arg := &pb.MarchRequest{
- TeamID: dbTeam.TeamID,
- ObjectID: dbTeam.MarchObjectID,
- MarchType: int32(enum.MarchType_Retreat),
- Point: endPoint.ToProto(),
- Path: path,
- IsAutoRetreat: true, // 自动撤退
- RetreatState: int32(marchState),
- TargetObjectID: dbTeam.RedeployObject.Key, // 如果是0,要在 logic 判断撤退的目标
- }
- rsp, errCode := mapCall.Logic.Retreat(arg)
- if code.IsFail(errCode) {
- p.Warn("auto retreat failed. teamID = %d, errCode = %d", teamID, errCode)
- return
- }
- team.Service().UpdateTeamStateByMarchState(playerTable, dbTeam, enum.MarchState(rsp.Value))
- // 取消自动征兵 如果存在
- p.marchOutsideTroopsCancel(playerTable, dbTeam)
- }
- // 更新声望
- func (p *actorPlayer) updatePrestige(req *pb.I32Map) {
- prestigeMap := map[enum.PrestigeType]int32{}
- for k, v := range req.Value {
- prestigeMap[enum.PrestigeType(k)] = v
- }
- player.Service().UpdatePrestige(p.playerID, prestigeMap)
- }
- // 地图标记
- func (p *actorPlayer) mapMark(session *cproto.Session, req *pb.MapMarkRequest) {
- var (
- playerTable = db.GetMapPlayerTable(p.playerID)
- title = req.Title
- point = req.Point
- update = false
- markID, ok = data.PointToTileID(point.X, point.Y)
- )
- // TODO 判断坐标是否正确
- if !ok {
- p.ResponseCode(session, code.MapGetPointFail)
- return
- }
- // 判断地图标记上限
- if playerTable.MapMarks.Size() >= data.Const.MapMarkNumLimit {
- p.ResponseCode(session, code.MapMark_NumLimit)
- return
- }
- // 判断标题长度是否合法
- if !data.Const.CheckMapMarkTitle(title) {
- p.ResponseCode(session, code.MapMark_TitleLenLimit)
- return
- }
- mapMark, found := playerTable.MapMarks[markID]
- if !found {
- mapMark = &dbMapPlayer.MapMark{
- Title: title,
- Point: types.NewPoint(point.X, point.Y),
- }
- playerTable.MapMarks.Put(markID, mapMark)
- update = true
- }
- if mapMark.Title != title {
- mapMark.Title = title
- update = true
- }
- if update {
- // 更新标记时间戳
- mapMark.MarkTime = ctime.Now().ToSecond()
- playerTable.Save2Queue()
- }
- resp := mapMark.ToProto(markID)
- p.Response(session, resp)
- }
- // 地图标记删除
- func (p *actorPlayer) mapMarkDelete(session *cproto.Session, req *pb.I32) {
- var (
- playerTable = db.GetMapPlayerTable(p.playerID)
- markID = req.Value
- )
- _, found := playerTable.MapMarks.Get(markID)
- if !found {
- p.ResponseCode(session, code.MapMark_NotExist)
- return
- }
- playerTable.MapMarks.Remove(markID)
- playerTable.Save2Queue()
- p.ResponseCode(session, code.OK)
- }
- // 攻城集结
- func (p *actorPlayer) siegeAssemble(session *cproto.Session, req *pb.SiegeAssembleRequest) {
- p.updateNowTime()
- playerTable := db.GetMapPlayerTable(p.playerID)
- dbTeam, ok := playerTable.Teams.GetTeam(req.TeamID)
- if !ok {
- p.ResponseCode(session, code.MapTeamNotFound)
- return
- }
- if errCode := dbTeam.IsBusy(); code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- var (
- startPoint types.Point
- endPoint types.Point
- )
- // 如果是待命状态,行军点就是玩家当前位置
- if dbTeam.IsNeedSync() {
- startPoint = playerTable.Point
- // 只打目标集结点就够了
- errCode := mapCall.Logic.GetObject1Point(req.SiegeBaseObjectID, enum.ObjectType_Castle, &endPoint)
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- } else {
- // 非待命状态,要找行军对象坐标和集结点坐标
- var (
- marchObject = enum.NewObject(dbTeam.MarchObjectID, enum.ObjectType_March)
- siegeObject = enum.NewObject(req.SiegeBaseObjectID, enum.ObjectType_Castle)
- errCode = mapCall.Logic.GetObject2Point(marchObject, siegeObject, &startPoint, &endPoint)
- )
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- }
- path, errCode := mapCall.PathFind.Find(startPoint.X, startPoint.Y, endPoint.X, endPoint.Y, p.playerID, playerTable.LeagueID, enum.MarchType_SiegeAssemble)
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- // 检查资源是否足够
- errCode = team.Service().CheckMarchCost(p.playerID, req.TeamID, enum.MarchType_SiegeAssemble, len(path))
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- // 调用地图行军
- arg := &pb.MarchRequest{
- TeamID: dbTeam.TeamID,
- ObjectID: dbTeam.MarchObjectID,
- MarchType: int32(enum.MarchType_SiegeAssemble),
- Point: endPoint.ToProto(),
- Path: path,
- IsMainForce: req.IsMainForce,
- TargetObjectID: req.SiegeBaseObjectID,
- }
- if dbTeam.IsNeedSync() {
- arg.MarchSync = team.Service().GetTeamMarchSyncProto(playerTable, dbTeam)
- }
- rsp, errCode := mapCall.Logic.SiegeAssemble(arg)
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- if dbTeam.MarchObjectID == 0 {
- dbTeam.MarchObjectID = rsp.Key
- }
- // 更新部队调动对象
- dbTeam.RedeployObject.Set(req.SiegeBaseObjectID, enum.ObjectType_Castle)
- playerTable.Save2Queue()
- // 扣除资源
- team.Service().MarchCost(p.playerID, req.TeamID, enum.MarchType_SiegeAssemble, len(path))
- // 更新队伍状态
- team.Service().UpdateTeamStateByMarchState(playerTable, dbTeam, enum.MarchState(rsp.Value))
- p.ResponseCode(session, code.OK)
- }
- // 获取城池首占信息
- func (p *actorPlayer) siegeRank(session *cproto.Session, req *pb.I64) {
- rsp, errCode := mapCall.Logic.SiegeRank(req.Value)
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- p.Response(session, rsp)
- }
- // 查询寻路信息
- func (p *actorPlayer) findPath(session *cproto.Session, req *pb.MapFindPathRequest) {
- playerTable := db.GetMapPlayerTable(p.playerID)
- dbTeam, ok := playerTable.Teams.GetTeam(req.TeamID)
- if !ok {
- p.ResponseCode(session, code.MapTeamNotFound)
- return
- }
- var startPoint types.Point
- if dbTeam.IsStandby() {
- startPoint.Set(&playerTable.Point)
- } else {
- // 获取行军对象坐标
- errCode := mapCall.Logic.GetObject1Point(dbTeam.MarchObjectID, enum.ObjectType_March, &startPoint)
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- }
- paths, errCode := p.findMarchPath(playerTable, startPoint.X, startPoint.Y, req.Point.X, req.Point.Y, 0, enum.MarchType_Retreat)
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- rsp := &pb.Points{}
- for _, path := range paths {
- point := &pb.Point{
- X: path.X,
- Y: path.Y,
- }
- rsp.List = append(rsp.List, point)
- }
- p.Response(session, rsp)
- }
- // 获取地图对象位置
- func (p *actorPlayer) mapObjectPosition(session *cproto.Session, req *pb.MapObjectPositionRequest) {
- var position types.Point
- errCode := mapCall.Logic.GetObject1Point(req.ObjectID, enum.ObjectType(req.ObjectType), &position)
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- p.Response(session, &pb.Point{
- X: position.X,
- Y: position.Y,
- })
- }
- // 自动防守退出
- func (p *actorPlayer) autoDefendQuit(req *pb.I64) {
- p.Debug("[autoDefendQuit] req = %+v", req)
- playerTable := db.GetMapPlayerTable(p.playerID)
- playerTable.AutoDefend.Remove(req.Value)
- playerTable.Save2Queue()
- }
- // 玩家主城被攻打
- func (p *actorPlayer) mainCitySiege(req *pb.I64) {
- p.Debug("[mainCitySiege] ObjectID = %v", req.Value)
- playerTable := db.GetMapPlayerTable(p.playerID)
- // 让所有在城内的部队加入自动防守
- for _, dbTeam := range playerTable.Teams {
- if dbTeam.IsStandby() {
- defendTeams, ok := playerTable.AutoDefend[req.Value]
- if !ok {
- defendTeams = types.Map[int32, int64]{}
- playerTable.AutoDefend[req.Value] = defendTeams
- }
- defendTeams.Put(dbTeam.TeamID, 0)
- }
- }
- playerTable.Save2Queue()
- p.updateNowTime()
- // 立即触发一次自动防守
- sandMap.Service().CheckAutoDefend(playerTable, p.now.ToMillisecond())
- }
- func (p *actorPlayer) updateWatcherPoint(req *pb.Point) {
- playerTable := db.GetMapPlayerTable(p.playerID)
- if playerTable == nil {
- return
- }
- p.Debug("update watcher point: %+v", req)
- player.Service().UpdateWatcherPoint(playerTable, req.X, req.Y)
- }
- // autoDefendNotice 自动防守通知
- func (p *actorPlayer) autoDefendRequest(req *pb.AutoDefendRequest) {
- p.Debug("[autoDefendRequest] req = %+v", req)
- playerTable := db.GetMapPlayerTable(p.playerID)
- defendTeams, ok := playerTable.AutoDefend.Get(req.BuildObjectID)
- if !ok {
- defendTeams = types.Map[int32, int64]{}
- playerTable.AutoDefend[req.BuildObjectID] = defendTeams
- }
- // 所有部队加入自动防守
- defendTeams.PutKeys(req.TeamIDs, 0)
- playerTable.Save2Queue()
- p.updateNowTime()
- // 立即触发一次自动防守
- sandMap.Service().CheckAutoDefend(playerTable, p.now.ToMillisecond())
- }
- func (p *actorPlayer) resOccupy(e cfacade.IEventData) {
- evt, ok := e.(*event.MapResOccupy)
- if !ok {
- p.Warn("[resOccupy] event type error. e = %+v", e)
- return
- }
- p.Debug("[resOccupy] %+v", evt)
- data := evt.Data()
- playerTable := db.GetMapPlayerTable(p.playerID)
- playerTable.ResMap.Put(data.ObjectID, &dbMapPlayer.Res{
- ObjectID: data.ObjectID,
- TileID: data.TileID,
- ConfigID: data.ConfigID,
- InLeagueArea: data.InLeagueArea,
- })
- // TODO 更新产量
- playerTable.Save2Queue()
- }
- func (p *actorPlayer) resUpdate(e cfacade.IEventData) {
- evt, ok := e.(*event.MapResUpdate)
- if !ok {
- p.Warn("[resUpdate] event type error. e = %+v", e)
- return
- }
- p.Debug("[resUpdate] %+v", evt)
- data := evt.Data()
- playerTable := db.GetMapPlayerTable(p.playerID)
- res, ok := playerTable.ResMap.Get(data.ObjectID)
- if !ok {
- p.Warn("[resUpdate] res not found. e = %+v", e)
- return
- }
- switch data.UpdateType {
- case enum.ResUpdate_InLeagueArea:
- res.InLeagueArea = data.InLeagueArea
- case enum.ResUpdate_Delete:
- playerTable.ResMap.Remove(data.ObjectID)
- }
- // TODO 更新产量
- playerTable.Save2Queue()
- }
- func (p *actorPlayer) updateCastleResYield(req *pb.I32Bool) {
- var (
- configID = req.Key
- isRemove = req.Value
- )
- p.Debug("[updateCastleResYield] configID = %v, isRemove = %v", configID, isRemove)
- playerTable := db.GetMapPlayerTable(p.playerID)
- if isRemove {
- playerTable.CastleResYield.Remove(configID)
- } else {
- playerTable.CastleResYield.Add(configID)
- }
- playerTable.Save2Queue()
- }
- // 获取攻占城池列表
- func (p *actorPlayer) occupyCastleList(session *cproto.Session, _ *pb.None) {
- // 请求logic 获取攻占城池列表
- rsp, errCode := mapCall.Logic.OccupyCastleList()
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- p.Response(session, rsp)
- }
- // 主城加固
- func (p *actorPlayer) reinforce(session *cproto.Session, _ *pb.None) {
- rsp, errCode := mapCall.Logic.Reinforce(p.playerID)
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- p.Response(session, rsp)
- }
- // 主城加固取消
- func (p *actorPlayer) reinforceCancel(session *cproto.Session, _ *pb.None) {
- errCode := mapCall.Logic.ReinforceCancel(p.playerID)
- p.ResponseCode(session, errCode)
- }
- // 获取资源守军
- func (p *actorPlayer) resArmies(session *cproto.Session, req *pb.I64) {
- rsp, errCode := mapCall.Logic.ResArmies(req)
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- p.Response(session, rsp)
- }
- // 发起侦察
- func (p *actorPlayer) scoutRequest(session *cproto.Session, req *pb.I32I64) {
- var (
- playerTable = db.GetMapPlayerTable(p.playerID)
- queueID = req.Key
- objectID = req.Value
- curTime = ctime.Now().ToMillisecond()
- )
- if objectID <= 0 {
- p.ResponseCode(session, code.IllegalArgument)
- return
- }
- // 侦察队列不存在
- scout, found := playerTable.Scouts.GetScout(queueID)
- if !found {
- p.ResponseCode(session, code.ScoutQueueNotExist)
- return
- }
- // 检测侦察队列是否正在使用
- if scout.IsScouting(curTime) {
- p.ResponseCode(session, code.ScoutQueueBusy)
- return
- }
- // 道具不足
- if !storage.Service().IsAllEnough(p.playerID, data.Const.MapScoutCosts) {
- p.ResponseCode(session, code.ItemNotEnough)
- return
- }
- // 去logic校验是否可侦察
- resp, errCode := mapCall.Logic.ScoutCheck(p.playerID, objectID)
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- endTime := data.Const.GetMapScoutMarchTime()
- // 更新当前为侦察-行军状态
- errCode = mapCall.Scout.ScoutUpdateStatus(queueID, enum.ScoutType_March, p.playerID, endTime)
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- // 侦察消耗
- _, errCode = storage.Service().AssetSubs(p.playerID, data.Const.MapScoutCosts, ao.MapScoutCost, true)
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- scout.ObjectID = objectID
- scout.TargetPlayerID = resp.TargetPlayerID
- scout.ScoutStatus = enum.ScoutType_March
- scout.Point = types.NewPoint(resp.Point.X, resp.Point.Y)
- scout.EndTime = endTime
- playerTable.Save2Queue()
- proto := scout.ToScoutProto(queueID)
- p.Response(session, proto)
- }
- // 开始侦察通知处理
- func (p *actorPlayer) scoutUpdateNotice(req *pb.ScoutUpdateNotice) {
- var (
- starts = req.Starts
- ends = req.Ends
- playerTable = db.GetMapPlayerTable(p.playerID)
- updateScouts = []int32{}
- )
- // 处理侦察开始队列
- for _, queueID := range starts {
- curScout, found := playerTable.Scouts.GetScout(queueID)
- if !found {
- p.Warn("[scoutUpdateNotice] start fail, queue not found. queueID = %d", queueID)
- continue
- }
- errCode := scout.Service().CheckScoutSuccess(playerTable, queueID, curScout)
- if code.IsFail(errCode) {
- curScout.Reset()
- updateScouts = append(updateScouts, queueID)
- continue
- }
- // 更新侦察结束时间
- curScout.EndTime = data.Const.GetMapScoutTime(curScout.EndTime)
- errCode = mapCall.Scout.ScoutUpdateStatus(queueID, enum.ScoutType_Start, p.playerID, curScout.EndTime)
- if code.IsFail(errCode) {
- curScout.Reset()
- updateScouts = append(updateScouts, queueID)
- p.Warn("[scoutUpdateNotice] start fail, update status fail. queueID = %d", queueID)
- continue
- }
- curScout.ScoutStatus = enum.ScoutType_Start
- updateScouts = append(updateScouts, queueID)
- }
- // 处理侦察结束队列
- for _, queueID := range ends {
- curScout, found := playerTable.Scouts.GetScout(queueID)
- if !found {
- p.Warn("[scoutUpdateNotice] end fail, queue not found. queueID = %d", queueID)
- continue
- }
- errCode := scout.Service().CheckScoutSuccess(playerTable, queueID, curScout)
- if code.IsFail(errCode) {
- curScout.Reset()
- updateScouts = append(updateScouts, queueID)
- continue
- }
- // 发送call到目标玩家获取目标玩家的木石粮铁
- errCode = mapCall.Player.ScoutSearch(queueID, p.playerID, curScout.TargetPlayerID)
- if code.IsFail(errCode) {
- curScout.Reset()
- updateScouts = append(updateScouts, queueID)
- }
- }
- if len(updateScouts) > 0 {
- playerTable.SetChangeData()
- // 通知客户端更新
- if p.isOnline {
- scout.Service().ChangePush(playerTable, updateScouts...)
- }
- }
- }
- // 侦察查询
- func (p *actorPlayer) scoutSearch(req *pb.I32I64) {
- // 获取目标玩家的木石粮铁
- var (
- playerStorageTable = db.GetMapPlayerStorageTable(p.playerID)
- playerTable = db.GetMapPlayerTable(p.playerID)
- )
- // 获取木石粮铁
- assets := playerStorageTable.GetScoutCurrencys(enum.MapScoutItemIDList...)
- // 返回给侦察者
- mapCall.Player.ScoutSearchResult(req.Key, req.Value, p.playerID, playerTable.PlayerName, assets)
- // TODO 判断是否需要通知被侦察玩家
- }
- // 侦察结果
- func (p *actorPlayer) scoutSearchResult(req *pb.ScoutSearchResult) {
- var (
- queueID = req.QueueID
- playerTable = db.GetMapPlayerTable(p.playerID)
- )
- curScout, found := playerTable.Scouts.GetScout(req.QueueID)
- if !found {
- p.Warn("[scoutSearchResult] scout not found. playerID=%d, queueID = %d", p.playerID, req.QueueID)
- return
- }
- // 构建战报
- reportGroup := battle.Service().BuildScoutReportGroup(p.playerID, req.TargetPlayerID, playerTable.LeagueID,
- playerTable.PlayerName, req.TargetPlayerName, curScout.Point.ToProto(), req.Assets, enum.ScoutState_Success)
- // 发送侦察成功战报
- battle.Service().AddReport(p.playerID, reportGroup)
- curScout.Reset()
- playerTable.SetChangeData()
- // 通知客户端队列更新
- if p.isOnline {
- scout.Service().ChangePush(playerTable, queueID)
- }
- }
- func (p *actorPlayer) notifyRebornPush(req *pb.Point) {
- p.Debug("[notifyRebornPush] req = %+v", req)
- playerTable := db.GetMapPlayerTable(p.playerID)
- if p.isOnline {
- sessions.PushPlayer(p.playerID, nameRoute.PushMapPlayer_Reborn, &pb.RebornPush{
- Point: &pb.Point{
- X: req.X,
- Y: req.Y,
- },
- })
- return
- }
- // 玩家不在线,保存一下,玩家登录时推送
- playerTable.RebornInfo.NeedPush = true
- playerTable.RebornInfo.Point.SetValue(req.X, req.Y)
- playerTable.Save2Queue()
- }
- // 自动行军
- func (p *actorPlayer) autoMarch(req *pb.AutoMarchRequest) {
- p.Debug("[autoMarch] req = %+v", req)
- // 寻路
- arg := &pb.FindMultiPathRequest{
- FindType: int32(enum.FindMultiPath_AllSuccess), // 所有的路径都要成功
- }
- for _, auto := range req.List {
- arg.Requests = append(arg.Requests, &pb.FindPathRequest{
- StartX: auto.Start.X,
- StartY: auto.Start.Y,
- EndX: auto.End.X,
- EndY: auto.End.Y,
- PlayerID: req.PlayerID,
- LeagueID: req.LeagueID,
- MarchType: int32(auto.MarchType),
- })
- }
- path, errCode := mapCall.PathFind.FindMulti(arg)
- if code.IsFail(errCode) {
- p.Debug("[autoMarch] find path fail. errCode = %d", errCode)
- return
- }
- rsp := &pb.AutoMarchResult{
- PlayerID: req.PlayerID,
- ObjectID: req.ObjectID,
- }
- for i, auto := range req.List {
- rsp.List = append(rsp.List, &pb.AutoMarchResultData{
- MarchType: auto.MarchType,
- Path: path.List[i].List,
- })
- }
- // 发送自动行军通知
- mapCall.Logic.AutoMarchResult(rsp)
- }
- // 更新时间偏移量
- func (p *actorPlayer) updateTimeOffset(req *pb.I64) {
- offset := req.Value
- ctime.AddOffsetTime(time.Duration(offset) * time.Second)
- p.Warn("[updateTimeOffset] playerID=%d, offset = %d, time = %d", p.playerID, offset, ctime.Now().ToSecond())
- }
|