--※注意这里面的代码需要兼容服务器BattleCheck,需要遵循一些规范 --1、不能访问 ExpEntity.components ,因为 ExpEntity.components 是在 Init里初始化的,而 Init 方法被重定向了,所以components为空 --2、所有纯视图的代码,建议都加一个 if not USE_LUA_STANDALONE then 来在BattleCheck里跳过,以免发生报空 local EventSystem = require('Event/EventSystem') local FormulaCalculator = require"Battle/Logic/Missile/FormulaCalculator" local AttrSystem = require "Battle/Logic/Entity/System/AttrSystem" local SkillMissileSystem = require"Battle/Logic/Entity/System/SkillMissileSystem" local SkillTimeSystem = require"Battle/Logic/Entity/System/SkillTimeSystem" local ChangeAvatarSystem = require "Battle/Logic/Entity/System/ChangeAvatarSystem" local AdjutantSystem = require "Battle/Logic/Entity/System/AdjutantSystem" local FirstPersonEventDispatcher = require"Battle/Logic/Event/FirstPersonEventDispatcher" local ColliderManager = require("Battle/Logic/Level/ColliderManager") local BattleEffect = {} local FP = FP local tonumberV1 = FP.tonumberV1 local paramsBuilderDic = {} local LuaConst = LuaConst local MonsterBeTriggerType_All = LuaConst.MonsterBeTriggerType.All --------------------------------入口--------------------------------------- local loopWatchGuard = 0 local MAX_LOOP_COUNT = 20 local effectIdStack = {} --local TEST_ID_MAX = 1000 local COMMON_HURT_BUFF = 200001 local _tempV1 = FP.newV1(0) local _tempV1_2 = FP.newV1(0) local _tempV2 = FP.newV2(0,0) local _tempV2_2 = FP.newV2(0,0) function BattleEffect.BeforeLevelInit() loopWatchGuard = 0 --清空计数防止缓存污染 table.clearArray(effectIdStack) --清空以防止缓存污染 end --对外入口 --outParams:包含事件参数和buff数据 function BattleEffect.ExecuteByEffectId(effectId, outParams, caster, target) local err = nil repeat local effectData = DataSheetManager.BattleEffectData:GetDataByID(effectId) if not effectData then err = "01 effectData nil error! effectId:" .. tostring(effectId) break end -- ID check↓ -- if effectId < TEST_ID_MAX then -- logging.error(LTAG.ERROR, "HYW : 使用了测试的effectId : ", effectId, " 建议策划复制为一行新的") -- end --↑ --防止无限循环↓----------- loopWatchGuard = loopWatchGuard + 1 if loopWatchGuard > MAX_LOOP_COUNT then logging.error(LTAG.ERROR, "HYW : BattleEffect循环次数超过", MAX_LOOP_COUNT, " effectId : ", effectId) if #effectIdStack > 0 then logging.error(LTAG.ERROR, "HYW : BattleEffect id 堆栈 : ") for i,id in ipairs(effectIdStack) do logging.error(LTAG.ERROR, "HYW : ", id) end table.clearArray(effectIdStack) end loopWatchGuard = loopWatchGuard - 1 break end table.insert(effectIdStack,effectId) --防止无限循环↑----------- local funcName = effectData.funcName local params = {} params.caster = caster params.target = target params.effectData = effectData if outParams then params.buff = outParams.buff --是buffObject对象 params.buffUpdateData = outParams.buffUpdateData params.outParams = outParams end BattleEffect.BuildParams(funcName,effectData,params) err = BattleEffect.Execute(funcName,params) table.remove(effectIdStack,#effectIdStack) loopWatchGuard = loopWatchGuard - 1 until true if err then logging.error(LTAG.ERROR, "HYW : ExecuteByEffectId : ", effectId, " Error : ", err) end end --构造参数,会根据funcName选择不同的构造参数的方法 --执行完毕后,params里会根据effect function的不同而被填充各种各样的参数 function BattleEffect.BuildParams(funcName,effectData,params) if paramsBuilderDic[funcName] then return paramsBuilderDic[funcName](effectData,params) --else --正常情况,因为存在一些BattleEffect不需要参数 end end --执行 function BattleEffect.Execute(funcName,params) if BattleEffect[funcName] then return BattleEffect[funcName](params) else logging.error(LTAG.ERROR, "HYW : 不存在名为:", funcName, " 的效果. 效果ID : ", params.effectData.ID) end end ------------------------------region end------------------------------------------------------ --------region effect functions start start start------------------------------- local changeAttrKeyCache = {} --获取属性修饰记录的key function BattleEffect.GetChangeAttrKey(params) if params.buff then local buffID = params.buff.BuffID local effectId = params.effectData.ID if changeAttrKeyCache[buffID] and changeAttrKeyCache[buffID][effectId] then return changeAttrKeyCache[buffID][effectId] else changeAttrKeyCache[buffID] = changeAttrKeyCache[buffID] or {} changeAttrKeyCache[buffID][effectId] = buffID .. "_effect" .. effectId --原本buff改变属性时key只有buffID,Effect改变属性则增加EffectID后缀 return changeAttrKeyCache[buffID][effectId] end end end -- params需要的参数: prop-属性枚举, delta-属性改变量(必须传number类型) function BattleEffect._ChangeAttr(params) if not AttrSystem.IsRealtimeAttrType(params.prop) and not params.buff then logging.error(LTAG.ERROR, "HYW : 只有buff才可以触发非实时属性的ChangeAttr效果") return end local sourceEntityId = nil if params.buffUpdateData and params.buffUpdateData.SourceEntity then sourceEntityId = params.buffUpdateData.SourceEntity.EntityID end local changeAttrKey = BattleEffect.GetChangeAttrKey(params) local delta = FP.newV1(params.delta) if not AttrSystem.IsRealtimeAttrType(params.prop) then --回退之前的属性修改 AttrSystem.DeleteBuffUpdateAttr(params.target, changeAttrKey, sourceEntityId, params.prop) --else --如果是RealtimeAttrType,是不要回退的 end --logging.error(LTAG.ERROR, "HYW : caster entityId : ", params.target.EntityID) local realDelta = FP.newV1(0) if params.prop == LuaConst.RealtimeAttrType.hp then realDelta:Reset(params.target:GetAttrValue(params.prop)) if delta > FP.Const.Zero then if not params.dontApplyBehealeff then if params.target:GetAttrValue(LuaConst.AttrType.behealeff) ~= FP.Const.Zero then local temp = FP.newV1(1) temp:Add(params.target:GetAttrValue(LuaConst.AttrType.behealeff)) delta:Mul(temp) end end end end local result = params.target:GetAttrValue(params.prop) + delta params.target:SetAttrBaseValue(params.prop, result) --logging.error(LTAG.ERROR, "HYW : ", params.prop, " : ", params.target:GetAttrValue(params.prop)) if AttrSystem.IsRealtimeAttrType(params.prop) then --如果是RealtimeAttrType,不需要CollectModify的记录 if params.prop == LuaConst.RealtimeAttrType.hp then realDelta:Mul(-1):Add(params.target:GetAttrValue(params.prop)) SystemManager.OnHPChange(params.target, params.caster, delta, realDelta, result, "add",params.hpChangeType or LuaConst.EHpChangeType.LIFE_STEAL, params.hpChangeBatch) end else local calData = RuntimeDataManager.New_AttrCalculate(changeAttrKey, sourceEntityId, delta, "add") --TODO:感觉有个对象池比较好 AttrSystem.CollectModify(params.target,params.prop, calData) end end function BattleEffect.ChangeAttrByEntityNum(params) local delta = BattleEffect._GetChangeAttrByEntityNumDelta(params) if delta then params.delta = delta BattleEffect._ChangeAttr(params) end end function BattleEffect.SetSpeedSameAsMaster(params) local master = params.target:GetMasterEntity() if master then local spd if params.effectData.intParams[1] == 2 then spd = master:GetAttrValue(LuaConst.AttrType.ridespd) * master:GetAttrValue(LuaConst.AttrType.ridegear) else spd = master:GetAttrValue(LuaConst.AttrType.spd) end --- 随从的spd值, 如果用变化后的数据,受‘回退之前的属性修改’影响, 此delta就是计算错误的了 --- 举个例子:初始为6,变为12,主人恢复为6后,delta=6-12=-6,_ChangeAttr回退变化spd = 6,然后 6 +delta(-6)= 0 。故最终算的值就是0了。 --- 但是:使用init的Spd也有问题:如果spd受到其他buff影响,那么spd就不是主人的spd了。 --- 为解决这个问题,方案1 :先回退之前的变化,再算值了 。方案2 :直接设置值(每隔一段时间会检测是否需要重新设值,故不会出现因数据上没记录变化而导致的 变化丢失 问题) local mySpd = params.target:GetAttrValue(LuaConst.AttrType.spd) if mySpd == spd then return -- 不做这个处理的话 ,速度总会变化的。速度相等时,变成最初的速度了 end --[[ 方案1: local sourceEntityId = nil if params.buffUpdateData and params.buffUpdateData.SourceEntity then sourceEntityId = params.buffUpdateData.SourceEntity.EntityID end local changeAttrKey = BattleEffect.GetChangeAttrKey(params) AttrSystem.DeleteBuffUpdateAttr(params.target, changeAttrKey, sourceEntityId, LuaConst.AttrType.spd) mySpd = params.target:GetAttrValue(LuaConst.AttrType.spd) params.delta = FP.tonumberV1(spd - mySpd) params.prop = LuaConst.AttrType.spd BattleEffect._ChangeAttr(params)--]] --方案2: params.target:SetAttrBaseValue(LuaConst.AttrType.spd, spd) else logging.error(LTAG.ERROR, "HYW : SetSpeedSameAsMaster Error ! 不存在主人! CharacterID : ", params.target:GetCharacterID()) end end function BattleEffect.ChangeRealtimeAttrByEventParam(params) local attrIntType = params.effectData.intParams[1] local attrStrType = nil if attrIntType == 1 then attrStrType = LuaConst.RealtimeAttrType.hp elseif attrIntType == 2 then attrStrType = LuaConst.RealtimeAttrType.sa elseif attrIntType == 3 then attrStrType = LuaConst.RealtimeAttrType.am elseif attrIntType == 4 then attrStrType = LuaConst.RealtimeAttrType.pc end if attrStrType then local deltaFilterType = params.effectData.intParams[2] local value = params.outParams[params.effectData.stringParam] if value then if deltaFilterType == 0 or deltaFilterType == 1 or deltaFilterType == 2 and value > 0 or deltaFilterType == 3 and value < 0 then local opVal = FP.newV1(value) params.target:AttrAdd(attrStrType,opVal:Mul(params.effectData.floatParams[1] or 1)) end else logging.error(LTAG.ERROR, "HYW : 事件参数[", params.effectData.stringParam, "]不存在, effectData : ", params.effectData.ID) end else logging.error(LTAG.ERROR, "HYW : attrStrType nil ,错误的intParams[1] effectData : ", params.effectData.ID) end end local _tempV1ChangeAttrByOriginEntityVariable = FP.newV1(0) function BattleEffect.ChangeAttrByOriginEntityVariable(params) local originEntity = params.caster:GetOriginEntity() local key = params.effectData.intParams[1] local variable = originEntity.components.record:GetVariable(key) or 0 local variableFactor = params.effectData.floatParams[1] local delta = FP.newV1(variable) if variableFactor then if variableFactor ~= 1 and variableFactor ~= 0 then delta:Mul(variableFactor) end local baseValue = params.effectData.floatParams[2] if baseValue then delta:Add(baseValue) end end params.delta = FP.tonumberV1(delta) params.prop = params.effectData.stringParam BattleEffect._ChangeAttr(params) end -- 使用 OriginEntity的record.Variable 设置某个buff的时长或者 本buff时长 function BattleEffect.AddBuffDurationByOriginEntityVariable(params) local originEntity = params.caster:GetOriginEntity() local variableValue = originEntity.components.record:GetVariable(params.effectData.stringParam) or 0 local dealBuff = params.effectData.intParams[1] if dealBuff and dealBuff > 0 then local buffObject = params.target.components.buff:GetBuffObjectByBuffId(dealBuff) if buffObject then local buffUpdateData if buffObject.BuffUpdateData then buffUpdateData = buffObject.BuffUpdateData else for i,_buffUpdateData in ipairs(buffObject.BuffUpdateList) do if _buffUpdateData.SourceEntity == params.caster then buffUpdateData = _buffUpdateData break end end end if buffUpdateData and buffUpdateData.BuffLayer > 0 then buffUpdateData.BuffTimer:Add(variableValue) end end else -- 如果不是修改某个buff ,则默认是修改本buff自身的时长 local buffUpdateData = params.buffUpdateData buffUpdateData.BuffTimer:Add(variableValue) end end function BattleEffect.HealByDamageWithLimitOfHplmt(params) if params.outParams.delta and params.outParams.delta < 0 then local healAmount = _tempV1 healAmount:Reset(params.outParams.delta):Mul(-1):Mul(params.effectData.floatParams[1]) if params.effectData.floatParams[2] then local max = _tempV1_2 max:Reset(params.effectData.floatParams[2]) max:Mul(params.target:GetAttrValue(LuaConst.AttrType.hplmt)) if healAmount > max then healAmount = max end end params.prop = LuaConst.RealtimeAttrType.hp params.delta = tonumberV1(healAmount) BattleEffect._ChangeAttr(params) else logging.error(LTAG.ERROR, "HYW : 事件参数delta不合法!只有伤害事件才能触发HealByDamageWithLimitOfHplmt效果! delta : ", params.outParams.delta) end end -- 将当前血量上限设置为初始的血量上限(此方法不需要buff消失时恢复,故hplmt不用BattleEffect._ChangeAttr记录。) function BattleEffect.ResetHplmtToInitHplmt(params) local result = params.target.components.attr.InitAttr[LuaConst.AttrType.hplmt] params.target:SetAttrBaseValue(LuaConst.AttrType.hplmt, result) if params.effectData.intParams[1] == 1 then --params.target:SetAttrBaseValue(LuaConst.RealtimeAttrType.hp, result) params.delta = tonumberV1(params.target:GetAttrValue(LuaConst.AttrType.hplmt)) params.prop = LuaConst.RealtimeAttrType.hp params.hpChangeType = LuaConst.EHpChangeType.DAMAGE_DEAL BattleEffect._ChangeAttr(params) end end function BattleEffect.HealByHplmt(params) if not params.target:IsAlive() then return end params.delta = tonumberV1(params.target:GetAttrValue(LuaConst.AttrType.hplmt) * params.effectData.floatParams[1]) params.prop = LuaConst.RealtimeAttrType.hp BattleEffect._ChangeAttr(params) end -- 通过护盾值改变血量 function BattleEffect.HealByEventPCLeftVal(params) if not params.target:IsAlive() then return end if params.outParams.leftVal then params.delta = tonumberV1(params.outParams.leftVal * params.effectData.floatParams[1]) params.prop = LuaConst.RealtimeAttrType.hp params.hpChangeType = LuaConst.EHpChangeType.NORMAL params.hpChangeBatch = LuaConst.EHpChangeBatch.HEAL_BY_EVENT_PC_LEFT BattleEffect._ChangeAttr(params) end end function BattleEffect.Heal(params) --params.effectData.intParams[1] == 1 表示死亡也可以加血, 并且这个加血量不受 behealeff 属性影响 if params.effectData.intParams[1] == 1 or params.target:IsAlive() then params.delta = params.effectData.floatParams[1] params.prop = LuaConst.RealtimeAttrType.hp params.dontApplyBehealeff = params.effectData.intParams[1] == 1 BattleEffect._ChangeAttr(params) end end function BattleEffect.HpLessStepChangeAttr(params) if params then local delta = BattleEffect.GetHpLessStepDelta(params) if delta then params.delta = delta BattleEffect._ChangeAttr(params) --else --正常现象,如果没有到达threshold,delta就是nil,就不产生任何效果 end else logging.error(LTAG.ERROR, "HYW : params nil Error @HpLessStepChangeAttr") end end function BattleEffect.AddPcByVariable(params) local variable = params.target.components.record:GetVariable(params.effectData.intParams[1]) if variable then local ratio = params.effectData.floatParams[1] local tempV1 = FP.newV1(0) tempV1:Reset(params.effectData.floatParams[1]):Mul(variable):Mul(-1) if tempV1 > FP.Const.Zero then local limitRatio = params.effectData.floatParams[2] if limitRatio then local tempV2 = FP.newV1(0) tempV2:Reset(params.effectData.floatParams[2]):Mul(params.target:GetAttrValue(LuaConst.AttrType.hplmt)) if tempV1 > tempV2 then tempV1:Reset(tempV2) end end params.target:AttrAdd(LuaConst.RealtimeAttrType.pc, tempV1) if params.effectData.intParams[2] then if DataSheetManager.BuffData:GetDataByBuffID(params.effectData.intParams[2]) then SystemManager.AddBuff(params.target, params.effectData.intParams[2], params.caster) --else --正常情况,表示添加一次不走buff时长的pc end SystemManager.OnAddPCAttr(params.target, params.effectData.intParams[2], tempV1, params.caster.EntityID) else logging.error(LTAG.ERROR, "HYW : 没有指定PC值添加的ID!(intParams第2个没填) EffectID : ", params.effectData.ID) end else logging.error(LTAG.ERROR, "HYW : 试图添加小于0的pc值 @BattleEffect.AddPcByVariable EffectID : ", params.effectData.ID) end if params.effectData.intParams[3] and params.effectData.intParams[3] > 0 then params.target.components.record:ClearVariable(params.effectData.intParams[1]) end --else --正常情况,没挨打就没有变量 end end --减少具体某个buff的PC值(pc值是某个属性的百分比) function BattleEffect.ReducePcByBuffID(params) local attrComp = params.target.components.attr local limitBuffId = params.effectData.intParams[1] local value = params.effectData.floatParams[1] local attrStr = params.effectData.stringParam local result = FP.newV1(value) if not string.isNilOrEmpty(attrStr) then result:Mul(attrComp:GetAttrValue(attrStr)) end _tempV1:Reset() -- 记录buffId最多有多少护盾值 for i,pcBuffData in ipairs(attrComp.PCBuffList) do if limitBuffId == pcBuffData.buffId then _tempV1:Add(pcBuffData.leftVal) end end if _tempV1 < result then -- 现有值不够扣的,则就扣这么多了 result:Reset(_tempV1) end attrComp:AttrSub("pc",result) SystemManager.OnSubPCAttr(params.target, params.caster, result, false, false, limitBuffId) end --这个方法不是统一方法,BattleEffect其他添加buff的地方自己调用 SystemManager.AddBuff function BattleEffect.AddBuff(params) local targetType = params.effectData.intParams[2] or 1 local targetEntity = nil local targetEntityList = nil if targetType == 1 then targetEntity = params.target elseif targetType == 2 then targetEntity = params.caster elseif targetType == 3 then if params.outParams then targetEntity = params.outParams.target end elseif targetType == 4 then if params.outParams then targetEntity = params.outParams.caster end elseif targetType == 5 then targetEntity = params.target:GetMasterEntity() elseif targetType == 6 then --给指定MonsterType的所有怪物加 local monsterType = params.effectData.intParams[4] if monsterType then targetEntityList = {} local distSqr local compareEntity = params.caster if params.effectData.floatParams[1] then distSqr = FP.newV1(params.effectData.floatParams[1]) distSqr:Mul(params.effectData.floatParams[1]) if params.effectData.floatParams[2] == 1 then compareEntity = params.target end end for i,v in ipairs(LogicUpdateManager.EntityList_Normal) do if v:IsMonster() and v:GetFeatureID() == monsterType then if distSqr == nil or distSqr >= FP.V2.DistanceSqr(v:GetLogicPos(), compareEntity:GetLogicPos()) then table.insert(targetEntityList, v) end end end end end if targetEntity or targetEntityList then if targetEntity then BattleEffect._AddBuffToEntity(params, targetEntity) end if targetEntityList then for i,v in ipairs(targetEntityList) do BattleEffect._AddBuffToEntity(params, v) end end end end function BattleEffect.SimpleAddBuffToMonsterOfId(params) local monsterID = params.effectData.intParams[1] local buffID = params.effectData.intParams[2] for i,v in ipairs(LogicUpdateManager.EntityList_Normal) do if v:GetCharacterID() == monsterID then SystemManager.AddBuff(v, buffID, params.caster) end end end -- 给武将和非武将添加不同的buff。仿写的是子弹表的PlayerHitBuffID字段 function BattleEffect.AddDiffBuffToHeroAndMonster(params) local characterType = params.target._logicInitData.CharacterType local heroBuffID = params.effectData.intParams[1] local monsterBuffID = params.effectData.intParams[2] local buffCtrlParam = RuntimeDataManager.New_BuffCtrl() buffCtrlParam.ForceDuration:Reset(params.effectData.floatParams[1]) if characterType == LuaConst.CharacterType.Hero or characterType == LuaConst.CharacterType.Illusion then SystemManager.AddBuff(params.target, heroBuffID, params.caster, nil, buffCtrlParam) else SystemManager.AddBuff(params.target, monsterBuffID, params.caster, nil, buffCtrlParam) end end function BattleEffect._AddBuffToEntity(params, targetEntity) if targetEntity then repeat if params.effectData.intParams[5] == 1 then if targetEntity.components.buff:HasBuffOfSourceEntity(params.effectData.intParams[1], params.caster) then break end end local buffCtrlParam local layer = params.effectData.intParams[3] or 1 if not string.isNilOrEmpty(params.effectData.stringParam) then if params.outParams and params.outParams[params.effectData.stringParam] then layer = tonumber(params.outParams[params.effectData.stringParam]) end end if layer > 0 then local sourceEntity if params.effectData.intParams[7] == 1 then sourceEntity = params.caster:GetMasterEntity() end if not sourceEntity then sourceEntity = params.caster end if params.effectData.intParams[6] and params.effectData.intParams[6] > 0 then buffCtrlParam = buffCtrlParam or RuntimeDataManager.New_BuffCtrl() buffCtrlParam.MissileHurtID = params.effectData.intParams[6] end if layer <= 1 then SystemManager.AddBuff(targetEntity, params.effectData.intParams[1], sourceEntity, nil, buffCtrlParam) else for i=1,layer do SystemManager.AddBuff(targetEntity, params.effectData.intParams[1], sourceEntity, nil, buffCtrlParam) end end else logging.error(LTAG.ERROR, "HYW : BattleEffect.AddBuff layer <= 0 layer : ", layer, " BattleEffectID : ", params.effectData.ID) end until true else logging.error(LTAG.ERROR, "HYW : AddBuff效果的目标为空 targetType : ", params.effectData.intParams[2] or 1) if params.outParams and params.outParams.buff then logging.error(LTAG.ERROR, "HYW : 出错的AddBuff效果由buff : ", params.outParams.buff.BuffID, " 施加") end end end function BattleEffect.AddBuffByLayer(params) if params.buff then local layer = params.buff:GetBuffLayer() for i=1,#params.effectData.intParams / 2 do if layer == params.effectData.intParams[i*2-1] then if params.effectData.intParams[i*2] then SystemManager.AddBuff(params.target, params.effectData.intParams[i*2], params.caster) end end end else logging.error(LTAG.ERROR, "HYW : 只能通过buff发动BattleEffect.AddBuffByLayer") end end -- 用某光环buff里面的人数值 修改一个buff的公式 function BattleEffect.RefreshBuffFormulaByInHaloBuffNum(params) local haloBuffId = params.effectData.intParams[1] local count = SystemManager.GetInHaloBuffCount(params.target, haloBuffId, params.target) local toolBuffId = params.effectData.intParams[2] -- 用来被携带公式的buff SystemManager.DeleteBuff(params.target, toolBuffId, params.target) local offsetCount = params.effectData.floatParams[1] or 0 -- 这是整数,虽然用了floatParams count = count + offsetCount if count > 0 then local buffCtrlParam = RuntimeDataManager.New_BuffCtrl() buffCtrlParam.BuffOverRideFomula = string.format(params.effectData.stringParam, count) SystemManager.AddBuff(params.target, toolBuffId, params.target, nil, buffCtrlParam) end end -- 用某组光环buff里面的人数值 修改一个buff的公式 function BattleEffect.RefreshBuffFormulaByInHaloBuffGroupNum(params) local haloBuffGroupId = params.effectData.intParams[1] local count = SystemManager.GetInHaloBuffGroupCount(params.target, haloBuffGroupId, params.target) local toolBuffId = params.effectData.intParams[2] -- 用来被携带公式的buff组id SystemManager.DeleteBuff(params.target, toolBuffId, params.target) local offsetCount = params.effectData.floatParams[1] or 0 -- 这是整数,虽然用了floatParams count = count + offsetCount if count > 0 then local buffCtrlParam = RuntimeDataManager.New_BuffCtrl() buffCtrlParam.BuffOverRideFomula = string.format(params.effectData.stringParam, count) SystemManager.AddBuff(params.target, toolBuffId, params.target, nil, buffCtrlParam) end end -- 删除来源是 事件中的 originEntity 的 buff function BattleEffect.DeleteBuffIfEventOriginIsCaster(params) if params.caster:GetOriginEntity() == params.outParams.originEntity then SystemManager.DeleteBuff(params.target, params.effectData.intParams[1], params.caster) if params.caster ~= params.outParams.originEntity then SystemManager.DeleteBuff(params.target, params.effectData.intParams[1], params.outParams.originEntity) end end end -- 删除来源是 事件中的某个Entity 的 buff function BattleEffect.DeleteBuffIfEventParamIsCaster(params) local checkEntity = params.outParams[params.effectData.stringParam] if params.caster:GetOriginEntity() == checkEntity then SystemManager.DeleteBuff(params.target, params.effectData.intParams[1], params.caster) if params.caster ~= checkEntity then SystemManager.DeleteBuff(params.target, params.effectData.intParams[1], checkEntity) end end end function BattleEffect.DeleteBuff(params) for i,v in ipairs(params.effectData.intParams) do SystemManager.DeleteBuff(params.target, v) end end function BattleEffect.DeleteBuffOnMonsterOfId(params) local monsterID = params.effectData.intParams[1] local buffID = params.effectData.intParams[2] for i,v in ipairs(LogicUpdateManager.EntityList_Normal) do if v:GetCharacterID() == monsterID then SystemManager.DeleteBuff(v, buffID) end end end function BattleEffect.AddRandomBuff(params) local weightSum = 0 local weightList = params.effectData.floatParams local buffId for i,weight in ipairs(weightList) do weightSum = weightSum + weight end if weightSum > 0 then local rand = LogicRandom.GetIntegerValue(params.caster, 0, weightSum, 99436) weightSum = 0 for i,weight in ipairs(weightList) do weightSum = weightSum + weight if weightSum >= rand then buffId = params.effectData.intParams[i] break end end else buffId = params.effectData.intParams[LogicRandom.GetIntegerValue(params.caster, 1, #params.effectData.intParams, 99446)] end SystemManager.AddBuff(params.target, buffId, params.caster) end function BattleEffect.AddBuffByDistAndSetDurSameWithBattleEffectBuff(params) _tempV1:Reset(1):Mul(params.effectData.floatParams[1]):Mul(params.effectData.floatParams[1]) local distSqr = FP.V2.DistanceSqr(params.target:GetLogicPos(), params.caster:GetLogicPos()) local buffCtrlParam local updateData = params.buff and params.buff:GetUpdateData(1) if updateData then buffCtrlParam = RuntimeDataManager.New_BuffCtrl() buffCtrlParam.ForceDuration:Reset(updateData.BuffTimer) end if distSqr < _tempV1 then SystemManager.AddBuff(params.target, params.effectData.intParams[1], params.caster, nil, buffCtrlParam) else SystemManager.AddBuff(params.target, params.effectData.intParams[2], params.caster, nil, buffCtrlParam) end end function BattleEffect.SlotMachine3X3AddBuff(params) local randomIndex = 1 local weightSum = 0 local weightList = params.effectData.floatParams for i=1,7 do weightSum = weightSum + (weightList[i] or 0) end if weightSum > 0 then local rand = LogicRandom.GetIntegerValue(params.caster, 1, weightSum, 99450) weightSum = 0 for i,weight in ipairs(weightList) do weightSum = weightSum + weight if weightSum >= rand then randomIndex = i break end end else randomIndex = LogicRandom.GetIntegerValue(params.caster, 1, 7, 99451) end local caster = params.caster local intParams = params.effectData.intParams local psEffectRandom if randomIndex == 1 then --AAA psEffectRandom = {1,1,1} elseif randomIndex == 2 then --BBB psEffectRandom = {2,2,2} elseif randomIndex == 3 then --CCC psEffectRandom = {3,3,3} elseif randomIndex == 4 then --AAX psEffectRandom = {1,1,1} psEffectRandom[LogicRandom.GetIntegerValue(params.caster, 1, 3, 99452)] = LogicRandom.GetIntegerValue(params.caster, 2, 3, 99453) elseif randomIndex == 5 then --BBX psEffectRandom = {2,2,2} psEffectRandom[LogicRandom.GetIntegerValue(params.caster, 1, 3, 99454)] = LogicRandom.GetIntegerValue(params.caster, 1, 2, 99455) == 1 and 1 or 3 elseif randomIndex == 6 then --CCX psEffectRandom = {3,3,3} psEffectRandom[LogicRandom.GetIntegerValue(params.caster, 1, 3, 99456)] = LogicRandom.GetIntegerValue(params.caster, 1, 2, 99457) else local randomType = LogicRandom.GetIntegerValue(params.caster, 1, 6, 99458) if randomType == 1 then psEffectRandom = {1,2,3} elseif randomType == 2 then psEffectRandom = {1,3,2} elseif randomType == 3 then psEffectRandom = {2,1,3} elseif randomType == 4 then psEffectRandom = {2,3,1} elseif randomType == 5 then psEffectRandom = {3,1,2} else psEffectRandom = {3,2,1} end end local psEffectBuff = intParams[7+psEffectRandom[1]] if psEffectBuff and psEffectBuff > 0 then SystemManager.AddBuff(params.target, psEffectBuff, caster) end psEffectBuff = intParams[10+psEffectRandom[2]] if psEffectBuff and psEffectBuff > 0 then SystemManager.AddBuff(params.target, psEffectBuff, caster) end psEffectBuff = intParams[13+psEffectRandom[3]] if psEffectBuff and psEffectBuff > 0 then SystemManager.AddBuff(params.target, psEffectBuff, caster) end if randomIndex >= 1 and randomIndex <= 3 then --3个相同图案 psEffectBuff = intParams[17] if psEffectBuff and psEffectBuff > 0 then SystemManager.AddBuff(params.target, psEffectBuff, caster) end end local result = intParams[randomIndex] if result and result > 0 then SystemManager.AddBuff(params.target, result, caster) end end function BattleEffect._DotBuffUpdateBurst(params) if params.buffUpdateData then local buffData = params.buffObject:GetData() if buffData.BuffType == LuaConst.BuffType.DotBuff then _tempV1:Reset(params.buffUpdateData.BuffTimer):Mul(1000):Div(buffData.CallFrequency) local count = math.ceil(tonumberV1(_tempV1)) if not buffData.IsEffectOnStart then count = count - 1 --count不需要乘以层数,因为BuffOperator_Dot:Execute后续的FormularCalculator里面计算公式会带入层数 end if count > 1 then FormulaCalculator.PileDamageFactor(count) end local BuffOperator_Dot = require "Battle/Logic/Buff/BuffManager/BuffOperator_Dot" BuffOperator_Dot.Execute(buffData, params.target, params.buffUpdateData.SourceEntity, params.buffUpdateData) SystemManager.DeleteBuff(params.target, params.buffID, params.caster) FormulaCalculator.ResetDamageFactor() --强行reset一下伤害系数,避免因为一些特殊情况(比如伤害免疫)导致没有消费掉伤害系数的情况 else logging.error(LTAG.ERROR, "HYW : 尝试爆发非Dot buff!! 出错的BattleEffect ID : ", params.effectData.ID) end end end function BattleEffect.DotBuffBurst(params) local buffObject = params.target.components.buff:GetBuffObjectByBuffId(params.effectData.intParams[1]) if buffObject then local buffUpdateData if buffObject.BuffUpdateData then buffUpdateData = buffObject.BuffUpdateData else for i,_buffUpdateData in ipairs(buffObject.BuffUpdateList) do if _buffUpdateData.SourceEntity == params.caster then buffUpdateData = _buffUpdateData break end end end if buffUpdateData and buffUpdateData.BuffLayer > 0 then params.buffID = params.effectData.intParams[1] params.buffUpdateData = buffUpdateData params.buffObject = buffObject BattleEffect._DotBuffUpdateBurst(params) end end end function BattleEffect.AddBuffToMasterWithLayerBySlaveCount(params) local master = params.target:GetMasterEntity() if master then local count = 0 for j=1,#LogicUpdateManager.EntityList_Normal do local entity = LogicUpdateManager.EntityList_Normal[j] if entity:GetMasterEntity() == master then for i=2,#params.effectData.intParams do local monsterID = params.effectData.intParams[i] if entity:GetCharacterID() == monsterID and entity:IsAlive() then count = count + 1 end end end end local layer = 0 if count > 0 then layer = count * (params.effectData.floatParams[1] or 0) + (params.effectData.floatParams[2] or 0) end SystemManager.DeleteBuff(master, params.effectData.intParams[1], master) if layer > 0 then for i=1,layer do --注意这里必须得用这种方式添加,因为改变属性类型的buff如果设置ForceDuration来初始化层数,属性只会被改变一次,也就是永远只有1层buff的效果 SystemManager.AddBuff(master, params.effectData.intParams[1], master) end end else logging.error(LTAG.ERROR, "HYW : 警告!战斗策划注意!单位不存在主人,但是发动了BattleEffect.AddBuffToMasterWithLayerBySlaveCount 单位CharacterID: ", params.caster:GetCharacterID(), " 单位类型 : ", params.caster:GetCharacterType()) end end -- 根据同master下的entity数量,调用不同的call。(包含自己) function BattleEffect.CallByBrotherNum(params) local filterMonsterID = params.effectData.intParams[1] local master = params.target:GetMasterEntity() if master then local count = 0 for i=1,#LogicUpdateManager.EntityList_Normal do local entity = LogicUpdateManager.EntityList_Normal[i] if entity._logicInitData.RootMasterEntity == master and entity._logicInitData.CharacterID == filterMonsterID then count = count + 1 end end for j=1,#params.effectData.floatParams do if count == params.effectData.floatParams[j] then params.callBulletId = params.effectData.intParams[j + 1] BattleEffect._Call(params) break end end end end function BattleEffect.AddSafeAreaEffect(params) if params.target:IsBoss() then SystemManager.AddBuff(params.target, LuaConst.SpecialBuffs.ForceReturn, params.target) elseif params.target:IsHero() then end end function BattleEffect.DeleteBuffLayer(params) local buffID = params.effectData.intParams[1] local updateData = params.target.components.buff:GetBuffUpdateData(buffID, params.caster) if updateData and updateData.BuffLayer > 0 then local addLayer = updateData.BuffLayer - params.effectData.intParams[2] SystemManager.DeleteBuff(params.target, buffID, params.caster) for i=1,addLayer do SystemManager.AddBuff(params.target, buffID, params.caster) end end end function BattleEffect.DeleteBuffLayerByFactor(params) local buffID = params.effectData.intParams[1] local updateData = params.target.components.buff:GetBuffUpdateData(buffID, params.caster) if updateData and updateData.BuffLayer > 0 then local addLayer = tonumberV1(_tempV1:Reset(updateData.BuffLayer):Mul(params.effectData.floatParams[1])) addLayer = math.ceil(addLayer) addLayer = updateData.BuffLayer - addLayer SystemManager.DeleteBuff(params.target, buffID, params.caster) for i=1,addLayer do SystemManager.AddBuff(params.target, buffID, params.caster) end end end function BattleEffect.AddLevelRemainTime(params) LevelItemManager.Global:AddRemainTime(params.effectData.floatParams[1]) end -- 进入类似于子弹时间状态 ,非同步玩法。 设置除了自己外,其他所有都变慢 function BattleEffect.SetTimeScaleBatchNotSync(params) if LevelManager.ShouldKeepSyncLevel() then return end local isStart = params.effectData.intParams[1] ~= 0 local contantType = params.effectData.intParams[2] local slowTarget = params.outParams[params.effectData.stringParam] NotSyncBattleSetter.SetTimeScaleBatchNotSync(isStart,contantType ,params.caster, slowTarget, "BatchNotSync", params.effectData.floatParams[1], params.effectData.floatParams[2], LuaConst.TimeScaleBreakType.Buff) end function BattleEffect.SetTimeScale(params) if params.duration and params.duration > 0 then SystemManager.OnAddTimeScale( params.target, "battleEffect" .. params.effectData.ID, params.timescale, params.duration, LuaConst.TimeScaleBreakType.NeverBreak, LuaConst.ETimeScaleChannel.SKILL_ANIM_SOUND_ENTITY_POS_ROT) end end function BattleEffect.DeleteTimeScaleOfBattleEffect(params) SystemManager.OnDeleteTimeScale(params.target, "battleEffect" .. params.effectData.intParams[1]) end -- 设置奔跑的动画 速度变慢 function BattleEffect.SetMoveAnimationSpeedSlow(params) local speedState = params.effectData.intParams[1] SystemManager.ChangeMoveAnimationPlaySpeed(params.target, speedState) end --params.value是伤害量,得设置为负数 --params.hpChangeBuffId是造成伤害的Buff,策划会用于做过滤,比如无敌就是互斥掉了200001(COMMON_HURT_BUFF),多数情况下不需要指定,使用默认值COMMON_HURT_BUFF function BattleEffect.DealDamage(params) if params.value < 0 then local buffCtrlParam = RuntimeDataManager.New_BuffCtrl() buffCtrlParam.BuffOverRideFomula = "aim:add(hp," .. params.value ..")" buffCtrlParam.HpChangeType = params.hpChangeType or LuaConst.EHpChangeType.DAMAGE_DEAL SystemManager.AddBuff( params.target, params.hpChangeBuffId or COMMON_HURT_BUFF, params.caster, nil,buffCtrlParam) else if params.value > 0 then logging.error(LTAG.ERROR, "HYW : 伤害值必须设置为负数! 当前值: ", params.value, " effect:", params.effectData.ID) end end end function BattleEffect.HpRatioDamage(params) if params.outParams.hpChangeType ~= LuaConst.EHpChangeType.DAMAGE_DEAL then params.target = params.outParams.target if params.effectData.intParams[1] == 2 then --造成当前血量一定比例的伤害 params.value = -tonumberV1(params.effectData.floatParams[1] * params.target:GetHp()) else --造成最大血量一定比例的伤害 params.value = -tonumberV1(params.effectData.floatParams[1] * params.target:GetMaxHp()) end params.hpChangeBuffId = COMMON_HURT_BUFF params.hpChangeType = LuaConst.EHpChangeType.DAMAGE_DEAL BattleEffect.DealDamage(params) end end --根据最近N秒内的血量损失造成伤害,支持设置系数和参数化伤害上限 function BattleEffect.DealDmgByHpLossWithinTime(params) params.value = tonumberV1(params.caster.components.record:GetHpLossWithin(params.effectData.floatParams[1]) * (params.effectData.floatParams[2] or 1)) local limit = nil if params.effectData.floatParams[3] then limit = params.effectData.floatParams[3] * params.caster:GetAttrValueNum(params.effectData.stringParam) if -params.value > limit then params.value = -limit end end if params.value < 0 then BattleEffect.DealDamage(params) end end function BattleEffect.HpRatioDamage(params) if params.outParams.hpChangeType ~= LuaConst.EHpChangeType.DAMAGE_DEAL then params.target = params.outParams.target if params.effectData.intParams[1] == 2 then --造成当前血量一定比例的伤害 params.value = -tonumberV1(params.effectData.floatParams[1] * params.target:GetHp()) else --造成最大血量一定比例的伤害 params.value = -tonumberV1(params.effectData.floatParams[1] * params.target:GetMaxHp()) end params.hpChangeBuffId = COMMON_HURT_BUFF params.hpChangeType = LuaConst.EHpChangeType.DAMAGE_DEAL BattleEffect.DealDamage(params) end end function BattleEffect.DealDmgByVariable(params) local variable = params.caster.components.record:GetVariable(params.effectData.intParams[1]) or 0 --params.value = variable * params.effectData.floatParams[1] - (params.effectData.floatParams[2] or 0) --old 没有使用定点数 --new 使用定点数计算再转为number防止误差↓ _tempV1:Reset(variable):Mul(params.effectData.floatParams[1]):Sub((params.effectData.floatParams[2] or 0)) params.value = tonumberV1(_tempV1) --new 使用定点数↑ local limit = params.effectData.floatParams[3] if limit then --limit = limit * params.caster:GetAttrValueNum(params.effectData.stringParam)--old 没有使用定点数 --new 使用定点数计算再转为number防止误差↓ _tempV1_2:Reset(limit):Mul(params.caster:GetAttrValueNum(params.effectData.stringParam)) limit = tonumberV1(_tempV1_2) --new 使用定点数↑ if -params.value > limit then params.value = -limit end end if params.value < 0 then if params.effectData.intParams[2] and params.effectData.intParams[2] > 0 then local hp = tonumberV1(params.target:GetAttrValue(LuaConst.RealtimeAttrType.hp)) if -params.value >= hp then params.value = 1 - hp end end end if params.value < 0 then BattleEffect.DealDamage(params) --else --do nothing 正常现象 end end function BattleEffect.DealDmgByVariableAndClear(params) BattleEffect.DealDmgByVariable(params) BattleEffect.VariableClear(params) end function BattleEffect.SetDmg7ByStringVariableOfTarget(params) local variableValue if params.effectData.intParams[1] == 2 then variableValue = params.target.components.record:GetVariable(params.effectData.stringParam) else variableValue = params.target.components.record:GetVariableFromMaster(params.effectData.stringParam) end FormulaCalculator.SetDamage7OverrideValue(variableValue) end function BattleEffect.ReturnDamage(params) if params.outParams.hpChangeType ~= LuaConst.EHpChangeType.DAMAGE_RETURN then --只有非反伤伤害才能被反伤 if CampManager.IsEnemyEntity(params.outParams.caster, params.outParams.target)then --不同阵营之间造成的伤害才能反伤 local value = 0 if params.returnDamageType == 1 then --value = params.outParams.delta * params.returnDamageValue --old 没有使用定点数 --new 使用定点数↓ _tempV1:Reset(params.outParams.delta):Mul(params.returnDamageValue) value = tonumberV1(_tempV1) --new 使用定点数↑ elseif params.returnDamageType == 2 then value = params.returnDamageValue else logging.error(LTAG.ERROR, "HYW : 未实现的returnDamageType : ", params.returnDamageType, " effectId : ", params.effectData.ID) end if value ~= 0 then --old1↓ --FormulaCalculator.ChangeHp(params.outParams.caster,params.outParams.target,value,LuaConst.EHpChangeType.DAMAGE_RETURN) --old↑ -- old2↓ -- local buffData = DataSheetManager.BuffData:GetDataByBuffID(params.outParams.hpChangeBuffId) -- local updateData = RuntimeDataManager.New_BuffUpdate() -- updateData.SourceEntity = params.caster -- updateData.BuffOverRideFomula = "aim:add(hp," .. value ..")" -- FormulaCalculator.CalculateResult(buffData,updateData,params.outParams.caster,params.outParams.target,nil,LuaConst.EHpChangeType.DAMAGE_RETURN) -- old2↑ --new↓ params.value = value params.hpChangeBuffId = params.outParams.hpChangeBuffId params.target = params.outParams.caster params.hpChangeType = LuaConst.EHpChangeType.DAMAGE_RETURN EventSystem.Dispatch(EventID.TryAddAttackLog, LuaConst.HurtFormulaStepEnum.Step_DamageReturn, value) BattleEffect.DealDamage(params) --new↑ end end end end function BattleEffect.WhenDeadKeepOneHP(params) local dmg = params.outParams.delta -- 类型是number ,不是定点数 ,掉血的时候为负数 if dmg < 0 then dmg = - dmg local leftHp = tonumberV1(params.target:GetHp()) if dmg >= leftHp then -- 伤害量大于等于剩余血 local realDmg = leftHp - 1 FormulaCalculator.SetFinalDamageOverrideValue(realDmg) end end end function BattleEffect.PileAmFactor(params) FormulaCalculator.PileAmFactor(params.effectData.floatParams[1]) end function BattleEffect.PileDamageFactor(params) FormulaCalculator.PileDamageFactor(params.value) end function BattleEffect.PileFinalDamageFactor(params) FormulaCalculator.PileFinalDamageFactor(params.effectData.floatParams[1]) end function BattleEffect.PileDmgFactorByBuffLayer(params) if params.buff then _tempV1:Reset(params.buff:GetBuffLayer()):Mul(params.effectData.floatParams[1]):Add(1) params.value = tonumberV1(_tempV1) BattleEffect.PileDamageFactor(params) else logging.error(LTAG.ERROR, "HYW : BattleEffect.PileDmgFactorByBuffLayer 没有实现的配置方法,如果有需求请联系战斗程序") end end function BattleEffect.SkipBehealEff(params) FormulaCalculator.SkipNegBehealEff() end --通过来源者叠加的buff层数来修改伤害系数(intParams是层,floatParams是值) function BattleEffect.PileDmgFactorByBuffLayerFromCaster(params) if params.buff then local buffSourceEntity = params.caster local buffLayer = params.buff:GetBuffLayer(buffSourceEntity) local count = #params.effectData.intParams for i,layer in ipairs(params.effectData.intParams) do if buffLayer >= layer and (count == i or buffLayer < params.effectData.intParams[i+1]) then params.value = params.effectData.floatParams[i] BattleEffect.PileDamageFactor(params) break end end else logging.error(LTAG.ERROR, "GWS : BattleEffect.PileDmgFactorByBuffLayerFromCaster 没有实现的配置方法,如果有需求请联系战斗程序") end end function BattleEffect.PileHealFactor(params) FormulaCalculator.PileHealFactor(params.effectData.floatParams[1]) end function BattleEffect.PilePCLossFactor(params) FormulaCalculator.PilePCLossFactor(params.effectData.floatParams[1]) end function BattleEffect.PileParryEffRatioPlus(params) FormulaCalculator.PileParryEffRatioPlus(params.effectData.floatParams[1]) end function BattleEffect.PileAntiParryEffRatioPlus(params) FormulaCalculator.PileAntiParryEffRatioPlus(params.effectData.floatParams[1]) end function BattleEffect.PileParryRatePlus(params) FormulaCalculator.PileParryRatePlus(params.effectData.floatParams[1]) end function BattleEffect.PileAntiParryRatePlus(params) FormulaCalculator.PileAntiParryRatePlus(params.effectData.floatParams[1]) end function BattleEffect.PileCritRatePlus(params) FormulaCalculator.PileCritRatePlus(params.effectData.floatParams[1]) end function BattleEffect.PileAntiCritRatePlus(params) FormulaCalculator.PileAntiCritRatePlus(params.effectData.floatParams[1]) end function BattleEffect.PileCritEffRatioPlus(params) FormulaCalculator.PileCritEffRatioPlus(params.effectData.floatParams[1]) end function BattleEffect.PileAntiCritEffRatioPlus(params) FormulaCalculator.PileAntiCritEffRatioPlus(params.effectData.floatParams[1]) end function BattleEffect.AddRatioOfHplmtPcByBuffLayer(params) if params.outParams.eventBuffUpdateData then local buffLayer = params.outParams.eventBuffUpdateData.BuffLayer if buffLayer > 0 then local ratio if buffLayer <= #params.effectData.floatParams then ratio = params.effectData.floatParams[buffLayer] else ratio = params.effectData.floatParams[#params.effectData.floatParams] end if ratio then _tempV1:Reset(params.target:GetAttrValue(LuaConst.AttrType.hplmt)) _tempV1:Mul(ratio) params.target:AttrAdd(LuaConst.RealtimeAttrType.pc, _tempV1) SystemManager.OnAddPCAttr(params.target, params.outParams.buffId, _tempV1, params.caster.EntityID) else logging.error(LTAG.ERROR, "HYW : battleEffect配置错误 ID : ", params.effectData.ID) end end else logging.error(LTAG.ERROR, "HYW : 事件参数没有附带eventBuffUpdateData,无法使用AddRatioOfHplmtPcByBuffLayer效果,尝试使用20001事件? 出错的BuffID : ", params.buff and params.buff.BuffID) end end function BattleEffect.SetMissileHitRateByTriggerNum(params) local triggerNum = params.outParams.missileHitCount -- 撞击数 local hitRateList = params.effectData.floatParams if triggerNum and triggerNum > 0 then local result = nil if triggerNum > #hitRateList then result = hitRateList[#hitRateList] else result = hitRateList[triggerNum] end FormulaCalculator.PileMissileHitRate(result) end end function BattleEffect.HpLessStepPileDmgFactor(params) if params then local delta = BattleEffect.GetHpLessStepDelta(params) if delta then params.value = delta BattleEffect.PileDamageFactor(params) --else --正常现象,如果没有到达threshold,delta就是nil,就不产生任何效果 end else logging.error(LTAG.ERROR, "HYW : params nil Error @HpLessStepPileDmgFactor") end end function BattleEffect.PileDmgFactorIfHasBuff(params) if params.checkTarget then if params.checkTarget.components.buff:GetBuffUpdateData(params.checkBuffID) then --这里不能用GetBuffObjectByBuffId BattleEffect.PileDamageFactor(params) end end end function BattleEffect.PileDmgFactorOnMissile(params) if params.outParams.missileData then for i,checkMissileID in ipairs(params.checkMissileIDs) do if params.outParams.missileData.ID == checkMissileID then BattleEffect.PileDamageFactor(params) break end end --else --正常现象 end end function BattleEffect.AddMissileDmgFactor(params) local recordComp = params.target.components.record for i,missileID in ipairs(params.effectData.intParams) do local val = params.effectData.floatParams[i] if val then recordComp:AddMissileDmgFactor(missileID, val) else logging.error(LTAG.ERROR, "[战斗策划]:BattleEffect 配置错误 。BattleEffectID = ", params.effectData.ID , " int数量和float数量不一样") end end end function BattleEffect.ClearMissileDmgFactor(params) local recordComp = params.target.components.record for i,missileID in ipairs(params.effectData.intParams) do recordComp:ClearMissileDmgFactor(missileID) end end function BattleEffect.RemoveMissileDmgFactor(params) local recordComp = params.target.components.record for i,missileID in ipairs(params.effectData.intParams) do local val = params.effectData.floatParams[i] if val then recordComp:RemoveMissileDmgFactor(missileID, val) else logging.error(LTAG.ERROR, "[战斗策划]:BattleEffect 配置错误 。BattleEffectID = ", params.effectData.ID , " int数量和float数量不一样") end end end function BattleEffect.AddMissileGroupDmgFactor(params) local recordComp = params.target.components.record for i,missileGroupID in ipairs(params.effectData.intParams) do local val = params.effectData.floatParams[i] if val then recordComp:AddMissileGroupDmgFactor(missileGroupID, val) else logging.error(LTAG.ERROR, "[战斗策划]:BattleEffect 配置错误 。BattleEffectID = ", params.effectData.ID , " int数量和float数量不一样") end end end function BattleEffect.ClearMissileGroupDmgFactor(params) local recordComp = params.target.components.record for i,missileGroupID in ipairs(params.effectData.intParams) do recordComp:ClearMissileGroupDmgFactor(missileGroupID) end end function BattleEffect.RemoveMissileGroupDmgFactor(params) local recordComp = params.target.components.record for i,missileGroupID in ipairs(params.effectData.intParams) do local val = params.effectData.floatParams[i] if val then recordComp:RemoveMissileGroupDmgFactor(missileGroupID, val) else logging.error(LTAG.ERROR, "[战斗策划]:BattleEffect 配置错误 。BattleEffectID = ", params.effectData.ID , " int数量和float数量不一样") end end end function BattleEffect.SetDamage7OverrideValue(params) if params.effectData.floatParams[1] and params.effectData.floatParams[1] > 0 then FormulaCalculator.SetDamage7OverrideValue(params.effectData.floatParams[1]) end end function BattleEffect.SetFinalDamageOverrideValue(params) if params.effectData.floatParams[1] and params.effectData.floatParams[1] > 0 then FormulaCalculator.SetFinalDamageOverrideValue(params.effectData.floatParams[1]) end end --限制一段时间内受到的伤害 function BattleEffect.RestrictDmgWithinTime(params) local dmgValue = FP.newV1(params.effectData.floatParams[1]) --伤害值(小于1代表百分比,大于1代表数值 if dmgValue > FP.Const.Zero then local time = params.effectData.floatParams[2] --时间(秒) local hpLoss = params.target.components.record:GetHpLossWithin(time) local isPercentage = dmgValue <= FP.Const.One --配置的值如果小于1,代表以百分比限制伤害(比如每秒血量损失不能大于1%),否则代表以数值限制伤害(比如每秒血量损失不能超过5000) if isPercentage then dmgValue:Mul(params.target:GetMaxHp()) end if params.dmgValueFactor then dmgValue:Mul(params.dmgValueFactor) end local limit = dmgValue + hpLoss --还能造成的伤害 if limit > FP.Const.Zero then --如果还能造成伤害 if limit < FP.newV1(-params.outParams.delta) then FormulaCalculator.SetFinalDamageOverrideValueIfSmaller(limit) --else --还能造成的伤害大于等于即将受到的伤害 --do nothing end else --如果还能造成的伤害小于等于0,就归零伤害 FormulaCalculator.FinalDamageMakeZero() end else --如果伤害值小于等于0,则直接归零伤害 FormulaCalculator.FinalDamageMakeZero() end end function BattleEffect.FinalDamageMakeZero(params) FormulaCalculator.FinalDamageMakeZero() end function BattleEffect.FinalHealthMakeZero(params) FormulaCalculator.FinalHealthMakeZero() end function BattleEffect.RestrictDmgByParamWithinTime(params) if params.effectData.intParams[1] == 1 then --params.dmgValueFactor = VIP_LEVEL --未完成HYW 设置 dmgValueFactor为VIP等级 end BattleEffect.RestrictDmgWithinTime(params) end --限制一段时间内最大的吸血量 function BattleEffect.RestrictLifeStealWithinTime(params) local value = FP.newV1(params.effectData.floatParams[1]) --配置的可获得吸血量(小于1代表百分比,大于1代表数值 if value > FP.Const.Zero then local time = params.effectData.floatParams[2] --时间(秒) local lifeSteal = params.target.components.record:GetLifeStealWithin(time) local isPercentage = value <= FP.Const.One --配置的值如果小于1,代表以百分比限制吸血量(比如每秒吸血不能大于1%最大生命值),否则代表以数值限制吸血值(比如每秒吸血值不能超过5000) if isPercentage then value:Mul(params.target:GetMaxHp()) end -- if params.dmgValueFactor then -- value:Mul(params.dmgValueFactor) -- end local limit = value - lifeSteal --还能获得的吸血量 --logging.error(LTAG.ERROR, "HYW : limit : ", limit, " delta : ", params.outParams.delta) if limit > FP.Const.Zero then --如果还能获得吸血值 if limit < FP.newV1(params.outParams.delta) then FormulaCalculator.SetFinalLifeStealOverrideValueIfSmallser(limit) --else --还能获得的吸血大于等于即将获得的吸血时,什么都不用干 --do nothing end else --如果还能获得的吸血量小于等于0,就归零吸血值 FormulaCalculator.FinalLifeStealMakeZero() end else --如果可以获得的吸血值等于0,则直接归零吸血值 FormulaCalculator.FinalLifeStealMakeZero() end end function BattleEffect.VariableAddEventParam(params) local value = params.outParams[params.effectData.stringParam] if value then _tempV1:Reset(value) local factor = params.effectData.floatParams[1] if factor then _tempV1:Mul(factor) end params.value = tonumberV1(_tempV1) params.key = params.effectData.intParams[1] BattleEffect._VariableAdd(params) else logging.error(LTAG.ERROR, "HYW : VariableAddEventParam执行失败,指定的事件变量不存在 effectId : ", params.effectData.ID) end end function BattleEffect._VariableAdd(params) params.target.components.record:VariableAdd(params.key, params.value) end function BattleEffect.VariableClear(params) if params.key then params.target.components.record:ClearVariable(params.key) end if params.effectData.intParams[1] then params.target.components.record:ClearVariable(params.effectData.intParams[1]) end if params.effectData.stringParam then params.target.components.record:ClearVariable(params.effectData.stringParam) end end function BattleEffect.VariableAdd(params) params.value = params.effectData.floatParams[1] params.key = params.effectData.intParams[1] or params.effectData.stringParam BattleEffect._VariableAdd(params) end function BattleEffect.RecordTimestamp(params) local key if string.isNilOrEmpty(params.effectData.stringParam) then key = params.effectData.intParams[1] else key = params.effectData.stringParam end if key then params.caster.components.record:VariableSet(key, LogicUpdateManager._clientHandleFrame) else logging.error(LTAG.ERROR, "HYW : key bad value @BattleEffect.RecordTimestamp EffectID :", params.effectData.ID) end if #params.effectData.floatParams > 0 then BattleEffect._ShowOrHideSkillProgress(params.target, true, params.effectData.floatParams) end end function BattleEffect.CallAtPosByRecordTimestamp(params) local key if string.isNilOrEmpty(params.effectData.stringParam) then key = params.effectData.intParams[1] else key = params.effectData.stringParam end if key then local timestamp = params.caster.components.record:GetVariable(key) if type(timestamp) == "number" then local timeElaFrame = LogicUpdateManager._clientHandleFrame - timestamp if timeElaFrame > 0 then _tempV1:Reset(timeElaFrame):Mul(LuaConst.TimeSpan):Mul(params.effectData.floatParams[1]):Add(params.effectData.floatParams[2]) if params.effectData.floatParams[3] and tonumberV1(_tempV1) > params.effectData.floatParams[3] then _tempV1:Reset(params.effectData.floatParams[3]) end --logging.error(LTAG.ERROR, "HYW : distance : ", _tempV1) params.forcePos = params.caster.components.move.LogicRotateDir:cloneV2() params.forcePos:Normalize() params.forcePos:Mul(_tempV1):Add(params.caster.components.move.LogicPos) params.callBulletId = params.effectData.intParams[2] BattleEffect._Call(params) else logging.error(LTAG.ERROR, "HYW : timestamp in future Error @BattleEffect.CallAtPosByRecordTimestamp! EffectID : ", params.effectData.ID) end else logging.error(LTAG.ERROR, "HYW : timestamp bad value BattleEffect.CallAtPosByRecordTimestamp! value : ", timestamp, " EffectID : ", params.effectData.ID) end else logging.error(LTAG.ERROR, "HYW : key bad value @BattleEffect.CallAtPosByRecordTimestamp EffectID :", params.effectData.ID) end end function BattleEffect.CallWithIdByRecordTimestamp(params) local intParams = params.effectData.intParams local key if string.isNilOrEmpty(params.effectData.stringParam) then key = intParams[1] else key = params.effectData.stringParam end if key then local timestamp = params.caster.components.record:GetVariable(key) or LogicUpdateManager._clientHandleFrame local timeElaFrame = LogicUpdateManager._clientHandleFrame - timestamp if timeElaFrame >= 0 then local minFrame local maxFrame local cellCount = 0 for i=2,#intParams do cellCount = cellCount + 1 if cellCount == 1 then params.callBulletId = intParams[i] elseif cellCount == 2 then minFrame = intParams[i] elseif cellCount == 3 then maxFrame = intParams[i] if timeElaFrame >= minFrame and timeElaFrame <= maxFrame then BattleEffect._Call(params) end cellCount = 0 end end else logging.error(LTAG.ERROR, "HYW : timestamp in future Error @BattleEffect.CallWithIdByRecordTimestamp! EffectID : ", params.effectData.ID) end else logging.error(LTAG.ERROR, "HYW : key bad value @BattleEffect.CallWithIdByRecordTimestamp EffectID :", params.effectData.ID) end end -- 天命发射子弹,由于这不让策划随便配置,故未写入文档 function BattleEffect.TryCallWeaponSoulBullet(params) SystemManager.TryCallWeaponSoulBullet(params.target) end function BattleEffect.StartStateRecord(params) params.target.components.record:StartStateRecord(params.effectData.intParams[1]) end function BattleEffect.ResetToOldestStateRecord(params) local target = params.target if target:IsAlive() then local tempV1 local hp, sa, cdList, pos = target.components.record:GetOldestStateRecord() if hp then --hp、sa、cdList(闪避、技能1、技能2、技能3)、pos (数值都是number类型,从定点数里拿的,不会导致不一致) if params.effectData.intParams[1] and params.effectData.intParams[1] > 0 then if hp <= 0 then hp = target.GetAttrValue(LuaConst.AttrType.hplmt) end tempV1 = target:GetAttrValue(LuaConst.RealtimeAttrType.hp):cloneV1() tempV1[1] = tempV1[1] - hp tempV1:Mul(-1) if tempV1 ~= FP.Const.Zero then params.delta = FP.tonumberV1(tempV1) params.prop = LuaConst.RealtimeAttrType.hp params.dontApplyBehealeff = true BattleEffect._ChangeAttr(params) end end if params.effectData.intParams[2] and params.effectData.intParams[2] > 0 then tempV1 = target:GetAttrValue(LuaConst.RealtimeAttrType.sa):cloneV1() tempV1:Sub(sa):Mul(-1) if tempV1 ~= FP.Const.Zero then params.delta = tempV1[1] params.prop = LuaConst.RealtimeAttrType.sa params.dontApplyBehealeff = true BattleEffect._ChangeAttr(params) end end if params.effectData.intParams[3] and params.effectData.intParams[3] > 0 then local skillData = target.components.skillBase:GetSkillDataByKeyPosition(LuaConst.ESkillKeyPosition.Dodge); if skillData and cdList[1] then SkillTimeSystem.SetSkillCurrentCD(target, skillData.ID, cdList[1]) end skillData = target.components.skillBase:GetSkillDataByKeyPosition(LuaConst.ESkillKeyPosition.Skill1); if skillData and cdList[2] then SkillTimeSystem.SetSkillCurrentCD(target, skillData.ID, cdList[2], cdList[5]) end skillData = target.components.skillBase:GetSkillDataByKeyPosition(LuaConst.ESkillKeyPosition.Skill2); if skillData and cdList[3] then SkillTimeSystem.SetSkillCurrentCD(target, skillData.ID, cdList[3], cdList[6]) end skillData = target.components.skillBase:GetSkillDataByKeyPosition(LuaConst.ESkillKeyPosition.Skill3); if skillData and cdList[4] then SkillTimeSystem.SetSkillCurrentCD(target, skillData.ID, cdList[4], cdList[7]) end end if params.effectData.intParams[4] and params.effectData.intParams[4] > 0 then SystemManager.OnConvey(target, LuaShoveManager.TrimAimPosByObstacleAndPriority(target, pos), nil, nil, nil, false, true) end else logging.error(LTAG.ERROR, "HYW : record 不存在!无法reset! BattleEffect ID:", params.effectData.ID) end end end -- 显示蓄力条 function BattleEffect.ShowOrHideSkillProgress(params) local timeTable = params.effectData.floatParams BattleEffect._ShowOrHideSkillProgress(params.target, params.effectData.intParams[1]==1, timeTable) end function BattleEffect._ShowOrHideSkillProgress(entity, isShow, timeTable) EventSystem.Dispatch(EventID.UIBattle_ShowOrHideSkillProgress, entity, isShow, timeTable) end -- 如果是友方则替换某个buff的特效( 这是条纯表现的代码) function BattleEffect.ReplaceBuffResourceIfFriend(params) local myCamp = LogicUpdateManager._curEntity and LogicUpdateManager._curEntity:GetCampID() or LevelPlayerManager.MainEntityCampID -- 此代码只涉及表现,不影响逻辑,故可这样用 safe if not CampManager.IsEnemyCamp(myCamp,params.target:GetCampID()) then local buffResource if not string.isNilOrEmpty(params.effectData.stringParam) then buffResource = params.effectData.stringParam end params.target.components.replace:SetExtraBuffEffectResourceDic(params.effectData.intParams[1], buffResource) end end -- 替换技能 function BattleEffect.ReplaceNormalSkillBySkillID(params) SystemManager.ReplaceNormalSkillBySkillID(params.target, params.effectData.intParams[1]) end -- 添加技能的装饰功能 (技能的额外功能) - 计数替换技能 function BattleEffect.AddSkillDecoratorQuitReplaceSkillByCount(params) local entity = params.target local skillID = params.effectData.intParams[1] local replaceSkillID = params.effectData.intParams[2] local limitCount = params.effectData.intParams[3] local skillDecoratorType = LuaConst.SkillDecoratorType.QuitReplaceSkillByCount SystemManager.AddSkillDecorator(entity, skillID, skillDecoratorType, replaceSkillID, limitCount) end -- 添加技能的装饰功能 (技能的额外功能) - 额外的CD function BattleEffect.AddSkillDecoratorExtraCD(params) local entity = params.target local skillID = params.effectData.intParams[1] local maxCD = params.effectData.intParams[2] local skillDecoratorType = LuaConst.SkillDecoratorType.ExtraCD SystemManager.AddSkillDecorator(entity, skillID, skillDecoratorType, maxCD) end -- 给技能装饰添加计数 function BattleEffect.AddSkillDecoratorCount(params) local skillBaseComp = params.target.components.skillBase skillBaseComp:CallSkillDecoratorFuncBySkillID(params.effectData.intParams[1], "AddCount", params.effectData.intParams[2]) end function BattleEffect.DeleteSkillDecorator(params) local skillID = params.effectData.intParams[1] local skillDecoratorType = params.effectData.intParams[2] SystemManager.DeleteSkillDecorator(params.target, skillID, skillDecoratorType) end function BattleEffect._GetOverrideDataValue(overrideInfo) local value local valueType = overrideInfo.ValueType if valueType == "int32" or valueType == "uint32" then -- int类型 value = math.floor(overrideInfo.NumberValue + 0.5) elseif valueType == "string" then -- string类型 value = overrideInfo.StringValue elseif valueType == "int32[]" then value = overrideInfo.NumberListValue elseif valueType == "float[]" then value = overrideInfo.NumberListValue elseif valueType == "float" then value = overrideInfo.NumberValue else value = nil logging.error(LTAG.ERROR, "HYW : 不支持的重写 ValueType : ", valueType) end return value end function BattleEffect.OverrideSkillData(params) for i,v in ipairs(params.effectData.intParams) do local overrideData = DataSheetManager.SkillOverrideData:GetDataByID(v); local skillID = overrideData.SkillID local valueType local value for i,v in ipairs(overrideData.OverrideInfo_Table) do --[[ valueType = v.ValueType if valueType == "int32" or valueType == "uint32" then -- int类型 value = math.floor(v.NumberValue + 0.5) elseif valueType == "string" then -- string类型 value = v.StringValue elseif valueType == "float" then --默认是浮点数类型 value = v.NumberValue else value = nil logging.error(LTAG.ERROR, "HYW : 不支持的重写 ValueType : ", valueType) end --]] value = BattleEffect._GetOverrideDataValue(v) if value then params.target.components.record:OverrideSkillDataCell(skillID, v.ColumnName, value, v.TableIndex, v.TableName) end end --替换完毕技能后需要刷新一些缓存 params.target.components.skillBase:RefreshSkillInitCache(skillID) end end function BattleEffect.OverrideCallData(params) for i,v in ipairs(params.effectData.intParams) do local overrideData = DataSheetManager.CallOverrideData:GetDataByID(v); local callID = overrideData.CallID local valueType local value for i,v in ipairs(overrideData.OverrideInfo_Table) do --[[ valueType = v.ValueType if valueType == "int32" or valueType == "uint32" then -- int类型 value = math.floor(v.NumberValue + 0.5) elseif valueType == "string" then -- string类型 value = v.StringValue elseif valueType == "float" then --默认是浮点数类型 value = v.NumberValue else logging.error(LTAG.ERROR, "HYW : 不支持的重写 ValueType : ", valueType) end --]] value = BattleEffect._GetOverrideDataValue(v) if value then params.target.components.record:OverrideCallDataCell(callID, v.ColumnName, value, v.TableIndex, v.TableName) end end end end function BattleEffect.OverrideMissileData(params) for i,v in ipairs(params.effectData.intParams) do local overrideData = DataSheetManager.MissileOverrideData:GetDataByID(v); local missileID = overrideData.MissileID local valueType local value for i,v in ipairs(overrideData.OverrideInfo_Table) do --[[ valueType = v.ValueType if valueType == "int32" or valueType == "uint32" then -- int类型 value = math.floor(v.NumberValue + 0.5) elseif valueType == "string" then -- string类型 value = v.StringValue elseif valueType == "float" then --默认是浮点数类型 value = v.NumberValue else logging.error(LTAG.ERROR, "HYW : 不支持的重写 ValueType : ", valueType) end --]] value = BattleEffect._GetOverrideDataValue(v) if value then params.target.components.record:OverrideMissileDataCell(missileID, v.ColumnName, value, v.TableIndex, v.TableName) end end end end function BattleEffect.OverrideTrackerData(params) for i,v in ipairs(params.effectData.intParams) do local overrideData = DataSheetManager.TrackerOverrideData:GetDataByID(v); local trackerID = overrideData.TrackerID local valueType local value for i,v in ipairs(overrideData.OverrideInfo_Table) do --[[ valueType = v.ValueType if valueType == "int32" or valueType == "uint32" then -- int类型 value = math.floor(v.NumberValue + 0.5) elseif valueType == "string" then -- string类型 value = v.StringValue elseif valueType == "float" then --默认是浮点数类型 value = v.NumberValue else logging.error(LTAG.ERROR, "HYW : 不支持的重写 ValueType : ", valueType) end --]] value = BattleEffect._GetOverrideDataValue(v) if value then params.target.components.record:OverrideTrackerDataCell(trackerID, v.ColumnName, value, v.TableIndex, v.TableName) end end end end function BattleEffect.GsAdd(params) params.target.components.attr:AddGs(params.effectData.intParams[1]) end function BattleEffect._Call(params) SkillMissileSystem.TryToDoCall(params.caster, params.callBulletId, params.skillData, params.effForward, params.forceFireDir, params.forcePos, params.trackerTarget, params.forceTarget, LuaConst.ESkillMissileCallType.BATTLEEFFECT, params.forceOffsetY) end local HP_LOWEST_ENEMY_TARGET_FIND_PARAM function BattleEffect.CallTowardsHpLowestEnemy(params) if not HP_LOWEST_ENEMY_TARGET_FIND_PARAM then HP_LOWEST_ENEMY_TARGET_FIND_PARAM = { campType = LuaConst.ETargetCampType.ENEMY, ignoreBeSkillTargetBuff = true, ignoreEnemyListValid = true, regionParams = { shapeType = LuaConst.ERegionShapeType.CIRCLE, shapeNumParams = {100}, }, sortParams = { sortType = LuaConst.ETargetSortType.HP_LOW }, } end local target = TargetManager.GetTarget(params.caster, HP_LOWEST_ENEMY_TARGET_FIND_PARAM) if target then params.forceFireDir = target:GetLogicPos() - params.caster:GetLogicPos() params.forceFireDir:Normalize() end BattleEffect.Call(params) end function BattleEffect.CallAtNearestEnemyPos(params) local entity = params.caster local pos = entity:GetLogicPos() local target = TargetManager.GetNearestEnemyInCircle(params.caster, pos, 100, true, false, true) -- 100米的半径够大了 if target then params.forcePos = target:GetLogicPos():cloneV2() BattleEffect.Call(params) end end function BattleEffect.CallRetinue(params) local entity = params.caster if entity:IsActive() and entity:IsAlive() then local characterID = params.effectData.intParams[2] if not entity:HasValidRetinueOfCharacterID(characterID) then local RetinueSystem = require"Battle/Logic/Entity/System/RetinueSystem" local randomBornPos = RetinueSystem.GetRandomPosInBornAreaByData(entity, DataSheetManager.RetinueData:GetDataByID(characterID)) if randomBornPos then params.forcePos = randomBornPos end BattleEffect.Call(params) --else --正常情况 do nothing end end end --召唤(以CallBulletData数据进行召唤) function BattleEffect.Call(params) if params.callBulletId == nil then params.callBulletId = params.effectData.intParams[1] --else --正常情况,Call有可能被别的BattleEffect调用,此时别的BattleEffet可能已经提前把callBulletId设置好了 end BattleEffect._Call(params) end function BattleEffect.TargetCall(params) SkillMissileSystem.TryToDoCall(params.target, params.effectData.intParams[1], params.skillData, params.effForward, params.forceFireDir, params.forcePos, params.trackerTarget, params.forceTarget, LuaConst.ESkillMissileCallType.BATTLEEFFECT) end function BattleEffect.RandomCall(params) local weightSum = 0 for i,weight in ipairs(params.effectData.floatParams) do weightSum = weightSum + weight end if weightSum > 0 then local rand = LogicRandom.GetIntegerValue(nil, 0, weightSum, 9998) weightSum = 0 for i,weight in ipairs(params.effectData.floatParams) do weightSum = weightSum + weight if weightSum >= rand then params.callBulletId = params.effectData.intParams[i] break end end else params.callBulletId = params.effectData.intParams[LogicRandom.GetIntegerValue(nil, 1, #params.effectData.intParams, 9999)] end if params.callBulletId then -- 上面随机出来的params.callBulletId可能为-1,这种情况是正常的,代表配置了一定概率什么也不召唤 if params.callBulletId > 0 then if string.isNilOrEmpty(params.effectData.stringParam) then BattleEffect._Call(params) elseif BattleEffect[params.effectData.stringParam] then BattleEffect[params.effectData.stringParam](params) else logging.error(LTAG.ERROR, "HYW : RandomCall 里由stringParam指定的BattleEffect不存在! 出错的EffectID : ", params.effectData.ID) end end else logging.error(LTAG.ERROR, "HYW : callBulletId 获取失败,无法执行随机召唤 @BattleEffect.RandomCall EffectID : ", params.effectData.ID) end end function BattleEffect.CallAtMissilePos(params) if params.outParams.missile then params.forcePos = params.outParams.missile.Pos:cloneV2() BattleEffect.Call(params) else logging.error(LTAG.ERROR, "HYW : 策划注意! CallAtMissilePos只能搭配子弹事件使用 出错的BattleEffect : ", params.effectData.ID) end end function BattleEffect.CallAtBuffHostPos(params) if params.buff then if params.buff.hostEntity then params.forcePos = params.buff.hostEntity:GetLogicPos():cloneV2() BattleEffect.Call(params) end else logging.error(LTAG.ERROR, "HYW : 策划注意! CallAtBuffHostPos只能由buff使用 出错的BattleEffect : ", params.effectData.ID) end end function BattleEffect.CallSomeEntityAsForceTarget(params) if not string.isNilOrEmpty(params.effectData.stringParam) then local posEntity = params.outParams[params.effectData.stringParam] if posEntity then params.forceTarget = posEntity BattleEffect.Call(params) else logging.error(LTAG.ERROR, "GWS : 策划注意! CallSomeEntityAsForceTarget 没有检测到 事件中存在 : ", params.effectData.stringParam, "应该换个事件ID。 出错的BattleEffect : " ,params.effectData.ID) end else logging.error(LTAG.ERROR, "GWS : 策划注意! CallSomeEntityAsForceTarget 没有配置stringParam 出错的BattleEffect : ", params.effectData.ID) end end function BattleEffect.CallAtSomeEntityPos(params) if not string.isNilOrEmpty(params.effectData.stringParam) then local posEntity = params.outParams[params.effectData.stringParam] if posEntity then params.forcePos = posEntity:GetLogicPos():cloneV2() BattleEffect.Call(params) else logging.error(LTAG.ERROR, "GWS : 策划注意! CallAtSomeEntityPos 没有检测到 事件中存在 : ", params.effectData.stringParam, "应该换个事件ID。 出错的BattleEffect : " ,params.effectData.ID) end else logging.error(LTAG.ERROR, "GWS : 策划注意! CallAtSomeEntityPos 没有配置stringParam 出错的BattleEffect : ", params.effectData.ID) end end function BattleEffect.CallBySkillJoystickTargetNum(params) repeat local isSuccess,skillJoystickData local intParams = params.effectData.intParams local skillBase = params.caster.components.skillBase if intParams[1] > 0 then isSuccess, skillJoystickData = DataSheetManager.SkillJoyStickData:TryGetDataByID(intParams[1]) else if skillBase.CurSkillData then isSuccess, skillJoystickData = DataSheetManager.SkillJoyStickData:TryGetDataByID(skillBase.CurSkillData.ID) end end if not isSuccess then logging.error(LTAG.ERROR, "HYW : cant find skillJoystickData @BattleEffect.CallBySkillJoystickTargetNum ID : ", params.effectData.intParams[1]) break end local joystickPos = FP.newV2(0, 0) local joystickDirX = skillBase.SkillJoystickOffsetX local joystickDirZ = skillBase.SkillJoystickOffsetZ if joystickDirX == nil or joystickDirZ == nil or (joystickDirX == FP.Const.Zero and skillBase.SkillJoystickOffsetZ == FP.Const.Zero) then joystickPos:Reset(params.caster.components.move.LogicRotateDir) else joystickPos:Reset(FP.tonumberV1(joystickDirX), FP.tonumberV1(joystickDirZ)) end joystickPos:Add(params.caster:GetLogicPos()) --↓ 目标数量的规则,目前因为没有加列,没办法特别好的指定。 现在仅能支持一种规则:当params.effectData.floatParams[1] == 0时,目标数量=params.effectData.floatParams[2] local chooseTargetCount if params.effectData.floatParams[1] == 0 then chooseTargetCount = params.effectData.floatParams[2] else logging.error(LTAG.ERROR, "HYW : 没有支持的规则, 可能需要在SkillJoystick表增加 chooseTargetCount 配置") chooseTargetCount = 5 end --↑ local targets if chooseTargetCount == 1 then targets = {TargetManager.GetTargetByJoystick(params.caster, skillJoystickData, joystickPos, chooseTargetCount, true)} else targets = TargetManager.GetTargetByJoystick(params.caster, skillJoystickData, joystickPos, chooseTargetCount, true, LuaConst.ETargetSortType.HP_PERCENT_LOW) --未完成HYW now now now now LuaConst.ETargetSortType.HP_PERCENT_LOW 应该配在双摇杆表里 end local targetCount = 0 if targets then targetCount = #targets end local maxCallCount = intParams[2] local minCallCount = intParams[3] if minCallCount > maxCallCount then local temp = minCallCount minCallCount = maxCallCount maxCallCount = temp end local callCount = FP.newV1(0) callCount:Reset(params.effectData.floatParams[1]):Mul(targetCount):Add(params.effectData.floatParams[2]) callCount = math.floor(FP.tonumberV1(callCount) + 0.5) if callCount < minCallCount then callCount = minCallCount end if callCount > maxCallCount then callCount = maxCallCount end if intParams[4] < 0 then local oldEffectData local randomCallBattleEffectData = DataSheetManager.BattleEffectData:GetDataByID(-intParams[4]) if not randomCallBattleEffectData then logging.error(LTAG.ERROR, "HYW : randomCallBattleEffectData nil Error @BattleEffect.CallBySkillJoystickTargetNum effectId : ", params.effectData.ID) break end if randomCallBattleEffectData.funcName ~= "RandomCall" then logging.error(LTAG.ERROR, "HYW : randomCallBattleEffectData.funcName ~= RandomCall Error! effectId : ", params.effectData.ID) break end oldEffectData = params.effectData params.effectData = randomCallBattleEffectData for i=1,callCount do if targetCount > 0 then local target = targets[(i - 1) % targetCount + 1] params.forceFireDir = FP.newV2(0, 0) params.forceFireDir:Reset(target:GetLogicPos()):Sub(params.caster:GetLogicPos()) params.forceFireDir:Normalize() if not string.isNilOrEmpty(params.effectData.stringParam) and i <= targetCount then --SystemManager.OnReceivePsEffect(target, params.effectData.stringParam, false) --old 无延迟,在小黑屋的无双时,会因为dummyInst跟visualInst转换是异步的导致高概率播不出特效 LevelManager.CurLevelFunc.exp:AddPlayPsEffectRequest(target, params.effectData.stringParam, 3) --new 延迟播特效 end end params.trackerTarget = target BattleEffect.RandomCall(params) end params.effectData = oldEffectData else local batchCallCountEndIndex = #intParams local batchCallCountStartIndex = 4 if batchCallCountEndIndex >= batchCallCountStartIndex then for i=1,callCount do local target = targets[(i - 1) % targetCount + 1] if targetCount > 0 then params.forceFireDir = FP.newV2(0, 0) params.forceFireDir:Reset(target:GetLogicPos()):Sub(params.caster:GetLogicPos()) params.forceFireDir:Normalize() if not string.isNilOrEmpty(params.effectData.stringParam) and i <= targetCount then --SystemManager.OnReceivePsEffect(target, params.effectData.stringParam, false)--old 无延迟,在小黑屋的无双时,会因为dummyInst跟visualInst转换是异步的导致高概率播不出特效 LevelManager.CurLevelFunc.exp:AddPlayPsEffectRequest(target, params.effectData.stringParam, 3)--new 延迟播特效 end end params.trackerTarget = target params.callBulletId = intParams[(i - 1) % (batchCallCountEndIndex - batchCallCountStartIndex + 1) + batchCallCountStartIndex] BattleEffect._Call(params) end end end until true end function BattleEffect.CallByBuffSkill(params) local buffSkillId = params.effectData.intParams[1] params.callBulletId = params.effectData.intParams[2] local buffSkillData = DataSheetManager.BuffSkillData:GetDataByID(buffSkillId) if buffSkillData.JoystickID > 0 then local skillJoystickData = DataSheetManager.SkillJoyStickData:GetDataByID(buffSkillData.JoystickID) if skillJoystickData then local skillBase = params.caster.components.skillBase if skillBase.SkillJoystickOffsetX ~= FP.Const.Zero or skillBase.SkillJoystickOffsetZ ~= FP.Const.Zero then local position = params.caster:GetLogicPos():cloneV2() position.x:Add(skillBase.SkillJoystickOffsetX) position.z:Add(skillBase.SkillJoystickOffsetZ) params.forcePos = position params.forceFireDir = FP.newV2(skillBase.SkillJoystickOffsetX, skillBase.SkillJoystickOffsetZ) params.forceFireDir:Normalize() else local buffSkillTarget = SystemManager.SearchTargetByBuffSkill(params.caster, buffSkillData) if buffSkillTarget then params.forceTarget = buffSkillTarget else -- gws:当找不到目标时,区域型的设置强制位置点为双摇杆配置的默认位置,方向型的设置强制朝向为施法者的朝向 if skillJoystickData.UEType == LuaConst.ESkillJoystickUEType.JOYSTICK_DIR then params.forceFireDir = params.caster:GetLogicRotateDir():cloneV2() elseif skillJoystickData.UEType == LuaConst.ESkillJoystickUEType.JOYSTICK_RANGE and #skillJoystickData.DefaultCallPos > 2 then params.forcePos = FP.newV2(0,5) FP.V2.GetOffsetToForward(params.caster:GetLogicRotateDir(),params.forcePos, params.forcePos) params.forcePos:Add(params.caster:GetLogicPos()) end end end BattleEffect._Call(params) else logging.error(LTAG.ERROR, "HYW : CallByBuffSkill Error! skillJoystickData nil Error! buffSkillData.ID : ", buffSkillData.ID) end else --- gws: 无双摇杆时的情况 local buffSkillTarget = SystemManager.SearchTargetByBuffSkill(params.caster, buffSkillData) if buffSkillTarget then params.forceTarget = buffSkillTarget end BattleEffect._Call(params) end end --发射弹射子弹 function BattleEffect.CallBounceMissile(params) local missile = params.outParams.missile if missile == nil then logging.error(LTAG.ERROR, "GWS : 事件参数没有missile参数!!无法执行BattleEffect.CallBounceMissile。 EffectID : ", params.effectData.ID) return end local fireNum = params.effectData.intParams[5] -- 一次发射几个 local mustFireAll = params.effectData.intParams[6] == 1 -- 当敌人数小于发射数时,怎样处理?1-强制全部发射(均摊); 0、不填-不强制都发射出去 local curFrameHitNum = #missile.CurFrameHitEntityIdList if curFrameHitNum == 0 then logging.error(LTAG.ERROR, "GWS : 事件发生时子弹并没有碰撞到敌人 !无法执行BattleEffect.CallBounceMissile。 EffectID : ", params.effectData.ID) return end local callId = params.effectData.intParams[1] -- callId local totalCount = params.effectData.intParams[2] -- 弹射的次数 local searchRadius = params.effectData.intParams[3] -- 搜索半径 local dynamicDmgRate = params.effectData.floatParams[1] -- 伤害变化倍数(0-1衰减倍数。1-n增强倍数) local noTargetThenOpt = params.effectData.intParams[4] -- 1= 找不到目标则停止弹射 2-找不到目标从旧的目标中找 3-找不到目标从新的目标中找再找不到则选择此次的受击目标 local dynamicDmgRateIsOnce = params.effectData.floatParams[2] == 1 -- 1=伤害变化倍数只生效一次,0=每次弹射都生效 local index = 0 local fromEntity for i = 1, fireNum do if curFrameHitNum >= i then fromEntity = LogicUpdateManager._entityDic[missile.CurFrameHitEntityIdList[i]] else if mustFireAll then index = i % curFrameHitNum if index == 0 then index = curFrameHitNum end fromEntity = LogicUpdateManager._entityDic[missile.CurFrameHitEntityIdList[index]] else break end end local bounceInfo = { leftCount = totalCount, dynamicDmgRate = dynamicDmgRate, dynamicDmgRateIsOnce = dynamicDmgRateIsOnce, isFirst = true, searchRadius = searchRadius, noTargetThenOpt = noTargetThenOpt, exclusions = {fromEntity }, } SystemManager.CallNextBounceBullet(params.caster, missile, bounceInfo, fromEntity, callId) end end function BattleEffect.SetSkillListByCharacterID(params) SystemManager.SetSkillListByCharacterID(params.target, params.effectData.intParams[1]) end function BattleEffect.RevertToOriginSkillList(params) SystemManager.RevertToOriginSkillList(params.target) end function BattleEffect.TryUseSkillBySkillIndex(params) if params.outParams.command then params.outParams.command.SkillIndex = params.effectData.intParams[1] else logging.error(LTAG.ERROR, "HYW : 事件参数没有command参数!!无法执行BattleEffect.TryUseSkillBySkillIndex。 EffectID : ", params.effectData.ID) end end -- 强制使用某技能(忽略各种技能释放的限制条件) function BattleEffect.ForceToUseSkill(params) local skillIndex = params.effectData.intParams[1] local skillData = params.target.components.skillBase:GetSkillDataBySkillIndex(skillIndex) params.target.components.move:SetWantRotateDir(nil) -- 清除一些cmd命令,防止此技能被cmd修改 if params.effectData.intParams[2] == 1 then -- 标记为时手动释放的技能,可触发ENTITY_SKILL_START=10101、等事件 params.target.components.record.BtnSkillId = skillData.ID end if params.effectData.intParams[3] == 1 then -- 是否重新选择技能释放目标 SystemManager.OnSearchTargetBySkill(params.target,skillData.ID) end SystemManager.SetNextState(LuaConst.StateType.Attack,params.target,skillData.ID,"",{}) end --skill强制进入CD function BattleEffect.ForceSkillEnterCD(params) local skillIndex = params.effectData.intParams[1] SystemManager.ForceEnterCD(params.target, skillIndex) end --在指定的一组键位中随机1个键位所代表的技能进入或补满CD function BattleEffect.ForceRandomSkillEnterOrFillCDInKeyPositions(params) local skillBaseComp = params.target.components.skillBase local pool = {} local hasAdjutant = (params.target.components.adjutant.AdjutantEntity ~= nil) for i,keyPos in ipairs(params.effectData.intParams) do if skillBaseComp:GetSkillDataByKeyPosition(keyPos) or (hasAdjutant and keyPos == LuaConst.ESkillKeyPosition.Adjutant) then pool[#pool + 1] = keyPos end end if #pool > 0 then local keyPos = pool[LogicRandom.GetIntegerValue(params.caster, 1, #pool, 435340481)] local skillData = skillBaseComp:GetSkillDataByKeyPosition(keyPos) if keyPos == LuaConst.ESkillKeyPosition.Adjutant then AdjutantSystem.ForceEnterCD(params.target) else local updateData = skillBaseComp.CurUpdateDataGroup[skillData.BelongTo] if skillData.Type == LuaConst.SkillType.Charge then SkillTimeSystem.ForceEnterCharge(params.target, skillData.BelongTo, updateData, true, true) elseif skillData.Type == LuaConst.SkillType.Enegy then SkillTimeSystem.ClearEnegy(params.target, skillData, updateData, true) --elseif 如果 then else if updateData.CD > FP.Const.Zero then SkillTimeSystem.SetSkillCurrentCD(params.target, skillData.BelongTo, tonumberV1(skillData.SkillCD * 1000)) else SystemManager.ForceEnterCDByKeyPos(params.target, keyPos) end end end BattleEventSystem.OnForceRandomSkillEnterOrFillCD(params.target, keyPos, skillData) end end --删除100006(在马上的buff)成功 时触发一堆逻辑(删除马,换state和动作) function BattleEffect.OnOffHorse(params) SystemManager.OnOffHorse(params.caster) end function BattleEffect.InterruptSkill(params) local notEnterCD = params.notEnterCD -- 中断技能,但是不进入CD if params.banKeyPosList == nil then SystemManager.InterruptSkill(params.target) else local curSkillData = params.target.components.skillBase:GetCurSkillData() if curSkillData then for i,v in ipairs(params.banKeyPosList) do if curSkillData.KeyPosition == v then SystemManager.InterruptSkill(params.target, nil, notEnterCD) break end end end end end function BattleEffect.IgnoreEnemyOfMonsterType(params) SystemManager.IgnoreEnemyOfMonsterType(params.target, params.effectData.intParams) end function BattleEffect.IgnoreEnemyOfCharacterType(params) SystemManager.IgnoreEnemyOfCharacterType(params.target, params.effectData.intParams) end --禁用移动摇杆(左摇杆) function BattleEffect.ForbidMoveJoystick(params) SystemManager.ForbidMoveJoystick(params.target) end function BattleEffect.SetUiOverrideSkillJoystick(params) EventSystem.Dispatch(EventID.UIBattle_SetOverrideSkillJoystick, params.target, params.effectData.intParams[1], params.effectData.intParams[2]) end function BattleEffect.CancelForbidMoveJoystick(params) SystemManager.CancelForbidMoveJoystick(params.target) end local SLIENT_KEY_POS_LIST = {LuaConst.ESkillKeyPosition.Slash, LuaConst.ESkillKeyPosition.Skill1, LuaConst.ESkillKeyPosition.Skill2, LuaConst.ESkillKeyPosition.Skill3, LuaConst.ESkillKeyPosition.Dodge, LuaConst.ESkillKeyPosition.MusouNormal, LuaConst.ESkillKeyPosition.Adjutant, LuaConst.ESkillKeyPosition.BuffSkill2,} function BattleEffect.Silent(params) SystemManager.BanKeyPositions(params.target, params.caster, params.banKeyPosList) params.notEnterCD = true BattleEffect.InterruptSkill(params) end function BattleEffect.SilentByCustom(params) params.banKeyPosList = params.effectData.intParams params.notEnterCD = true SystemManager.BanKeyPositions(params.target, params.caster, params.banKeyPosList) BattleEffect.InterruptSkill(params) end --禁用追攻技能 function BattleEffect.ForbidCastSkill(params) params.target.components.skillBase:SetCanUseCastSkill(params.effectData.intParams[1] == 1) end function BattleEffect.CancelSilent(params) SystemManager.CancelBanKeyPosition(params.target, params.caster) end function BattleEffect.ShowAllSkillSilentMask(params) FirstPersonEventDispatcher.Player_BanKeyPositions(params.target, {1,2,3,4,8,9,99999,99996}) end function BattleEffect.HideAllSkillSilentMask(params) FirstPersonEventDispatcher.Player_CancelBanKeyPosition(params.target) end function BattleEffect.RemoveParentEquipment(params) SystemManager.RemoveParentEquipment(params.target) end function BattleEffect.StartGrab(params) --↓ check -- local buffData = params.buff and params.buff:GetData() -- if buffData then -- if not buffData.IsRecordSource then -- logging.error(LTAG.ERROR, "HYW :策划注意 !只有记录来源的Buff才允许发动投技效果!错误的BuffID : " , buffData.BuffID) -- return -- end -- end --↑ --params.target --通知target的RenderEntity不再更新(有可能可以更新,因为保存的是引用) --caster的renderEntity挂上target的模型 SystemManager.StartGrab( params.caster, params.target, params.effectData.intParams[1], params.effectData.floatParams[1] or 0, params.effectData.floatParams[2] or 0, params.effectData.floatParams[3] or 0, params.effectData.floatParams[4] or 0, params.effectData.floatParams[5] or 0, params.effectData.floatParams[6] or 0, params.buff and params.buff.BuffID) end function BattleEffect.UpdateGrab(params) --暂时没需求,以后再做 logging.error(LTAG.ERROR, "HYW : UpdateGrab BattleEffect还没有完成,请立刻联系战斗程序") end function BattleEffect.StopGrab(params) SystemManager.StopGrab(params.caster, params.target, params.buff and params.buff.BuffID) end function BattleEffect.PlayPsEffect(params) local effect = params.effectData.stringParam SystemManager.ShowPSEffect(params.target, effect) end function BattleEffect.StopPsEffect(params) local effect = params.effectData.stringParam SystemManager.ShowPSEffect(params.target, effect) end --控制神兵铸魂天命盘子边的球显隐 function BattleEffect.ShowWeaponSoulPsEffect(params) if USE_LUA_STANDALONE then return end local isShow = params.effectData.intParams[1] == 1 local expEntity = params.target.ExpEntity expEntity:ShowWeaponHaloLightBallEffect(isShow) end function BattleEffect.Play3DSound(params) params.caster.ExpEntity:PlayObjSound(params.effectData.stringParam) end function BattleEffect.Stop3DSound(params) params.caster.ExpEntity:StopObjSound(params.effectData.floatParams[1]) end function BattleEffect.OriginPlayPsEffect(params) local originEntity = params.target:GetOriginEntity() SystemManager.ShowPSEffect(originEntity, params.effectData.stringParam) end function BattleEffect.PlayPsEffectByCampRelationType(params) local shouldPlayEffect = false local myCamp = LevelPlayerManager.MainEntityCampID if myCamp then-- 不用LogicUpdateManager._curEntity的原因是:当玩家还没出生时,但是怪物出生了,怪物要能播放特效。 if params.effectData.intParams[1] == LuaConst.ETargetCampType.ENEMY then shouldPlayEffect = params.caster:GetOriginEntity():GetCampID() ~= myCamp elseif params.effectData.intParams[1] == LuaConst.ETargetCampType.FRIEND_EXCLUDE_SELF then shouldPlayEffect = params.caster:GetOriginEntity():GetCampID() == myCamp and params.caster:GetOriginEntity() ~= LogicUpdateManager._curEntity --主视角safe,因为是纯视图调用 elseif params.effectData.intParams[1] == LuaConst.ETargetCampType.ONLY_SELF then shouldPlayEffect = params.caster:GetOriginEntity() == LogicUpdateManager._curEntity --主视角safe,因为是纯视图调用 elseif params.effectData.intParams[1] == LuaConst.ETargetCampType.FRIEND_INCLUDE_SELF then shouldPlayEffect = params.caster:GetOriginEntity():GetCampID() == myCamp else logging.error(LTAG.ERROR, "HYW : 不支持的类型 @PlayPsEffectByCampRelationType 类型 : ", params.effectData.intParams[1], " 出错的BuffID : ", params.buff and params.buff.BuffID or "nil") end end if shouldPlayEffect then SystemManager.ShowPSEffect(params.caster, params.effectData.stringParam, true) end end -- 尝试播放一个光效的特效(如果已存在则不播放) function BattleEffect.TryShowLightEffect(params) local lightEffectID = params.effectData.intParams[1] if not LevelManager.IsShowHeroLightEffect() and table.containValue(params.target._logicInitData.LightEffectIDs,lightEffectID) then SystemManager.ShowOrHideLightEffect(params.target, lightEffectID, true) end end --显示屏幕上方的蓝色tips,如果IDS可以format加参,会把target的名字显示在那里 function BattleEffect.ShowBuffDialogueWithName(params) local monsterFeature = params.caster.components.base.CurMonsterFeature if monsterFeature.CanShowBuffDialogue then ExpSystemManager.ShowDialogueWithName(params.target ,params.effectData.stringParam) end end function BattleEffect.StopBlendHurtAnim(params) params.caster.ExpEntity:SetBlendHurtAnim(false) end function BattleEffect.OpenBlendHurtAnim(params) params.caster.ExpEntity:SetBlendHurtAnim(true) end function BattleEffect.LockAI(params) SystemManager.OnLockAI(params.target,true) end function BattleEffect.UnlockAI(params) SystemManager.OnLockAI(params.target,false) end function BattleEffect.ChangeEntityAI(params) params.target.components.aiBase:ChangeAiByAIID(params.effectData.intParams[1]) end function BattleEffect.DisActiveDriver(params) local driveComp = params.target.components.drive if driveComp then local driver = driveComp.BeDrivedByEntity if params.effectData.intParams[1] == 1 then ExpSystemManager.OnSetVisible(driver.ExpEntity, false) else SystemManager.DisActive(driver ,true) end end end function BattleEffect.DeadDriver(params) local driveComp = params.target.components.drive if driveComp then local driver = driveComp.BeDrivedByEntity if params.outParams.killer then driver.components.record.KillerEntity = params.outParams.killer end SystemManager.OnDead(driver) SystemManager.SetNextState(LuaConst.StateType.Dead,driver , -1 , "dead_loop" , nil) end end --给司机加buff function BattleEffect.DriverAddBuff(params) local carEntity = params.target local driveComp = carEntity.components.drive if driveComp then local driver = driveComp:GetDriver() for i,buffID in ipairs(params.effectData.intParams) do SystemManager.AddBuff(driver, buffID, carEntity, nil, nil) end end end --给司机删buff function BattleEffect.DriverDeleteBuff(params) local carEntity = params.target local driveComp = carEntity.components.drive if driveComp then local driver = driveComp:GetLastDriver() for i,buffID in ipairs(params.effectData.intParams) do SystemManager.DeleteBuff(driver,buffID,carEntity) end end end --司机身上的buff传给车(buff时长不变) -- params.target 是司机 function BattleEffect.DriverBuffToCar(params) local buffId = params.effectData.intParams[1] local driverEntity = params.target local driveComp = driverEntity.components.drive if driveComp then local carEntity = driveComp:GetDrivedEntity() if carEntity then local updateData = driverEntity.components.buff:GetBuffUpdateData(buffId) local buffCtrlParam = RuntimeDataManager.New_BuffCtrl() buffCtrlParam.IsTracker = updateData.IsTracker buffCtrlParam.BuffOverRideFomula = updateData.BuffOverRideFomula buffCtrlParam.ForceLayer = updateData.BuffLayer buffCtrlParam.ForceDuration:Reset(updateData.BuffTimer) SystemManager.AddBuff(carEntity, buffId, carEntity, nil, buffCtrlParam) SystemManager.DeleteBuff(driverEntity,buffId,updateData.SourceEntity) end end end --车身上的buff传给司机(buff时长不变)-- -- params.target 是车 function BattleEffect.CarBuffToDriver(params) local buffId = params.effectData.intParams[1] local carEntity = params.target local driveComp = carEntity.components.drive if driveComp then local driverEntity = driveComp:GetLastDriver() if driverEntity then local updateData = carEntity.components.buff:GetBuffUpdateData(buffId) local buffCtrlParam = RuntimeDataManager.New_BuffCtrl() buffCtrlParam.IsTracker = updateData.IsTracker buffCtrlParam.BuffOverRideFomula = updateData.BuffOverRideFomula buffCtrlParam.ForceLayer = updateData.BuffLayer buffCtrlParam.ForceDuration:Reset(updateData.BuffTimer) SystemManager.AddBuff(driverEntity, buffId, driverEntity, nil, buffCtrlParam) SystemManager.DeleteBuff(carEntity,buffId,updateData.SourceEntity) end end end -- 只能给无敌的车使用,其他车不好使 。司机血量为0,车要陪葬。 function BattleEffect.DriverDeadTryDeadCar(params) local carEntity = params.target local driveComp = carEntity.components.drive if driveComp then local driver = driveComp:GetLastDriver() if (not driver:IsAlive()) and carEntity:IsAlive() then SystemManager.OnDead(carEntity) end end end function BattleEffect.SetBornItem(params) LevelItemManager.Global:SetBornItem(params.effectData.intParams, params.effectData.stringParam) end function BattleEffect.ActiveMission(params) local missionLevelItem = LevelItemManager.GetItemByID(params.effectData.intParams[1], LuaConst.LevelItemType.Mission) if missionLevelItem then missionLevelItem:DoAction(LuaConst.LevelActionType.Mission_Active) else logging.error(LTAG.ERROR, "HYW : missionLevelItem nil Warning @BattleEffect.ActiveMission") end end function BattleEffect.DeactiveMission(params) local missionLevelItem = LevelItemManager.GetItemByID(params.effectData.intParams[1], LuaConst.LevelItemType.Mission) if missionLevelItem then missionLevelItem:DoAction(LuaConst.LevelActionType.Mission_Deactive) else logging.error(LTAG.ERROR, "HYW : missionLevelItem nil Warning @BattleEffect.ActiveMission") end end function BattleEffect.SendLevelItemGlobalMessage(params) local messageId = params.effectData.intParams[1] LevelItemManager.Global:Notify_MonsterAIMessage(params.target, messageId) end function BattleEffect.ExpSetMissionHintByLevelItemId(params) if not USE_LUA_STANDALONE then params.target.ExpEntity.components.ui.missionHintLevelItemId = params.effectData.intParams[1] EventSystem.Dispatch(EventID.UIBattle_Mission_StartMissionByItemID, params.target, params.effectData.intParams[1]) end end -- 载具除了移动速度和转速 ,其他属性都继承主将的 function BattleEffect.AttrInheritFromDriverNoSpd(params) local carEntity = params.target local driveComp = carEntity.components.drive if driveComp then local driver = driveComp:GetDriver() local carAttrComp = carEntity.components.attr local driverAttrComp = driver.components.attr for i,attrName in ipairs(LuaConst.AttrIntType) do local value = driverAttrComp.InitAttr[attrName] if value then if attrName ~= LuaConst.AttrType.spd and attrName ~= LuaConst.AttrType.angvel then carAttrComp:SetAttrBaseValue(attrName,value) end end end carAttrComp:SetAttrBaseValue("hp",driverAttrComp.hp) carAttrComp:SetAttrBaseValue("sa",driverAttrComp.sa) carAttrComp:SetGs(driverAttrComp:GetGs()) end end -- 把载具的部分属性(血量和无双) 设置给 司机 ; 且恢复车的原生属性 function BattleEffect.SetDriverHpAndSaFromCarThenResetCar(params) local carEntity = params.target local driveComp = carEntity.components.drive if driveComp then local driver = driveComp:GetLastDriver() local carAttrComp = carEntity.components.attr local driverAttrComp = driver.components.attr driverAttrComp:SetAttrBaseValue("hp",carAttrComp.hp) driverAttrComp:SetAttrBaseValue("sa",carAttrComp.sa) for i,attrName in ipairs(LuaConst.AttrIntType) do local value = carAttrComp.InitAttr[attrName] if value then carAttrComp:SetAttrBaseValue(attrName,value) end end end end -- 杀死固定featureID的entity function BattleEffect.DeadEntityByFeatureID(params) for i,featureID in ipairs(params.effectData.intParams) do for i,checkEntity in ipairs(LogicUpdateManager.EntityList_Sync) do if checkEntity.components.base.CurMonsterFeature.ID == featureID and checkEntity:IsActive() then SystemManager.OnDead(checkEntity) end end for i,checkEntity in ipairs(LogicUpdateManager.EntityList_Normal) do if checkEntity.components.base.CurMonsterFeature.ID == featureID and checkEntity:IsActive() then SystemManager.OnDead(checkEntity) end end end end function BattleEffect.DeadEntity(params) SystemManager.OnDead(params.target) end -- 这个主要是为天罚buff用(吕布不能立刻死亡,其他武将能被立刻杀死) function BattleEffect.DeadEntityButSpecialHeroAddBuff(params) local specialHeroId = params.effectData.intParams[1] if specialHeroId == params.target:GetCharacterID() then SystemManager.AddBuff(params.target, params.effectData.intParams[2], params.caster, nil, nil) else SystemManager.OnDead(params.target) end end --有个细节,如果这个BattleEffect调用过早,则不会把params.caster加到count里 function BattleEffect.DeadOldestSlaveOfCasterIfCountBigger(params) local caster = params.caster local count = 0 local oldestSlaveEntity for j=1,#LogicUpdateManager.EntityList_Normal do local entity = LogicUpdateManager.EntityList_Normal[j] for i=2,#params.effectData.intParams do local monsterID = params.effectData.intParams[i] if entity:GetMasterEntity() == caster and entity:GetCharacterID() == monsterID and entity:IsAlive() and entity:IsActive() then count = count + 1 if oldestSlaveEntity == nil or entity._logicInitData.BirthFrame < oldestSlaveEntity._logicInitData.BirthFrame then oldestSlaveEntity = entity end break end end end if params.effectData.intParams[1] < count and oldestSlaveEntity then SystemManager.OnDead(oldestSlaveEntity) end end --调用该BattleEffect,会让target处于Decision_Patrol、Decision_ChangeTarget时,调用SystemManager.OnSearchTarget时可以选取身上挂有buffID为100047(AI寻敌不能被设置为target)的单位作为目标 function BattleEffect.IgnoreCanNotBeTargetBuffInDecisionPatrol(params) params.target.components.target.IgnoreCanNotBeTargetBuffInDecisionPatrolOrChangeTarget = true end -- 给目标entity 添加一个boxcollider ,派发一些玩法特殊的事件 ,和一些参数 function BattleEffect.AddCircleCollider(params) local range = FP.newV1(params.effectData.intParams[1]) local eventID = params.effectData.stringParam local entity = params.target local colliderID = ColliderManager.CreateCircleCollider(entity.components.move.LogicPos:cloneV2(),range) local enterCallBack = function(triggerEntity) EventSystem.Dispatch(EventID[eventID],triggerEntity, entity, true, colliderID) end -- true 标记进入 local exitCallBack = function(triggerEntity, exitReason) EventSystem.Dispatch(EventID[eventID],triggerEntity, entity, false, colliderID) end -- false 标记出来 ColliderManager.AddEnterEvent(colliderID, enterCallBack ) ColliderManager.AddExitEvent(colliderID, exitCallBack) local who = params.effectData.intParams[2] if who == 0 then -- 只是玩家 ColliderManager.ActiveCollider(colliderID, LogicUpdateManager.ValidSyncEntityIter) elseif who == 1 then --全部entity ColliderManager.ActiveCollider(colliderID, LogicUpdateManager.ValidAllEntityIter) end end -- 设置entity的玩家归属 function BattleEffect.SetOwnerPlayerID(params) local entity = params.target local playerID = params.effectData.intParams[1] entity.components.record:SetOwnerPlayerID(playerID) local ownerEntity = LevelPlayerManager.GetPlayerActiveEntity(playerID) if not ownerEntity or not ownerEntity:IsValid() then --如果没有归属 ,则销毁这个entity SystemManager.DeadQuit(entity) end end --特殊用法:使用出生buff的startEffect调用该效果时,可以让单位出生时的视图处于不可见状态(RenderEntity不可见,场景里的Entity的GameObject处于disactive状态) function BattleEffect.ForbidExpEntitySetVisible(params) params.target.ExpEntity:ForbidExpEntitySetVisible() end function BattleEffect.ApproveAndCallExpEntitySetVisible(params) params.target.ExpEntity:ApproveExpEntitySetVisible() if params.effectData.intParams[1] then params.target.ExpEntity:SetVisible(params.effectData.intParams[1] > 0) end end -- 显隐名字板 function BattleEffect.SetHeadUIVisible(params) local visible = params.effectData.intParams[1] == 1 and true or false LogicUpdateManager._curEntity.ExpEntity:SetModelUIVisible(visible) end --设置entity的名字 function BattleEffect.SetUIName(params) local entity = params.target local name = UIUtils.GetLocalizedTxt(Const_IDS[params.effectData.stringParam]) SystemManager.ChangeEntityName(entity, name) end --设置entity的名字,用ownerplayerid的name 和 buff剩余时长 function BattleEffect.SetUIName_OwnerName_BuffLeftTime(params) local entity = params.target local idsStr = UIUtils.GetLocalizedTxt(Const_IDS[params.effectData.stringParam]) if idsStr then local playerID = entity.components.record:GetOwnerPlayerID() local playerName = LevelPlayerManager.GetPlayerName(playerID) local buffTime = math.floor( tonumberV1(params.buffUpdateData.BuffTimer) ) local name = string.FormatByIdsKey(params.effectData.stringParam, playerName, buffTime) SystemManager.ChangeEntityName(entity, name) end end function BattleEffect.SetSaveRecordOfMonsterLvItem(params) if params.target:IsMonster() then LevelManager.CurLevelFunc:SetSaveRecordValue_LevelItem(params.target._logicInitData.OriginBornItemID, params.effectData.stringParam, params.effectData.intParams[1]) else logging.error(LTAG.ERROR, "HYW : 只有怪物才可以调用SetSaveRecordOfMonsterLvItem BattleEffect") end end function BattleEffect.AddBlindFlagIfTargetIsHero(params) if params.target:IsHero() then params.target.components.record:AddBlindFlag(params.buff and params.buff:GetBuffID(), params.caster.EntityID) end end function BattleEffect.CancelBlindFlagIfTargetIsHero(params) if params.target:IsHero() then params.target.components.record:CancelBlindFlag(params.buff and params.buff:GetBuffID(), params.caster.EntityID) end end function BattleEffect.KickDriverOff(params) local driveComp = params.target.components.drive if driveComp then local driver = driveComp.BeDrivedByEntity if driver then SystemManager.OffDrive(driver) end end end function BattleEffect.AddBattleProp(params) if #params.effectData.intParams == 1 then SystemManager.AddBattleProp(params.target, params.effectData.intParams[1]) -- 适配5更时候的旧功能 return end local entity = nil if params.effectData.intParams[1] == 0 then entity = params.target -- (交互物 、持有buff者) elseif params.effectData.intParams[1] == 1 then entity = params.caster -- (交互者 、施加buff者) end local unlimitedUse = params.effectData.intParams[3] == 1 SystemManager.AddBattleProp(entity, params.effectData.intParams[2], unlimitedUse) end function BattleEffect.DeleteBattleProp(params) SystemManager.DeleteBattlePropsByID(params.target, params.effectData.intParams[1], params.effectData.intParams[2] or 0) end function BattleEffect.AbortUseBattleProp(params) local entity = params.target SystemManager.AbortUseBattleProp(entity) end function BattleEffect.AddInteract(params) local interactEntity = params.target -- 交互物 SystemManager.AddInteract(interactEntity, params.effectData.intParams[1]) end function BattleEffect.DeleteInteract(params) local interactEntity = params.target -- 交互物 SystemManager.DeleteInteract(interactEntity, params.effectData.intParams[1]) end function BattleEffect.Interact_VisitedNPC(params) local interactEntity = params.target -- 交互npc EventSystem.Dispatch(interactEntity.Event_EntityVisited, interactEntity) end function BattleEffect.Interact_Drive(params) local entity = params.caster local interactEntity = params.target local interactIndex = params.outParams.interactIndex SystemManager.Drive(entity ,interactEntity, interactIndex) end function BattleEffect.Interact_OffDrive(params) local entity = params.caster local interactEntity = params.target local interactIndex = params.outParams.interactIndex SystemManager.OffDrive(entity,false,interactEntity, interactIndex) end function BattleEffect.Interact_TaskInteractFinish(params) local interactEntity = params.target local delaytime = params.effectData.intParams[1] if delaytime and delaytime > 0 then TimerUtil.Interval(function () EventSystem.Dispatch(EventID.Task_FinishInteract, interactEntity:GetCharacterID()) end,delaytime,1) else EventSystem.Dispatch(EventID.Task_FinishInteract, interactEntity:GetCharacterID())--发送交互物的ID end end function BattleEffect.Interact_DigTreasureBoxOver(params) local entity = params.caster local interactEntity = params.target local selectId = interactEntity:GetFeatureID() - LuaConst.DigTreasureRewardBoxBaseFeature EventSystem.Dispatch(EventID.DigTreasure_OpenBoxOver, selectId)--单人挖宝副本中发送某玩家挖宝箱完毕 SystemManager.DeadQuit(interactEntity) end function BattleEffect.Interact_DigTreasureOpenedMulOwnerBox(params) --local entity = params.caster local interactEntity = params.target SystemManager.DeadQuit(interactEntity) local playerID = interactEntity.components.record:GetOwnerPlayerID() EventSystem.Dispatch(EventID.DigTreasure_OpenedMulOwnerBox, playerID, params.buff)--多人挖宝副本,归属宝箱打开完成 end function BattleEffect.Interact_DigTreasureOpenMulDoor(params) --local entity = params.caster local interactEntity = params.target local doorId = interactEntity.components.record:GetVariable("digDoorID") EventSystem.Dispatch(EventID.DigTreasure_OpenMulDoor, doorId)--与盗洞交互完毕 ,打开挖宝界面 end -- 主城膜拜 function BattleEffect.Interact_Worship(params) --local entity = params.caster --local interactEntity = params.target local worshipType = params.effectData.intParams[1] -- 1 天地群雄 2-国战 3 天地群雄3v3 if worshipType == 1 then EventSystem.Dispatch(EventID.HeroMatch1v1_WorshipClick) elseif worshipType == 2 then -- 国战膜拜 EventSystem.Dispatch(EventID.Country_WorshipClick) elseif worshipType == 3 then EventSystem.Dispatch(EventID.HeroMatch3v3_WorshipClick) end end -- 悬赏任务交互完毕 function BattleEffect.Interact_WantedTask(params) local interactEntity = params.target -- 交互物 local uniqId = interactEntity.components.record:GetVariable("townUniqId") local collectServerDataId = interactEntity.components.record:GetVariable("collectServerDataId") EventSystem.Dispatch(EventID.WantedTask_InteractFinish, uniqId, collectServerDataId) end -- 和城镇的npc交互完毕(宠物捕捉、等) function BattleEffect.Interact_TownNpcEvent(params) local interactEntity = params.target -- 交互物 local uniqId = interactEntity.components.record:GetVariable("townUniqId") EventSystem.Dispatch(EventID[params.effectData.stringParam], uniqId) end --减少指定ID技能的CD function BattleEffect.ReduceCurrentCD(params) for i,skillID in ipairs(params.effectData.intParams) do SystemManager.ReduceSkillCurrentCD(params.target, skillID, params.effectData.floatParams[1]) end end --减少单位所有技能的CD function BattleEffect.ReduceCurrentCDOfAllSkill(params) SystemManager.ReduceCurrentCDOfAllSkill(params.target, params.effectData.floatParams[1]) end -- 如果outParams的杀手是 则百分比减少CD --【task】 典韦:在敌人身上上了标记后,当此敌人死亡,若是典韦杀死则减少CD 40%,如其他人则是60%。由于Check条件时无法识别buff来源者,故把条件写入到BattleEffect中 function BattleEffect.ReduceCurrentCDByPercentIfOriginCasterIsKiller(params) local overrideCD if params.outParams.killer == params.caster:GetOriginEntity() then overrideCD = params.effectData.floatParams[1] else overrideCD = params.effectData.floatParams[2] end BattleEffect.ReduceCurrentCDByPercent(params, overrideCD) end function BattleEffect.ReduceCurrentCDByPercentCheckKillerAndMissile(params) -- 这个是为了典韦特写的。 判断子弹和killer,然后用不同的值执行代码 local cdPercent if params.outParams.killer == params.caster:GetOriginEntity() and params.outParams.missileID == params.effectData.intParams[1] then cdPercent = params.effectData.floatParams[1] else cdPercent = params.effectData.floatParams[2] end local opEntity = params.target if params.effectData.stringParam == "casterOrigin" then opEntity = params.caster:GetOriginEntity() end for i,skillID in ipairs(params.effectData.intParams) do if i > 1 then SystemManager.ReduceSkillCurrentCDByPercent(opEntity, skillID, cdPercent) end end end --百分比减少CD function BattleEffect.ReduceCurrentCDByPercent(params, overrideCD) local opEntity = params.target if params.effectData.stringParam == "casterOrigin" then opEntity = params.caster:GetOriginEntity() end for i,skillID in ipairs(params.effectData.intParams) do SystemManager.ReduceSkillCurrentCDByPercent(opEntity, skillID, overrideCD or params.effectData.floatParams[1]) end end --百分比减少单位所有技能的CD function BattleEffect.ReduceCurrentCDOfAllSkillByPercent(params) SystemManager.ReduceCurrentCDOfAllSkillByPercent(params.target, params.effectData.floatParams[1]) end --百分比减少 事件中的技能 CD (充能的技能也受影响 ) function BattleEffect.ReduceEventSkillCDByPercent(params) local skillData = params.outParams.skillData if skillData == nil then logging.error(LTAG.ERROR, "[战斗策划注意]: battleEffect :ReduceEventSkillCDByPercent,在buffTrigger表中的对应事件不存在参数 skillData" ) return end SystemManager.ReduceSkillCurrentCDByPercent(params.target, skillData.ID, params.effectData.floatParams[1]) end -- 百分比减少宠物的技能CD(注意不是普攻) function BattleEffect.ReducePetSkillCDByPercent(params) SystemManager.ReducePetSkillCDByPercent(params.target, params.effectData.floatParams[1]) end -- 减少宠物的普攻或技能CD n 秒 (参数1是类型 参数2是毫秒) function BattleEffect.ReducePetNormalOrSkillCD(params) SystemManager.ReducePetNormalOrSkillCD(params.target, params.effectData.intParams[1], params.effectData.intParams[2]) end -- 减少宠物的普攻或技能CD n 秒 (intParams 参数1是类型, 参数2n是层数,2n+1是减少的CD--毫秒 ; ) function BattleEffect.ReducePetNormalOrSkillCDByBuffLayer(params) local buffLayer = params.buffUpdateData.BuffLayer local skillType = params.effectData.intParams[1] -- all = 0, Normal = 1, Skill = 2, for i=#params.effectData.intParams,3,-2 do if buffLayer >= params.effectData.intParams[i-1] then SystemManager.ReducePetNormalOrSkillCD(params.target, skillType, params.effectData.intParams[i]) break end end end -- 改变 事件中的eventBuffUpdateData的 持续时间 function BattleEffect.AddEventBuffDuration(params) local eventBuffUpdateData = params.outParams.eventBuffUpdateData if eventBuffUpdateData then local buffLayer = eventBuffUpdateData.BuffLayer if buffLayer > 0 then local timeVal = params.effectData.floatParams[1] eventBuffUpdateData.BuffTimer:Add(timeVal) end else logging.error(LTAG.ERROR, " 事件参数没有附带eventBuffUpdateData,无法使用AddEventBuffDuration效果,出错的BuffID : ", params.buff and params.buff.BuffID) end end -- 改变 buff的 持续时间 function BattleEffect.AddBuffDuration(params) local timeVal = params.effectData.floatParams[1] local dealBuff = params.effectData.intParams[1] if dealBuff and dealBuff > 0 then local buffObject = params.target.components.buff:GetBuffObjectByBuffId(dealBuff) if buffObject then local buffUpdateData if buffObject.BuffUpdateData then buffUpdateData = buffObject.BuffUpdateData else for i,_buffUpdateData in ipairs(buffObject.BuffUpdateList) do if _buffUpdateData.SourceEntity == params.caster then buffUpdateData = _buffUpdateData break end end end if buffUpdateData and buffUpdateData.BuffLayer > 0 then buffUpdateData.BuffTimer:Add(timeVal) end end else logging.error(LTAG.ERROR, " BattleEffect AddBuffDuration 没有设置buffID") end end -- 改变dot类buff的 调用频率(毫秒) function BattleEffect.ChangeDotBuffCallFrequency(params) local count = #params.effectData.intParams for i = 2, count do local newCallFrequency = FP.newV1(params.effectData.intParams[1]) -- 不放于循环外,避免多个指针指向同一个对象 params.target.components.buff:SetDotBuffCallFrequency(params.effectData.intParams[i], newCallFrequency) end end function BattleEffect.SetFightModeOfAllPlayer(params) SystemManager.SetFightModeOfAllPlayer(params.effectData.intParams[1]) end function BattleEffect.SetCanEnterCliff(params) SystemManager.SetCanEnterCliff(params.target,true) end function BattleEffect.CancelCanEnterCliff(params) SystemManager.SetCanEnterCliff(params.target,false) end --仅限单机战斗 function BattleEffect.TryStartConfrontation(params) local confrontations = LevelItemManager.Global:GetConfrontations() if not confrontations then return end if params.caster.components.autoFight.IsStandaloneAuto then --自动战斗不触发对峙 return end local disCheck = LuaConst.ConfrontationDistance local casterPos = params.caster:GetLogicPos() for i, v in pairs(confrontations) do local against = v.entity local comp_Attr = against.components.attr if FP.Greater(comp_Attr.am,0) and --check Armor not FP.Greater(comp_Attr:HitPointPercents(), v.hpChecker) and --check HP not FP.V2.IsDistanceGreater(casterPos, against:GetLogicPos(), disCheck) then --check Distance SystemManager.StartConfrontation(params.caster, against) LevelItemManager.Global:Notify_ConfrontationOccured(v) break end end end --满足条件的情况下进行大受击 function BattleEffect.TryBigHurt(params) local target = params.target --目标身上有"可被大受击"的buff local shouldAddBigHurt = false if params.effectData.intParams[1] == 1 then --强制模式,只要目标身上有LuaConst.SpecialBuffs.CanBeBigHurtWhenUsingSkill或者LuaConst.SpecialBuffs.CanBeBigHurtWhenNotUsingSkill就添加大受击 if target:HasBuff(LuaConst.SpecialBuffs.CanBeBigHurtWhenUsingSkill) or target:HasBuff(LuaConst.SpecialBuffs.CanBeBigHurtWhenNotUsingSkill) then shouldAddBigHurt = true end else if target:HasBuff(LuaConst.SpecialBuffs.InSkilling) then if target:HasBuff(LuaConst.SpecialBuffs.CanBeBigHurtWhenUsingSkill) then shouldAddBigHurt = true end else if target:HasBuff(LuaConst.SpecialBuffs.CanBeBigHurtWhenNotUsingSkill) then shouldAddBigHurt = true end end end if shouldAddBigHurt then SystemManager.AddBuff(target, LuaConst.SpecialBuffs.BigHurt, params.caster, nil, nil) end end --向这个buff的施法者(buff来源)移动 function BattleEffect.MoveToBuffSource(params) local entity = params.target -- 要操作的人 local posTarget = params.caster -- 要走向的人 local command = params.outParams.command --最后要输出的指令 command.SkillIndex = 0 --特殊指令 command.SpecialCommand = LuaConst.SpecialCommandType.None command.MoveDir:Reset(posTarget:GetLogicPos()):Sub(entity:GetLogicPos()):Normalize() command.RotateDir:Reset(command.MoveDir) end function BattleEffect.RestrictMoveToLogicRotateDir(params) params.target.components.move:SetRestrictMoveToLogicRotateDir(true) end function BattleEffect.CancelRestrictMoveToLogicRotateDir(params) params.target.components.move:SetRestrictMoveToLogicRotateDir(false) end --清除手动输入或者AI输入 function BattleEffect.ClearCommand(params) local command = params.outParams.command --最后要输出的指令 command.SkillIndex = 0 if LuaConst.CanClearSpecialCommandType[command.SpecialCommand] then command.SpecialCommand = LuaConst.SpecialCommandType.None end command.MoveDir:Reset() command.RotateDir:Reset() command.DecisionID = nil -- 让decision_node 不在执行Handle end --播放一个动画 function BattleEffect.PlayAnim(params) local entity = params.target -- 要操作的人 local anim = params.effectData.stringParam SystemManager.SetNextState(LuaConst.StateType.Common, entity, -1, anim, nil, params.buff) end function BattleEffect.ResetCurStateToMoveState(params) local entity = params.target -- 要操作的人 SystemManager.SetNextState(LuaConst.StateType.Move, entity, 0) end function BattleEffect.SetAnimIDOverride(params) local splits = string.split(params.effectData.stringParam, ",") SystemManager.SetAnimIDOverride(params.target, splits[1], splits[2]) end function BattleEffect.CancelAnimIDOverride(params) SystemManager.SetAnimIDOverride(params.target, params.effectData.stringParam, nil) end function BattleEffect._AddRewardRecord(params) local originEntity = params.target:GetOriginEntity() if originEntity:GetPlayerID() > 0 then LevelManager.CurLevelFunc:AddRewardRecord(originEntity:GetPlayerID(), params.id) else logging.error(LTAG.ERROR, "HYW : AddRewardRecord只能对玩家发动 target :", params.target:GetCharacterID(), " effectId : ", params.effectData.ID) end end function BattleEffect.AddRewardRecord(params) params.id = params.effectData.intParams[1] BattleEffect._AddRewardRecord(params) end function BattleEffect.AddRewardRecordByMonsterIdOfCaster(params) local monsterID = params.caster:GetCharacterID() local data = nil for _,v in DataSheetManager.BoxRewardData:GetEnumerator() do if v.MonsterID == monsterID then data = v break end end if data then params.id = data.ID BattleEffect._AddRewardRecord(params) else logging.error(LTAG.ERROR, "HYW : 找不到MonsterID : ", monsterID, "对应的BoxRewardData行") end end --纯视图BattleEffect function BattleEffect.SetExpInvisibleByCamp(params) ExpSystemManager.SetExpInvisibleByCamp(params.target) end function BattleEffect.SetMaterialByType(params) local matType = params.effectData.intParams[1] if matType == 1 then --这里是因为ExpEntity强行改了材质类型的枚举值,导致跟以前对不上了,所以这里只能强行重定向一下 matType = LuaConst.EMaterialType.FROZEN elseif matType == LuaConst.EMaterialType.FROZEN then matType = 1 end SystemManager.SetMaterialByType(params.target, matType) end function BattleEffect.ResetMaterial(params) SystemManager.ResetMaterial(params.target) end function BattleEffect.SetTargetRotateDirByCaster(params) local dirType = params.effectData.intParams[1] local dir = params.caster:GetLogicPos() - params.target:GetLogicPos() dir:Normalize() if dirType == 0 then --do nothing elseif dirType == 1 then dir:Mul(-1) else logging.error(LTAG.ERROR, "HYW : SetTargetRotateDirByCaster dirType Error! effectData ID : ", params.effectData.ID) end params.target.components.move:SetLogicRotateDir(dir) end function BattleEffect.SetRotateToSkillJoystickDir(params) local skillBase = params.target.components.skillBase if skillBase.SkillJoystickOffsetX ~= FP.Const.Zero or skillBase.SkillJoystickOffsetZ ~= FP.Const.Zero then params.target.components.move:SetLogicRotateDirXZ(FP.tonumberV1(skillBase.SkillJoystickOffsetX), FP.tonumberV1(skillBase.SkillJoystickOffsetZ)) end end function BattleEffect.SetWantRotateToSkillJoystickDir(params) local skillBase = params.target.components.skillBase if skillBase.SkillJoystickOffsetX ~= FP.Const.Zero or skillBase.SkillJoystickOffsetZ ~= FP.Const.Zero then params.target.components.move.WantRotateDir:Reset(FP.tonumberV1(skillBase.SkillJoystickOffsetX), FP.tonumberV1(skillBase.SkillJoystickOffsetZ)) end end function BattleEffect.StartTimeline(params) SystemManager.PlayTimeline(params.effectData.stringParam, params.effectData.intParams[1] == 1, -1, nil) end function BattleEffect.PlayTimelineJustExp(params) if USE_LUA_STANDALONE then return end AuxUtil.StartTimeline(params.effectData.stringParam, false, -1, false, nil, 0, 0) end -- 170 版本才有的接口 function BattleEffect.PlayTimelineWithEntity(params) if USE_LUA_STANDALONE then return end if GameAppInfo.IsVersionGreaterThan117000() then return end local pause = params.effectData.intParams[1] == 1 local duration = params.effectData.floatParams[1] AuxUtil.StartTimeLineWithEntity(params.effectData.stringParam, pause, duration, params.target.ExpEntity.RenderEntity, nil, 0, 0) end -- 暴风专用:boss出现后换UI展示 function BattleEffect.StormBossChangeBattleUI(params) local state = params.effectData.intParams[1] -- 0:正常倒计时 ; 1:n秒后进入狂暴 ;2:狂暴中 local second = params.effectData.intParams[2] or 0 -- second ,当state==1时,才有用 EventSystem.Dispatch(EventID.UI_Storm_OnBossStateChange, state, second) end function BattleEffect.ShowTips(params) local entity = params.target if params.effectData.intParams[2] == 1 then entity = params.caster end ExpLevelManager.ShowTips(entity, params.effectData.stringParam, params.effectData.intParams[1] ~= 1) end function BattleEffect.ShowLevelDialogue(params) EventSystem.Dispatch(EventID.UI_MainShowDialogue, params.effectData.stringParam) end -- 播放一个跑马灯(终结连杀),string 带三个参数 杀手name、target的name、target连杀 function BattleEffect.ShowMarqueeByKillerAndDeadAndCombKill(params) local killer = params.target.components.record.KillerEntity if killer then local killerName = killer._logicInitData.Name local targetName = params.target._logicInitData.Name local comboKillNum = LevelManager.CurLevelFunc:GetPlayerComboKillNum(params.target:GetPlayerID()) ExpSystemManager.ShowMarquee(params.effectData.stringParam, killerName, targetName, comboKillNum, params.effectData.intParams[1] == 1) end end -- 战报 function BattleEffect.ShowBattleReport(params) local entity if params.effectData.intParams[1] == 1 then -- 谁的 entity = params.caster -- buff来源者、交互者 else entity = params.target -- buff持有者、交互物 end local str = "" if params.effectData.intParams[2] == 1 then -- 用名字补充%s str = entity._logicInitData.Name if string.isNilOrEmpty(str) then str = UIUtils.GetLocalizedTxt(Const_IDS[entity.components.base.CurCharacterData.MonsterNameIDS]) end elseif params.effectData.intParams[2] == 2 then -- 用势力名字补充 %s local sourceData = LevelPlayerManager.GetPlayerInfoByPlayerIDInRoom(entity:GetPlayerID()) str = sourceData.guildName elseif params.effectData.intParams[2] == 3 then -- 用 国家名字+玩家名字 补充 %s local sourceData = LevelPlayerManager.GetPlayerInfoByPlayerIDInRoom(entity:GetPlayerID()) local countryData = DataSheetManager.CountryBase:GetDataByID(sourceData.countryId) if countryData then local countryName = UIUtils.GetLocalizedTxt(Const_IDS[countryData.CountryName]) or "" str = "[" .. countryName .. "]" .. entity._logicInitData.Name else str = entity._logicInitData.Name end end local showType = params.effectData.intParams[3] -- 0-黄 1-蓝 2-鼓 默认黄 local showTime = params.effectData.floatParams[1] -- 展示时长(只限制于 黄、蓝)单位:秒 local justPlayerSelfShow = params.effectData.intParams[4] == 1 -- 是否仅仅对 params.effectData.intParams[1]的人 可见。 ExpSystemManager.ShowBattleReport(entity, params.effectData.stringParam, str, showType, showTime, justPlayerSelfShow) end --显示非实时属性改变的tips(非实时属性:除了血量、无双值、护盾、霸体值以外的属性) function BattleEffect.ShowNoRealTimeAttrChangeTips(params) local outParams = params.outParams if not AttrSystem.IsRealtimeAttrType(outParams.attrType) then ExpSystemManager.ShowNoRealTimeAttrChangeTips(outParams.target.ExpEntity, outParams.caster, outParams.attrType, outParams.delta, params.effectData.intParams[1]) end end function BattleEffect.SetClimbTowerBossRageTips(params) EventSystem.Dispatch(EventID.UIBattle_RefereshRampageInClimbTower, params.effectData.stringParam, params.buff and params.buff:GetBuffID()) end function BattleEffect.StartClimbTowerBossRageTips(params) EventSystem.Dispatch(EventID.UIBattle_RefereshRampageInClimbTower, params.effectData.stringParam, 0) end function BattleEffect.ShowDevelopEffectBuffTips(params) EventSystem.Dispatch(EventID.UIBattle_DevelopEffect_Tips, params.target, params.effectData.intParams[1]) end function BattleEffect.ShowExpelMonsterTips(params) EventSystem.Dispatch(EventID.UI_ExpelMonster_BossTips, params.effectData.intParams[1], params.effectData.stringParam) end local GUILDWAR_TIPS_TYPE_CHONGCHE = 1 local GUILDWAR_TIPS_TYPE_BOMB = 2 --势力战:刷新头顶炸弹的状态(纯表现的) function BattleEffect.SetGuildWarBombUI(params) params.target.ExpEntity:SetModelUI_GuildBossBomb(params.effectData.intParams[1] == 1, params.effectData.floatParams[1]) end function BattleEffect.ShowGuildWarPreSuperChongCheTips(params) if LogicUpdateManager._curEntity then --主视角safe ,下面是纯视图代码 if LogicUpdateManager._curEntity.CampID == params.caster.CampID then if params.caster.CampID == LevelManager.CurLevelFunc.chongCheOccupierCampID then EventSystem.Dispatch(EventID.UI_ShowGuildWarTips, Const_IDS["IDS_GuildWar_Type1AllyInfoCode2"], GUILDWAR_TIPS_TYPE_CHONGCHE) else EventSystem.Dispatch(EventID.UI_ShowGuildWarTips, Const_IDS["IDS_GuildWar_Type1AllyInfoCode1"], GUILDWAR_TIPS_TYPE_CHONGCHE) end end end end function BattleEffect.ShowGuildWarSuperChongCheBornTips(params) if LogicUpdateManager._curEntity then --主视角safe ,下面是纯视图代码 if LogicUpdateManager._curEntity.CampID ~= params.caster.CampID then EventSystem.Dispatch(EventID.UI_AddTipsMsg, Const_IDS["IDS_GuildWar_ErrorCode1"]) end end end function BattleEffect.HideGuildWarSuperChongCheTips(params) if LogicUpdateManager._curEntity then --主视角safe ,下面是纯视图代码 if LogicUpdateManager._curEntity.CampID == params.caster.CampID then EventSystem.Dispatch(EventID.UI_CloseGuildWarTips, GUILDWAR_TIPS_TYPE_CHONGCHE) -- 且关闭冲车tips end end end function BattleEffect.ShowGuildWarBombBornTips(params) if LogicUpdateManager._curEntity then --主视角safe ,下面是纯视图代码 if LogicUpdateManager._curEntity.CampID == params.caster.CampID then EventSystem.Dispatch(EventID.UI_ShowGuildWarTips, Const_IDS["IDS_GuildWar_Type2AllyInfoCode1"], GUILDWAR_TIPS_TYPE_BOMB) end end end function BattleEffect.ShowGuildWarBombPickedTips(params) if USE_LUA_STANDALONE then return end if LogicUpdateManager._curEntity then --主视角safe ,下面是纯视图代码 if LogicUpdateManager._curEntity.CampID == params.caster.CampID then EventSystem.Dispatch(EventID.UI_MainShowBattleReport, string.FormatByIdsKey("IDS_GuildWar_Type2AllyInfoCode2", params.caster._logicInitData.Name)) EventSystem.Dispatch(EventID.UI_CloseGuildWarTips, GUILDWAR_TIPS_TYPE_BOMB) -- 且关闭炸弹tips else EventSystem.Dispatch(EventID.UI_AddTipsMsg, Const_IDS["IDS_GuildWar_ErrorCode2"]) end end end function BattleEffect.HideGuildWarBombTips(params) if LogicUpdateManager._curEntity then --主视角safe ,下面是纯视图代码 if LogicUpdateManager._curEntity.CampID == params.caster.CampID then EventSystem.Dispatch(EventID.UI_CloseGuildWarTips, GUILDWAR_TIPS_TYPE_BOMB) end end end function BattleEffect._CreateHookMissile(params) if params.hookStartEntity and params.hookStartEntity:IsAlive() and params.hookStartEntity:IsActive() and params.hookEntity and params.hookEntity:IsAlive() and params.hookEntity:IsActive() then local callBulletData = params.caster:GetCallData(params.callBulletId) if callBulletData then -- local sourceEffectPlayID = nil --params.buff and params.buff.EffectPlayID or nil 。注释掉的原因:子弹就能配置特效无需配置在buff特效上,导致buff特效多播放一次。 MissileManager.CreateHookMissileAndFire(params.caster, params.hookEntity, callBulletData, nil, params.hookStartEntity) else logging.error(LTAG.ERROR, "HYW : callBulletData为空,无法创建钩子子弹" .. " effectData ID : " , params.effectData.ID , " params.callBulletId : " , params.callBulletId) end --else --do nothing 就不创建钩子子弹了 end end function BattleEffect.CreateHookMissile(params) repeat params.hookStartEntity = params.caster params.hookEntity = params.target params.callBulletId = params.effectData.intParams[1] BattleEffect._CreateHookMissile(params) until true end function BattleEffect.BreakAllHookOfCasterAndTarget(params) MissileManager.BreakHookOf2Entities(params.caster, params.target) end function BattleEffect.CreateHookMissileToRandomHero(params) local count = #LogicUpdateManager.EntityList_Sync if count >= 2 then local start = LogicRandom.GetIntegerValue(params.caster, 1, count, 3934959) local hookStartEntity local hookEntity if count == 2 then --只有两个英雄 hookStartEntity = LogicUpdateManager.EntityList_Sync[(start - 1) % 2 + 1] hookEntity = LogicUpdateManager.EntityList_Sync[(start) % 2 + 1] else local index = start local checkEntity for i=1,count do checkEntity = LogicUpdateManager.EntityList_Sync[index] if checkEntity:IsHero() and checkEntity:IsAlive() and checkEntity:IsActive() then if hookStartEntity == nil then hookStartEntity = checkEntity else hookEntity = checkEntity break end end index = index + 1 if index > count then index = index - count end end end if hookStartEntity and hookEntity then params.hookStartEntity = hookStartEntity params.hookEntity = hookEntity params.callBulletId = params.effectData.intParams[1] BattleEffect._CreateHookMissile(params) end --else --do nothing 不够两个英雄,不创建 end end --创建一个钩子子弹到指定ID的召唤物上 function BattleEffect.CreateHookMissileToSlave(params) local hookEntity local characterID = params.effectData.intParams[2] for i,v in ipairs(LogicUpdateManager.EntityList_Normal) do if v:GetMasterEntity() == params.target and v:GetCharacterID() == characterID then hookEntity = v break end end if hookEntity then params.hookStartEntity = params.target params.hookEntity = hookEntity params.callBulletId = params.effectData.intParams[1] BattleEffect._CreateHookMissile(params) end end --召唤物 创建一个钩子子弹到自己的最原始主人上 。如果已有则不创建 function BattleEffect.CreateHookMissileToMasterIfNo(params) local hookEntity if params.effectData.intParams[2] == 1 then hookEntity = params.target:GetOriginEntity() elseif params.effectData.intParams[2] == 2 then hookEntity = params.caster:GetOriginEntity() end if MissileManager.HasHookBetweenAToB(params.target, hookEntity) then return end if hookEntity then params.hookStartEntity = params.target params.hookEntity = hookEntity params.callBulletId = params.effectData.intParams[1] BattleEffect._CreateHookMissile(params) end end local CHMTME_TARGET_FIND_PARAM function BattleEffect._TryInitCHMTME_TARGET_FIND_PARAM() if not CHMTME_TARGET_FIND_PARAM then CHMTME_TARGET_FIND_PARAM = { ignoreCanNotBeTargetBuff = false, ignoreBeSkillTargetBuff = true, ignoreEnemyListValid = true, regionParams = { shapeType = LuaConst.ERegionShapeType.CIRCLE, shapeNumParams = {}, }, sortParams = {}, } end end function BattleEffect.CreateHookMissilesToMultiEntities(params) if params.target then local missileID = params.effectData.intParams[1] local count = params.effectData.intParams[2] local campType = params.effectData.intParams[3] local radius = params.effectData.floatParams[1] BattleEffect._TryInitCHMTME_TARGET_FIND_PARAM() CHMTME_TARGET_FIND_PARAM.campType = campType CHMTME_TARGET_FIND_PARAM.regionParams.shapeNumParams[1] = radius CHMTME_TARGET_FIND_PARAM.sortParams.sortType = params.effectData.intParams[4] or LuaConst.ETargetSortType.DIST_NEAR local targets = TargetManager.GetTargets(params.target, CHMTME_TARGET_FIND_PARAM, count) if targets and #targets > 0 then for i,target in ipairs(targets) do params.hookStartEntity = params.target params.hookEntity = targets[i] params.callBulletId = missileID BattleEffect._CreateHookMissile(params) end end end end --补充钩子到指定数量 function BattleEffect.ReplenishHookMissilesToMultiEntities(params) local missileID = params.effectData.intParams[1] local count = params.effectData.intParams[2] local campType = params.effectData.intParams[3] local radius = params.effectData.floatParams[1] BattleEffect._TryInitCHMTME_TARGET_FIND_PARAM() CHMTME_TARGET_FIND_PARAM.campType = campType CHMTME_TARGET_FIND_PARAM.regionParams.shapeNumParams[1] = radius CHMTME_TARGET_FIND_PARAM.sortParams.sortType = params.effectData.intParams[4] or LuaConst.ETargetSortType.DIST_NEAR --甄姬棱镜发动的 ReplenishHookMissilesToMultiEntities,caster是甄姬,target是棱镜 local existCount = MissileManager.GetHookCountOfMissileID(params.target, missileID) if existCount < count then local targets = TargetManager.GetTargets(params.target, CHMTME_TARGET_FIND_PARAM, count) if targets and #targets > 0 then for i,target in ipairs(targets) do if not MissileManager.HasHookBetween(params.target, target) then existCount = existCount + 1 params.hookStartEntity = params.target params.hookEntity = target params.callBulletId = missileID BattleEffect._CreateHookMissile(params) if existCount >= count then break end end end end end end function BattleEffect.CreateHookMissileIfNoHookBetween(params) repeat if MissileManager.HasHookBetween(params.caster, params.target) then break end if params.effectData.intParams[2] and params.effectData.intParams[2] > 0 and MissileManager.GetHookCount(params.caster) >= params.effectData.intParams[2] then break end BattleEffect.CreateHookMissile(params) until true end function BattleEffect.BreakHookMissileByEvent(params) if params.outParams.missile then params.outParams.missile:BreakHook(false) else logging.error(LTAG.ERROR, "HYW : 事件参数不包含missile,无法发动BreakHookMissileByEvent效果,BattleEffect的ID : " , params.effectData.ID) end end function BattleEffect.CancelMissile(params) for i,missileID in ipairs(params.effectData.intParams) do MissileManager.CancelMissileOfAttackerByMissileID(missileID, params.target) end end function BattleEffect.CancelEventMissile(params) if params.outParams.missile then params.outParams.missile:Cancelled() end end function BattleEffect.CancelMasterMissile(params) local master = params.caster:GetMasterEntity() if master then for i,missileID in ipairs(params.effectData.intParams) do MissileManager.CancelMissileOfAttackerByMissileID(missileID, master) end else logging.error(LTAG.ERROR, "HYW : 不存在主人,无法删除主人的子弹") end end --销毁target的子弹及其不可被他人打中的召唤物+此召唤物的子弹 function BattleEffect.CancelMissileAndEmptySlave(params) local opEntity = params.target MissileManager.CancelMissileOfAttacker(opEntity) for i= #LogicUpdateManager.EntityList_Normal, 1, -1 do local entity = LogicUpdateManager.EntityList_Normal[i] if not entity.isAdjuntant and entity._logicInitData.RootMasterEntity == opEntity and entity.isNotTriggerByOthers and entity:IsActive() then MissileManager.CancelMissileOfAttacker(entity) SystemManager.DeadQuit(entity) end end end --销毁call表中配置了ParentDead的子弹及其召唤物+此召唤物的子弹 function BattleEffect.CancelMissileAndSlaveOfParentDead(params) local opEntity = params.target MissileManager.CancelParentDeadMissileOfAttacker(opEntity) local deadComp = opEntity.components.dead if deadComp then local followList = deadComp:GetFollowDeadList() if followList then for i,sonEntity in ipairs(followList) do sonEntity._logicInitData.MasterEntity = nil MissileManager.CancelMissileOfAttacker(sonEntity) -- 这个地方就是清理 子entity的所有子弹 if sonEntity:IsActive() then SystemManager.DeadQuit(sonEntity) end end deadComp:ResetFollowDeadList() end end end -- 中断事件参数中的子弹的技能的特效 function BattleEffect.StopMissileSkillPSEffect(params) if params.outParams.missile then local skillID = params.outParams.missile.SkillID local skillResource = params.target:GetSkillData(skillID).SkillResource local skillResourcePath = params.target.components.replace:GetReplaceSkillPath(skillID, skillResource) SystemManager.StopPSEffect(params.target,skillResourcePath) else logging.error(LTAG.ERROR, "GWS : 策划注意 :BattleEffect的BreakMissileSkillPSEffect 的执行没有依赖于子弹事件") end end --删除指定MissileID的、钩上自己(不是自己发射的)的钩子子弹 function BattleEffect.BreakHookMissileByIDAsHookEntity(params) MissileManager.BreakHookMissileByIDAsHookEntity(params.effectData.intParams[1], params.target) end --删除指定MissileID的、由行为主体发射的钩子子弹 function BattleEffect.BreakHookMissileByIDAsAttacker(params) MissileManager.BreakHookMissileByIDAsAttacker(params.effectData.intParams[1], params.target) end --删除指定MissileID的、钩上自己 和 指定entity的钩子子弹 function BattleEffect.BreakHookMissileByIDAndEntity(params) local hookEntity if params.effectData.intParams[2] == 1 then hookEntity = params.target:GetOriginEntity() elseif params.effectData.intParams[2] == 2 then hookEntity = params.caster:GetOriginEntity() end MissileManager.BreakHookMissileByIDAndEntity(params.effectData.intParams[1], params.target, hookEntity) end function BattleEffect.OpenUIView(params) EventSystem.Dispatch(EventID.Level_OpenUIView, params.effectData.stringParam) end --region gws 修改事件中的子弹的某些数值 -- 修改子弹的伤害范围 function BattleEffect.EventMissileChangeShapeParam(params) local missile = params.outParams.missile if missile then missile:OverrideShapeParam1(FP.newV1(params.effectData.floatParams[1])) missile:OverrideShapeParam2(FP.newV1(params.effectData.floatParams[2])) missile:OverrideShapeParam3(FP.newV1(params.effectData.floatParams[3])) missile:TryCreateAttackRange(missile.Attacker)-- 改变下工具:现实子弹的范围大小 else logging.error(LTAG.ERROR, "GWS : 事件参数不包含missile,无法发动EventMissileChangeShapeParam效果,BattleEffect的ID : " , params.effectData.ID) end end -- 修改子弹的特效大小 function BattleEffect.EventMissileChangePsEffectScale(params) local missile = params.outParams.missile if missile and missile.ExpMissile then missile.ExpMissile:SetPsEffectScale(params.effectData.floatParams[1]) end end -- 修改环绕子弹的环绕半径 function BattleEffect.EventMissileAddAroundRadius(params) local missile = params.outParams.missile if missile then missile.PosOffsetDistance:Add(params.effectData.floatParams[1]) end end -- 修改环绕子弹的环绕角速度 function BattleEffect.EventMissileAddAngleSpeed(params) local missile = params.outParams.missile if missile then missile:OverrideAngleSpeedAdd(params.effectData.floatParams[1], params.effectData.intParams[1] == 1) end end --endregion gws 修改子弹的某些数值 --region 修改现有子弹的某些值 function BattleEffect.MissileAddAngleSpeed(params) local missileID = params.effectData.intParams[1] local addVal = params.effectData.floatParams[1] MissileManager.AddAngleSpeed(missileID,addVal) end --endregion 修改现有子弹的某些值 --资源战场↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ --添加资源到击杀者的阵营, 资源量会读取表的参数 function BattleEffect.AddResourceToKillerCampByResData(params) if params.caster:IsMonster() then local killer = params.caster.components.record.KillerEntity if killer then local data = DataSheetManager.MonsterResourcePoint:GetDataByMonsterID(params.caster:GetCharacterID()) if data then LevelManager.CurLevelFunc:ChangeResourceAmountOfCamp(killer:GetCampID(), data.Amount) --这里不传killer,这样就不会给killer算资源积分 else logging.error(LTAG.ERROR, "HYW : 怪物没有配置MonsterResourcePoint数据,怪物ID : ", params.caster:GetCharacterID()) end end end end function BattleEffect.AddResourceToTargetPlayerByEntity(params) local target = nil if params.effectData.stringParam and params.effectData.stringParam ~= "" then target = params.outParams[params.effectData.stringParam] else target = params.target end if target then if target:IsHero() then local amount = params.caster.components.record.resourceAmount if amount and amount > 0 then LevelManager.CurLevelFunc:ChangeResourceAmountOfPlayer(target, target:GetPlayerID(), amount, "touch") end end end end function BattleEffect.AddResourceToTargetPlayerByResData(params) local target = nil if params.effectData.stringParam and params.effectData.stringParam ~= "" then target = params.outParams[params.effectData.stringParam] else target = params.target end if target then if target:IsHero() then local data = DataSheetManager.MonsterResourcePoint:GetDataByMonsterID(params.caster:GetCharacterID()) if data then LevelManager.CurLevelFunc:ChangeResourceAmountOfPlayer(target, target:GetPlayerID(), data.Amount, params.effectData.stringParam) else logging.error(LTAG.ERROR, "HYW : 怪物没有配置MonsterResourcePoint数据,怪物ID : ", params.caster:GetCharacterID()) end end end end --添加资源到击杀者的阵营, 资源量会读取BattleEffect表的参数 function BattleEffect.AddResourceToKillerCampByData(params) local killer = params.caster.components.record.KillerEntity if killer then LevelManager.CurLevelFunc:ChangeResourceAmountOfCamp(killer:GetCampID(), params.effectData.intParams[1]) end end --添加资源到击杀者的阵营, 资源量会读取单位的携带量 function BattleEffect.AddResourceToKillerCampByEntity(params) local amount = params.caster.components.record.resourceAmount if amount and amount > 0 then params.caster.components.record.resourceAmount = 0 LevelManager.CurLevelFunc:ChangeResourceAmountOfCamp(killer:GetCampID(), amount) end end --添加玩家资源,资源量会读取BattleEffect表的参数 function BattleEffect.AddResourceToKillerPlayerByData(params) local killer = params.caster.components.record.KillerEntity if killer then LevelManager.CurLevelFunc:ChangeResourceAmountOfPlayer(killer, killer:GetPlayerID(), params.effectData.intParams[1]) end end --加分,不同关卡有不同的加分逻辑 function BattleEffect.AddScore(params) if LevelManager.CurLevelFunc.AddScore then local target = params.target if not target.isHero then --不是英雄的情况下,仅限载具的英雄类型驾驶者能获取积分,非载具都不可获取 target = target.components.drive and target.components.drive.BeDrivedByEntity end if target and target.isHero then LevelManager.CurLevelFunc:AddScore(target, params.effectData.intParams[1]) end else logging.error(LTAG.ERROR, "HYW : 警告!试图在不存在加分功能的玩法调用 BattleEffect.AddScore , 关卡ID : ", LevelManager.GetCurLevelID(), " EffectID : ", params.effectData.ID) end end --添加一个ServerBattleAction请求,请求会由服务器自主响应,但不是所有玩法服务器都会响应 function BattleEffect.ServerBattleAction(params) LevelManager.CurLevelFunc:AddServerBattleActionRequest(params.effectData.intParams[1]) end --添加一个指定campID的ServerBattleAction请求,请求会由服务器自主响应,但不是所有玩法服务器都会响应 function BattleEffect.ServerBattleActionByCampID(params) LevelManager.CurLevelFunc:AddServerBattleActionRequest(params.effectData.intParams[1] + params.target:GetCampID() - 1) end local _fakeCommand = {} --以服务器插帧的形式添加buff,实际调用的不一定是服务器插帧,也可能是普通战斗逻辑。 --添加这个接口的目的是要利用服务插帧添加buff的 给将来出生的单位也添加这个buff 的机制。 function BattleEffect.DoServerBattleActionAddBuff(params) _fakeCommand.SkillIndex = 1 _fakeCommand.MoveType = 0 _fakeCommand.DirAngle = 0 LevelManager.CurLevelFunc:DoServerActionByID(nil, params.effectData.intParams[1], _fakeCommand) end --上交玩家资源 function BattleEffect.HandInResource(params) LevelManager.CurLevelFunc:HandInResourceOfEntity(params.target) end function BattleEffect.DropResourceOfPlayer(params) --logging.error(LTAG.ERROR, "HYW : DropResourceOfPlayer") if params.caster:IsHero() then local playerID = params.caster:GetPlayerID() local playerAmount = LevelManager.CurLevelFunc:GetResourceAmountOfPlayer(playerID) if playerAmount and playerAmount > 0 then params.amount = math.ceil(playerAmount * params.effectData.floatParams[1]) if params.amount >= playerAmount then params.amount = playerAmount end if params.amount >= 1 then --掉落数量大于等于1才掉落 --LevelManager.CurLevelFunc:ChangeResourceAmountOfPlayer(params.caster, playerID, -params.amount) LevelManager.CurLevelFunc:DropResourceAmountOfPlayer(params.caster, playerID, -params.amount) BattleEffect._DropResourceByAmount(params) end elseif playerAmount == 0 then --策划需求 等于0也需要通知LevelFunc LevelManager.CurLevelFunc:DropResourceAmountOfPlayer(params.caster, playerID, 0) end else logging.error(LTAG.ERROR, "HYW : 只有英雄单位才可以掉落资源!!! BattleEffect ID : ", params.effectData.ID) end end function BattleEffect.DropResourceByData(params) params.amount = params.effectData.intParams[1] BattleEffect._DropResourceByAmount(params) end function BattleEffect._GetDropItemPosOffset(index, maxIndex, stride, maxColumn, maxRow, startX, startY) local offset = FP.newV2(0, 0) if not maxColumn then for i=1,15 do if i * i >= maxIndex then maxColumn = i break end if i == 15 then logging.error(LTAG.ERROR, "HYW : 爆出物品最大数量超过了最大值255 @_GetDropItemPosOffset") end end end local row = math.ceil(index / maxColumn) local column = index - maxColumn * (row - 1) maxRow = maxRow or math.ceil(maxIndex / maxColumn) local startX = startX or -math.floor((maxColumn - 1) / 2) * stride local startY = startY or -math.floor((maxRow - 1) / 2) * stride offset.x:Reset(stride):Mul(column - 1):Add(startX) offset.z:Reset(stride):Mul(row - 1):Add(startY) return offset, maxColumn, maxRow, startX, startY end function BattleEffect._GetDropResBoxTargetCount(resDropItemInfoList, amount, maxCount) local leftAmount = amount local targetCount = 0 for i,info in ipairs(resDropItemInfoList) do local count = math.floor(leftAmount / info.maxAmount) leftAmount = leftAmount - count * info.maxAmount targetCount = targetCount + count if targetCount >= maxCount then targetCount = maxCount leftAmount = 0 break end end if leftAmount > 0 then targetCount = targetCount + 1 end return targetCount end function BattleEffect._DropResourceByAmount(params) if params.amount then if params.amount >= 1 then -- new↓ 爆一堆 local amountLeft = params.amount local createdCount = 0 local resDropItemInfoList = LevelManager.CurLevelFunc:GetDropResourceInfoList() local curAmountIndex = 1 local curAmount = resDropItemInfoList[curAmountIndex].maxAmount local maxCount = LevelManager.CurLevelFunc:GetMaxDropResBoxOnceCount() local targetCount = BattleEffect._GetDropResBoxTargetCount(resDropItemInfoList, params.amount, maxCount) local maxColumn, maxRow, startX, startY local stride = LevelManager.CurLevelFunc:GetDropResBoxStride() while createdCount < targetCount do while curAmount > amountLeft and curAmountIndex < #resDropItemInfoList do curAmountIndex = curAmountIndex + 1 curAmount = resDropItemInfoList[curAmountIndex].maxAmount end params.monsterID = resDropItemInfoList[curAmountIndex].monsterID params.position, maxColumn, maxRow, startX, startY = BattleEffect._GetDropItemPosOffset(createdCount + 1, targetCount, stride, maxColumn, maxRow, startX, startY) params.position:Add(params.caster:GetLogicPos()) params.forward = params.caster.components.move.LogicRotateDir:cloneV2() local entity = BattleEffect._CreateMonster(params) if curAmount > amountLeft then entity.components.record.resourceAmount = amountLeft break else amountLeft = amountLeft - curAmount entity.components.record.resourceAmount = curAmount end createdCount = createdCount + 1 end -- new↑ end else logging.error(LTAG.ERROR, "HYW : _DropResourceByAmount 失败,amount为空。 BattleEffect ID : ", params.effectData.ID) end end --创建召唤物、掉落物、怪物子弹之类的 function BattleEffect._CreateMonster(params) if params.monsterID then -- new↓ return SystemManager.CreateMonster(params.monsterID, params.position.x, params.position.z, params.forward.x, params.forward.z, params.bornItemID) -- new↑ -- old↓ -- EntityFactory.SetType_ID(LuaConst.CharacterType.Monster, params.monsterID) -- EntityFactory.SetPos_Dir(params.position, params.forward) -- return EntityFactory.DoCreateEntity() -- old↑ end end --资源战场↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ --军团战↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ function BattleEffect.HandleGuildWarHeroDead(params) -- local deadEntity = params.outParams.deadEntity -- local killer = params.outParams.killer -- LevelManager.CurLevelFunc:HandleHeroDead(deadEntity, killer) -- 这里可以删了 英雄死亡处理做到了底层内置,不走buff了 end function BattleEffect.HandleGuildWarOccupyCampsite(params) LevelManager.CurLevelFunc:HandleGuildWarOccupyCampsite(params.target, params.outParams.occupierID, params.outParams.pos) end --如果目标单位的阵营等于指定阵营,且目标单位是英雄,就给这个目标单位所属的玩家加分 function BattleEffect.GuildWarAddDefendCampsitePoint(params) if params.target:IsHero() then if params.effectData.intParams[1] == params.target:GetCampID() then LevelManager.CurLevelFunc:GuildWarAddDefendCampsitePoint(params.target) end end end function BattleEffect.HandleGuildWarBossDead(params) --params.target = killer , LevelManager.CurLevelFunc:HandleGuildWarBossDead(params.caster, params.target) end function BattleEffect.HandleGuildWarCatapultDead(params) LevelManager.CurLevelFunc:HandleGuildWarCatapultDead(params.caster, params.target) end function BattleEffect.HandleGuildWarBallistaDead(params) LevelManager.CurLevelFunc:HandleGuildWarBallistaDead(params.caster, params.target) end --军团战↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ --逐鹿中原(大乱斗)↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ function BattleEffect.TryDropFlagOfPlayer(params) local deadFlagCount = LevelManager.CurLevelFunc:GetFlagAmountOfPlayer(params.target:GetPlayerID()) if deadFlagCount and deadFlagCount > 0 then LevelManager.CurLevelFunc:TryDropFlagAmountOfEntity(params.target) --死者令旗数-1 params.callBulletId = params.effectData.intParams[1] --生成令旗怪 intParams[1]是callBullet表ID local killer = params.target.components.record.KillerEntity if killer then killer = killer:GetOriginEntity() if killer:IsHero() then --如果originKiller是英雄,则如果originKiller令旗满了,那么就生成令旗怪; 如果originKiller令旗没满,就转移令旗 if LevelManager.CurLevelFunc:GetFlagAmountOfPlayer(killer:GetPlayerID()) == 0 then LevelManager.CurLevelFunc:ChangeFlagAmountOfPlayer(killer, killer:GetPlayerID(), 1, nil) --击杀者令旗数+1 else BattleEffect._Call(params) end else if params.callBulletId then BattleEffect._Call(params) end end else if params.callBulletId then BattleEffect._Call(params) end end end end function BattleEffect.AddFlagAmountToTarget(params) if params.target:IsHero() then LevelManager.CurLevelFunc:ChangeFlagAmountOfPlayer(params.target, params.target:GetPlayerID(), 1, "touch") else logging.error(LTAG.ERROR, "HYW : 警告!!试图给非英雄单位增加令旗数。 CharacterID : ", params.target:GetCharacterID(), " CharacterType : ", params.target:GetCharacterType()) end end function BattleEffect._AddCollectAmountToTarget(params) if params.target:IsHero() then LevelManager.CurLevelFunc:ChangeCollectAmountOfPlayerByCollectKey(params.target, params.target:GetPlayerID(), params.collectType, params.amount) else logging.error(LTAG.ERROR, "HYW : 警告!!试图给非英雄单位增加拾取物数量。 CharacterID : ", params.target:GetCharacterID(), " CharacterType : ", params.target:GetCharacterType()) end end function BattleEffect.AddCollectAmountToTarget(params) params.collectType = params.effectData.intParams[1] params.amount = params.effectData.intParams[2] BattleEffect._AddCollectAmountToTarget(params) end function BattleEffect.AddCollectRandomAmountToTarget(params) local min = params.effectData.intParams[2] local max = params.effectData.intParams[3] if min and max then params.amount = LogicRandom.GetIntegerValue(params.caster, min, max, 4389534) params.collectType = params.effectData.intParams[1] BattleEffect._AddCollectAmountToTarget(params) else logging.error(LTAG.ERROR, "HYW : AddCollectRandomAmountToTarget BattleEffect配置错误,intParams长度不够,effectID : ", params.effectData.ID) end end function BattleEffect.AddCollectByPossibility(params) local possiblityMul1000 = params.effectData.intParams[2] if LogicRandom.GetIntegerValue(params.caster, 1, 1000, 54849549) <= possiblityMul1000 then params.amount = 1 params.collectType = params.effectData.intParams[1] BattleEffect._AddCollectAmountToTarget(params) end end function BattleEffect.AddCollectByNumWeightPairs(params) local count = 0 local weightSum = 0 for i=2,#params.effectData.intParams do count = count + 1 if count % 2 == 0 then weightSum = weightSum + params.effectData.intParams[i] end end if count % 2 == 0 then count = count / 2 local rand = LogicRandom.GetIntegerValue(params.caster, 1, weightSum, 54849550) local curWeight = 0 params.amount = 0 for i=1,count do curWeight = curWeight + params.effectData.intParams[i*2+1] if rand <= curWeight then params.amount = params.effectData.intParams[i*2] break end end if params.amount ~= 0 then params.collectType = params.effectData.intParams[1] BattleEffect._AddCollectAmountToTarget(params) end else logging.error(LTAG.ERROR, "HYW : AddCollectByNumWeightPairs 配置参数错误,intParams必须得配单数个参数 BattleEffectID : ", params.effectData.ID) end end --逐鹿中原(大乱斗)↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ --城池战;刷新防御塔的状态(纯表现的) function BattleEffect.RefreshCityWarTowerState(params) params.target.ExpEntity:SetModelUIDefendTower() end --城池战;刷新冲车的状态(纯表现的) function BattleEffect.RefreshCityWarCrushCarState(params) params.target.ExpEntity:SetModelUICrushCar(params.effectData.intParams[1] == 1, params.effectData.intParams[2] == 1, params.effectData.intParams[3] == 1) end --城池战;刷新攻击型载具的状态(纯表现的) function BattleEffect.RefreshCityWarAttackVehicleState(params) params.target.ExpEntity:SetModelUIAttackVehicle() end function BattleEffect.AddFourCountryScore(params) if params.target:IsHero() then if LevelManager.IsFourCountry() then local reason if (params.buff and params.buff.BuffID) == 520523 then reason = LuaConst.EFourCountryScoreChangeReason.COIN elseif params.effectData.ID == 5312 or params.effectData.ID == 5313 or params.effectData.ID == 5314 then reason = LuaConst.EFourCountryScoreChangeReason.OCCUPY end LevelManager.CurLevelFunc:TryAddScore(params.target, params.effectData.intParams[1], reason) end end end function BattleEffect.SendPositionChatLink(params) local speaker if params.effectData.stringParam ~= "" then speaker = params.outParams[params.effectData.stringParam] if not speaker then logging.error(LTAG.ERROR, "HYW : SendPositionChatLink 通过stringParam指定说话人失败! EffectID : ", params.effectData.ID) end else speaker = params.caster end if speaker then LevelManager.CurLevelFunc:SendPositionChatLink(params.target:GetLogicPos(), speaker) end end function BattleEffect.RideHorse(params) local horseModelID = params.effectData.intParams[1] local notShowEffect = params.effectData.intParams[2] == 0 SystemManager.ChangeHorse_ByModelID(params.target ,horseModelID) if not params.target.components.buff:CheckHasBuffState(LuaConst.SpecialBuffs.InRiding) then -- 如果在马上的话 ,不用再一次上马了 SystemManager.ExecuteRideHorse(params.target, notShowEffect, true) end end function BattleEffect.ForceReturn(params) params.target.components.patrol:ForceReturn() end function BattleEffect.CancelForceReturn(params) params.target.components.patrol:CancelForceReturn() end --设置位置到主人面向之前 function BattleEffect.SetPositionBeforeMaster(params) local master = params.target:GetMasterEntity() if master then local rho = master.components.record:GetVariable("__SetPositionBeforeMasterRho") local pos if rho then if params.effectData.floatParams[2] then local masterSkillBase = master.components.skillBase if masterSkillBase.SkillJoystickOffsetX ~= FP.Const.Zero or masterSkillBase.SkillJoystickOffsetZ ~= FP.Const.Zero then _tempV2.x:Reset(masterSkillBase.SkillJoystickOffsetX) _tempV2.z:Reset(masterSkillBase.SkillJoystickOffsetZ) local targetPos = master.components.record:GetVariable("__SetPositionBeforeMasterTargetPos") _tempV2_2:Reset(targetPos):Sub(master:GetLogicPos()) FP.V2.Angle(_tempV2_2, _tempV2, _tempV1) if tonumberV1(_tempV1) < params.effectData.floatParams[2] then if master.components.record:GetVariable("__SetPositionBeforeMasterTargetPos") then pos = master.components.record:GetVariable("__SetPositionBeforeMasterTargetPos") end end end end else rho = _tempV1_2 rho:Reset(params.effectData.floatParams[1]) end if not pos then pos = master.components.move.LogicRotateDir * rho pos = pos:Add(master:GetLogicPos()) end pos = LuaShoveManager.TrimAimPosByObstacleAndPriority(master, pos) SystemManager.OnConvey(params.target, pos, master.components.move.LogicRotateDir, nil, nil, true, true) end end function BattleEffect.SetDistOfSetPositionBeforeMasterByToMasterDist(params) local master = params.target:GetMasterEntity() if master then master.components.record:VariableSet("__SetPositionBeforeMasterRho", FP.V2.Distance(master:GetLogicPos(), params.target:GetLogicPos())) master.components.record:VariableSet("__SetPositionBeforeMasterTargetPos", params.target:GetLogicPos()) end end function BattleEffect.RemoveDistOfSetPositionBeforeMaster(params) local master = params.target:GetMasterEntity() if master then master.components.record:VariableSet("__SetPositionBeforeMasterRho", nil) master.components.record:VariableSet("__SetPositionBeforeMasterTargetPos", nil) end end function BattleEffect.AddObstruct(params) local pos = params.target:GetLogicPos() local forwardV2 = params.target:GetLogicRotateDir() local id = "BE" .. params.target.EntityID LuaShoveManager.SetObstructData(id, pos, forwardV2, FP.newV1(params.effectData.floatParams[1]), FP.newV1(params.effectData.floatParams[2])) LuaShoveManager.OpenObstruct(id) end function BattleEffect.RemoveObstruct(params) local id = "BE" .. params.target.EntityID LuaShoveManager.CloseObstruct(id, true) end --region 锚点 function BattleEffect.AddPositionAnchor(params) local posType = params.effectData.intParams[1] local pos if posType == 1 then pos = params.caster:GetLogicPos() else pos = params.target:GetLogicPos() end params.target.components.move:AddPosAnchor(params.caster, pos, params.effectData.floatParams[1], params.buff and params.buff.BuffID, params.effectData.intParams[2], params.effectData.intParams[3]) end function BattleEffect.RemovePositionAnchor(params) if params.effectData.intParams and #params.effectData.intParams > 0 then for i,v in ipairs(params.effectData.intParams) do params.target.components.move:RemovePosAnchor(params.caster, v) end else params.target.components.move:RemovePosAnchor(params.caster, nil) end end -- 删除 group 的 锚点 function BattleEffect.RemovePositionAnchorByGroup(params) for i,v in ipairs(params.effectData.intParams) do params.target.components.move:RemovePosAnchorByGroup(v) end end -- 禁止添加某groupid的锚点 .intParams[1] 1 禁止添加 ,0 删除禁止 function BattleEffect.ImmunoPositionAnchorByGroup(params) local isImmuno = params.effectData.intParams[1] == 1 local count = #params.effectData.intParams for i = 2, count do local groupId = params.effectData.intParams[i] params.target.components.move:SetImmunoPosAnchorGroup(groupId, isImmuno) end end -- 为所有敌人添加锚点(以buff携带者的位置和朝向为基础信息)。 排除: 忽略地形挤压和不被子弹打中的怪 function BattleEffect.AddPositionAnchorToEnemy(params) local pos = params.target:GetLogicPos() local ignoreBoss = params.effectData.intParams[2] == 1 local enemyList = TargetManager.Get2DNoFriendList(params.target) for key,entityList in ipairs(enemyList) do for i,entity in ipairs(entityList) do if not ignoreBoss or not entity:IsBoss() then local buffComp = entity.components.buff if not buffComp:GetBuffUpdateData(LuaConst.SpecialBuffs.CantBeTrigger) and not buffComp:GetBuffUpdateData(LuaConst.SpecialBuffs.IgnoreBlock) then entity.components.move:AddPosAnchor(params.caster, pos, params.effectData.floatParams[1], params.buff and params.buff.BuffID, params.effectData.intParams[1] , params.effectData.intParams[3]) end end end end end -- 为所有敌人移除锚点 function BattleEffect.RemovePositionAnchorToEnemy(params) local enemyList = TargetManager.Get2DNoFriendList(params.target) for camp,entityList in ipairs(enemyList) do for i,entity in ipairs(entityList) do entity.components.move:RemovePosAnchor(params.caster, params.buff and params.buff.BuffID) end end end -- 为事件中的bornEntity(必须是敌人)添加锚点(以buff携带者的位置和朝向为基础信息)。 排除: 忽略地形挤压和不被子弹打中的怪 function BattleEffect.AddPositionAnchorToBornEnemy(params) local ignoreBoss = params.effectData.intParams[2] == 1 local bornEntity = params.outParams.bornEntity if bornEntity then if not ignoreBoss or not bornEntity:IsBoss() then local buffComp = bornEntity.components.buff if not buffComp:GetBuffUpdateData(LuaConst.SpecialBuffs.CantBeTrigger) and not buffComp:GetBuffUpdateData(LuaConst.SpecialBuffs.IgnoreBlock) and CampManager.IsEnemyEntity(bornEntity, params.target) then local pos = params.target:GetLogicPos() bornEntity.components.move:AddPosAnchor(params.caster, pos, params.effectData.floatParams[1], params.buff and params.buff.BuffID, params.effectData.intParams[1], params.effectData.intParams[3]) end end end end -- 让某groupid的锚点失效 .intParams[1] 1 失效 ,0 恢复阻挡效果 function BattleEffect.PausePositionAnchorByGroup(params) local isPause = params.effectData.intParams[1] == 1 local count = #params.effectData.intParams for i = 2, count do local groupId = params.effectData.intParams[i] params.target.components.move:SetPausePosAnchorGroup(groupId, isPause) end end --endregion 锚点 --region rougeLike相关的 -- 肉鸽玩法中:括大玩家的拾取范围 function BattleEffect.AddRogueLikePickUpRange(params) local range = params.effectData.intParams[1] if LevelManager.CurLevelFunc.AddPickUpRange then LevelManager.CurLevelFunc:AddPickUpRange(params.target, range) else logging.error(LTAG.ERROR, "GWS : 警告!试图在不存在AddPickUpRange功能的玩法调用 BattleEffect.AddRogueLikePickUpRange , 关卡ID : ", LevelManager.GetCurLevelID(), " EffectID : ", params.effectData.ID) end end -- 肉鸽玩法中:增加积分 function BattleEffect.AddRogueLikeScore(params) local score = params.effectData.intParams[1] if LevelManager.CurLevelFunc.AddRogueScore then LevelManager.CurLevelFunc:AddRogueScore(params.target, score) else logging.error(LTAG.ERROR, "GWS : 警告!试图在不存在AddScore功能的玩法调用 BattleEffect.AddRogueLikeScore , 关卡ID : ", LevelManager.GetCurLevelID(), " EffectID : ", params.effectData.ID) end end -- 肉鸽玩法中:增加积分倍率 function BattleEffect.AddRogueLikeScoreRate(params) local rate = params.effectData.floatParams[1] if LevelManager.CurLevelFunc.AddRogueScoreRate then LevelManager.CurLevelFunc:AddRogueScoreRate(rate) else logging.error(LTAG.ERROR, "GWS : 警告!非肉鸽试图在调用 BattleEffect.AddRogueScoreRate , 关卡ID : ", LevelManager.GetCurLevelID(), " EffectID : ", params.effectData.ID) end end -- 肉鸽玩法中:增加经验值加成 function BattleEffect.AddRogueLikeGradeExp(params) local rate = params.effectData.floatParams[1] if LevelManager.CurLevelFunc.AddRogueLikeGradeExp then LevelManager.CurLevelFunc:AddRogueLikeGradeExp(rate) end end -- 肉鸽玩法中:增加复活机会 function BattleEffect.AddRogueLikeReviveNum(params) local num = params.effectData.intParams[1] if LevelManager.CurLevelFunc.AddRogueReviveNum then LevelManager.CurLevelFunc:AddRogueReviveNum(num) end end -- 肉鸽玩法中:增加重选机会 function BattleEffect.AddRogueLikeReselectNum(params) local num = params.effectData.intParams[1] if LevelManager.CurLevelFunc.AddRogueReselectNum then LevelManager.CurLevelFunc:AddRogueReselectNum(num) end end -- 肉鸽玩法中:找出附近的n个怪物,释放子弹 function BattleEffect.RogueLikeRandomCall(params) local searchList = LevelManager.CurLevelFunc:GetNearSearchList() local num = #searchList if num == 0 then return end params.callBulletId = params.effectData.intParams[1] local count = params.effectData.intParams[2] local randomOffset = LogicRandom.GetIntegerValue(params.target, 1, num, 20240529) for i = 1, count do local target = searchList[(i - 1 + randomOffset) % num + 1] if target then params.forceTarget = target BattleEffect._Call(params) end end end --endregion -- 变到hero表中的ChangeMonsterList的第几个模型 function BattleEffect.ChangeAvatarByCharacterIndex(params) local entity = params.target local toIndex = params.effectData.intParams[1] local duration = params.effectData.floatParams[1] and FP.newV1(params.effectData.floatParams[1]) local inheritSkillCD = params.effectData.intParams[2] == 1 local skillChangeMonsters = entity.components.base.CurCharacterData.ChangeMonsterList if skillChangeMonsters then local characterID = skillChangeMonsters[toIndex] if characterID then local inheritSkillKeyPosList if inheritSkillCD and params.effectData.intParams[3] then inheritSkillKeyPosList = {params.effectData.intParams[3], params.effectData.intParams[4], params.effectData.intParams[5], params.effectData.intParams[6]} end ChangeAvatarSystem.ChangeAvatar(entity, characterID, duration, true, true, nil,nil, inheritSkillCD, inheritSkillKeyPosList) else logging.error(LTAG.ERROR, "策划配表错误 : 变身时,ChangeMonsterList无值;characterId =", entity.components.base.CurCharacterData.ID, " toIndex =", toIndex) end else logging.error(LTAG.ERROR, "策划配表错误 : 变身时,发现skill大变身字段没有值;characterId =", entity.components.base.CurCharacterData.ID) end end function BattleEffect.ChangeAvatar(params) local ChangeAvatarSystem = require "Battle/Logic/Entity/System/ChangeAvatarSystem" local isInheritSkillCD = params.effectData.intParams[3] == 1 local inheritSkillKeyPosList if isInheritSkillCD and params.effectData.intParams[4] then inheritSkillKeyPosList = {params.effectData.intParams[4], params.effectData.intParams[5], params.effectData.intParams[6], params.effectData.intParams[7]} end ChangeAvatarSystem.ChangeAvatar(params.target, params.effectData.intParams[1], FP.newV1(params.effectData.intParams[2] or 0), false, false, false, true, isInheritSkillCD, inheritSkillKeyPosList) end function BattleEffect.ChangeModel(params) local modelID = params.effectData.intParams[1] local canRideHorse = params.effectData.intParams[2] == 1 SystemManager.ChangeModel(params.target, modelID, false, canRideHorse) end function BattleEffect.CreatePlayerIllusionEntity(params) local entity = params.target local pos = entity:GetLogicPos():cloneV2() local angle = params.effectData.intParams[1] local dir = FP.V2.GetOffsetToAngle(angle,entity:GetLogicRotateDir()) local aiId = params.effectData.intParams[2] local markId = params.effectData.intParams[3] LevelManager.CurLevelFunc:CreatePlayerIllusionEntity(entity, pos, dir, aiId, markId) end function BattleEffect.ActiveMonsterItem(params) local levelItem = LevelItemManager.GetItemByID(params.effectData.intParams[1], LuaConst.LevelItemType.Monster) if levelItem then levelItem:DoAction(LuaConst.LevelActionType.Monster_Active) else logging.error(LTAG.ERROR, "HYW : 没有找到ID为 ", params.effectData.intParams[1], " 的怪物元素 @BattleEffect.SetMonsterLevelItemBornPosByID buffID : ", params.buff and params.buff.BuffID) end end function BattleEffect.SetMonsterLevelItemBornPosByID(params) local levelItem = LevelItemManager.GetItemByID(params.effectData.intParams[1], LuaConst.LevelItemType.Monster) if levelItem then levelItem:SetOverrideBornPos(FP.newV2(params.effectData.floatParams[1], params.effectData.floatParams[2])) else logging.error(LTAG.ERROR, "HYW : 没有找到ID为 ", params.effectData.intParams[1], " 的怪物元素 @BattleEffect.SetMonsterLevelItemBornPosByID buffID : ", params.buff and params.buff.BuffID) end end function BattleEffect.SetMonsterItemBornPosToAnotherItemPos(params) local monsterItem = LevelItemManager.GetItemByID(params.effectData.intParams[1], LuaConst.LevelItemType.Monster) if monsterItem then local anotherLevelItem = LevelItemManager.GetItemByID(params.effectData.intParams[2]) monsterItem:SetOverrideBornPos(anotherLevelItem.ItemData.ItemPos:cloneV2()) else logging.error(LTAG.ERROR, "HYW : 没有找到ID为 ", params.effectData.intParams[1], " 的怪物元素 @BattleEffect.SetMonsterLevelItemBornPosByID buffID : ", params.buff and params.buff.BuffID) end end function BattleEffect.SetMonsterItemOverrideMonsterID(params) local monsterItem = LevelItemManager.GetItemByID(params.effectData.intParams[1], LuaConst.LevelItemType.Monster) if monsterItem then monsterItem:SetOverrideMonsterID(params.effectData.intParams[2]) else logging.error(LTAG.ERROR, "HYW : 没有找到ID为 ", params.effectData.intParams[1], " 的怪物元素 @BattleEffect.SetMonsterItemMonsterID buffID : ", params.buff and params.buff.BuffID) end end function BattleEffect.CancelMonsterItemOverrideMonsterID(params) local monsterItem = LevelItemManager.GetItemByID(params.effectData.intParams[1], LuaConst.LevelItemType.Monster) if monsterItem then monsterItem:SetOverrideMonsterID(nil) else logging.error(LTAG.ERROR, "HYW : 没有找到ID为 ", params.effectData.intParams[1], " 的怪物元素 @BattleEffect.CancelMonsterItemOverrideMonsterID buffID : ", params.buff and params.buff.BuffID) end end function BattleEffect.ReplaceMonsterSequentially(params) if LevelItemManager.Global:IsLevelFinished() then return end local oldMonsterID = params.target:GetCharacterID() local replaceToMonsterID if params.target:IsAlive() and (params.effectData.stringParam == "1" or params.target.components.anim.CurAnimID ~= "die") then for i,v in ipairs(params.effectData.intParams) do if v == oldMonsterID then replaceToMonsterID = params.effectData.intParams[i + ((params.effectData.floatParams[1] and params.effectData.floatParams[1] < 0) and -1 or 1)] break end end end if replaceToMonsterID then EntityFactory.SetType_ID(LuaConst.CharacterType.Monster, replaceToMonsterID) EntityFactory.SetPos_Dir(params.target:GetLogicPos(), params.target.components.move.LogicRotateDir) local bornItemID = params.target._logicInitData.BornItemID if bornItemID then EntityFactory.SetParams("BornItemID", bornItemID) end local entity = EntityFactory.DoCreateEntity() if bornItemID then local bornItem = LevelItemManager.GetItemByID(bornItemID) if bornItem then if bornItem.RegistEntity then bornItem:RegistEntity(entity) end if bornItem.UnregistEntity then bornItem:UnregistEntity(params.target) end end end local hpInheritType = params.effectData.floatParams[2] if hpInheritType then if hpInheritType == 1 then --继承血量损失 local hpLoss = params.target:GetAttrValue(LuaConst.AttrType.hplmt) - params.target:GetAttrValue(LuaConst.RealtimeAttrType.hp) if hpLoss > FP.Const.Zero then local curHplmt = entity:GetAttrValue(LuaConst.AttrType.hplmt) if hpLoss < curHplmt then entity:SetAttrBaseValue(LuaConst.RealtimeAttrType.hp, curHplmt - hpLoss) entity.ExpEntity:SetModelUI_HP(entity:GetAttrValueNum("hp"), entity:GetAttrValueNum("pc"), entity:GetAttrValueNum("hplmt")) else logging.error(LTAG.ERROR, "HYW : ReplaceMonsterSequentially 后血量上限比之前的血量损失还低,无法使用1类型的血量继承! buffID : ", params.buff and params.buff.BuffID) end end end end local driveComp = params.target.components.drive if driveComp then local driver = driveComp.BeDrivedByEntity if driver then SystemManager.OffDrive(driver) end end SystemManager.DeadQuit(params.target, nil, {replaceToMonsterID = entity.featureID}) else if LevelManager.CurLevelFunc.OnReplaceMonsterSequentiallyFailed then --如果替换失败,则可以通知关卡就通知关卡 LevelManager.CurLevelFunc:OnReplaceMonsterSequentiallyFailed(oldMonsterID, params.effectData.intParams, params.target._logicInitData.BornItemID) end end end function BattleEffect._CreateMonsterAtMonsterLevelItem(params) local levelItem = LevelItemManager.GetItemByID(params.levelItemID, LuaConst.LevelItemType.Monster) if levelItem then params.position = levelItem._overrideBornPos or levelItem.ItemData.ItemPos params.forward = levelItem.ItemData.ItemDir params.bornItemID = params.levelItemID local entity = BattleEffect._CreateMonster(params) if entity then levelItem:RegistEntity(entity) else logging.error(LTAG.ERROR, "HYW : _CreateMonsterAtMonsterLevelItem failed! monsterID : ", params.monsterID, " buffId : ", params.buff and params.buff.BuffID or " nil ") end else logging.error(LTAG.ERROR, "HYW : _CreateMonsterAtMonsterLevelItem failed! LevelItem no exsit levelItemID : ", levelItemID, " buffId : ", params.buff and params.buff.BuffID or " nil ") end end function BattleEffect.CreateMonsterAtFirstEmptyMonsterLevelItem(params) local intParams = params.effectData.intParams for i=2,#intParams do local levelItem = LevelItemManager.GetItemByID(intParams[i], LuaConst.LevelItemType.Monster) if levelItem and levelItem:GetAliveMonsterCount() <= 0 then if not LevelManager.CurLevelFunc.CanCreateMonsterAtFirstEmptyMonsterLevelItem or LevelManager.CurLevelFunc:CanCreateMonsterAtFirstEmptyMonsterLevelItem(intParams[1], intParams[i]) then params.monsterID = intParams[1] params.levelItemID = intParams[i] BattleEffect._CreateMonsterAtMonsterLevelItem(params) else if LevelManager.CurLevelFunc.OnCreateMonsterAtFirstEmptyMonsterLevelItemFailed then LevelManager.CurLevelFunc:OnCreateMonsterAtFirstEmptyMonsterLevelItemFailed(intParams[1], intParams[i]) end end break end end end function BattleEffect.BornMonsterAtRandomEmptyMonsterLevelItem(params) local intParams = params.effectData.intParams local levelItemIdIndex = LogicRandom.GetIntegerValue(params.caster, 1, #intParams, 5435345) for i=1,#intParams do local levelItemId = intParams[levelItemIdIndex] local levelItem = LevelItemManager.GetItemByID(levelItemId, LuaConst.LevelItemType.Monster) if levelItem and levelItem:GetAliveMonsterCount() <= 0 then levelItem:OnActive() levelItem:BornMonsterCache() break end levelItemIdIndex = levelItemIdIndex + 1 if levelItemIdIndex > #intParams then levelItemIdIndex = 1 end end end function BattleEffect.SetAsMasterPosTraceEntity(params) local masterEntity = params.target:GetMasterEntity() if masterEntity then masterEntity.components.record:SetPosTraceEntity(params.target) else logging.error(LTAG.ERROR, "HYW : 单位没有主人,但是试图调用BattleEffect.SetAsMasterPosTraceEntity characterID : ", params.target:GetCharacterID(), " buffID : ", params.buff and params.buff:GetBuffID() or " nil ") end end -- 将target设置为原始caster的追踪点目标entity function BattleEffect.SetTargetAsOriginCasterPosTraceEntity(params) local casterOriginEntity = params.caster:GetOriginEntity() if casterOriginEntity then casterOriginEntity.components.record:SetPosTraceEntity(params.target) end end -- 将 事件参数中的某entity 设置为target的追踪点目标entity function BattleEffect.SetEventParamAsPosTraceEntity(params) local targetEntity = params.outParams[params.effectData.stringParam] if targetEntity == nil then logging.error(LTAG.ERROR, "gws : BattleEffect-SetEventParamAsPosTraceEntity 未找到策划配置的entity,可能是配置错误。") return end local type = params.effectData.intParams[1] if type == 1 then -- 向上筛选出可被打中的entity(非最原始主人)【如:a(可被攻击)->b(可被攻击)->c(可被攻击)->d,从d向a依次找出可被攻击的c。】 for i=1,10 do-- 这个地方应该用while,但是为了安全起见用for代替了。现在游戏中一般的entity的父级不会超过4层 if targetEntity.components.base.CurMonsterFeature.CantBeTrigger == MonsterBeTriggerType_All then break; else targetEntity = targetEntity._logicInitData.MasterEntity if targetEntity == nil then -- 发现是个不能被打的entity打我了,反击则一定选它 targetEntity = params.outParams[params.effectData.stringParam] break; end end if i == 10 then logging.error(LTAG.ERROR, "gws : BattleEffect-SetEventParamAsPosTraceEntity 未找到可被攻击的entity,可能是配置错误。") end end end if targetEntity then params.target.components.record:SetPosTraceEntity(targetEntity) else logging.error(LTAG.ERROR, "gws : BattleEffect-SetEventParamAsPosTraceEntity 未找到可被攻击的entity,事件中的", params.effectData.stringParam, "向上找父entity,未找到可被攻击的。") end end -- 清除原始caster的追踪点目标entity function BattleEffect.ClearOriginCasterPosTraceEntity(params) local casterOriginEntity = params.caster:GetOriginEntity() if casterOriginEntity then casterOriginEntity.components.record:SetPosTraceEntity(nil) end end -- 清除target的追踪点目标entity function BattleEffect.ClearOriginPosTraceEntity(params) local targetOriginEntity = params.target:GetOriginEntity() if targetOriginEntity then if targetOriginEntity.components.record.posTraceEntity == params.buff.hostEntity then targetOriginEntity.components.record:SetPosTraceEntity(nil) end end end -- 暂停宠物的攻击 function BattleEffect.PausePetAttack(params) local petComp = params.target.components.pet if petComp then petComp:SetPauseAttack(params.effectData.intParams[1] == 1) end end function BattleEffect._VehiclePullAboard(params) local vehicle = params.vehicle if vehicle:IsVehicle() then if not vehicle.components.drive.BeDrivedByEntity then local variable = params.variable local entity = nil if variable > 0 then --这种情况下 variable代表playerID entity = LevelPlayerManager.GetPlayerActiveEntity(variable) elseif variable < 0 then --这种情况下做特殊规则,比如-1代表拉取最近的 -- -1代表拉取最近的hero上车 if variable == -1 then entity = TargetManager.GetNearestHero(vehicle:GetLogicPos()) end else logging.error(LTAG.ERROR, "HYW : 战斗程序注意! 载具发动_VehiclePullAboard效果时,发现没有设置Variable值(Variable值为0)。 BattleEffectID : ", params.effectData.ID, " 载具CharacterID :", vehicle:GetCharacterID()) end if entity then SystemManager.Drive(entity, vehicle) end --else --本载具已经有驾驶者了,啥也不干 end else logging.error(LTAG.ERROR, "HYW : 策划注意! 非载具单位试图发动VehiclePullAboardByVariable效果,这是个配置错误。 BattleEffectID : ", params.effectData.ID, " 载具CharacterID :", vehicle:GetCharacterID()) end end function BattleEffect.VehiclePullAboard(params) local variable = params.effectData.intParams[1] if variable then params.variable = variable params.vehicle = params.caster BattleEffect._VehiclePullAboard(params) else logging.error(LTAG.ERROR, "HYW : 策划注意! VehiclePullAboard效果没有配置intParams[1]。 BattleEffectID : ", params.effectData.ID, " 发动者CharacterID :", params.caster:GetCharacterID()) end end --载具拉人上车,拉取的人由自身的RecordComponent里的key为LuaConst.PreDriverPlayerIDVariableKey的Value指定。这个Value一般是由关卡元素设置的。 function BattleEffect.VehiclePullAboardByVariable(params) local variable = params.caster.components.record:GetVariable(LuaConst.PreDriverPlayerIDVariableKey) if variable then params.variable = variable params.vehicle = params.caster BattleEffect._VehiclePullAboard(params) end end function BattleEffect.SetSkillMaxChargetCount(params) params.target.components.skillBase:SetMaxChargeCountBySkillID(params.effectData.intParams[1], params.effectData.intParams[2]) EventSystem.Dispatch(EventID.SetSkillMaxChargetCount, params.effectData.intParams[1]) end function BattleEffect.SetSkillRSAimDir(params) local entity = params.target local target = entity.components.target.Target if target then local aimDir = target:GetLogicPos() - entity:GetLogicPos() -- 不用缓存了,这个内存虽有分配,但很小且使用次数很少 SystemManager.SetSkillRSAimDir(entity,aimDir, params.effectData.intParams[1]) end end function BattleEffect.SetCameraMode(params) params.target.ExpEntity:SetCameraMode(params.effectData.intParams[1] or 0) end --target停止被其他玩家锁定其自己 function BattleEffect.ClearSkillHighestPriorityTarget(params) for i,playerID in ipairs(LevelPlayerManager.PlayerIDList) do local entity = LevelPlayerManager.GetPlayerActiveEntity(playerID) if entity.components.target.SkillHighestPriorityTarget == params.target then SystemManager.SetSkillHighestPriorityTarget(playerID, nil) if playerID == LevelPlayerManager.MyPlayerIDInRoom then ExpSystemManager.OnEscapeCameraLock(params.target) end end end ExpSystemManager.SetCameraAddPreparedTargetOnUpdateValid(false, params.target) end -- 给分身加上入到相机锁定。illusion function BattleEffect.AddIllusionToCameraLockList(params) if LevelManager.IsSolo() then -- 也可以放在具体的levelFunction中 local illusionEntity = params.outParams.illusion local master = params.outParams.master local checkLockingMaster = params.effectData.intParams[1] == 1 if master:GetPlayerID() == LevelPlayerManager.MyPlayerIDInRoom then -- 我自己放的分身 ,不能改变我自己的视角 return end if illusionEntity then for i,playerID in ipairs(LevelPlayerManager.PlayerIDList) do local entity = LevelPlayerManager.GetPlayerActiveEntity(playerID) if not checkLockingMaster or entity.components.target.SkillHighestPriorityTarget == master then -- 如果以后在多个敌我(>4),敌方锁定我队友,我自己放分身 ,我的分身要进入到敌方锁定列表 if playerID == LevelPlayerManager.MyPlayerIDInRoom and CampManager.IsEnemyEntity(master, LogicUpdateManager._curEntity) then -- safe 下面的代码是exp的 ExpSystemManager.SetCameraTarget(illusionEntity.ExpEntity) end end end else logging.error(LTAG.ERROR, "【gws】:BattleEffect.AddIllusionToCameraLockList依赖的事件不存在 illusion 参数。 策划查看下bufftrigger表的说明中的事件参数") end end end function BattleEffect.StopPsEffectByType(params) params.caster.ExpEntity:StopEffectByType(params.effectData.intParams[1]) end function BattleEffect.SetPsEffectScaleByRecordTimestamp(params) local key if string.isNilOrEmpty(params.effectData.stringParam) then key = params.effectData.intParams[1] else key = params.effectData.stringParam end if key then local timestamp = params.caster.components.record:GetVariable(key) if type(timestamp) == "number" then local timeElaFrame = LogicUpdateManager._clientHandleFrame - timestamp if timeElaFrame >= 0 then --此处计算视图尺寸,不需要使用FP local scale = timeElaFrame * LuaConst.TimeSpan * params.effectData.floatParams[1] + params.effectData.floatParams[2] if params.effectData.floatParams[3] and scale > params.effectData.floatParams[3] then scale = params.effectData.floatParams[3] end params.caster.ExpEntity:SetEffectScaleByType(params.effectData.intParams[2], scale, 1 , scale) else logging.error(LTAG.ERROR, "HYW : timestamp in future Error @BattleEffect.SetPsEffectScaleByRecordTimestamp! EffectID : ", params.effectData.ID) end else logging.error(LTAG.ERROR, "HYW : timestamp bad value @BattleEffect.SetPsEffectScaleByRecordTimestamp! value : ", timestamp, " EffectID : ", params.effectData.ID) end else logging.error(LTAG.ERROR, "HYW : key bad value @BattleEffect.SetPsEffectScaleByRecordTimestamp EffectID :", params.effectData.ID) end end --排除Buff的粒子特效,排除之后整场战斗将不再播放Buff的这个粒子特效 function BattleEffect.ExcludeBuffPsEffect(params) ExpSystemManager.ExcludeBuffPsEffect(params.effectData.stringParam) end --执行组合BattleEffect function BattleEffect.CombineBattleEffect(params) for i,effectId in ipairs(params.effectData.intParams) do BattleEffect.ExecuteByEffectId(effectId, params.outParams, params.caster, params.target) end end -- 判断距离然后执行BattleEffect [ 这么做很无奈,目的是: params.target要和多个buff来源做距离比较,然后根据结果对对应的buff来源者做各种不同处理。bufftrigger表的条件判断节点FuncNode_xxx 参数只有buffObject] function BattleEffect.CheckDistanceThenBattleEffect(params) local targetType = params.effectData.intParams[1] local compareType = params.effectData.intParams[2] -- 比较大小的类型 1-大于 2- 小于等于 local conditionDisSqr = params.effectData.intParams[3] -- 距离的平方 local aimEntity if targetType == 1 then -- buff的来源者 aimEntity = params.caster elseif targetType == 2 then -- buff的来源者的原始entity aimEntity = params.caster:GetOriginEntity() end FP.V2.DistanceSqr(aimEntity:GetLogicPos(), params.target:GetLogicPos(), _tempV1) -- _tempV1 就是距离的平方 local canDo = (compareType == 1 and FP.Greater(_tempV1,conditionDisSqr)) or (compareType == 2 and FP.LessEquals(_tempV1, conditionDisSqr)) if canDo then BattleEffect.ExecuteByEffectId(params.effectData.intParams[4], params.outParams, params.caster, params.target) end end -- 计略 :修改计略的内置cd (触发间隔)单位ms。整数增加cd,负数减少cd function BattleEffect.AddStratagemCD(params) local entity = params.target local stratagemComp = entity.components.stratagem if stratagemComp then stratagemComp:AddTriggerCD(params.effectData.intParams[1]) end end -- 计略 :开始CD计时 function BattleEffect.StratagemEnterCD(params) local entity = params.target SystemManager.StratagemEnterCD(entity) end function BattleEffect.AddBuffSkill(params) SystemManager.AddBuffSkillById(params.target, params.effectData.intParams[1]) end function BattleEffect.ChangeBuffSkillCd(params) local canChange = true local buffSkillData = DataSheetManager.BuffSkillData:GetDataByID(params.effectData.intParams[1]) if buffSkillData.KeyPosition == LuaConst.ESkillKeyPosition.BuffSkill2 then if params.target.isHero then --如果是神兽技,只有第一军的可以改变CD,因为所有养成效果都会一式三份发给每一军,只需要第一军减cd生效,否则会出现3倍效果 canChange = LevelPlayerManager.GetPlayerActiveEntity(params.target:GetPlayerID()) == params.target end end if canChange then SystemManager.ChangeBuffSkillCd(params.target, params.effectData.intParams[1], params.effectData.floatParams[1]) end end function BattleEffect.SetOverrideVisibilityLv(params) local key = params.effectData.intParams[2] key = key or (params.buff and params.buff:GetBuffID()) if key then params.target.components.visualField:SetOverrideVisibilityLv(params.effectData.intParams[1], key) else logging.error(LTAG.ERROR, "HYW : key nil Error SetOverrideVisibilityLv failed! ") end end function BattleEffect.CancelOverrideVisibilityLv(params) local key = params.effectData.intParams[1] key = key or (params.buff and params.buff:GetBuffID()) if key then params.target.components.visualField:SetOverrideVisibilityLv(nil, key) else logging.error(LTAG.ERROR, "HYW : key nil Error CancelOverrideVisibilityLv failed! ") end end -- 让target以一定速度移动到释放者的位置(floatParams[1] m/s) function BattleEffect.CasterAddGravityToTarget(params) local isAdd = params.effectData.intParams[1] == 1 if isAdd then params.target.components.move.GravityForceEntity = params.caster params.target.components.move.GravitySpeed = FP.newV1(params.effectData.floatParams[1]):Mul(LuaConst.TimeSpan) else params.target.components.move.GravityForceEntity = nil params.target.components.move.GravitySpeed = nil end end -- 让target以一定速度移动到释放者的Origin某个点上 function BattleEffect.AddHitMoveToOriginCaster(params) _tempV2:Reset(params.effectData.intParams[1], params.effectData.intParams[2])-- _tempV2 相对偏移位置 local baseEntity = params.caster:GetOriginEntity() FP.V2.GetOffsetToForward(baseEntity:GetLogicRotateDir(), _tempV2, _tempV2) -- _tempV2 绝对偏移位置 _tempV2:Add(baseEntity:GetLogicPos()) -- _tempV2 绝对位置 SystemManager.AddHitMoveToPosBySpd(params.target, _tempV2, params.effectData.intParams[3]) end -- 让同master的entity在固定时间内来到自身位置上 -- intParams[3-n] -- 从3开始,后面都是buffID function BattleEffect.AddHitMoveOnTimeToBrother(params) local masterEntity = params.target._logicInitData.RootMasterEntity _tempV2:Reset(params.target:GetLogicPos())-- _tempV2 目标位置点 local characterID = params.effectData.intParams[1] local time = params.effectData.intParams[2] local limitDistanceSqr = params.effectData.floatParams[1] -- 限制多少距离内 local filterBuff = params.effectData.floatParams[2] -- 限制身上不能有的buff -- 找寻同master的entity for i,entity in ipairs(LogicUpdateManager.EntityList_Normal) do if entity._logicInitData.RootMasterEntity == masterEntity and entity._logicInitData.CharacterID == characterID and params.target ~= entity then if filterBuff == nil or not entity:HasBuff(filterBuff) then if limitDistanceSqr == 0 or (not FP.V2.IsDistanceSqrGreater(_tempV2, entity:GetLogicPos(), limitDistanceSqr)) then SystemManager.AddHitMoveToPosOnTime(entity, _tempV2, time) for buffIndex = 3, #params.effectData.intParams do local buffCtrlParam = RuntimeDataManager.New_BuffCtrl() buffCtrlParam.ForceDuration:Reset(time/1000) SystemManager.AddBuff(entity, params.effectData.intParams[buffIndex], params.target, nil, buffCtrlParam) end end end end end end --改变子弹击退距离 function BattleEffect.ChangeMissileHitDistance(params) if params.outParams.hitDistance then if params.outParams.isHitHero then params.outParams.hitDistance:Reset(params.effectData.intParams[2]) else params.outParams.hitDistance:Reset(params.effectData.intParams[1]) end else logging.error(LTAG.ERROR, "GWS : 策划注意! ChangeMissileHitDistance只能搭配 子弹设置位移数据 事件使用(如10313), 出错的BattleEffect : ", params.effectData.ID) end end --子弹:添加一个击退效果(纯抄写的) function BattleEffect.AddMissileHitDistance(params) if params.outParams.missile then local attacker = params.outParams.attacker local hitEntity = params.outParams.target local missileData = params.outParams.missileData local characterType = hitEntity._logicInitData.CharacterType local addBuffID = params.effectData.intParams[1] local hitMoveDir = params.effectData.intParams[2] local hitMoveDirOffsetAngle = params.effectData.intParams[3] local hitMoveTime = params.effectData.intParams[4] local hitDistance = params.effectData.floatParams[1] if characterType == LuaConst.CharacterType.Hero then addBuffID = params.effectData.intParams[5] hitMoveDir = params.effectData.intParams[6] hitMoveDirOffsetAngle = params.effectData.intParams[7] hitMoveTime = params.effectData.intParams[8] hitDistance = params.effectData.floatParams[2] end -- 有受击动作 if addBuffID ~= 0 then if hitEntity:IsActive() then local hitBuffCtrl = RuntimeDataManager.New_BuffCtrl() hitBuffCtrl.MissileHitMoveID = missileData.ID hitBuffCtrl.HitMoveTime:Reset(hitMoveTime) hitBuffCtrl.HitDistance:Reset(hitDistance) hitBuffCtrl.HitMoveDir = hitMoveDir hitBuffCtrl.HitMoveDirOffsetAngle = hitMoveDirOffsetAngle -- 被打死啦 if not hitEntity.components.attr:IsAlive() then local addBuffData = DataSheetManager.BuffData:GetDataByBuffID(addBuffID) local immuned = BuffManager.CheckBuffImmune(hitEntity, addBuffData) if not immuned then --如果受击buff没有被免疫,则进行受击buff死亡转换 addBuffID = LuaConst.DeadChangeBuff[addBuffID] or LuaConst.SpecialBuffs.InDying end else local buffComp = hitEntity.components.buff if buffComp:GetBuffUpdateData(LuaConst.SpecialBuffs.InHitUp) or buffComp:GetBuffUpdateData(LuaConst.SpecialBuffs.InHitFlyMonster) or buffComp:GetBuffUpdateData(LuaConst.SpecialBuffs.InFlyFlyingMonster) then if addBuffID ~= LuaConst.SpecialBuffs.InHitFlyMonster then addBuffID = LuaConst.SpecialBuffs.InFlyFlyingMonster end end end SystemManager.AddBuff(hitEntity, addBuffID, attacker, params.outParams.missile, hitBuffCtrl) end end else logging.error(LTAG.ERROR, "GWS : 策划注意! AddMissileHitDistance只能搭配 子弹设置位移数据 事件使用(如10313 10312), 出错的BattleEffect : ", params.effectData.ID) end end -- 设置一些覆盖技能摇杆表的数据【这个方法的前提是技能摇杆表没有字段转为定点数,若以后有字段转为定点数则方法需补充上】 function BattleEffect.OverrideSkillJoyStickData(params) local skillJoyStickId = params.effectData.intParams[1] --要修改的字段名称 local fieldName = params.effectData.stringParam local val = params.effectData.floatParams[1] params.target.components.skillBase:OverrideSkillJoyStickData(skillJoyStickId, fieldName, val) end function BattleEffect.DragonArteryRandomTransport(params) --龙脉争夺战随机传送(去掉两个最近的传送点,在剩下的传送点内随机传送) if LevelManager.CurLevelFunc.DragonArteryRandomTransport then LevelManager.CurLevelFunc:DragonArteryRandomTransport(params.target) else logging.error(LTAG.ERROR, "HYW : 关卡没有实现随机传送功能! LevelID : ", LevelManager.GetCurLevelID()) end end --发起召唤请求,给所有友方英雄弹窗 function BattleEffect.SummonRequest(params) if LevelManager.CurLevelFunc.SummonRequest then LevelManager.CurLevelFunc:SummonRequest(params.caster, params.outParams) else logging.error(LTAG.ERROR, "HYW : 关卡没有实现招人功能! LevelID : ", LevelManager.GetCurLevelID()) end end function BattleEffect.HeroesInLevelItemTransport(params) local levelItemID1 = params.effectData.intParams[1] local levelItemID2 = params.effectData.intParams[2] local spreadType = params.effectData.intParams[3] local levelItem1 = LevelItemManager.GetItemByID(levelItemID1) if levelItem1 then local heroList = {} local levelItem2 = LevelItemManager.GetItemByID(levelItemID2) if levelItem2 then local levelItem1Pos = levelItem1.ItemData.ItemPos if levelItem1.ItemData.Radius then local radiusSqr = levelItem1.ItemData.Radius * levelItem1.ItemData.Radius for i,_entity in ipairs(LogicUpdateManager.EntityList_Sync) do if _entity.isHero then if not FP.V2.IsDistanceSqrGreater(_entity:GetLogicPos(), levelItem1Pos, radiusSqr) then heroList[#heroList + 1] = _entity end end end elseif levelItem1.ItemData.Width then local levelItem1Dir = levelItem1.ItemData.ItemDir local width = levelItem1.ItemData.Width local length = levelItem1.ItemData.Length for i,_entity in ipairs(LogicUpdateManager.EntityList_Sync) do if _entity.isHero then if FP.V2.IsInRectRange(_entity:GetLogicPos(), levelItem1Pos, levelItem1Dir, length, width) then heroList[#heroList + 1] = _entity end end end else logging.error(LTAG.ERROR, "HYW : levelItem1 不是一个区域,无法调用 BattleEffect.HeroesInLevelItemTransport BattleEffectID : ", params.effectData.ID) end local levelItem2Pos = levelItem2.ItemData.ItemPos if spreadType == 1 then -- spreadType == 1 表示随机分布 if levelItem2.ItemData.Radius then local levelItem2Radius = levelItem2.ItemData.Radius for i,hero in ipairs(heroList) do SystemManager.OnConvey(hero, LogicRandom.GetRandomPointInCircle(nil, levelItem2Radius, 43554319, _tempV2):Add(levelItem2Pos)) end elseif levelItem2.ItemData.Width then local width = levelItem2.ItemData.Width local length = levelItem2.ItemData.Length for i,hero in ipairs(heroList) do SystemManager.OnConvey(hero, LogicRandom.GetRandomPointInRect(nil, width, length, 43554619, _tempV2):Add(levelItem2Pos)) end else logging.error(LTAG.ERROR, "HYW : 警告!!试图以散布的形式调用 BattleEffect.HeroesInLevelItemTransport,但是目标元素不是一个区域!", params.effectData.ID) for i,hero in ipairs(heroList) do SystemManager.OnConvey(hero, levelItem2Pos) end end else for i,hero in ipairs(heroList) do SystemManager.OnConvey(hero, levelItem2Pos) end end end end end function BattleEffect.AddBuffToDragonArteryCarrier(params) if LevelManager.CurLevelFunc.dragonArteryEntity then for i,buffId in ipairs(params.effectData.intParams) do SystemManager.AddBuff(LevelManager.CurLevelFunc.dragonArteryEntity, buffId, params.caster) end end end function BattleEffect.AddBuffToHeroWithSameCamp(params) local caster = params.caster local entityList = CampManager.GetEntityListOfCampId(caster:GetCampID()) if entityList then local buffIdList = params.effectData.intParams for i,entity in ipairs(entityList) do if entity:IsHero() and entity:IsValid() then for i,buffId in ipairs(buffIdList) do SystemManager.AddBuff(entity, buffId, caster) end end end else logging.error(LTAG.ERROR, "HYW : entityList nil Error @BattleEffect.AddBuffToHeroWithSameCamp") end end function BattleEffect.AddBuffToEnemyHero(params) local caster = params.caster local enemy2dList = CampManager.Get2DEnitityListExceptCampId(caster:GetCampID()) local buffIdList = params.effectData.intParams for i,enemyList in ipairs(enemy2dList) do for i,entity in ipairs(enemyList) do if entity:IsHero() then for i,buffId in ipairs(buffIdList) do SystemManager.AddBuff(entity, buffId, caster) end end end end end -- 创建一个entity并驾驶(伪大变身)交互功能用 function BattleEffect.Interact_CreateAndControlEntity(params) BattleEffect.CreateAndControlEntity(params, params.caster) end -- 创建一个entity并驾驶(伪大变身) function BattleEffect.CreateAndControlEntity(params, forceDriver) local driver = forceDriver or params.target local comp_Base = driver.components.base if comp_Base.CurCharacterData ~= driver._logicInitData._characterData then ChangeAvatarSystem.ChangeAvatar(driver,0) end local characterType = params.effectData.intParams[1] -- Hero = 0, Monster = 1, NPC = 2, Adjutant = 3,-- local characterID = params.effectData.intParams[2] -- 创建怪不用统一的接口 BattleEffect._CreateMonster local posV2 = driver:GetLogicPos() local dirV2 = driver:GetLogicRotateDir() EntityFactory.SetType_ID(characterType, characterID) EntityFactory.SetPos_Dir(posV2, dirV2) EntityFactory.SetParams("CampID", driver:GetCampID()) local entity = EntityFactory.DoCreateEntity() -- 被驾驶的entity -- 属性继承(非实时属性跟随其变化) if params.effectData.intParams[3] ~= 1 then SystemManager.OnAdopted(entity,driver ,false ,FP.Const.One) end SystemManager.ForceDrive(driver,entity, nil, true) SystemManager.DisActive(driver ,true) -- 隐藏武将 EventSystem.Dispatch(EventID.UIBattle_HeroElement_Create, entity.ExpEntity, nil, driver) -- 替换名字版为司机的 end -- 取消控制一个entity并让且死亡(伪大变身回来) function BattleEffect.CancelControlAndDeadEntity(params) local carEntity = params.target local driver = carEntity.components.drive.BeDrivedByEntity if driver then SystemManager.OffDrive(driver) -- 为了防止发送AfterDrivedVehicleDead事件。(为区分car被打死和自动消失) end SystemManager.DeadQuit(carEntity) end -- 给分身加上buff function BattleEffect.AddBuffToIllusion(params) local illusionEntity = params.outParams.illusion if illusionEntity then SystemManager.AddBuff(illusionEntity, params.effectData.intParams[1], params.outParams.master) else logging.error(LTAG.ERROR, "【gws】:BattleEffect.AddBuffToIllusion依赖的事件不存在 illusion 参数。 策划查看下bufftrigger表的说明中的事件参数") end end --绑定目标单位到子弹上 function BattleEffect.BindToMissile(params) params.target.components.record:BindToMissile(params.outParams.missile) end function BattleEffect.SetRotateToBindingMissile(params) local bindingMissile = params.target.components.record.bindingMissile if bindingMissile then if not bindingMissile.Unload then params.target.components.move:SetLogicRotateDir(bindingMissile.MoveDir) else params.target.components.record:BindToMissile(nil) end end end local NEAREST_TARGET_FIND_PARAM function BattleEffect.CallByNearsetMonsterPosAndDirOfLevelItem(params) local levelItem = params.outParams.levelItem if levelItem then if not NEAREST_TARGET_FIND_PARAM then NEAREST_TARGET_FIND_PARAM = { campType = LuaConst.ETargetCampType.ALL, ignoreCanNotBeTargetBuff = true, ignoreBeSkillTargetBuff = true, monsterTypes = {}, noInvincible = false, regionParams = { shapeType = LuaConst.ERegionShapeType.CIRCLE, shapeNumParams = {100}, }, sortParams = { sortType = LuaConst.ETargetSortType.DIST_NEAR }, } end NEAREST_TARGET_FIND_PARAM.monsterTypes[1] = params.effectData.intParams[1] + 100 --参数以枚举ESearchTargetCharacterType指定monsterType,需要在原始指定的monsterType+100 NEAREST_TARGET_FIND_PARAM.regionParams.pos = levelItem.ItemData.ItemPos local target = TargetManager.GetTarget(params.target, NEAREST_TARGET_FIND_PARAM) if target then params.callBulletId = params.effectData.intParams[2] params.forcePos = target.components.move.LogicPos BattleEffect._Call(params) end end end --------region effect functions end end end------------------------------- --参数构造方法 --------------------ParamsBuilder ↓↓↓↓↓↓↓↓↓--------------------------- function BattleEffect.ParamsBuilder_PileDamageFactor(effectData,params) params.value = effectData.floatParams[1] return params end function BattleEffect.ParamsBuilder_HpLessStep(effectData,params) local requiredParamsLength = 4 if #effectData.floatParams >= requiredParamsLength then params.threshold = effectData.floatParams[1] params.startValue = effectData.floatParams[2] params.step = effectData.floatParams[3] params.deltaValue = effectData.floatParams[4] params.contentThreshold = effectData.intParams[1] == 1 params.hpBaseEntity = effectData.intParams[2] == 1 and params.outParams.target or params.caster else params = nil logging.error(LTAG.ERROR, "HYW : BattleEffect ", effectData.ID, " floatParams长度为 : ", #effectData.floatParams, " 长度必须大于", requiredParamsLength) end return params end function BattleEffect.ParamsBuilder_HpLessStepPileDmgFactor(effectData,params) return BattleEffect.ParamsBuilder_HpLessStep(effectData,params) end function BattleEffect.ParamsBuilder_HpLessStepChangeAttr(effectData,params) params = BattleEffect.ParamsBuilder_HpLessStep(effectData,params) params.prop = effectData.stringParam return params end function BattleEffect.ParamsBuilder_ReturnDamage(effectData,params) params.returnDamageType = effectData.intParams[1] params.returnDamageValue = effectData.floatParams[1] end function BattleEffect.ParamsBuilder_PileDmgFactorIfHasBuff(effectData,params) if effectData.intParams[1] == 1 then params.checkTarget = params.target elseif effectData.intParams[1] == 2 then params.checkTarget = params.caster else logging.error(LTAG.ERROR, "HYW : checkTarget nil Error ! BattleEffectData ID : ", effectData.ID) end params.checkBuffID = effectData.intParams[2] params.value = effectData.floatParams[1] return params end function BattleEffect.ParamsBuilder_PileDmgFactorOnMissile(effectData,params) params.checkMissileIDs = effectData.intParams params.value = effectData.floatParams[1] return params end function BattleEffect.ParamsBuilder_ChangeAttrByEntityNum(effectData,params) params.entityType = effectData.intParams[1] params.step = effectData.floatParams[1] params.base = effectData.floatParams[2] or 0 params.max = effectData.floatParams[3] params.distance = effectData.floatParams[4] params.min = effectData.floatParams[5] params.prop = effectData.stringParam end function BattleEffect.Paramsbuilder_SetTimeScale(effectData,params) params.timescale = effectData.floatParams[1] if params.effectData.intParams[1] == 1 then --指定持续时间 params.duration = effectData.floatParams[2] elseif params.effectData.intParams[1] == 2 then --跟Buff持续时间保持一致 if params.buffUpdateData then params.duration = tonumberV1(params.buffUpdateData.BuffTimer) * 1000 end end end function BattleEffect.ParamsBuilder_Silent(effectData,params) params.banKeyPosList = SLIENT_KEY_POS_LIST end function BattleEffect.ParamsBuilder_CreateHookMissile(effectData, params) if params.outParams and params.outParams.target then params.target = params.outParams.target end end paramsBuilderDic["PileDamageFactor"] = BattleEffect.ParamsBuilder_PileDamageFactor paramsBuilderDic["HpLessStepPileDmgFactor"] = BattleEffect.ParamsBuilder_HpLessStepPileDmgFactor paramsBuilderDic["HpLessStepChangeAttr"] = BattleEffect.ParamsBuilder_HpLessStepChangeAttr paramsBuilderDic["PileDmgFactorIfHasBuff"] = BattleEffect.ParamsBuilder_PileDmgFactorIfHasBuff paramsBuilderDic["PileDmgFactorOnMissile"] = BattleEffect.ParamsBuilder_PileDmgFactorOnMissile paramsBuilderDic["ChangeAttrByEntityNum"] = BattleEffect.ParamsBuilder_ChangeAttrByEntityNum paramsBuilderDic["Silent"] = BattleEffect.ParamsBuilder_Silent paramsBuilderDic["ReturnDamage"] = BattleEffect.ParamsBuilder_ReturnDamage paramsBuilderDic["SetTimeScale"] = BattleEffect.Paramsbuilder_SetTimeScale paramsBuilderDic["CreateHookMissile"] = BattleEffect.ParamsBuilder_CreateHookMissile --------------------↑↑↑↑↑↑↑↑↑↑↑↑---------------------------------- --工具方法 -------------------Tools ↓↓↓↓↓↓↓↓↓--------------------------- --计算血量越少,改变值阶梯变化规则下的改变值 function BattleEffect.GetHpLessStepDelta(params) local delta = nil local hpPecent = tonumberV1(params.hpBaseEntity.components.attr:HitPointPercents()) if hpPecent < params.threshold or (params.contentThreshold and hpPecent == params.threshold) then if params.step > 0 then --delta = math.floor((params.threshold - hpPecent) / params.step) * params.deltaValue + params.startValue --old 没有使用定点数 --new↓ 使用定点数 _tempV1:Reset(params.threshold):Sub(hpPecent):Div(params.step) _tempV1:Reset(math.floor(tonumberV1(_tempV1))):Mul(params.deltaValue):Add(params.startValue) delta = tonumberV1(_tempV1) --new↑ 使用定点数 if delta < 0 then delta = 0 end else logging.error(LTAG.ERROR, "HYW : step <= 0 Error!!") end end return delta end function BattleEffect._GetChangeAttrByEntityNumDelta(params) local delta = nil local entityNum = 0 if params.entityType == 1 then --本阵营单位数量 if params.distance and params.distance > 0 then --有距离限制 entityNum = TargetManager.GetEntityCountInCircleOfCamp(params.caster:GetLogicPos(), params.distance, params.caster:GetCampID()) else --无距离限制 entityNum = CampManager.GetEntityCountOfCampId(params.caster:GetCampID()) end elseif params.entityType == 2 then --敌人单位数量 if params.distance and params.distance > 0 then --有距离限制 entityNum = TargetManager.GetEnemyCountInCircle(params.caster, params.caster:GetLogicPos(), params.distance) else --无距离限制 entityNum = TargetManager.GetEnemyCount(params.caster) end else logging.error(LTAG.ERROR, "HYW : params.entityType bad delta : ", params.entityType, " effectId : ", effectData.ID) end --delta = params.base + params.step * entityNum --old 没有使用定点数 --new↓ _tempV1:Reset(params.step):Mul(entityNum):Add(params.base) delta = tonumberV1(_tempV1) --new↑ if params.max then delta = math.min(params.max, delta) end if params.min then delta = math.max(params.min, delta) end return delta end --------------------↑↑↑↑↑↑↑↑↑↑↑↑---------------------------------- return BattleEffect