local Base = require("Battle/Logic/Level/LevelFunction/SyncCityWarBaseLevelFunction") local SyncCityWarMainFirstStageLevelFunction = class("SyncCityWarMainFirstStageLevelFunction", Base) local siege_city_battlecheck_pb = require 'Proto/siege_city_battlecheck_pb' local EStatisticType = LuaConst.EStatisticType local LEVELITEMTYPE_MONSTER = LuaConst.LevelItemType.Monster local FEATUREID_WALL = 622002 local FEATUREID_CHONGCHE = 622001 local FEATUREID_LIST_ATTACKER_VEHICLE = {622011, 622012, 622013} --攻方载具 local FEATUREID_TOWER_EMPTY = 622021 local FEATUREID_TOWER_BASE = 622022 --守方1级炮塔(刚购买出来的) local FEATUREID_DEFEND_BOSS = 622031 --守城boss local FEATUREID_LIST_TOWER_UPGRADED = {622023, 622024, 622025, 622026, 622027, 622028} --守方2级和2级以上的炮塔 local SiegeCityTankLimit = DataSheetManager.ConstData:GetDataByID("SiegeCityTankLimit").IntValue --主战场攻方造车数量上限 local AttackerGoodsBase = DataSheetManager.ConstData:GetDataByID("SiegeCityMainBattleAttackerGoodsBase").IntValue --主战场攻方物资基础值 local DefenderGoodsBase = DataSheetManager.ConstData:GetDataByID("SiegeCityMainBattleDefenderGoodsBase").IntValue --主战场守方物资基础值 local AttackerGoodsIncrease = DataSheetManager.ConstData:GetDataByID("SiegeCityMainBattleAttackerGoodsIncrease").IntValue --主战场攻方物资每秒增加(xxx/s) local DefenderGoodsIncrease = DataSheetManager.ConstData:GetDataByID("SiegeCityMainBattleDefenderGoodsIncrease").IntValue --主战场守方物资每秒增加(xxx/s) local SiegeCityMainBattleKillPoint = DataSheetManager.ConstData:GetDataByID("SiegeCityMainBattleKillPoint").IntValue local SiegeCityMainBattleAssistPoint = DataSheetManager.ConstData:GetDataByID("SiegeCityMainBattleAssistPoint").IntValue local SiegeCityTowerDamagePointRate = DataSheetManager.ConstData:GetDataByID("SiegeCityTowerDamagePointRate").FloatValue -- 对塔的伤害转化为贡献的比例 local SiegeCityTankDamagePointRate = DataSheetManager.ConstData:GetDataByID("SiegeCityTankDamagePointRate").FloatValue -- 对车的伤害转化为贡献的比例 local SiegeCityGateDamagePointRate = DataSheetManager.ConstData:GetDataByID("SiegeCityGateDamagePointRate").FloatValue -- 对城门的伤害转化为贡献的比例 local CityWarTowerLevelItemIdList = DataSheetManager.ConstData:GetDataByID("CityWarTowerLevelItemIdList").IntListValue --可以造塔的LevelItem列表 local Const_OccupyTimers = 99 -- 当 连续占领次数大于0时又找不到数据则默认为最高次数 99 function SyncCityWarMainFirstStageLevelFunction:InitLevel() Base.InitLevel(self) self.wallHpLoss = FP.newV1(0) self.campResourceAmountDic = {0,0} self.campResourceAmountDic[self.attackCampID] = AttackerGoodsBase --self.attackCampID = 1 self.campResourceAmountDic[self.defendCampID] = DefenderGoodsBase --self.defendCampID = 2 self.vehicleEntityList = {} self.towerEventList = {} --塔的事件列表,仅发送给服务器用作信息同步。服务器驱动清理 self.attackerCountryId = nil self.defenderCountryId = nil self.bornItemPhase = 1 self.defineBossDead = false -- 标记守城boss是否死亡 self.crushCarList = {} -- 冲车entity的列表 --冲车需要添加的debuff local occupyTimers = LevelManager.GetNewBattleInfoIntParam() local success, dataInfo = DataSheetManager.SiegeCityOccupyDebuff:TryGetDataBySiegeCityOccupyMuchTimes(occupyTimers) if success then self.buffToChongChe = dataInfo.SiegeCityOccupyMuchCarBuff elseif occupyTimers > 0 then dataInfo = DataSheetManager.SiegeCityOccupyDebuff:GetDataBySiegeCityOccupyMuchTimes(Const_OccupyTimers) self.buffToChongChe = dataInfo.SiegeCityOccupyMuchCarBuff end end function SyncCityWarMainFirstStageLevelFunction:InitPlayerStatistic(statistic) Base.InitPlayerStatistic(self, statistic) statistic[EStatisticType.GateDamage] = FP.newV1(0) statistic[EStatisticType.TowerDamage] = FP.newV1(0) statistic[EStatisticType.VehicleDamage] = FP.newV1(0) end function SyncCityWarMainFirstStageLevelFunction:OnCreatePlayer(playerID, playerInfo, firstEntity) Base.OnCreatePlayer(self, playerID, playerInfo, firstEntity) if self.attackerCountryId == nil or self.defenderCountryId == nil then if playerInfo.campID == self.attackCampID then self.attackerCountryId = playerInfo.countryId else self.defenderCountryId = playerInfo.countryId end end end function SyncCityWarMainFirstStageLevelFunction:TryRecalculateBornItemIDOfPlayer() --do nothing 这个玩法不随机出生点 end function SyncCityWarMainFirstStageLevelFunction:AddBornItemID2WeightList(idInfo, idWeightPairsList) Base.AddBornItemID2WeightList(self, idInfo, idWeightPairsList) if idWeightPairsList[1] and (idWeightPairsList[1].key == 1003 or idWeightPairsList[1].key == 1005) then self.bornItemPhase = 2 end end function SyncCityWarMainFirstStageLevelFunction:GetBornItem(playerInfo, index) if self.bornItemPhase == 2 then if playerInfo.campID == self.attackCampID then return LevelItemManager.GetItemByID(1005) else if LogicRandom.GetRandom01(nil, 3489238) <= FP.Const.Half then return LevelItemManager.GetItemByID(1003) else return LevelItemManager.GetItemByID(1004) end end else return Base.GetBornItem(self, playerInfo, index) end end function SyncCityWarMainFirstStageLevelFunction:IsTowerFeatureID(featureID) return self:IsBaseTowerFeatureID(featureID) or self:IsUpgradedTowerFeatureID(featureID) end function SyncCityWarMainFirstStageLevelFunction:IsBaseTowerFeatureID(featureID) return featureID == FEATUREID_TOWER_BASE end function SyncCityWarMainFirstStageLevelFunction:IsUpgradedTowerFeatureID(featureID) for i,v in ipairs(FEATUREID_LIST_TOWER_UPGRADED) do if v == featureID then return true end end return false end function SyncCityWarMainFirstStageLevelFunction:IsAttackerVehicleFeatureID(featureID) for i,v in ipairs(FEATUREID_LIST_ATTACKER_VEHICLE) do if v == featureID then return true end end return false end function SyncCityWarMainFirstStageLevelFunction:GetResourceAmount() return self.campResourceAmountDic end function SyncCityWarMainFirstStageLevelFunction.GetKillScore(killNum) --静态方法 return killNum * SiegeCityMainBattleKillPoint end function SyncCityWarMainFirstStageLevelFunction.GetAssistScore(assistNum) --静态方法 return assistNum * SiegeCityMainBattleAssistPoint end function SyncCityWarMainFirstStageLevelFunction:GetVehicleEntityList() return self.vehicleEntityList end function SyncCityWarMainFirstStageLevelFunction:GetVehicleEntityCount() return #self.vehicleEntityList end -- container : 容器,会把 container[1] - container[5] 赋值为塔的单位 function SyncCityWarMainFirstStageLevelFunction:GetTowerEntityList(container) local towerEntityList = container or {} for i,itemId in ipairs(CityWarTowerLevelItemIdList) do local levelItem = LevelItemManager.GetItemByID(itemId, LEVELITEMTYPE_MONSTER) local monsterEntity = levelItem:GetMonsterEntity() if monsterEntity then table.insert(towerEntityList, monsterEntity) end end return towerEntityList end function SyncCityWarMainFirstStageLevelFunction:GetTowerEntityByIndex(index) return LevelItemManager.GetItemByID(CityWarTowerLevelItemIdList[index], LEVELITEMTYPE_MONSTER):GetMonsterEntity() end function SyncCityWarMainFirstStageLevelFunction:GetTowerMonsterIdByIndex(index) local monsterEntity = self:GetTowerEntityByIndex(index) if monsterEntity then return monsterEntity:GetCharacterID() else return -1 end end function SyncCityWarMainFirstStageLevelFunction:CanCreateMonsterAtFirstEmptyMonsterLevelItem(monsterID, levelItemId) local isSucceed, monsterData = DataSheetManager.MonsterData:TryGetDataByID(monsterID) if isSucceed then if self:IsAttackerVehicleFeatureID(monsterData.MonsterType) then if self:GetVehicleEntityCount() < SiegeCityTankLimit then return true end end end return false end function SyncCityWarMainFirstStageLevelFunction:OnCreateMonsterAtFirstEmptyMonsterLevelItemFailed(monsterID, levelItemId) local isSucceed, monsterData = DataSheetManager.MonsterData:TryGetDataByID(monsterID) if isSucceed then if self:IsAttackerVehicleFeatureID(monsterData.MonsterType) then local vehicleEvent = siege_city_battlecheck_pb.SiegeCityBuildingEvent() vehicleEvent.buildId = monsterID vehicleEvent.eventType = 2 -- 1.破坏 2.建造失败 vehicleEvent.positionIdx = levelItemId vehicleEvent.frameId = LogicUpdateManager._clientHandleFrame self.towerEventList[#self.towerEventList + 1] = vehicleEvent end end end --服务器用的查询接口 --除了包含塔的事件信息,也包含载具的(2023年8月28日新增需求) function SyncCityWarMainFirstStageLevelFunction:GetTowerEventListPbBytes() if #self.towerEventList > 0 then local msg = siege_city_battlecheck_pb.SiegeCityBuildingEventList() for i,event in ipairs(self.towerEventList) do local eventMsg = siege_city_battlecheck_pb.SiegeCityBuildingEvent() eventMsg.buildId = event.buildId eventMsg.eventType = event.eventType eventMsg.frameId = event.frameId eventMsg.positionIdx = event.positionIdx table.insert(msg.eventList, eventMsg) end return msg:SerializeToString() else return "" end end --服务器调用来清空塔事件列表 --frameIndex : 如果传nil,则会清空所有的事件,如果传一个number,则会清理掉列表里所有frameId <= frameIndex的事件 function SyncCityWarMainFirstStageLevelFunction:ClearTowerEventList(toFrameIndex) if #self.towerEventList > 0 then if frameIndex then for i=#self.towerEventList,1,-1 do if self.towerEventList[i].frameId <= frameIndex then table.remove(self.towerEventList, i) end end else table.clearArray(self.towerEventList) end end end --服务器用的查询接口 获取国家资源数量信息列表 function SyncCityWarMainFirstStageLevelFunction:GetResourcesListPbBytes() if self.attackerCountryId or self.defenderCountryId then local msg = siege_city_battlecheck_pb.SiegeCityResourcesList() if self.attackerCountryId then local resouceMsg = siege_city_battlecheck_pb.SiegeCityResources() resouceMsg.countryId = self.attackerCountryId resouceMsg.resources = self.campResourceAmountDic[self.attackCampID] table.insert(msg.resourceList, resouceMsg) end if self.defenderCountryId then local resouceMsg = siege_city_battlecheck_pb.SiegeCityResources() resouceMsg.countryId = self.defenderCountryId resouceMsg.resources = self.campResourceAmountDic[self.defendCampID] table.insert(msg.resourceList, resouceMsg) end return msg:SerializeToString() else return "" end end --服务器用的查询接口 function SyncCityWarMainFirstStageLevelFunction:GetWallDamage() return FP.tonumberV1(self.wallHpLoss) end function SyncCityWarMainFirstStageLevelFunction:GetTowerPosIndexByLevelItemId(levelItemId) for i,_itemId in ipairs(CityWarTowerLevelItemIdList) do if _itemId == levelItemId then return i end end end function SyncCityWarMainFirstStageLevelFunction:OnReplaceMonsterSequentiallyFailed(oldMonsterID, idSequenceList, bornItemID) local towerEvent = siege_city_battlecheck_pb.SiegeCityBuildingEvent() towerEvent.buildId = idSequenceList[2] towerEvent.eventType = 2 -- 1.破坏 2.建造失败 local posIndex = self:GetTowerPosIndexByLevelItemId(bornItemID) if posIndex then towerEvent.positionIdx = posIndex else logging.error(LTAG.ERROR, "HYW : 找不到地块index, 元素ID : ", bornItemID) end towerEvent.frameId = LogicUpdateManager._clientHandleFrame self.towerEventList[#self.towerEventList + 1] = towerEvent end function SyncCityWarMainFirstStageLevelFunction:OnEntityBorn(entity) Base.OnEntityBorn(self, entity) if entity.isMonster and self:IsAttackerVehicleFeatureID(entity.featureID) then self.vehicleEntityList[#self.vehicleEntityList + 1] = entity end --给冲车添加deBuff if self.buffToChongChe and FEATUREID_CHONGCHE == entity.featureID then SystemManager.AddBuff(entity, self.buffToChongChe, entity) end if FEATUREID_CHONGCHE == entity.featureID then table.insert(self.crushCarList, entity) end end function SyncCityWarMainFirstStageLevelFunction:OnEntityActive(entity, activeType) local featureID = entity.featureID if featureID == FEATUREID_TOWER_EMPTY or self:IsTowerFeatureID(featureID) then -- 塔基和炮塔出生完毕后要告知UI self.exp:OnTowerActive(entity) end if self:IsAttackerVehicleFeatureID(entity.featureID) then self.exp:OnAttackerVehicleActive(entity) end if featureID == FEATUREID_CHONGCHE then self.exp:OnCrushCarActive(entity) end end function SyncCityWarMainFirstStageLevelFunction:OnEntityDead(entity, deadParams) Base.OnEntityDead(self, entity, deadParams) if entity.isMonster then if self:IsAttackerVehicleFeatureID(entity.featureID) then self:OnVehicleDead(entity, deadParams) elseif self:IsTowerFeatureID(entity.featureID) then self:OnTowerDead(entity, deadParams) end if entity.featureID == FEATUREID_DEFEND_BOSS then self.defineBossDead = true end end end function SyncCityWarMainFirstStageLevelFunction:OnVehicleDead(entity, deadParams) local vehicleEvent = siege_city_battlecheck_pb.SiegeCityBuildingEvent() vehicleEvent.buildId = entity:GetCharacterID() vehicleEvent.eventType = 1 -- 1.破坏 2.建造失败 vehicleEvent.positionIdx = entity._logicInitData.BornItemID vehicleEvent.frameId = LogicUpdateManager._clientHandleFrame self.towerEventList[#self.towerEventList + 1] = vehicleEvent table.removebyvalue(self.vehicleEntityList, entity) end function SyncCityWarMainFirstStageLevelFunction:OnTowerDead(entity, deadParams) if deadParams and deadParams.replaceToMonsterID == FEATUREID_TOWER_EMPTY then local towerEvent = siege_city_battlecheck_pb.SiegeCityBuildingEvent() towerEvent.buildId = entity:GetCharacterID() towerEvent.eventType = 1 -- 1.破坏 2.建造失败 local posIndex = self:GetTowerPosIndexByLevelItemId(entity._logicInitData.BornItemID) if posIndex then towerEvent.positionIdx = posIndex else logging.error(LTAG.ERROR, "HYW : 找不到地块index, 元素ID : ", entity._logicInitData.BornItemID) end towerEvent.frameId = LogicUpdateManager._clientHandleFrame self.towerEventList[#self.towerEventList + 1] = towerEvent --else --没有 KillerEntity的情况,代表是被系统杀死,此时可以认为是升级的时候杀死了塔,不需要生成事件 end end function SyncCityWarMainFirstStageLevelFunction:OnHpChange(entity, caster, delta, op, realDelta) Base.OnHpChange(self, entity, caster, delta, op, realDelta) repeat if op ~= "sub" or delta >= FP.Const.Zero then break end if entity.isMonster then local originCaster = caster:GetOriginEntity() local playerStatistic if originCaster.isHero then playerStatistic = self.PlayerStatisticDic[originCaster:GetPlayerID()] end local featureID = entity.featureID if featureID == FEATUREID_WALL then if playerStatistic then playerStatistic[EStatisticType.GateDamage]:Sub(delta) end self.wallHpLoss:Sub(delta) else if playerStatistic then local featureID = entity.featureID if self:IsTowerFeatureID(featureID) then playerStatistic[EStatisticType.TowerDamage]:Sub(delta) elseif self:IsAttackerVehicleFeatureID(featureID) then playerStatistic[EStatisticType.VehicleDamage]:Sub(delta) end end end if entity:GetOriginEntity().isHero then if self:IsTowerFeatureID(caster.featureID) then self.exp:OnTowerCauseDamage(entity, caster, delta, op, realDelta) end end elseif entity.isHero then if self:IsTowerFeatureID(caster.featureID) then self.exp:OnTowerCauseDamage(entity, caster, delta, op, realDelta) end end until true end function SyncCityWarMainFirstStageLevelFunction:OnUpdate() Base.OnUpdate(self) if LogicUpdateManager._isIntegralSecond then self.campResourceAmountDic[self.attackCampID] = self.campResourceAmountDic[self.attackCampID] + AttackerGoodsIncrease self.campResourceAmountDic[self.defendCampID] = self.campResourceAmountDic[self.defendCampID] + DefenderGoodsIncrease end end function SyncCityWarMainFirstStageLevelFunction:GetPlayerScoreInfo(playerID) local playerStatistic = self.PlayerStatisticDic[playerID] if playerStatistic then local playerInfo = LevelPlayerManager.GetPlayerInfoByPlayerIDInRoom(playerID) local info = {} local killNum = playerStatistic[EStatisticType.HeroKillNum] local assistNum = playerStatistic[EStatisticType.AssistHeroKillNum] info.killScore = killNum * SiegeCityMainBattleKillPoint info.assistScore = assistNum * SiegeCityMainBattleAssistPoint info.chongcheScore = playerStatistic[EStatisticType.ScorePlus] info.towerDmgScore = FP.tonumberV1(playerStatistic[EStatisticType.TowerDamage] * SiegeCityTowerDamagePointRate) info.vehicleDmgScore = FP.tonumberV1(playerStatistic[EStatisticType.VehicleDamage] * SiegeCityTankDamagePointRate) info.gateDmgScore = FP.tonumberV1(playerStatistic[EStatisticType.GateDamage] * SiegeCityGateDamagePointRate) if playerInfo.campID == self.attackCampID then info.otherScore = info.towerDmgScore + info.gateDmgScore + info.chongcheScore else info.otherScore = info.vehicleDmgScore + info.chongcheScore end info.playerInfo = playerInfo return info end end return SyncCityWarMainFirstStageLevelFunction