| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348 |
- package conscript
- import (
- actorRemote "f1-game/internal/actor_remote"
- capp "f1-game/internal/cherry_app"
- "f1-game/internal/code"
- "f1-game/internal/constant"
- "f1-game/internal/data"
- "f1-game/internal/enum"
- "f1-game/internal/event"
- "f1-game/internal/extend/math"
- facade "f1-game/internal/facade"
- nameRoute "f1-game/internal/name/route"
- "f1-game/internal/sessions"
- ao "f1-game/nodes/game/player/asset/origin"
- "f1-game/nodes/map/internal/db"
- mapFacade "f1-game/nodes/map/internal/facade"
- "f1-game/nodes/map/player/storage"
- ctime "github.com/cherry-game/cherry/extend/time"
- clog "github.com/cherry-game/cherry/logger"
- cproto "github.com/cherry-game/cherry/net/proto"
- )
- var srv = &service{}
- type service struct {
- facade.PlayerServiceBase[*db.MapPlayerTable]
- }
- func Service() *service {
- return srv
- }
- func (p *service) OnLogin(mapPlayerTable *db.MapPlayerTable, session *cproto.Session) {
- // 当前没有征兵/升级任务
- if mapPlayerTable.Conscripts.IsNotConscriptAction() {
- return
- }
- // 计算登录时间和登出的时间差
- var (
- nowMilliSecond = ctime.Now().ToMillisecond()
- lastLogoutTime = mapPlayerTable.Stats.LastLogoutTime
- diffSecond = (nowMilliSecond - lastLogoutTime) / ctime.MillisecondsPerSecond
- )
- // 结算离线征兵/兵种升级
- p.handleConscriptSettle(mapPlayerTable, int32(diffSecond))
- }
- func (p *service) OnLogout(mapPlayerTable *db.MapPlayerTable) {
- mapPlayerTable.Stats.LastLogoutTime = ctime.Now().ToMillisecond()
- mapPlayerTable.Save2Queue()
- }
- // func (p *service) OnReset(mapPlayerTable *db.PlayerTable, time *ctime.CherryTime, byLogin bool) {
- // }
- // 推送征兵信息
- func (p *service) Push(mapPlayerTable *db.MapPlayerTable, session *cproto.Session) {
- resp := mapPlayerTable.Conscripts.ToProto()
- sessions.PushWithSession(session, nameRoute.PushMapPlayer_Conscript, &resp)
- }
- // 每秒执行征兵结算
- func (p *service) ConscriptSettle(playerID, nowSecond int64) {
- mapPlayerTable := db.GetMapPlayerTable(playerID)
- if mapPlayerTable == nil {
- clog.Warnf("conscript settle player not found. playerID:%d", playerID)
- return
- }
- // 1s 计算
- p.handleConscriptSettle(mapPlayerTable, 1)
- }
- func (p *service) handleConscriptSettle(mapPlayerTable *db.MapPlayerTable, second int32) {
- // 当前没有征兵/升级任务
- if mapPlayerTable.Conscripts.IsNotConscriptAction() {
- return
- }
- var (
- conscripts = mapPlayerTable.Conscripts
- save = false
- )
- // 当前为征兵
- if conscripts.IsConscript() {
- // 执行1s征兵结算
- save = p.doConscriptSettle(mapPlayerTable, second)
- // 如果当前征兵已完成 且 开启自动征兵 则执行下一次征兵
- if conscripts.Conscript.IsConscriptFinish() && conscripts.Conscript.AutoConscript {
- if ok := p.AutoConscript(mapPlayerTable, conscripts.Conscript.ArmID); ok {
- save = true
- }
- }
- }
- // 当前为士兵升级
- if conscripts.IsConscriptUp() {
- save = p.doConscriptUpSettle(mapPlayerTable, second)
- }
- // 保存征兵数据
- if save {
- mapPlayerTable.Save2Queue()
- // 通知客户端
- session, found := sessions.GetSession(mapPlayerTable.PlayerID)
- if found {
- p.Push(mapPlayerTable, session)
- }
- }
- }
- // TODO 后面改成 执行征兵结算
- func (p *service) doConscriptSettle(mapPlayerTable *db.MapPlayerTable, second int32) bool {
- var (
- playerID = mapPlayerTable.PlayerID
- armID = mapPlayerTable.Conscripts.Conscript.ArmID
- num = int64(mapPlayerTable.Conscripts.Conscript.ConscriptRemain())
- )
- if num <= 0 || armID <= 0 {
- return false
- }
- armLevelRow, found := data.ArmLevel.GetByID(armID)
- if !found {
- clog.Warnf("[doConscriptSettle] arm level config not found. armID:%d", armID)
- return false
- }
- var (
- // 预备兵上限
- armLimit = mapPlayerTable.Facilities.Attrs.Get(enum.AttrArmsLimit)
- // 获取征兵/升级的士兵当前数量
- curNum = p.GetCurTroopNum(playerID)
- )
- // 判断如果数量已达上限 则更新时间 不结算
- if curNum >= armLimit {
- return false
- }
- // 获得兵力= 结算次数 * 结算时间 * 单次兵力
- addNum := p.calConscriptNumSecond(mapPlayerTable, second*armLevelRow.ConscriptNumSecond)
- if addNum <= 0 {
- clog.Warnf("[doConscriptSettle] calConscriptNumSecond num <= 0. playerID = %d", playerID)
- return false
- }
- if addNum >= num {
- addNum = num
- }
- // 修正添加数量
- if curNum+addNum > armLimit {
- addNum = armLimit - curNum
- }
- mapPlayerStorageTable := db.GetMapPlayerStorageTable(playerID)
- conscript := mapPlayerStorageTable.Storage.CurrencyMap.GetEntity(armID)
- conscript.Num += addNum
- mapPlayerStorageTable.Save2Queue()
- clog.Debugf("[doConscriptSettle] playerID = %d, armID = %d, addNum = %d", playerID, armID, addNum)
- // 推送兵力变更
- storage.Service().ChangePush(playerID, armID)
- progress := int32(addNum)
- // 增加征兵进度
- mapPlayerTable.Conscripts.AddConscriptProgress(progress)
- // 当前征兵/升级完成
- if mapPlayerTable.Conscripts.Conscript.IsConscriptFinish() {
- // 提交事件
- capp.PostEvent(event.NewConscriptTroopSettle(playerID, armID, mapPlayerTable.Conscripts.Conscript.Total))
- // 系统消息
- actorRemote.GamePlayer.GamePlayerCallSystemMsg(mapPlayerTable.GameNodeID, playerID, enum.ChatMsgType_conscript, nil, nil, armID, mapPlayerTable.Conscripts.Conscript.Total)
- // 如果没有设置自动补兵 则重置
- if !mapPlayerTable.Conscripts.Conscript.AutoConscript {
- mapPlayerTable.Conscripts.ResetConscript()
- } else {
- mapPlayerTable.Conscripts.Conscript.Total = 0
- mapPlayerTable.Conscripts.Conscript.Progress = 0
- }
- }
- return true
- }
- // 执行士兵升级结算
- func (p *service) doConscriptUpSettle(mapPlayerTable *db.MapPlayerTable, second int32) bool {
- var (
- playerID = mapPlayerTable.PlayerID
- upArmID = mapPlayerTable.Conscripts.ConscriptUp.UpArmID
- remain = int64(mapPlayerTable.Conscripts.ConscriptUp.ConscriptUpRemain())
- )
- if upArmID <= 0 || remain <= 0 {
- return false
- }
- upArmLevelRow, found := data.ArmLevel.GetByID(upArmID)
- if !found {
- clog.Warnf("[doConscriptUpSettle] up arm level config not found. playerID:%d,upArmID:%d", playerID, upArmID)
- return false
- }
- var (
- // 预备兵上限
- armLimit = mapPlayerTable.Facilities.Attrs.Get(enum.AttrArmsLimit)
- // 获取征兵/升级的士兵当前数量
- curNum = p.GetCurTroopNum(playerID)
- )
- // 判断如果数量已达上限 则更新时间 不结算
- if curNum >= armLimit {
- return false
- }
- // 获得兵力= 结算次数 * 结算时间 * 单次兵力
- addNum := p.calConscriptNumSecond(mapPlayerTable, second*upArmLevelRow.ConscriptNumSecond)
- if addNum <= 0 {
- clog.Warnf("[doConscriptUpSettle] calConscriptNumSecond num <=0. playerID:%d", mapPlayerTable.PlayerID)
- return false
- }
- if addNum >= remain {
- addNum = remain
- }
- // 修正添加数量
- addNum = math.Min(addNum, armLimit-curNum)
- mapPlayerStorageTable := db.GetMapPlayerStorageTable(playerID)
- conscript := mapPlayerStorageTable.Storage.CurrencyMap.GetEntity(upArmID)
- conscript.Num += addNum
- mapPlayerStorageTable.Save2Queue()
- clog.Debugf("[doConscriptUpSettle] playerID = %d, upArmID = %d, addNum = %d", playerID, upArmID, addNum)
- // 推送兵力变更
- storage.Service().ChangePush(playerID, upArmID)
- progress := int32(addNum)
- // 增加征兵进度
- mapPlayerTable.Conscripts.AddConscriptUpProgress(progress)
- // 当前征兵/升级完成
- if mapPlayerTable.Conscripts.ConscriptUp.IsConscriptUpFinish() {
- // 提交事件
- capp.PostEvent(event.NewConscriptTroopSettle(playerID, upArmID, mapPlayerTable.Conscripts.ConscriptUp.Total))
- actorRemote.GamePlayer.GamePlayerCallSystemMsg(mapPlayerTable.GameNodeID, playerID, enum.ChatMsgType_conscriptUp, nil, nil, upArmID, mapPlayerTable.Conscripts.ConscriptUp.Total)
- mapPlayerTable.Conscripts.ResetConscriptUp()
- }
- return true
- }
- // 计算征兵的数量
- func (p *service) calConscriptNumSecond(mapPlayerTable *db.MapPlayerTable, oneSecondNum int32) int64 {
- addRatio := float64(mapPlayerTable.Facilities.Attrs.Get(enum.AttrConscriptSpeed)) / constant.RatioBase
- singleAdd := math.Round[float64, int64]((1 + addRatio) * float64(oneSecondNum))
- return singleAdd
- }
- // 执行自动征兵 默认都是征兵 没有升级
- func (p *service) AutoConscript(mapPlayerTable *db.MapPlayerTable, armID int32) bool {
- playerID := mapPlayerTable.PlayerID
- armLevelRow, found := data.ArmLevel.GetByID(armID)
- if !found {
- clog.Warnf("auto conscript arm level config not found. armID:%d", armID)
- return false
- }
- var (
- // 预备兵上限
- armLimit = mapPlayerTable.Facilities.Attrs.Get(enum.AttrArmsLimit)
- // 获取征兵/升级的士兵当前数量
- curNum = p.GetCurTroopNum(playerID) + int64(mapPlayerTable.Conscripts.Conscript.ConscriptRemain())
- // 征兵数量
- conscriptNum = armLimit - curNum
- )
- // 当前数量已达上限 跳过
- if conscriptNum <= 0 {
- return false
- }
- // 获取当前征兵消耗
- for _, item := range armLevelRow.ConscriptCostItems {
- // 获取当前资源数量
- curNum := mapFacade.Storage.Get(playerID, item.ID)
- if curNum <= 0 {
- return false
- }
- // 当前道具可征兵数量
- diffNum := curNum / item.Num
- if diffNum <= 0 {
- return false
- }
- conscriptNum = math.Min(conscriptNum, diffNum)
- }
- if conscriptNum <= 0 {
- return false
- }
- // 计算征兵消耗
- costs := armLevelRow.CalConscriptAssets(conscriptNum)
- // 扣除资源
- _, errCode := mapFacade.Storage.AssetSubs(playerID, costs, ao.ConscriptCost)
- if code.IsFail(errCode) {
- return false
- }
- // 开始征兵
- mapPlayerTable.Conscripts.StartConscript(armID, int32(conscriptNum))
- return true
- }
- // 获取当前预备兵数量
- func (p *service) GetCurTroopNum(playerID int64) int64 {
- total := int64(0)
- for _, armLevelRow := range data.ArmLevel.List() {
- // TODO 暂时调用game player的service等背包迁移到地图 获取当前资源数量
- total += mapFacade.Storage.Get(playerID, armLevelRow.ID)
- }
- return total
- }
|