| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466 |
- 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"
- 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.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) {
- 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)
- // 登录前事件处理
- 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) {
- 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)
- }
- // 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 := 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 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 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) 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) 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
- }
- // 去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.NeedPush = true
- playerTable.RebornInfo.Point.SetValue(req.X, req.Y)
- playerTable.Save2Queue()
- }
|