package facility import ( actorRemote "f1-game/internal/actor_remote" capp "f1-game/internal/cherry_app" "f1-game/internal/constant" "f1-game/internal/data" "f1-game/internal/enum" "f1-game/internal/event" facade "f1-game/internal/facade" nameRoute "f1-game/internal/name/route" "f1-game/internal/pb" "f1-game/internal/sessions" "f1-game/internal/types" "f1-game/nodes/map/internal/db" "f1-game/nodes/map/player/player" "f1-game/nodes/map/player/storage" "f1-game/nodes/map/player/team" clog "github.com/cherry-game/cherry/logger" cproto "github.com/cherry-game/cherry/net/proto" ) var srv = &service{} func Service() *service { return srv } type service struct { facade.PlayerServiceBase[*db.MapPlayerTable] } func (p *service) OnLogin(mapPlayerTable *db.MapPlayerTable, session *cproto.Session) { // 根据常量表配置初始化城建,支持配表增量变化 isFacilityChange := p.initDefaultFacilities(mapPlayerTable) isQueueChange := p.initDefaultQueues(mapPlayerTable) if isFacilityChange || isQueueChange { mapPlayerTable.Save2Queue() if isFacilityChange { // 只有属性更新才需要刷新声望值 player.Service().RefreshFacilityPrestige(mapPlayerTable.PlayerID) } clog.Infof("map facility init: playerID = %d", mapPlayerTable.PlayerID) } } // func (p *service) OnLogined(playerTable *db.MapPlayerTable, session *cproto.Session) { // } // func (p *service) OnLogout(playerTable *db.MapPlayerTable) { // } // func (p *service) OnReset(playerTable *db.MapPlayerTable, time *ctime.CherryTime, byLogin bool) { // } // 建筑推送 func (p *service) Push(playerTable *db.MapPlayerTable, session *cproto.Session) { proto := playerTable.Facilities.ToProto() sessions.PushWithSession(session, nameRoute.PushMapPlayer_FacilityList, &proto) } // 创建默认开启的建筑 func (p *service) initDefaultFacilities(playerTable *db.MapPlayerTable) (isChange bool) { for _, build := range data.Const.BuildDefaultOpen { facility, found := playerTable.Facilities.Facilitys.Get(build.Key) if found && facility.Level >= build.Value { continue } if !found { facility = playerTable.Facilities.CreateFacility(build.Key) } facility.Level = build.Value isChange = true } if isChange { // 更新默认开启的建筑属性 p.UpdateAttrs(playerTable, true) } return } // 创建默认解锁的建筑队列 func (p *service) initDefaultQueues(playerTable *db.MapPlayerTable) (isChange bool) { for _, facilityQueue := range data.FacilityQueue.List() { if facilityQueue.IsUnlock { if playerTable.Facilities.Queues.Contains(facilityQueue.ID) { continue } playerTable.Facilities.UnlockQueue(facilityQueue.ID) isChange = true } } return } // 推送完成的建筑 func (p *service) FinishPush(playerID int64, facilityIDList ...int32) { if len(facilityIDList) == 0 { return } var ( playerTable = db.GetMapPlayerTable(playerID) list []*pb.Facility ) if playerTable == nil { return } for _, facilityID := range facilityIDList { if facility, ok := playerTable.Facilities.Facilitys.Get(facilityID); ok { proto := facility.ToProto() list = append(list, &proto) } } if len(list) == 0 { return } rsp := pb.FacilityList{List: list} sessions.PushPlayer(playerID, nameRoute.PushMapPlayer_FacilityFinish, &rsp) } // CheckQueue 检查建筑队列 func (p *service) CheckQueue(playerID int64, nowSecond int64) { var ( playerTable = db.GetMapPlayerTable(playerID) facilityMap = types.NewMap[int32, int32]() ) if playerTable == nil { return } for _, queue := range playerTable.Facilities.Queues { if queue.FinishTime > nowSecond || queue.FacilityID < 1 { continue } build, _ := playerTable.Facilities.Facilitys.Get(queue.FacilityID) build.Level++ facilityMap.Put(build.FacilityID, build.Level) queue.Reset() } if len(facilityMap) > 0 { p.UpdateAttrs(playerTable) playerTable.Save2Queue() p.FinishPush(playerID, facilityMap.Keys()...) for facilityID, level := range facilityMap { capp.PostEvent(event.NewFacilityUp(playerID, facilityID, level)) // 发送系统消息 actorRemote.GamePlayer.GamePlayerCallSystemMsg(playerTable.GameNodeID, playerID, enum.ChatMsgType_buildUp, nil, nil, facilityID, level) } } } // 更新属性,只在变更的时候推送,登录在领主信息协议里推送 func (p *service) UpdateAttrs(playerTable *db.MapPlayerTable, isLogin ...bool) { var ( mapPlayerStorageTable = db.GetMapPlayerStorageTable(playerTable.PlayerID) attrs = newAttrs() ) for _, fn := range attrFnList { fn(playerTable.PlayerID, attrs) } playerTable.Facilities.Attrs = attrs.result() // 更新建筑属性,转换为战斗对象属性 p.UpdateFacilityFighterAttrs(playerTable) if playerTable.IsSelectBornState() { // 抛事件 capp.PostEvent(event.NewMapWatcherSync(playerTable.PlayerID, &event.MapWatcherData{ PlayerID: playerTable.PlayerID, IsFacilitySync: true, FacilityAttrs: playerTable.Facilities.Attrs, })) } // 是否推送,登录不推送 isPush := len(isLogin) == 0 || !isLogin[0] if isPush { // 推送属性变更 sessions.PushPlayer(playerTable.PlayerID, nameRoute.PushMapPlayer_FacilityAttrChange, playerTable.Facilities.Attrs.ToProto()) } // 检查更新资源容量 isChange := mapPlayerStorageTable.Storage.CurrencyMap.Check(playerTable.Facilities.Attrs.GetI64(enum.AttrResCapacity), enum.ItemMaxNumList) if isChange { mapPlayerStorageTable.Save2Queue() if isPush { // 推送资源容量变更,登录不推送 storage.Service().ChangePush(playerTable.PlayerID, enum.ItemMaxNumList...) } } } // 建筑升级,城建属性转战斗对象的属性 func (p *service) UpdateFacilityFighterAttrs(playerTable *db.MapPlayerTable) { attrs := types.NewAttrs() for _, facility := range playerTable.Facilities.Facilitys { if levelRow, ok := data.FacilityLevel.GetByFacilityIDLevel(facility.FacilityID, facility.Level); ok { for k, v := range levelRow.Attrs { switch k { case enum.AttrTeamDamageRatio: attrs.Add(enum.Attr_DamageBonus, v) case enum.AttrTeamDamageReduceRatio: attrs.Add(enum.Attr_DamageReduction, v) case enum.AttrInfantryAllAttrRatio: attrs.Add(enum.Attr_InfantryAllAttributeBonus, v) case enum.AttrCavalryAllAttrRatio: attrs.Add(enum.Attr_CavalryAllAttributeBonus, v) case enum.AttrArcherAllAttrRatio: attrs.Add(enum.Attr_ArcherAllAttributeBonus, v) } } } } for _, team := range playerTable.Teams { team.FacilityAttrs = attrs } playerTable.Save2Queue() // 更新所有队伍 team.Service().UpdatePlayerTeams(playerTable.PlayerID, playerTable.Teams...) } func (*service) GetBuildCountLimit(playerTable *db.MapPlayerTable, mapBuildRow *data.MapBuildRow) int32 { attrID := int32(0) switch mapBuildRow.ConfigID { // 营帐 case constant.MapBuild_Camp: attrID = enum.AttrTentLimit } if attrID <= 0 { return mapBuildRow.InitBuildLimit } return playerTable.Facilities.GetAttrs(attrID) }