package mapPlayer import ( actorRemote "f1-game/internal/actor_remote" "f1-game/internal/code" "f1-game/internal/data" "f1-game/internal/enum" "f1-game/internal/event" nameLocal "f1-game/internal/name/local" "f1-game/internal/pb" ao "f1-game/nodes/game/player/asset/origin" "f1-game/nodes/map/internal/db" mapFacade "f1-game/nodes/map/internal/facade" fs "f1-game/nodes/map/player/facility" ctime "github.com/cherry-game/cherry/extend/time" cproto "github.com/cherry-game/cherry/net/proto" ) func (p *actorPlayer) initFacility() { p.Local().Register(nameLocal.MapPlayerFacilityUp, p.facilityUp) p.Local().Register(nameLocal.MapPlayerFacilityCancel, p.facilityCancel) p.Local().Register(nameLocal.MapPlayerFacilityFinish, p.facilityFinish) p.Local().Register(nameLocal.MapPlayerFacilityQueueUnlock, p.facilityQueueUnlock) } // 建筑升级 func (p *actorPlayer) facilityUp(session *cproto.Session, req *pb.I32) { var ( facilityID = req.Value ) if facilityID < 1 { p.ResponseCode(session, code.IllegalArgument) return } playerTable := db.GetMapPlayerTable(p.playerID) // 检查建筑是否解锁 if !playerTable.Facilities.CheckUnlock(facilityID) { p.ResponseCode(session, code.FacilityNotUnlock) return } // 是否真正在升级中 if _, ok := playerTable.Facilities.GetQueueByFacilityID(facilityID); ok { p.ResponseCode(session, code.FacilityIsUpgrading) return } facility, ok := playerTable.Facilities.Facilitys.Get(facilityID) if !ok { facility = playerTable.Facilities.CreateFacility(facilityID) } // 检查是否满足前置条件 if !playerTable.Facilities.CheckPreFacility(facilityID, facility.Level) { p.ResponseCode(session, code.FacilityUpPreConditionNotMet) return } facilityLevelRow, ok := data.FacilityLevel.GetByFacilityIDLevel(facilityID, facility.Level) // 检查等级上限 if !ok || facility.Level >= data.FacilityLevel.GetMaxLevel(facilityID) { p.ResponseCode(session, code.FacilityLevelLimit) return } // 获取可用队列 facilityQueue, ok := playerTable.Facilities.GetAvailableQueue() if !ok { p.ResponseCode(session, code.FacilityQueueFull) return } // 检查队列配置 if _, ok := data.FacilityQueue.GetByID(facilityQueue.FacilityQueueID); !ok { p.ResponseCode(session, code.ConfigNotFound_FacilityQueue) return } // 升级建筑的消耗 if _, errCode := mapFacade.Storage.AssetSubs(p.playerID, facilityLevelRow.UpgradeCost, ao.FacilityUpCost); code.IsFail(errCode) { p.ResponseCode(session, errCode) return } nowSec := ctime.Now().ToSecond() // 升级累计次数+1 playerTable.Facilities.UpgradeCount += 1 facilityQueue.FacilityID = facilityID facilityQueue.StartTime = nowSec facilityQueue.FinishTime = facilityLevelRow.GetUpgradeTime(nowSec) playerTable.Save2Queue() // 建筑建造/升级事件 p.PostEvent(event.NewFacilityBuild(p.playerID, facilityID)) rsp := facilityQueue.ToProto() p.Response(session, &rsp) p.Debug("facilityUp success. facilityID = %d", facilityID) } // 建筑升级取消 func (p *actorPlayer) facilityCancel(session *cproto.Session, req *pb.I32) { var ( facilityID = req.Value ) if facilityID < 1 { p.ResponseCode(session, code.IllegalArgument) return } playerTable := db.GetMapPlayerTable(p.playerID) // 获取建筑对应的建筑队列 facilityQueue, ok := playerTable.Facilities.GetQueueByFacilityID(facilityID) if !ok { p.ResponseCode(session, code.FacilityNotInQueue) return } facility, ok := playerTable.Facilities.Facilitys.Get(facilityID) if !ok { facility = playerTable.Facilities.CreateFacility(facilityID) } // 获取取消返还的消耗 assets, ok := data.FacilityLevel.GetRefundAssets(facilityID, facility.Level) if !ok { p.ResponseCode(session, code.ConfigNotFound_FacilityLevel) return } if _, errCode := mapFacade.Storage.AssetAdds(p.playerID, assets, ao.FacilityUpClear); code.IsFail(errCode) { p.ResponseCode(session, errCode) return } // 队列重置 facilityQueue.Reset() playerTable.Save2Queue() p.ResponseCode(session, code.OK) p.Debug("facilityCancel success. facilityID = %d", facilityID) } // 建筑立刻完成 func (p *actorPlayer) facilityFinish(session *cproto.Session, req *pb.I32) { var ( facilityID = req.Value // 建筑ID ) if facilityID < 1 { p.ResponseCode(session, code.IllegalArgument) return } playerTable := db.GetMapPlayerTable(p.playerID) // 获取建筑对应的建筑队列 facilityQueue, ok := playerTable.Facilities.GetQueueByFacilityID(facilityID) if !ok { p.ResponseCode(session, code.FacilityNotInQueue) return } // TODO 按资源消耗计算,可能需要改成扣除加速池资源 if _, errCode := mapFacade.Storage.AssetSubs(p.playerID, data.Const.BuildUpNowCost, ao.FacilityUpFinishCost); code.IsFail(errCode) { p.ResponseCode(session, errCode) return } facility, ok := playerTable.Facilities.Facilitys.Get(facilityID) if !ok { facility = playerTable.Facilities.CreateFacility(facilityID) } // 升级建筑 facility.Level++ // 重置队列 facilityQueue.Reset() // 更新默认开启的建筑属性 fs.Service().UpdateAttrs(playerTable) playerTable.Save2Queue() // 发送升级事件 p.PostEvent(event.NewFacilityUp(p.playerID, facilityID, facility.Level)) // 发送系统消息 actorRemote.GamePlayer.GamePlayerCallSystemMsg(playerTable.GameNodeID, p.playerID, enum.ChatMsgType_buildUp, nil, nil, facilityID, facility.Level) p.ResponseCode(session, code.OK) fs.Service().FinishPush(p.playerID, facilityID) p.Debug("facilityFinish success. facilityID = %d", facilityID) } // 解锁队列 func (p *actorPlayer) facilityQueueUnlock(session *cproto.Session, req *pb.I32) { var ( facilityQueueID = req.Value // 队列ID ) if facilityQueueID < 1 { p.ResponseCode(session, code.IllegalArgument) return } facilityQueueConfig, found := data.FacilityQueue.GetByID(facilityQueueID) if !found { p.ResponseCode(session, code.ConfigNotFound_FacilityQueue) return } playerTable := db.GetMapPlayerTable(p.playerID) if _, found := playerTable.Facilities.Queues[facilityQueueID]; found { p.ResponseCode(session, code.FacilityQueueRepeatUnlock) return } // 判断解锁顺序 if nextQueueID, found := playerTable.Facilities.GetNextUnlockQueueID(); !found || nextQueueID != facilityQueueID { p.ResponseCode(session, code.FacilityQueueUnlockOrder) return } // 解锁队列的消耗 if _, errCode := mapFacade.Storage.AssetSubs(p.playerID, facilityQueueConfig.Cost, ao.FacilityQueueUnlockCost); code.IsFail(errCode) { p.ResponseCode(session, errCode) return } playerTable.Facilities.UnlockQueue(facilityQueueID) playerTable.Save2Queue() p.ResponseCode(session, code.OK) p.Debug("facilityQueueUnlock success. queueID = %d", facilityQueueID) }