| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521 |
- package mapLeague
- import (
- "f1-game/internal/code"
- "f1-game/internal/constant"
- "f1-game/internal/data"
- "f1-game/internal/enum"
- "f1-game/internal/event"
- "f1-game/internal/extend/utils"
- nameEvent "f1-game/internal/name/event"
- nameLocal "f1-game/internal/name/local"
- nameRemote "f1-game/internal/name/remote"
- nameRoute "f1-game/internal/name/route"
- "f1-game/internal/pb"
- "f1-game/internal/sessions"
- mapCall "f1-game/nodes/map/internal/call"
- "f1-game/nodes/map/internal/db"
- leagueAttr "f1-game/nodes/map/league/attr"
- leagueBase "f1-game/nodes/map/league/base"
- leagueMail "f1-game/nodes/map/league/mail"
- 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 *actorLeague) initMap() {
- p.Local().Register(nameLocal.MapLeague_Build, p.build)
- p.Local().Register(nameLocal.MapLeague_BuildUpgrade, p.buildUpgrade)
- p.Local().Register(nameLocal.MapLeague_BuildDiscard, p.buildDiscard)
- p.Local().Register(nameLocal.MapLeague_DiscardCancel, p.discardCancel)
- p.Remote().Register(nameRemote.MapLeague_BuildUpdate, p.buildUpdate)
- p.EventRegister(nameEvent.League_BuildFinish, p.buildFinish)
- p.EventRegister(nameEvent.League_PointDestroy, p.pointDestroy)
- }
- func (p *actorLeague) build(session *cproto.Session, req *pb.MapBuildRequest) {
- p.Debug("[build] req = %v", req)
- opPlayerID := sessions.GetPlayerID(session)
- leagueMemberTable, found := db.GetMapLeagueMemberTable(p.leagueID)
- if !found {
- p.ResponseCode(session, code.LeagueMembersEmpty)
- return
- }
- // 权限检查 需要同盟建设权限
- ok := leagueMemberTable.CheckPermission(opPlayerID, enum.League_Permission_Construction)
- if !ok {
- p.ResponseCode(session, code.LeaguePermissionDenied)
- return
- }
- row, ok := data.MapBuild.GetByConfigID(req.ConfigID)
- if !ok {
- p.ResponseCode(session, code.ConfigNotFound_MapBuild)
- return
- }
- // 不是联盟建筑
- if row.BuildType != enum.BuildType_League {
- p.ResponseCode(session, code.MapBuild_NotLeagueBuild)
- return
- }
- var (
- buildCount = p.leagueTable.Builds.GetBuildCount(req.ConfigID)
- buildLimit int32
- )
- // 获取当前联盟建筑建造上限
- attrID, found := constant.LeagueMapBuildCountLimitAttrIDMap[req.ConfigID]
- if found {
- buildLimit = p.leagueTable.LeagueInfo.Attrs.GetI32(attrID)
- }
- // 建造数量已达上限
- if buildCount >= buildLimit {
- p.ResponseCode(session, code.MapBuild_NumLimit)
- return
- }
- // 资源不足
- if len(row.BuildCost) > 0 && !p.isEnough(row.BuildCost) {
- p.ResponseCode(session, code.ItemNotEnough)
- return
- }
- // 计算建造时间
- buildTime := row.BuildTime
- // 首次建造
- if buildCount == 0 {
- if time, ok := data.Const.MapBuildFirstTimeElapsed[req.ConfigID]; ok {
- buildTime = time
- }
- }
- level := int32(1)
- if req.ConfigID == constant.MapBuild_LeaguePoint {
- level = p.leagueTable.LeagueInfo.Level
- }
- arg := pb.BuildLeagueRequest{
- ConfigID: req.ConfigID,
- LeagueID: p.leagueID,
- Level: level,
- X: req.Point.X,
- Y: req.Point.Y,
- BuildEndTime: ctime.Now().ToMillisecond() + buildTime*ctime.MillisecondsPerSecond,
- }
- rsp, errCode := mapCall.Logic.BuildLeague(&arg)
- if code.IsFail(errCode) {
- p.Debug("build fail: errCode = %d", errCode)
- p.ResponseCode(session, errCode)
- return
- }
- // 扣除资源
- if len(row.BuildCost) > 0 {
- p.subAssets(row.BuildCost)
- }
- newObjectID, removeObjectID := rsp.Key, rsp.Value
- newBuild := p.leagueTable.Builds.AddBuild(req.ConfigID, newObjectID, req.Point.X, req.Point.Y, arg.BuildEndTime)
- buildsUpdatePushRsp := &pb.MapObjectsUpdate{}
- if removeObjectID != 0 {
- p.leagueTable.Builds.RemoveBuild(removeObjectID)
- // 给所有联盟成员推送建筑更新
- buildsUpdatePushRsp.List = append(buildsUpdatePushRsp.List, &pb.MapObjectUpdate{
- IsDelete: true,
- ObjectID: removeObjectID,
- ObjectType: int32(enum.ObjectType_Build),
- })
- }
- p.leagueTable.Save2Queue()
- p.ResponseCode(session, code.OK)
- p.PostEvent(event.NewLeagueBuild(p.leagueID, req.ConfigID, req.Point))
- // 给所有联盟成员推送建筑更新
- buildsUpdatePushRsp.List = append(buildsUpdatePushRsp.List, &pb.MapObjectUpdate{
- ObjectID: newObjectID,
- ConfigID: newBuild.ConfigID,
- ObjectType: int32(enum.ObjectType_Build),
- Point: newBuild.Point.ToProto(),
- Time: newBuild.BuildEndTime,
- })
- p.pushToMembers(nameRoute.PushMapLeague_BuildUpdate, buildsUpdatePushRsp)
- // 添加日志
- opPlayerName := leagueBase.Service().GetPlayerName(opPlayerID)
- jobID := leagueMemberTable.GetLeagueMemberJob(opPlayerID)
- leagueLogTable, _ := db.GetMapLeagueLogTable(p.leagueID)
- leagueLogTable.AddLeagueLog(enum.Log_LeagueBuildBuilding, utils.ToStringSlice(jobID, opPlayerName, req.ConfigID)...)
- }
- // 联盟建筑升级
- func (p *actorLeague) buildUpgrade(session *cproto.Session, req *pb.I64) {
- opPlayerID := sessions.GetPlayerID(session)
- leagueMemberTable, found := db.GetMapLeagueMemberTable(p.leagueID)
- if !found {
- p.ResponseCode(session, code.LeagueMembersEmpty)
- return
- }
- // 权限检查 需要同盟建设权限
- ok := leagueMemberTable.CheckPermission(opPlayerID, enum.League_Permission_Construction)
- if !ok {
- p.ResponseCode(session, code.LeaguePermissionDenied)
- return
- }
- build, found := p.leagueTable.Builds.GetBuild(req.Value)
- if !found {
- p.ResponseCode(session, code.MapBuild_NotFound)
- return
- }
- // 联盟驻地不支持手动升级 跟随联盟等级
- if build.ConfigID == constant.MapBuild_LeaguePoint {
- p.ResponseCode(session, code.MapBuild_NotUpgrade)
- return
- }
- if build.IsBuilding() {
- p.ResponseCode(session, code.MapBuild_IsBuilding)
- return
- }
- if build.IsUpgrading() {
- p.ResponseCode(session, code.MapBuild_IsUpgrading)
- return
- }
- if build.DiscardTime > 0 {
- p.ResponseCode(session, code.MapBuild_AlreadyDiscarding)
- return
- }
- curMapBuildUpgradeRow, found := data.MapBuildUpgrade.GetByConfigIDLevel(build.ConfigID, build.Level)
- if !found {
- p.ResponseCode(session, code.MapBuildUpgrade_NotFound)
- return
- }
- var (
- nextLevel = build.Level + 1
- levelLimit = int32(0)
- )
- // 获取当前建筑等级上限
- attrID, found := constant.LeagueMapBuildLevelLimitAttrIDMap[build.ConfigID]
- if found {
- levelLimit = p.leagueTable.LeagueInfo.Attrs.GetI32(attrID)
- }
- // 判断等级是否已达当前上限
- if nextLevel >= levelLimit {
- p.ResponseCode(session, code.LevelLimit)
- return
- }
- // 判断下一等级的配置是否存在
- _, found = data.MapBuildUpgrade.GetByConfigIDLevel(build.ConfigID, nextLevel)
- if !found {
- p.ResponseCode(session, code.ConfigNotFound_MapBuildUpgrade)
- return
- }
- // 升级消耗不存在
- if curMapBuildUpgradeRow.UpgradeCost.IsEmpty() {
- p.ResponseCode(session, code.MapBuildUpgradeCost_NotExist)
- return
- }
- if !p.isEnough(curMapBuildUpgradeRow.UpgradeCost) {
- p.ResponseCode(session, code.ItemNotEnough)
- return
- }
- // 升级结束时间戳
- upgradeEndTime := ctime.Now().ToMillisecond() + curMapBuildUpgradeRow.UpgradeTime*ctime.MillisecondsPerSecond
- arg := &pb.BuildUpgradeRequest{
- ObjectID: build.ObjectID,
- ConfigID: build.ConfigID,
- LeagueID: p.leagueID,
- Level: build.Level,
- UpgradeEndTime: upgradeEndTime,
- }
- errCode := mapCall.Logic.BuildUpgrade(arg)
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- // 扣除资源
- p.subAssets(curMapBuildUpgradeRow.UpgradeCost)
- // TODO 是否单独字段保存升级结束时间戳 现在先放建造结束时间
- build.UpgradeEndTime = upgradeEndTime
- p.leagueTable.Save2Queue()
- p.ResponseCode(session, code.OK)
- // 给所有联盟成员推送建筑更新
- buildsUpdatePushRsp := &pb.MapObjectsUpdate{}
- buildsUpdatePushRsp.List = append(buildsUpdatePushRsp.List, &pb.MapObjectUpdate{
- ObjectID: build.ObjectID,
- ConfigID: build.ConfigID,
- ObjectType: int32(enum.ObjectType_Build),
- Point: build.Point.ToProto(),
- Time: build.BuildEndTime,
- })
- p.pushToMembers(nameRoute.PushMapLeague_BuildUpdate, buildsUpdatePushRsp)
- }
- // buildDiscard 摧毁联盟建筑
- func (p *actorLeague) buildDiscard(session *cproto.Session, req *pb.I64) {
- objectID := req.Value
- p.Debug("[buildDiscard] objectID = %d", objectID)
- build, found := p.leagueTable.Builds.GetBuild(objectID)
- if !found {
- p.ResponseCode(session, code.MapLeague_BuildNotFound)
- return
- }
- mapBuildRow, found := data.MapBuild.GetByConfigID(build.ConfigID)
- if !found {
- p.ResponseCode(session, code.ConfigNotFound_MapBuild)
- return
- }
- // 当前建筑不可摧毁
- if !mapBuildRow.Discardable {
- p.ResponseCode(session, code.MapLeague_NotCanDiscard)
- return
- }
- // TODO 建筑建造中是否能摧毁
- // 已经在摧毁中
- if build.DiscardTime > 0 {
- p.ResponseCode(session, code.MapBuild_AlreadyDiscarding)
- return
- }
- opPlayerID := sessions.GetPlayerID(session)
- mapLeagueMemberTable, _ := db.GetMapLeagueMemberTable(p.leagueID)
- // 检查权限
- if !mapLeagueMemberTable.CheckPermission(opPlayerID, enum.League_Permission_Construction) {
- p.ResponseCode(session, code.LeaguePermissionDenied)
- return
- }
- discardTime, errCode := mapCall.Logic.BuildDiscard(p.leagueID, objectID)
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- build.PlayerID = sessions.GetPlayerID(session)
- build.JobID = mapLeagueMemberTable.GetLeagueMemberJob(opPlayerID)
- build.DiscardTime = discardTime
- p.leagueTable.Save2Queue()
- p.ResponseCode(session, code.OK)
- // 给所有联盟成员推送建筑更新
- p.pushToMembers(nameRoute.PushMapLeague_BuildUpdate, &pb.MapObjectsUpdate{
- List: []*pb.MapObjectUpdate{
- {
- IsDelete: true,
- ObjectID: objectID,
- ConfigID: build.ConfigID,
- ObjectType: int32(enum.ObjectType_Build),
- Point: build.Point.ToProto(),
- Time: discardTime,
- },
- },
- })
- }
- // buildDiscard 摧毁联盟建筑
- func (p *actorLeague) discardCancel(session *cproto.Session, req *pb.I64I32) {
- var (
- objectID = req.Key
- objectType = enum.ObjectType(req.Value)
- )
- p.Debug("[discardCancel] objectID = %d, objectType = %s", objectID, enum.GetObjectTypeName(objectType))
- opPlayerID := sessions.GetPlayerID(session)
- mapLeagueMemberTable, _ := db.GetMapLeagueMemberTable(p.leagueID)
- // 检查权限
- if !mapLeagueMemberTable.CheckPermission(opPlayerID, enum.League_Permission_Construction) {
- p.ResponseCode(session, code.LeaguePermissionDenied)
- return
- }
- errCode := mapCall.Logic.DiscardCancelLeague(p.leagueID, objectID, int32(objectType))
- if code.IsFail(errCode) {
- p.ResponseCode(session, errCode)
- return
- }
- switch objectType {
- case enum.ObjectType_Build:
- build, found := p.leagueTable.Builds.GetBuild(objectID)
- if !found {
- p.ResponseCode(session, code.MapLeague_BuildNotFound)
- return
- }
- build.PlayerID = 0
- build.JobID = 0
- build.DiscardTime = 0
- p.leagueTable.Save2Queue()
- // 给所有联盟成员推送建筑更新
- p.pushToMembers(nameRoute.PushMapLeague_BuildUpdate, &pb.MapObjectsUpdate{
- List: []*pb.MapObjectUpdate{
- {
- ObjectID: objectID,
- ConfigID: build.ConfigID,
- ObjectType: int32(enum.ObjectType_Build),
- Point: build.Point.ToProto(),
- Time: 0,
- },
- },
- })
- }
- p.ResponseCode(session, code.OK)
- }
- func (p *actorLeague) buildUpdate(req *pb.BuildUpdate) {
- p.Debug("[buildUpdate] req = %+v", req)
- var (
- point = &pb.Point{
- X: req.X,
- Y: req.Y,
- }
- mapObjectUpdate = &pb.MapObjectUpdate{
- ObjectID: req.ObjectID,
- ConfigID: req.ConfigID,
- ObjectType: int32(enum.ObjectType_Build),
- Point: point,
- }
- )
- if req.IsAdd {
- // 占领获取了建筑,不用设置建造时间
- p.leagueTable.Builds.AddBuild(req.ConfigID, req.ObjectID, req.X, req.Y, 0)
- } else {
- removeBuild, success := p.leagueTable.Builds.RemoveBuild(req.ObjectID)
- mapObjectUpdate.IsDelete = true
- // 给所有联盟成员推送邮件
- // TODO 先用系统邮件通知,等后面有了联盟系统邮件再改
- leagueMail.Service().SendAllMemberMail(p.leagueID, constant.MailID_LeagueBuildDiscard, nil, req.ConfigID, point)
- if success {
- // 添加放弃日志
- opPlayerName := leagueBase.Service().GetPlayerName(removeBuild.PlayerID)
- leagueLogTable, _ := db.GetMapLeagueLogTable(p.leagueID)
- leagueLogTable.AddLeagueLog(enum.Log_LeagueGiveUpBuilding, utils.ToStringSlice(removeBuild.JobID, opPlayerName, removeBuild.ConfigID)...)
- }
- }
- p.leagueTable.Save2Queue()
- // 给所有联盟成员推送建筑更新
- p.pushToMembers(nameRoute.PushMapLeague_BuildUpdate, &pb.MapObjectsUpdate{
- List: []*pb.MapObjectUpdate{mapObjectUpdate},
- })
- }
- // 联盟建筑建造/升级完成事件处理
- func (p *actorLeague) buildFinish(eventData cfacade.IEventData) {
- p.Debug("[buildFinish] leagueID:%d, eventData=%+v", p.leagueID, eventData)
- evt, ok := eventData.(*event.LeagueBuildFinish)
- if !ok {
- p.Warn("[buildFinish] eventData error. leagueID:%d", p.leagueID)
- return
- }
- var (
- req = evt.Key()
- isUp = evt.Value()
- objectID = req.Key
- level = req.Value
- )
- build, ok := p.leagueTable.Builds.GetBuild(objectID)
- if !ok {
- p.Warn("[buildFinish] build not found. leagueID:%d, objectID:%d", p.leagueID, objectID)
- return
- }
- build.Level = level
- p.leagueTable.Save2Queue()
- if !isUp {
- // 建造完成的时候推送全员邮件
- // TODO 先用系统邮件通知,等后面有了联盟系统邮件再改
- leagueMail.Service().SendAllMemberMail(p.leagueID, constant.MailID_LeagueBuild, nil, build.ConfigID, build.Point)
- }
- mapBuildRow, found := data.MapBuild.GetByConfigID(build.ConfigID)
- // 当前完成的是联盟资源田 刷新联盟属性
- if found && mapBuildRow.BuildingCategory == enum.LeagueMapBuildType_Res {
- leagueAttr.Service().UpdateAttrs(p.leagueTable)
- }
- }
- // 联盟驻地摧毁
- func (p *actorLeague) pointDestroy(eventData cfacade.IEventData) {
- evt, ok := eventData.(*event.LeaguePointDestroy)
- if !ok {
- p.Warn("[leaguePointDestroy] eventData error. leagueID:%d", p.leagueID)
- return
- }
- p.Debug("[leaguePointDestroy] leagueID = %d, objectID = %d", p.leagueID, evt.ObjectID())
- // 通知所有联盟成员再起
- for _, re := range p.leagueTable.Residences {
- mapCall.Player.AutoReborn(re.PlayerID)
- }
- // 清空驻地
- p.leagueTable.Residences.Clear()
- // 删除驻地
- p.leagueTable.Builds.RemoveBuild(evt.ObjectID())
- p.leagueTable.Save2Queue()
- // 通知在线成员更新驻地信息
- p.pushToMembers(nameRoute.PushMapLeague_Residence, &pb.LeagueResidenceList{})
- }
|