| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465 |
- 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"
- "f1-game/nodes/map/player/player"
- "f1-game/nodes/map/player/scout"
- "f1-game/nodes/map/player/storage"
- "f1-game/nodes/map/player/team"
- ctime "github.com/cherry-game/cherry/extend/time"
- cfacade "github.com/cherry-game/cherry/facade"
- clog "github.com/cherry-game/cherry/logger"
- 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.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.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)
- }
- // login 玩家登录地图
- func (p *actorPlayer) login(session *cproto.Session, _ *pb.None) {
- clog.Debugf("player login map: %d", p.playerID)
- if p.isOnline {
- p.ResponseCode(session, code.OK)
- return
- }
- p.updateNowTime()
- // 检查玩家表是否存在,没有则创建
- playerTable, isNewPlayer := db.CheckMapPlayerTable(p.playerID)
- if isNewPlayer {
- session.Add(sessions.IsNewPlayer, isNewPlayer)
- }
- clog.Debugf("[login] Player enter map success: playerID = %d, objectID = %d", p.playerID)
- p.onReset(playerTable, true)
- // 登录前事件处理
- mapFacade.ServiceOnLogin(playerTable, session)
- // 推送各个模块数据
- mapFacade.ServicePush(playerTable, session)
- // 设置actor为登录状态
- p.isOnline = true
- // 返回玩家地图的信息
- p.Response(session, playerTable.ToMapLoginResponse())
- // 在线状态设置后,再启动定时器
- p.startTimer()
- // 登录后事件处理
- mapFacade.ServiceOnLogined(playerTable, session)
- }
- // enter 玩家进入地图
- func (p *actorPlayer) enter(session *cproto.Session, _ *pb.None) {
- clog.Debugf("player enter map: %d", p.playerID)
- if !p.isOnline {
- p.ResponseCode(session, code.PlayerNotLogin)
- return
- }
- playerTable := db.GetMapPlayerTable(p.playerID)
- // 未选择出生州
- if playerTable.BornStateID == 0 {
- p.ResponseCode(session, code.Map_NotSelectState)
- return
- }
- errCode := mapCall.Logic.Enter(p.playerID)
- p.ResponseCode(session, errCode)
- }
- // selectState 选择出生州,只在玩家首次进入地图时调用
- // 后序跨逻辑调选州再起
- func (p *actorPlayer) selectState(session *cproto.Session, req *pb.I32) {
- playerTable := db.GetMapPlayerTable(p.playerID)
- if playerTable.BornStateID != 0 {
- 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()
- 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) {
- clog.Debugf("player join map: %d", p.playerID)
- playerTable := db.GetMapPlayerTable(p.playerID)
- mapCall.AOI.Enter(playerTable.ToAOIWatcher())
- }
- // quit 以观察者退出地图
- func (p *actorPlayer) quit(session *cproto.Session, _ *pb.None) {
- clog.Debugf("player quit map: %d", p.playerID)
- playerTable := db.GetMapPlayerTable(p.playerID)
- mapCall.AOI.Leave(playerTable.ObjectID, enum.ObjectType_Player)
- }
- // slide 滑动屏幕
- func (p *actorPlayer) slide(session *cproto.Session, req *pb.Point) {
- clog.Debugf("player slide: %d %v", p.playerID, 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 := mapCall.PathFind.Find(startPoint.X, startPoint.Y, req.Point.X, req.Point.Y, p.playerID, playerTable.LeagueID, 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)
- }
- // 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 ok := mapFacade.Storage.IsAllEnough(p.playerID, row.BuildCost); !ok {
- 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 ok := mapFacade.Storage.IsAllEnough(p.playerID, mapBuildUpgradeRow.UpgradeCost); !ok {
- 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 playerTable.Builds.ComebackEndTime > p.now.ToMillisecond() {
- p.ResponseCode(session, code.MapComeback_Cooldown)
- return
- }
- if rechoose {
- // 不能重选当前州
- if stateID == playerTable.BornStateID {
- p.ResponseCode(session, code.MapComeback_SameState)
- return
- }
- // 需要退联盟
- if playerTable.LeagueID != 0 {
- p.ResponseCode(session, code.MapComeback_NeedLeagueQuit)
- return
- }
- } else {
- // 非重新选州,使用当前出生州
- stateID = playerTable.BornStateID
- }
- point, errCode := mapCall.Logic.Comeback(p.playerID, rechoose, stateID)
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- playerTable.Builds.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.Builds.ComebackEndTime,
- }
- 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.IsRebornFailed = true
- playerTable.Save2Queue()
- // 推送通知
- if p.isOnline {
- sessions.PushPlayer(p.playerID, nameRoute.PushMapPlayer_Reborn, playerTable.ToRebornPush())
- }
- return
- }
- // 更新坐标
- 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 = dbMapPlayer.NewRebornInfo(point.X, point.Y)
- playerTable.Save2Queue()
- }
- }
- // reborn 重新随机出生点
- func (p *actorPlayer) reborn(session *cproto.Session, _ *pb.None) {
- playerTable := db.GetMapPlayerTable(p.playerID)
- if !playerTable.IsRebornFailed {
- 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.ClearRebornInfo()
- 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 {
- clog.Warnf("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) {
- clog.Warnf("[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) {
- clog.Warnf("[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) {
- clog.Warnf("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) {
- clog.Warnf("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 ok := data.Const.CheckMapMarkTitle(title); !ok {
- 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 := mapCall.PathFind.Find(startPoint.X, startPoint.Y, req.Point.X, req.Point.Y, p.playerID, playerTable.LeagueID, 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) autoDefendQuit(req *pb.I32List) {
- clog.Debugf("[autoDefendQuit] req = %+v", req)
- playerTable := db.GetMapPlayerTable(p.playerID)
- // 自动防守退出
- for _, teamID := range req.List {
- dbTeam, ok := playerTable.Teams.GetTeam(teamID)
- if !ok {
- continue
- }
- dbTeam.IsAutoDefend = false
- }
- playerTable.Save2Queue()
- }
- // 玩家主城被攻打
- func (p *actorPlayer) mainCitySiege(req *pb.I64) {
- clog.Debugf("[mainCitySiege] ObjectID = %v", req.Value)
- playerTable := db.GetMapPlayerTable(p.playerID)
- // 获取所有在城内并且非重伤的部队去自动防守
- arg := &pb.AutoDefend{
- BuildObjectID: req.Value,
- }
- for _, dbTeam := range playerTable.Teams {
- if dbTeam.IsNotStandby() || code.IsFail(dbTeam.IsBusy()) || team.Service().IsTeamTroopsLack(playerTable, dbTeam) {
- continue
- }
- member := &pb.AutoDefendMember{
- MarchObjectID: dbTeam.MarchObjectID,
- }
- if dbTeam.IsNeedSync() {
- member.MarchSync = team.Service().GetTeamMarchSyncProto(playerTable, dbTeam)
- }
- arg.Members = append(arg.Members, member)
- }
- clog.Debugf("[mainCitySiege] ObjectID = %v, March size = %v", req.Value, len(arg.Members))
- // 通知加入自动防守
- if len(arg.Members) > 0 {
- rsp, errCode := mapCall.Logic.AutoDefend(arg)
- if code.IsFail(errCode) {
- clog.Warnf("[mainCitySiege] auto defend error: req = %+v, code = %v", arg, errCode)
- return
- }
- for _, pair := range rsp.List {
- if dbTeam, ok := playerTable.Teams.GetTeam(pair.Value); ok {
- if dbTeam.MarchObjectID == 0 {
- dbTeam.MarchObjectID = pair.Key
- }
- dbTeam.IsAutoDefend = true
- }
- }
- playerTable.Save2Queue()
- }
- }
- 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) {
- clog.Debugf("[autoDefendRequest] req = %+v", req)
- playerTable := db.GetMapPlayerTable(p.playerID)
- // 获取所有在城内并且非重伤的部队去自动防守
- arg := &pb.AutoDefend{
- BuildObjectID: req.BuildObjectID,
- }
- for _, teamID := range req.TeamIDs {
- dbTeam, ok := playerTable.Teams.GetTeam(teamID)
- if !ok {
- continue
- }
- if dbTeam.IsAutoDefend || code.IsFail(dbTeam.IsBusy()) || team.Service().IsTeamTroopsLack(playerTable, dbTeam) {
- continue
- }
- member := &pb.AutoDefendMember{
- MarchObjectID: dbTeam.MarchObjectID,
- }
- arg.Members = append(arg.Members, member)
- }
- clog.Debugf("[autoDefendRequest] ObjectID = %v, Arg = %+v", req.BuildObjectID, arg)
- // 通知加入自动防守
- if len(arg.Members) > 0 {
- rsp, errCode := mapCall.Logic.AutoDefend(arg)
- if code.IsFail(errCode) {
- clog.Warnf("[autoDefendRequest] auto defend error: req = %+v, code = %v", arg, errCode)
- return
- }
- for _, pair := range rsp.List {
- if dbTeam, ok := playerTable.Teams.GetTeam(pair.Value); ok {
- dbTeam.IsAutoDefend = true
- }
- }
- playerTable.Save2Queue()
- }
- }
- 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) 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) {
- errCode := mapCall.Logic.Reinforce(p.playerID)
- p.ResponseCode(session, errCode)
- }
- // 主城加固取消
- 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
- }
- // 去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.TargetPlayerID = resp.TargetPlayerID
- 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) {
- continue
- }
- // 更新侦察结束时间
- curScout.EndTime = data.Const.GetMapScoutTime()
- errCode = mapCall.Scout.ScoutUpdateStatus(queueID, enum.ScoutType_Start, p.playerID, curScout.EndTime)
- if code.IsFail(errCode) {
- p.Warn("[scoutUpdateNotice] start fail, update status fail. queueID = %d", queueID)
- continue
- }
- 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) {
- continue
- }
- // 发送call到目标玩家获取目标玩家的木石粮铁
- mapCall.Player.ScoutSearch(queueID, p.playerID, curScout.TargetPlayerID)
- 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.GetCurrencys(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 = &dbMapPlayer.RebornInfo{
- Point: types.NewPoint(req.X, req.Y),
- }
- playerTable.Save2Queue()
- }
|