战斗逻辑

lvxinran 2021-04-30 21:12:34 +08:00
parent d593a41660
commit a1dbf73f89
21 changed files with 1345 additions and 381 deletions

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,334 @@
ConfigName = {
-- AccomplishmentConfig = "AccomplishmentConfig",
ActivityRewardConfig = "ActivityRewardConfig",
-- AdventureConfig = "AdventureConfig",
AreaConfig = "AreaConfig",
ArtResourcesConfig = "ArtResourcesConfig",
AudioConfig = "AudioConfig",
ChallengeConfig = "ChallengeConfig",
ChallengeMapConfig = "ChallengeMapConfig",
ChallengeMissionConfig = "ChallengeMissionConfig",
ChapterEventPointConfig = "ChapterEventPointConfig",
ChapterOptionConfig = "ChapterOptionConfig",
DifferDemonsComonpentsConfig = "DifferDemonsComonpentsConfig",
DifferDemonsConfig = "DifferDemonsConfig",
DifferDemonsStageConfig = "DifferDemonsStageConfig",
EquipConfig = "EquipConfig",
EquipPropertyPool = "EquipPropertyPool",
EventPointConfig = "EventPointConfig",
ExploreFunctionConfig = "ExploreFunctionConfig",
FoodsConfig = "FoodsConfig",
GameSetting = "GameSetting",
GlobalActivity = "GlobalActivity",
GlobalSystemConfig = "GlobalSystemConfig",
GuideConfig = "GuideConfig",
HeroConfig = "HeroConfig",
HeroLevelConfig = "HeroLevelConfig",
HeroRankupConfig = "HeroRankupConfig",
HeroRankupGroup = "HeroRankupGroup",
ItemConfig = "ItemConfig",
LevelDifficultyConfig = "LevelDifficultyConfig",
LevelSetting = "LevelSetting",
LotteryRewardConfig = "LotteryRewardConfig",
LotterySetting = "LotterySetting",
LotterySpecialConfig = "LotterySpecialConfig",
MapPointConfig = "MapPointConfig",
MissionEventsConfig = "MissionEventsConfig",
MonsterConfig = "MonsterConfig",
MonsterGroup = "MonsterGroup",
MonsterViewConfig = "MonsterViewConfig",
OptionAddCondition = "OptionAddCondition",
OptionConfig = "OptionConfig",
PassiveSkillConfig = "PassiveSkillConfig",
PassiveSkillLogicConfig = "PassiveSkillLogicConfig",
PlayerLevelConfig = "PlayerLevelConfig",
PropertyConfig = "PropertyConfig",
RewardGroup = "RewardGroup",
RoleConfig = "RoleConfig",
RunesConfig = "RunesConfig",
RunesPoolConfig = "RunesPoolConfig",
SkillConfig = "SkillConfig",
SkillLogicConfig = "SkillLogicConfig",
StoreConfig = "StoreConfig",
StoreTypeConfig = "StoreTypeConfig",
UIConfig = "UIConfig",
VipLevelConfig = "VipLevelConfig",
PrivilegeTypeConfig = "PrivilegeTypeConfig",
TaskConfig = "TaskConfig",
WorkShopEquipmentConfig = "WorkShopEquipmentConfig",
WorkShopFoundationConfig = "WorkShopFoundationConfig",
WorkShopFunctionConfig = "WorkShopFunctionConfig",
WorkShopRebuildConfig = "WorkShopRebuildConfig",
WorkShopSetting = "WorkShopSetting",
ArenaReward = "ArenaReward",
ArenaSetting = "ArenaSetting",
DifferDemonsBoxSetting = "DifferDemonsBoxSetting",
-- AdventureReward = "AdventureReward",
DialogueViewConfig = "DialogueViewConfig",
JumpConfig = "JumpConfig",
RechargeCommodityConfig = "RechargeCommodityConfig",
DailyTasksConfig = "DailyTasksConfig",
WorkShopTechnology = "WorkShopTechnology",
WorkShopTechnologySetting = "WorkShopTechnologySetting",
ChallengeStarBox = "ChallengeStarBox",
TrialConfig = "TrialConfig",
TrialSetting = "TrialSetting",
BlessingConfig = "BlessingConfig",
BlessingRewardPool = "BlessingRewardPool",
ElementalResonanceConfig = "ElementalResonanceConfig",
TreasureTaskConfig = "TreasureTaskConfig",
EndlessMapConfig = "EndlessMapConfig",
SevenDaysActivity = "SevenDaysActivity",
LuckyCatConfig = "LuckyCatConfig",
SignInConfig = "SignInConfig",
-- BeginnerTask = "BeginnerTask",
GuildSetting = "GuildSetting",
GuildLevelConfig = "GuildLevelConfig",
GuildRewardConfig = "GuildRewardConfig",
ActivityRankingReward = "ActivityRankingReward",
ExchangeActivityConfig = "ExchangeActivityConfig",
FloodConfig = "FloodConfig",
LoginPosterConfig = "LoginPosterConfig",
QAConfig = "QAConfig",
BeStronger = "BeStronger",
SpecialConfig = "SpecialConfig",
EquipSign="EquipSign",
EquipTalismana = "EquipTalismana",
EquipTalismanaLottery="EquipTalismanaLottery",
EquipSignSetting="EquipSignSetting",
BloodyBattleSetting = "BloodyBattleSetting",
BloodyBattleReward = "BloodyBattleReward",
BloodyBattleTask = "BloodyBattleTask",
BloodyBattleTreasure = "BloodyBattleTreasure",
BloodyRankConfig = "BloodyRankConfig",
RandomName = "RandomName",
MainLevelConfig = "MainLevelConfig",
MainLevelSettingConfig = "MainLevelSettingConfig",
HeroReturn = "HeroReturn",
TreasureSunlongConfig = "TreasureSunlongConfig",
TreasureSunLongTaskConfig = "TreasureSunlongTaskConfig",
DialRewardSetting="DialRewardSetting",
DialRewardConfig="DialRewardConfig",
MainMapIconConfig="MainMapIconConfig",
ErrorCodeHint = "ErrorCodeHint",
SystemMessageConfig = "SystemMessageConfig",
ActivityDropReward = "ActivityDropReward",
-- PlayerAppearance = "PlayerAppearance",
PlayerMountLevelUp = "PlayerMountLevelUp",
MazeTreasure = "MazeTreasure",
MazeTreasureSetting = "MazeTreasureSetting",
ChampionshipReward="ChampionshipReward",
ChampionshipSetting="ChampionshipSetting",
LuxuryFundConfig="LuxuryFund",
PlayerRole="PlayerRole",
GuildBossConfig="GuildBossConfig",
GuildBossRewardConfig="GuildBossRewardConfig",
GuildRedPackConfig="GuildRedPackConfig",
ExpeditionFloorConfig="ExpeditionFloorConfig",
ExpeditionHolyConfig="ExpeditionHolyConfig",
ExpeditionSetting="ExpeditionSetting",
ExpeditionNodeConfig="ExpeditionNodeConfig",
AchievementConfig="AchievementConfig",
MonthcardConfig = "MonthcardConfig",
EquipStarsConfig = "EquipStarsConfig",
CombatControl="CombatControl",
EquipSuiteConfig = "EquipSuiteConfig",
BuffEffectConfig = "BuffEffectConfig",
RecommendTeam="RecommendTeam",
JewelConfig="JewelConfig",
JewelRankupConfig="JewelRankupConfig",
JewelResonanceConfig="JewelResonanceConfig",
DailyChallengeConfig="DailyChallengeConfig",
GuildTechnology="GuildTechnology",
WorldBossConfig="WorldBossConfig",
WorldBossRewardConfig="WorldBossRewardConfig",
WorldBossSetting="WorldBossSetting",
GuildSacrificeConfig="GuildSacrificeConfig",
GuildSacrificeRewardConfig="GuildSacrificeRewardConfig",
GuildWarConfig="GuildWarConfig",
GuildHelpConfig="GuildHelpConfig",
WorldBossTreasureConfig="WorldBossTreasureConfig",
TrialKillConfig="TrialKillConfig",
TrialQuestionConfig="TrialQuestionConfig",
TrialGameConfig="TrialGameConfig",
FakeBattle = "FakeBattle",
ArenaBattleReward = "ArenaBattleReward",
RaceTowerConfig = "RaceTowerConfig",
RaceTowerRewardConfig = "RaceTowerRewardConfig",
HeroSacrifice = "HeroSacrifice",
GuildCheckpointConfig = "GuildCheckpointConfig",
GuildCheckpointRank = "GuildCheckpointRank",
ThemeActivityTaskConfig = "ThemeActivityTaskConfig",
ExchangeRate = "ExchangeRate",
CustomEventConfig = "CustomEventConfig",
SpiritAnimal = "SpiritAnimal",
SpiritAnimalBook = "SpiritAnimalBook",
SpiritAnimalLevel = "SpiritAnimalLevel",
SpiritAnimalStar = "SpiritAnimalStar",
SpiritAnimalSetting = "SpiritAnimalSetting",
SpiritAnimalSkill = "SpiritAnimalSkill",
ExpeditionRecruitConfig = "ExpeditionRecruitConfig",
FreeTravel="FreeTravel",
FreeTravelStore="FreeTravelStore",
GodSacrificeConfig = "GodSacrificeConfig",
GodSacrificeSetting = "GodSacrificeSetting",
Language="Language",
FakeBattleNew = "FakeBattleNew",
HeroSkin = "HeroSkin",
BlessingConfigNew = "BlessingConfigNew",
BlessingRewardPoolNew = "BlessingRewardPoolNew",
SpiritAnimalSummon = "SpiritAnimalSummon",
NewHeroConfig = "NewHeroConfig",
PlayerHeadIcon = "PlayerHeadIcon",
GoodLuck = "GoodLuck",
Tips = "TipsConfig",
Hongmeng = "Hongmeng",
HongmengUp = "HongmengUp",
NewHeroConfig = "NewHeroConfig",
MainLevelBossConfig = "MainLevelBoss",
ActivityGroups = "ActivityGroups",
ArroGantFly = "ArroGantFly",
ComposeActivity = "ComposeActivity",
ComposeBook = "ComposeBook",
}
require "Modules/Battle/Framework/GameDataBase"
local configList = {}
ConfigManager = {}
function ConfigManager.Initialize()
configList = {}
end
function ConfigManager.GetConfig(cfgType)
if not configList[cfgType] then
local config = require("Modules/Battle/Config/Data/" .. cfgType)
GameDataBase.SheetBase.Init(config)
configList[cfgType] = config
end
return configList[cfgType]
end
---获取表格Id项
function ConfigManager.GetConfigData(cfgType, id)
local config = ConfigManager.GetConfig(cfgType)[id]
assert(config, string.format("%s not find Id:%s", cfgType, id))
return config
end
---获取表格Id项不返回错误
function ConfigManager.TryGetConfigData(cfgType, id)
return ConfigManager.GetConfig(cfgType)[id]
end
---获取某个key值为value的固定表格条目(取第一个)
function ConfigManager.GetConfigDataByKey(cfgType, key, value)
local configData
for _, configInfo in ConfigPairs(ConfigManager.GetConfig(cfgType)) do
if configInfo[key] == value then
configData = configInfo
break
end
end
assert(configData, string.format("%s not find key:%s,value:%s", cfgType, key, value))
return configData
end
---获取某个key值为value的固定表格条目(取第一个),不返回错误
function ConfigManager.TryGetConfigDataByKey(cfgType, key, value)
local configData
for _, configInfo in ConfigPairs(ConfigManager.GetConfig(cfgType)) do
if configInfo[key] == value then
configData = configInfo
break
end
end
return configData
end
---获取双重Key锁定下的表格条目(取第一个)
function ConfigManager.GetConfigDataByDoubleKey(cfgType, key1, value1, key2, value2)
local configData
for _, configInfo in ConfigPairs(ConfigManager.GetConfig(cfgType)) do
if configInfo[key1] == value1 and configInfo[key2] == value2 then
configData = configInfo
break
end
end
assert(configData, string.format("%s not find key1:%s,value1:%s,key2:%s, value2:%s", cfgType, key1, value1, key2, value2))
return configData
end
---获取双重Key锁定下的表格条目(取第一个),不返回错误
function ConfigManager.TryGetConfigDataByDoubleKey(cfgType, key1, value1, key2, value2)
local configData
for _, configInfo in ConfigPairs(ConfigManager.GetConfig(cfgType)) do
if configInfo[key1] == value1 and configInfo[key2] == value2 then
configData = configInfo
break
end
end
return configData
end
---获取三重Key锁定下的表格条目(取第一个),不返回错误
function ConfigManager.TryGetConfigDataByThreeKey(cfgType, key1, value1, key2, value2,key3, value3)
local configData
for _, configInfo in ConfigPairs(ConfigManager.GetConfig(cfgType)) do
if configInfo[key1] == value1 and configInfo[key2] == value2 and configInfo[key3] == value3 then
configData = configInfo
break
end
end
return configData
end
---获取某个key值为value的所有条目
function ConfigManager.GetAllConfigsDataByKey(cfgType, key, value)
local expectList = {}
for _, configInfo in ConfigPairs(ConfigManager.GetConfig(cfgType)) do
if configInfo[key] == value then
table.insert(expectList, configInfo)
end
end
assert(#expectList > 0, string.format("%s not find key:%s,value:%s", cfgType, key, value))
return expectList
end
---获取双重Key锁定下所有的表格条目
function ConfigManager.GetAllConfigsDataByDoubleKey(cfgType, key1, value1, key2, value2)
local expectList = {}
for _, configInfo in ConfigPairs(ConfigManager.GetConfig(cfgType)) do
if configInfo[key1] == value1 and configInfo[key2] == value2 then
table.insert(expectList, configInfo)
end
end
assert(#expectList > 0, string.format("%s not find key1:%s,value1:%s,key2:%s, value2:%s", cfgType, key1, value1, key2, value2))
return expectList
end
---获取三重Key锁定下所有的表格条目
function ConfigManager.GetAllConfigsDataByThreeKey(cfgType, key1, value1, key2, value2, key3, value3)
local expectList = {}
for _, configInfo in ConfigPairs(ConfigManager.GetConfig(cfgType)) do
if configInfo[key1] == value1 and configInfo[key2] == value2 and configInfo[key3] == value3 then
table.insert(expectList, configInfo)
end
end
assert(#expectList > 0, string.format("%s not find key1:%s,value1:%s,key2:%s, value2:%s,key3:%s, value3:%s", cfgType, key1, value1, key2, value2, key3, value3))
return expectList
end
---配置表遍历按照id的大小升序遍历
---用法:
---for k, v in ConfigPairs(configs) do
--- k 为id
--- v 为id对应的配置项
---end
function ConfigPairs(configs)
local i = 0
local keys = GameDataBase.SheetBase.GetKeys(configs)
return function()
i = i + 1
local key = keys[i]
if key then
return key, configs[key]
end
end
end

View File

@ -0,0 +1,269 @@
GameDataBase = {}
local floor = math.floor
local pairs = pairs
local type = type
local setmetatable = setmetatable
local function readonlyMT(t,k,v)
Log("attempt to update a read-only table")
end
local function setDefaultTable(rT, dT)
for i=1, #rT do
if type(rT[i]) == "table" then
setDefaultTable(rT[i], dT)
else
rT[i] = dT[rT[i]]
end
end
end
local function createTable(curD, index, val, parent)
if curD == #index then
parent[index[curD]] = val
else
parent[index[curD]] = parent[index[curD]] or {}
createTable(curD+1, index, val, parent[index[curD]])
end
end
local decode = {}
local function decodeList(encodeList)
if not encodeList or #encodeList < 1 then
return encodeList
end
local dCount = 0
local off,count,idx,n,n2,f
for i=1, #encodeList do
n = encodeList[i]
off = floor(n)
if off == n or off < 2 then
dCount = dCount + 1
decode[dCount] = n
else
n2, count, f = n, 0, 1
while n2 - floor(n2) > 1e-5 do
n2 = floor(n2 * 1000000 + 0.5) / 100000
count = count + floor(n2) % 10 * f
f = f * 10
end
idx = dCount
if count == 1 then
count = off
end
for j=1, count do
dCount = dCount + 1
decode[dCount] = decode[idx-off+j]
end
end
end
dCount = 0
for i=1, #decode do
n = decode[i]
off = floor(n)
if off == n then
dCount = dCount + 1
encodeList[dCount] = decode[i]
else
if n < 0 then
n = -n
off = floor(n)
end
n2, count, f = n, 0, 1
while n2 - floor(n2) > 1e-5 do
n2 = floor(n2 * 1000000 + 0.5) / 100000
count = count + floor(n2) % 10 * f
f = f * 10
end
for j=1, count do
dCount = dCount + 1
encodeList[dCount] = off
end
end
end
for i=1,#decode do
decode[i] = nil
end
local flag = encodeList[1]
for i=2, #encodeList do
flag = flag + encodeList[i]
encodeList[i] = flag
end
return encodeList
end
GameDataBase.SheetRefBase = {}
GameDataBase.SheetRefBase.__newindex = readonlyMT
GameDataBase.SheetRefBase.__index = function(t,k)
if t.m_refTB[k] then
return t.m_refTB[k]
end
local l_rt
for i, v in pairs(t.m_refData) do
if v[k] then
l_rt = l_rt or {}
createTable(1, i, t.m_DT[v[k]], l_rt)
end
end
t.m_refTB[k] = l_rt
return l_rt
end
GameDataBase.SheetLineBase = {}
GameDataBase.SheetLineBase.__newindex = readonlyMT
GameDataBase.SheetLineBase.__index = function(t,k)
local index = t.m_fIds[k]
if index then
return t.val[index]
end
end
GameDataBase.SheetBase = {}
GameDataBase.SheetBase.__newindex = readonlyMT
GameDataBase.SheetBase.__index = function(t,k)
local index = t.__ids[k]
if index then
local line = t.__lines[index]
if not line then
line = {val={k}}
for i=1, #t.__fields-1 do
if t.__defaults[i] then
if t.__refPoss[i] and t.__refPoss[i][index] then
line.val[i+1] = t.__refPoss[i][index]
else
line.val[i+1] = t.__defaults[i]
end
else
line.val[i+1] = t.__refs[i][index]
end
if type(line.val[i+1]) == "number" then
line.val[i+1] = t.__values[line.val[i+1]]
end
end
line.m_fIds = t.__fIds
setmetatable(line, GameDataBase.SheetLineBase)
t.__lines[index] = line
end
return line
end
end
function GameDataBase.SheetBase.GetCount(t)
return t.__count
end
function GameDataBase.SheetBase.Init(t)
t.__indexs = decodeList(t.__indexs)
t.__values = decodeList(t.__values)
if t.__exVals then
local count = #t.__values
for i=1,t.__exVals[1] do
t.__values[i+count] = t.__exVals[i+1]
end
t.__exVals = nil
end
t.__fIds = {}
for i=1, #t.__fields do
t.__fIds[t.__fields[i]] = i
end
t.__ids = {}
t.__lines = {}
for i=1,t.__count do
t.__ids[t.__indexs[i]] = i
end
local ids = {}
local refs = {}
for i=1, #t.__fields-1 do
local idList = decodeList(t.__refPoss[i])
if t.__refs[i] and type(t.__refs[i][1]) == "table" then
local rTs = { m_refData = {}, m_refTB = {}}
for j=1, #t.__refs[i] do
local data = decodeList(t.__refs[i][j][2])
local data_pos = decodeList(t.__refs[i][j][3])
if idList then
local dic = {}
if data_pos then
if #data_pos == #data then
for k=1, #data do
dic[idList[data_pos[k]]] = data[k]
end
else
local dIdx,dIdx2 = 1,0
for k=1, #data_pos+#data do
if k==data_pos[dIdx] then
dIdx = dIdx + 1
else
dIdx2 = dIdx2 + 1
dic[idList[k]] = data[dIdx2]
end
end
end
else
for k=1, #data do
dic[idList[k]] = data[k]
end
end
data = dic
else
if data_pos then
local dic = {}
if #data_pos == #data then
for k=1, #data do
dic[data_pos[k]] = data[k]
end
else
local dIdx,dIdx2 = 1,0
for k=1, #data_pos+#data do
if k==data_pos[dIdx] then
dIdx = dIdx + 1
else
dIdx2 = dIdx2 + 1
dic[k] = data[dIdx2]
end
end
end
data = dic
end
end
rTs.m_refData[t.__refs[i][j][1]] = data
end
rTs.m_DT = t.__values
setmetatable(rTs, GameDataBase.SheetRefBase)
refs[i] = rTs
else
refs[i] = decodeList(t.__refs[i])
end
if t.__defaults[i] and type(t.__defaults[i]) == "table" then
setDefaultTable(t.__defaults[i], t.__values)
end
if t.__defaults[i] and idList then
local tDic = {}
if type(t.__refs[i][1]) == "table" then
for j=1, #idList do
tDic[idList[j]] = refs[i][idList[j]]
end
else
for j=1, #idList do
tDic[idList[j]] = refs[i][j]
end
end
ids[i] = tDic
end
end
t.__refPoss = ids
t.__refs = refs
setmetatable(t,GameDataBase.SheetBase)
end
function GameDataBase.SheetBase.GetKeys(t)
return t.__indexs
end

View File

@ -8,13 +8,14 @@ local itemPool = BattleObjectPool.New(function ()
return { func = 0, obj = 0, once = false }
end)
function BattleEvent.New()
local instance = {}
local instance = {isTrigger=true}
setmetatable(instance, BattleEvent)
instance.m_listeners = {}
return instance
end
function BattleEvent:AddEvent(sEventName, fListener, pObj, bOnce)
function BattleEvent:AddEvent(sEventName, fListener, pObj, bOnce,_role)
if not self.m_listeners[sEventName] then
self.m_listeners[sEventName] = listPool:Get()
end
@ -22,9 +23,15 @@ function BattleEvent:AddEvent(sEventName, fListener, pObj, bOnce)
item.func = fListener
item.obj = pObj
item.once = bOnce
item.role = _role
self.m_listeners[sEventName]:Add(item)
end
function BattleEvent:SetIsTrigger(_trigger)
self.isTrigger=_trigger
end
function BattleEvent:RemoveEvent(sEventName, fListener, pObj)
if not self.m_listeners[sEventName] then
return
@ -41,20 +48,26 @@ function BattleEvent:RemoveEvent(sEventName, fListener, pObj)
end
function BattleEvent:DispatchEvent(sEventName, ...)
if not self.isTrigger then
return
end
if not self.m_listeners[sEventName] then
return
end
local v
for i=1, self.m_listeners[sEventName].size do
v = self.m_listeners[sEventName].buffer[i]
if not v.obj then
v.func(...)
else
v.func(v.obj, ...)
end
if v.once then
self:RemoveEvent(sEventName, v)
if v.role==nil or not v.role.isExile then
if not v.obj then
v.func(...)
else
v.func(v.obj, ...)
end
if v.once then
self:RemoveEvent(sEventName, v)
end
end
end
end
function BattleEvent:ClearEvent()

View File

@ -340,6 +340,7 @@ function BuffManager:PassUpdate()
and buff.roundDuration > 0 -- 不是无限存在的buff
and buff.caster.type~=BattleUnitType.Monster --灵兽的buff在这里处理
and buff.type~=BuffName.NoDead
and not buff.target.isExile --放逐单位buff不会更新
then
-- 当前轮释放的buff不结算
if buff.startRound ~= BattleLogic.GetCurRound() then
@ -368,6 +369,7 @@ function BuffManager:PassUpdateNoDead()
and buff.roundDuration > 0 -- 不是无限存在的buff
and buff.caster.type~=BattleUnitType.Monster --灵兽的buff在这里处理
and buff.type==BuffName.NoDead --不灭在这里处理
and not buff.target.isExile --放逐单位buff不会更新
then
-- 当前轮释放的buff不结算
buff.roundPass = buff.roundPass + 1
@ -389,11 +391,17 @@ function BuffManager:PassMonsterUpdate()
if buffList.size > 0 then
for index = 1, buffList.size do
local buff = buffList.buffer[index]
if not buff.disperse -- 没过期
--and buff.caster.camp == curCamp -- 释放者是当前轮到的人
--and buff.caster.position == curPos
and buff.roundDuration > 0 -- 不是无限存在的buff
and buff.caster.type==BattleUnitType.Monster --灵兽的buff在这里处理
if (not buff.disperse -- 没过期
and buff.roundDuration > 0 -- 不是无限存在的buff
and buff.caster.type==BattleUnitType.Monster --灵兽的buff在这里处理
and not buff.target.isExile) --放逐单位buff不会更新
or (not buff.disperse -- 没过期
and buff.roundDuration > 0 -- 不是无限存在的buff
and buff.caster.type==BattleUnitType.Monster --灵兽的buff在这里处理
and buff.target.isExile
and buff.type==BuffName.Exile)
-- and buff.type~=BuffName.Exile --buff名称不是放逐
then
-- 当前轮释放的buff不结算
if buff.startRound ~= BattleLogic.GetCurRound() then
@ -419,7 +427,9 @@ function BuffManager:TurnUpdate(sort)
if not buff.disperse -- 没有过期
and buff.sort == sort -- 当前buff刷新等级
and buff.target.camp == curCamp -- 当前阵营
and not buff.target.isExile --放逐单位buff不会更新
and buff.target.position == curPos then -- 当前位置
--触发buff
if buff.roundInterval >= 0 then
if buff.roundInterval == 0 or buff.roundPass % buff.roundInterval == 0 then

View File

@ -2388,6 +2388,17 @@ local effectList = {
end
end)
end,
--[a]% 的概率 放逐 目标[b]回合
--a[float],b[int]
[127] = function(caster, target, args, interval, skill)
local pro = args[1]
local round = args[2]
BattleLogic.WaitForTrigger(interval, function ()
BattleUtil.RandomAction(pro, function ()
target:AddBuff(Buff.Create(caster, BuffName.Exile, round))
end)
end)
end,
}
return effectList

View File

@ -174,6 +174,19 @@ function EffectCaster:GetDirectTargetsNoMiss()
return list
end
-- 获取直接目标和没有被放逐的目标不包含miss的目标可能为空
function EffectCaster:GetDirectTargetsNoExile()
local list = {}
for _, role in ipairs(self.effectTargets[1]) do
if not role.isExile then
table.insert(list, role)
end
end
return list
end
-- 获取技能目标最大人数
function EffectCaster:GetMaxTargetNum()
local mainEffect = self.effectList[1]

File diff suppressed because it is too large Load Diff

View File

@ -283,7 +283,7 @@ function BattleLogic.CheckBattleLogic()
-- 自己阵营中的位置 + 自己阵营的ID * 6 = 自己在PosList中的位置
local role = RoleManager.GetRole(CurCamp, p) --PosList[p + (CurCamp * 6)]
--角色如果被放逐不能行动 by:wangzhenxing 2020/12/23 11:35
if role and not role:IsRealDead() then
if role and not role:IsRealDead() and not role.isExile then
SkillRole = role
break
end

View File

@ -17,14 +17,17 @@ function Curse:ShareDamageTrigger(damagingFunc, atkRole, defRole, damage, skill,
if not BattleLogic.BuffMgr:HasBuff(defRole, BuffName.Curse, function(buff) return buff.curseType == CurseTypeName.ShareDamage end) then
-- 计算拥有此印记人的数量
local sdList = RoleManager.Query(function(role)
return role.camp == self.target.camp and BattleLogic.BuffMgr:HasBuff(role, BuffName.Curse, function(buff) return buff.curseType == CurseTypeName.ShareDamage end)
return role.camp == self.target.camp and BattleLogic.BuffMgr:HasBuff(role, BuffName.Curse, function(buff) return buff.curseType == CurseTypeName.ShareDamage end)
end)
if sdList and #sdList ~= 0 then
-- 计算收到的伤害
local f1 = self.args[1] --平分伤害的百分比
local sd = math.floor(BattleUtil.ErrorCorrection(damage * f1 / #sdList))
if sd ~= 0 then
BattleUtil.FinalDamage(nil, atkRole, self.target, sd)
if not self.target.isExile then
BattleUtil.FinalDamage(nil, atkRole, self.target, sd)
end
end
end
end

View File

@ -0,0 +1,36 @@
Exile = Buff:New()
--初始化Buff通过传入一些自定义参数控制成长相关的数值
function Exile:SetData(...)
-- 刷新排序等级
self.sort = 4
end
--初始化后调用一次
function Exile:OnStart()
self.target.isExile = true
if self.caster.exileTargets then
table.insert(self.caster.exileTargets,self.target)
end
self.target.Event:DispatchEvent(BattleEventName.RoleBeExile, self)
end
--间隔N帧触发返回true时表示继续触发返回false立刻触发OnEnd
function Exile:OnTrigger()
return true
end
--效果结束时调用一次
function Exile:OnEnd()
self.target.isExile = false
self.target.Event:DispatchEvent(BattleEventName.RoleExileEnd, self)
end
--只有当cover字段为true时触发返回true则被新效果覆盖
function Exile:OnCover(newBuff)
return true
end
return Exile

View File

@ -0,0 +1,48 @@
KylinMark = Buff:New()
--初始化Buff通过传入一些自定义参数控制成长相关的数值
function KylinMark:SetData(...)
self.pro1,
self.pro2,
self.v1,
self.pro3 = ...
-- 刷新排序等级
self.sort = 4
end
function KylinMark:roleTurnStar(role)
BattleUtil.RandomAction(self.pro1, function ()
local dd = floor(BattleUtil.ErrorCorrection(role:GetRoleData(BattlePropList[self.pro2])*self.v1))
BattleUtil.ApplyDamage(self.caster,self.target, dd)
end)
--概率消失
BattleUtil.RandomAction(self.pro3, function ()
self.disperse=true
end)
end
--初始化后调用一次
function KylinMark:OnStart()
self.target.Event:AddEvent(BattleEventName.RoleTurnStart,self.roleTurnStar)
end
--间隔N帧触发返回true时表示继续触发返回false立刻触发OnEnd
function KylinMark:OnTrigger()
return true
end
--效果结束时调用一次
function KylinMark:OnEnd()
self.target.Event:RemoveEvent(BattleEventName.RoleTurnStart,self.roleTurnStar)
end
--只有当cover字段为true时触发返回true则被新效果覆盖
function KylinMark:OnCover(newBuff)
return true
end
return KylinMark

View File

@ -164,6 +164,8 @@ BattleEventName = {
RecordBuff = indexAdd(), -- buff
RecordSecKill = indexAdd(), -- 斩杀
DisposeRoleCtrl_noheal = indexAdd(),--处理角色禁疗
RoleBeExile = indexAdd(),--角色被放逐
RoleExileEnd = indexAdd(),--角色放逐结束
}
BattleMaxFrame = 1000000

View File

@ -34,7 +34,8 @@ end
function BattleUtil.ChooseFRow(arr)
local tempArr = {}
for _, r in ipairs(arr) do
if r.position <= 3 and not r:IsRealDead() then
--不是放逐
if r.position <= 3 and not r:IsRealDead() and not r.isExile then
table.insert(tempArr, r)
end
end
@ -47,7 +48,7 @@ end
function BattleUtil.ChooseBRow(arr)
local tempArr = {}
for _, r in ipairs(arr) do
if r.position > 3 and not r:IsRealDead() then
if r.position > 3 and not r:IsRealDead() and not r.isExile then
table.insert(tempArr, r)
end
end
@ -60,7 +61,7 @@ end
function BattleUtil.ChooseCol(arr, col)
local tempArr = {}
for _, role in ipairs(arr) do
if role.position % 3 == col then
if role.position % 3 == col and not role.isExile then
table.insert(tempArr, role)
end
end
@ -267,7 +268,7 @@ function BattleUtil.ChooseTarget(role, chooseId)
if chooseType == 1 then
arr = RoleManager.Query(function (r) return r.camp == role.camp end)
elseif chooseType == 2 then
if role.lockTarget and not role.lockTarget:IsRealDead() and num == 1 then --嘲讽时对单个敌军生效
if role.lockTarget and not role.lockTarget:IsRealDead() and not role.lockTarget.isExile and num == 1 then --嘲讽时对单个敌军生效
return {role.lockTarget}
end
arr = RoleManager.Query(function (r) return r.camp ~= role.camp end)
@ -279,7 +280,7 @@ function BattleUtil.ChooseTarget(role, chooseId)
end
return {role}
elseif chooseType == 4 then
if role.lockTarget and not role.lockTarget:IsRealDead() then --嘲讽时对仇恨目标生效
if role.lockTarget and not role.lockTarget:IsRealDead() and not role.lockTarget.isExile then --嘲讽时对仇恨目标生效
return {role.lockTarget}
end
if role.ctrl_blind then --致盲时仇恨目标变随机
@ -372,9 +373,29 @@ function BattleUtil.ChooseTarget(role, chooseId)
-- local r1 = math.abs(role.position - a.position) * 10 + a.position
-- local r2 = math.abs(role.position - b.position) * 10 + b.position
-- if sort == 1 then return r1 > r2 else return r1 < r2 end
-- end)
elseif chooseWeight == 9 then --血量百分比->血量
BattleUtil.SortByHpFactorAndHp(arr,sort)
-- end)
elseif chooseWeight ==9 then --攻击最高且没被放逐过
local list=role.exileTargets
local tempArr = {}
local team = RoleManager.Query(function (r) return r.camp ~= role.camp end)
if list then
for key, value in pairs(team) do
if not value:IsRealDead() and not BattleUtil.ChecklistIsContainValue(role.exileTargets,value) then
--return arr[i]
table.insert(tempArr,value)
end
end
end
BattleUtil.SortByProp(tempArr,RoleDataName.Attack,sort)
arr=tempArr
elseif chooseWeight ==10 then --剩余血量百分比低于25%且生命绝对值最小
return BattleUtil.GetHpPctLessThanPctHero(arr,0.25)
elseif chooseWeight ==11 then --剩余血量百分比低于32%且生命绝对值最小
return BattleUtil.GetHpPctLessThanPctHero(arr,0.32)
elseif chooseWeight ==12 then --剩余血量百分比低于40%且生命绝对值最小
return BattleUtil.GetHpPctLessThanPctHero(arr,0.40)
elseif chooseWeight ==13 then --剩余血量百分比低于50%且生命绝对值最小
return BattleUtil.GetHpPctLessThanPctHero(arr,0.50)
end
local finalArr = {}
if num == 0 then
@ -393,6 +414,29 @@ function BattleUtil.ChooseTarget(role, chooseId)
return finalArr
end
--获取生命百分比少于指定百分比且生命置最少
function BattleUtil.GetHpPctLessThanPctHero(arr,pct)
local hp=0
local hero=nil
for i = 1, #arr[i] do
local aaa=arr[i]
local curHp=aaa:GetRoleData(RoleDataName.Hp)
local r1 = curHp / aaa:GetRoleData(RoleDataName.MaxHp)
if r1<pct then
if hero==nil then
hero=aaa
hp=curHp
else
if curHp<hp then
hero=aaa
hp=curHp
end
end
end
end
return hero
end
function BattleUtil.CreateBuffId(skill, index)
@ -507,7 +551,6 @@ function BattleUtil.SeckillHP(skill, atkRole, defRole, pro)
defRole.Event:DispatchEvent(BattleEventName.RoleDead, atkRole)
atkRole.Event:DispatchEvent(BattleEventName.RoleKill, defRole,skill)
BattleLogic.Event:DispatchEvent(BattleEventName.BattleRoleDead, defRole, atkRole)
atkRole.Event:DispatchEvent(BattleEventName.Seckill, defRole)
defRole.Event:DispatchEvent(BattleEventName.BeSeckill, atkRole)
BattleLogic.Event:DispatchEvent(BattleEventName.Seckill, atkRole, defRole)
@ -888,7 +931,14 @@ function BattleUtil.CheckIsHit(atkRole, defRole,skill)
end
--获取table的长度
function BattleUtil.LengthOfTable(table)
local length = 0
for i, v in pairs(table) do
length = length + 1
end
return length
end
function BattleUtil.RandomAction(rand, action)
if Random.Range01() <= rand and action then

View File

@ -23,7 +23,7 @@ function Monster:Init(data)
self.data:Init(self, data.property)
self.buffFilter:Clear() --buff屏蔽列表
self.Event:ClearEvent()
self.exileTargets={}--已经被放逐过的目标
self.skillGroup = MSkillManager.CreateMSkillGroup(self, data.skill)
end

View File

@ -80,7 +80,7 @@ local _ConditionConfig = {
local r = Random.Range01()
-- 判断概率
if isEnough then
return r>rand/10000
return rand/10000>r
end
return false
end,
@ -103,16 +103,35 @@ local _ConditionConfig = {
end
return false
end,
[7] = function(skill, condition) --7检测是否有可以放逐的目标
local list=skill.owner.exileTargets
if list then
local roleList = RoleManager.Query(function(role)
return role.camp ~= skill.owner.camp and not BattleUtil.ChecklistIsContainValue(list,role)
end)
if roleList and #roleList>0 then
return true
[7] = function(skill, condition) --7敌方上场神将数量 且概率(万分比)(检测放逐)
local conId = condition[1]
local comType = condition[2]
local comValue = condition[3]
local rand = condition[4]
local roleList = RoleManager.QueryIncludeExile(function(role)
return role.camp ~= skill.owner.camp
end)
--判断场上敌方数量是否足够
local isEnough=BattleUtil.CompareValue(#roleList, comValue, comType)
if isEnough then
local ishave=false
--是否有没被放逐的目标
local list=skill.owner.exileTargets
for key, value in pairs(roleList) do
if not BattleUtil.ChecklistIsContainValue(list,value) then
ishave=true
break
end
end
end
if ishave then
local r = Random.Range01()
-- 判断概率
if isEnough then
return rand/10000>r
end
end
return false
end
return false
end,
}

View File

@ -38,7 +38,7 @@ function MSkill:Init(owner, group, index, skillData)
self.effectCaster = EffectCaster:New()
self.effectCaster:Init(self, effects, targets)
--监听回合开始消息
BattleLogic.Event:AddEvent(BattleEventName.BattleRoundStart,function (round)
BattleLogic.Event:AddEvent(BattleEventName.BattleRoundChange,function (round)
self.curRoundCount = 0
end)
end
@ -63,6 +63,15 @@ function MSkill:Cast(func)
-- 技能效果生效
if self.effectCaster then
--放技能前判断是否有目标,没有就不会放技能,直接执行技能回调 by 王振兴 2021/03/26
--为解决攻击目标只剩被放逐的单位导致技能播放异常
self.effectCaster:ChooseTarget()
local targets=BattleUtil.LengthOfTable(self:GetDirectTargetsNoExile())
if targets==0 and self.castDoneFunc then
self.castDoneFunc()
return
end
--end
self.effectCaster:Cast()
end
@ -119,7 +128,10 @@ end
function MSkill:GetMaxTargetNum()
return self.effectCaster:GetMaxTargetNum()
end
-- 获取直接目标,不包含放逐的目标,可能为空
function MSkill:GetDirectTargetsNoExile()
return self.effectCaster:GetDirectTargetsNoExile()
end
-- 判断是否命中
function MSkill:CheckTargetIsHit(role)
return self.effectCaster:CheckTargetIsHit(role)

View File

@ -84,7 +84,7 @@ function RoleLogic:Init(uid, data, position)
self.type = BattleUnitType.Role
self.passiveList = {}
if data.passivity and #data.passivity > 0 then
table.sort(data.passivity,function(a,b)return a[1] < b[1] end)
table.sort(data.passivity,function(a,b)return a[1] < b[1] end)
for i = 1, #data.passivity do
local v = data.passivity[i]
local passivityId=v[1]
@ -106,6 +106,21 @@ function RoleLogic:Init(uid, data, position)
end
-- 根据被动id添加被动
function RoleLogic:AddPassiveById(id)
local config=ConfigManager.GetConfigData(ConfigName.PassiveSkillLogicConfig,id)
if not config then
return
end
local value=config.Value
if not value then
return
end
-- 被动生效
BattleUtil.Passivity[config.Type](self,value,id,config.Judge)
-- 加入被动列表
table.insert(self.passiveList, {id, value,id,config.judge})
end
-- 添加一个被动技能
function RoleLogic:AddPassive(id, args, isRepeat)
--判断是否可以叠加

View File

@ -131,14 +131,35 @@ end
-- 获取某阵营所有角色
function this.GetRoleByCamp(camp)
local list = {}
--放逐的不会被获取到
for i = 1, 6 do
list[i] = PosList[i + camp * 6]
if not list[i].isExile then
list[i] = PosList[i + camp * 6]
end
end
return list
end
-- 查找角色
function RoleManager.Query(func, inCludeDeadRole)
local list = {}
local index = 1
if func then
for pos, v in pairs(PosList) do
if func(v) and (inCludeDeadRole or not v:IsRealDead())and not v.isExile then
list[index] = v
index = index + 1
end
end
end
table.sort(list, function(a, b)
return a.position < b.position
end)
return list
end
-- 查找角包括放逐目标
function RoleManager.QueryIncludeExile(func, inCludeDeadRole)
local list = {}
local index = 1
if func then
@ -160,7 +181,7 @@ function RoleManager.QueryNoDead(func)
local index = 1
if func then
for pos, v in pairs(PosList) do
if func(v) and not v:IsRealDead() and v.deadFilter then
if func(v) and not v:IsRealDead() and v.deadFilter and not v.isExile then
list[index] = v
index = index + 1
end
@ -177,7 +198,7 @@ function RoleManager.NoOrder(func)
local index = 1
if func then
for pos, v in pairs(PosList) do
if func(v) and not v:IsRealDead() and v.deadFilter then
if func(v) and not v:IsRealDead() and v.deadFilter and not v.isExile then
list[index] = v
index = index + 1
end
@ -201,7 +222,7 @@ function this.GetAggro(role)
-- 向左
for i = startPos, c*3+1, -1 do
local pos = i + enemyCamp * 6
if PosList[pos] and not PosList[pos]:IsRealDead() then
if PosList[pos] and not PosList[pos]:IsRealDead() and not PosList[pos].isExile then
target = PosList[pos]
break
end
@ -210,7 +231,7 @@ function this.GetAggro(role)
-- 向右
for i = startPos + 1, c*3+3 do
local pos = i + enemyCamp * 6
if PosList[pos] and not PosList[pos]:IsRealDead() then
if PosList[pos] and not PosList[pos]:IsRealDead() and not PosList[pos].isExile then
target = PosList[pos]
break
end
@ -233,7 +254,7 @@ function this.GetAliveAggro(role)
-- 向左
for i = startPos, c*3+1, -1 do
local pos = i + enemyCamp * 6
if PosList[pos] and not PosList[pos]:IsDead() then
if PosList[pos] and not PosList[pos]:IsDead() and not PosList[pos].isExile then
target = PosList[pos]
break
end
@ -242,7 +263,7 @@ function this.GetAliveAggro(role)
-- 向右
for i = startPos + 1, c*3+3 do
local pos = i + enemyCamp * 6
if PosList[pos] and not PosList[pos]:IsDead() then
if PosList[pos] and not PosList[pos]:IsDead() and not PosList[pos].isExile then
target = PosList[pos]
break
end
@ -267,14 +288,14 @@ function this.GetArrAggroList(role, arr)
-- 向左
for i = startPos, c*3+1, -1 do
local pos = i
if plist[pos] and not plist[pos]:IsRealDead() then
if plist[pos] and not plist[pos]:IsRealDead() and not plist[pos].isExile then
table.insert(targetList, plist[pos])
end
end
-- 向右
for i = startPos + 1, c*3+3 do
local pos = i
if plist[pos] and not plist[pos]:IsRealDead() then
if plist[pos] and not plist[pos]:IsRealDead() and not plist[pos].isExile then
table.insert(targetList, plist[pos])
end
end
@ -343,7 +364,7 @@ function this.GetNeighbor(role, chooseType)
if chooseType == 1 then
target = role
else
if role.lockTarget and not role.lockTarget:IsRealDead() then
if role.lockTarget and not role.lockTarget:IsRealDead() and not role.isExile then
target = role.lockTarget
else
target = this.GetAggro(role)
@ -352,7 +373,7 @@ function this.GetNeighbor(role, chooseType)
if target then
local list = this.Query(function (r) return r.camp == target.camp end)
for i=1, #list do
if not list[i]:IsRealDead() then
if not list[i]:IsRealDead() and not list[i].isExile then
if list[i].position == target.position + 3 -- 后排的人
or list[i].position == target.position - 3 -- 前排的人
or (math.abs(target.position - list[i].position) <= 1 and math.floor((target.position-1)/3) == math.floor((list[i].position-1)/3)) then -- 旁边的人和自己

View File

@ -64,6 +64,16 @@ function Skill:Cast(func)
-- 技能效果生效
if self.effectCaster then
--放技能前判断是否有目标,没有就不会放技能,直接执行技能回调 by 王振兴 2021/03/26
--为解决攻击目标只剩被放逐的单位导致技能播放异常
self.effectCaster:ChooseTarget()
local targets=BattleUtil.LengthOfTable(self:GetDirectTargetsNoExile())
if targets==0 and self.castDoneFunc then
self.isRage=false
self.castDoneFunc()
return
end
--end
self.effectCaster:Cast()
end
@ -106,6 +116,11 @@ end
function Skill:GetDirectTargetsNoMiss()
return self.effectCaster:GetDirectTargetsNoMiss()
end
-- 获取直接目标,不包含放逐的目标,可能为空
function Skill:GetDirectTargetsNoExile()
return self.effectCaster:GetDirectTargetsNoExile()
end
-- 获取技能目标最大人数
function Skill:GetMaxTargetNum()
return self.effectCaster:GetMaxTargetNum()

View File

@ -14,6 +14,8 @@ this.MaxSkillCount = 20 -- 单个回合内最多释放20次技能
-- 初始化
function this.Init()
this.CurSkillCount = 0
-- 清除轮转方法,防止收到上一局战斗的影响
this.TurnRoundFunc = nil
this.Clear()
end