--属性 local AttrSystem = {} local private = {} local LuaConst=LuaConst local FP=FP local FP_NegOne = FP.Const.NegOne local FP_Zero = FP.Const.Zero local pairs = pairs local ipairs = ipairs local table_insert=table.insert local table_remove=table.remove local table_removebyvalue=table.removebyvalue local string_find=string.find local LuaConstInheritAttrTypePlus = LuaConst.InheritAttrType.Plus local LuaConstAdoptedAttrType = LuaConst.AdoptedAttrType local LuaConstAdoptedAttrPlusType = LuaConst.AdoptedAttrPlusType local BattleEventSystem_OnEntityDeletePCBuff = BattleEventSystem.OnEntityDeletePCBuff --[[ 保存公式改变的属性 calData是RuntimeDataManager.New_AttrCalculate的返回值,包含Value、AssignType --]] function AttrSystem.CollectModify(entity, attrType, calData) local attrComponent = entity.components.attr local realTimeAttr = LuaConst.RealtimeAttrType[attrType] -- 实时数值属性不记录 if realTimeAttr then return else --其他属性 local calDataList = attrComponent.AttrModificationDic[attrType] if not calDataList then calDataList = {} attrComponent.AttrModificationDic[attrType] = calDataList end table_insert(calDataList, calData) --子嗣属性也要改变 private.RefreshChildenAttrComp(attrComponent,attrType ) end end local _tempList = {} --[[ 属性更新,删除buff时 ※注意,这里的buffId并不一定是一个buffId,而是一个key。当buff修改属性时,这个key就是buffId。当BattleEffect修改属性时,这个key是BattleEffect.GetChangeAttrKey构造出来的key --]] function AttrSystem.DeleteBuffUpdateAttr(entity, buffId, sourceEntityId, attrType, deleteToBuffLayer) local attrComponent = entity.components.attr for key,calDataList in pairs(attrComponent.AttrModificationDic) do if attrType == nil or attrType == key then local removed = false local count = #calDataList if deleteToBuffLayer and deleteToBuffLayer > 0 then table.clearArray(_tempList) end for i = count , 1 , -1 do local calData = calDataList[i] if string_find(calData.SourceBuffId,buffId) then if sourceEntityId <= 0 or calData.SourceEntityId == sourceEntityId then --sourceEntityId <= 0不记录来源 if deleteToBuffLayer and deleteToBuffLayer > 0 then table.insert(_tempList, calData) else table_remove(calDataList,i) removed = true end end end end if deleteToBuffLayer and deleteToBuffLayer > 0 then if #_tempList > deleteToBuffLayer then for i=deleteToBuffLayer+1,#_tempList do for j,v in ipairs(calDataList) do if v == _tempList[i] then table_remove(calDataList, j) removed = true break end end end end end if removed then -- 有变换才更新 private.ReCalculate(attrComponent,key, calDataList) end end end local pcBuffList = attrComponent.PCBuffList for i,pcBuffData in ipairs(pcBuffList) do if string_find(pcBuffData.buffId,buffId) and pcBuffData.sourceEntityID == sourceEntityId then table_remove(pcBuffList,i) -- 这个地方只有在update时buff到期才会运行 --attrComponent.pc:Sub(pcBuffData.leftVal) -- 减少护盾值 attrComponent:AttrSub("pc",pcBuffData.leftVal) -- 减少护盾值 SystemManager.OnSubPCAttr(entity, nil, pcBuffData.leftVal ,true ,false) BattleEventSystem_OnEntityDeletePCBuff(entity,buffId,pcBuffData.leftVal,pcBuffData.curTotalVal) SystemManager.OnSubExpTotalPCAttr(entity,pcBuffData.curTotalVal) break end end end function AttrSystem.RecalculateAllModifyOfEntity(entity) local attrComponent = entity.components.attr for key,calDataList in pairs(attrComponent.AttrModificationDic) do private.ReCalculate(attrComponent,key, calDataList) end end function private.ReCalculate(attrComponent,key,calDataList) local initval = attrComponent.InitAttr[key] local result = initval for i,calData in ipairs(calDataList) do result = private.CalculateAttribution(calData, result) end result = DataSheetUtil.AttrDataGetResult(key,result,initval) attrComponent:SetAttrBaseValue(key,result) --子嗣属性也要改变 private.RefreshChildenAttrComp(attrComponent,key ) end function private.CalculateAttribution(calData, value) local result = value if calData.AssignType == LuaConst.AssignType.Direct then result = calData.Value elseif calData.AssignType == LuaConst.AssignType.Plus then result = value + calData.Value elseif calData.AssignType == LuaConst.AssignType.Subtract then result = value - calData.Value elseif calData.AssignType == LuaConst.AssignType.Multiply then result = value * calData.Value elseif calData.AssignType == LuaConst.AssignType.Divide then result = value / calData.Value end return result end function AttrSystem.IsRealtimeAttrType(attrType) return attrType == "hp" or attrType == "sa" or attrType == "am" or attrType == "pc" end function AttrSystem.OnRevive(entity) entity.components.attr:SetOnRevive() end function AttrSystem.OnSwitchHero(fromEntity, toEntity) if LevelManager.CurLevelFunc.SwitchHeroInheritSA then toEntity:SetAttrBaseValue("sa",fromEntity.components.attr.sa) end end --[[ 攻击进入 --]] local _saTemp1 = FP.newV1(0) function AttrSystem.OnAttackEnter(entity, skillData) if skillData then local saCost = skillData.MpCost if saCost == FP_Zero then return end if saCost == FP_NegOne then local salmt = entity:GetAttrValue(LuaConst.AttrType.salmt) _saTemp1:Reset(salmt):Negative() else _saTemp1:Reset(saCost):Negative() end entity.components.attr:AddSA(_saTemp1,entity, nil, true) end end --delta是变化值,带符号的,跟op类型无关 function AttrSystem.OnHPChange(entity, realDelta, value, op, hpChangeType, missileData) entity.components.record:OnHPChange(realDelta, value, op, hpChangeType, missileData) end --[[ 属性的继承 - 只是和伤害有关系的属性 ]]-- function AttrSystem.OnAdopted(entity , fatherEntity ,independent ,hpInherit, inheritAttrType) local sonAttrComp = entity.components.attr local fatherAttrComp = fatherEntity.components.attr local attrTypeList = inheritAttrType == LuaConstInheritAttrTypePlus and LuaConstAdoptedAttrPlusType or LuaConstAdoptedAttrType for k,attr in pairs(attrTypeList) do local attrVal = fatherAttrComp:GetAttrValue(attr) if sonAttrComp.InitAttr[attr] then sonAttrComp:ResetInitAttrValue(attr,attrVal) else sonAttrComp:SetInitAttrValue(attr,attrVal:cloneV1()) end if attr == attrTypeList.hplmt then if hpInherit ~= FP.Const.Zero then sonAttrComp:InitAttrMul(attr,hpInherit) end end sonAttrComp:SetAttrBaseValue(attr,sonAttrComp.InitAttr[attr]) if attr == attrTypeList.hplmt then sonAttrComp:SetAttrBaseValue("hp",sonAttrComp.InitAttr.hplmt) end end --父子绑定 if not independent then table_insert(fatherAttrComp.SonAttrCompList , sonAttrComp) sonAttrComp.FatherAttrComp = fatherAttrComp sonAttrComp.InheritFatherAttrType = inheritAttrType end -- 刷新自身buff导致的属性修改 AttrSystem.RecalculateAllModifyOfEntity(entity) end -- 更新子嗣的属性 function private.RefreshChildenAttrComp(fatherAttrComp,key ) if not LuaConstAdoptedAttrPlusType[key] then return end for _,sonAttrComp in ipairs(fatherAttrComp.SonAttrCompList) do local attrTypeList = sonAttrComp.InheritFatherAttrType == LuaConstInheritAttrTypePlus and LuaConstAdoptedAttrPlusType or LuaConstAdoptedAttrType if attrTypeList[key] then sonAttrComp:ResetInitAttrValue(key,fatherAttrComp:GetAttrValue(key)) local initval = sonAttrComp.InitAttr[key] local calDataList = sonAttrComp.AttrModificationDic[key] local result = initval if calDataList then for i,calData in ipairs(calDataList) do result = private.CalculateAttribution(calData, result) end end result = DataSheetUtil.AttrDataGetResult(key,result,initval) sonAttrComp:SetAttrBaseValue(key,result) for keyAttr,calDataList in pairs(sonAttrComp.AttrModificationDic) do if keyAttr == key then private.ReCalculate(sonAttrComp, key, calDataList) end end end end end --[[ 死亡 --]] function AttrSystem.OnDead(entity) local attrComp = entity.components.attr for i,sonAttrComp in ipairs(attrComp.SonAttrCompList) do -- 如果是父死亡 sonAttrComp.FatherAttrComp = nil end if attrComp.FatherAttrComp then -- 如果儿子死亡 table_removebyvalue(attrComp.FatherAttrComp.SonAttrCompList ,attrComp , true ) end end function AttrSystem.OnBreakAm(entity) local am = entity.components.attr.am if am > FP.Const.Zero then local preAm = am:cloneV1() entity.components.attr:SetAttrBaseValue("am",0) return preAm,am end end --[[ 护盾添加 --]] function AttrSystem.OnAddPCAttr(entity, buffId , addValue ,sourceEntityId) local attrComp = entity.components.attr local pcBuffList = attrComp.PCBuffList local findOld = false for i,pcBuffData in ipairs(pcBuffList) do if pcBuffData.buffId == buffId and pcBuffData.sourceEntityID == sourceEntityId then pcBuffData.leftVal:Add(addValue) pcBuffData.curTotalVal:Add(addValue) findOld = true break end end if not findOld then table_insert(attrComp.PCBuffList, { buffId = buffId, sourceEntityID = sourceEntityId, leftVal = addValue:cloneV1(), --该buff剩余的pc值 curTotalVal = addValue:cloneV1(), --该buff添加过的总值 }) end end --[[ 护盾值减少 --]] local _tempLeftDelta = FP.newV1(0) function AttrSystem.OnSubPCAttr(entity,delta, limitBuffId) -- buffId指定扣除哪些buff的护盾值 local attrComp = entity.components.attr local pcBuffList = attrComp.PCBuffList _tempLeftDelta:Reset(delta) for i,pcBuffData in ipairs(pcBuffList) do if limitBuffId == nil or limitBuffId == pcBuffData.buffId then if pcBuffData.leftVal <= _tempLeftDelta then -- 值不够 _tempLeftDelta:Sub(pcBuffData.leftVal) pcBuffData.leftVal:Reset() -- 删除buff else pcBuffData.leftVal:Sub(_tempLeftDelta) break end end end local count = #pcBuffList for i = count,1,-1 do local pcBuffData = attrComp.PCBuffList[i] if pcBuffData.leftVal[1] <= 0 then table_remove(pcBuffList,i) -- 这个在前面就能防止,删除buff时死循环调用DeleteBuffUpdateAttr SystemManager.OnSubExpTotalPCAttr(entity,pcBuffData.curTotalVal) SystemManager.DeleteBuff(entity,pcBuffData.buffId ,LogicUpdateManager._entityDic[pcBuffData.sourceEntityID]) BattleEventSystem_OnEntityDeletePCBuff(entity,pcBuffData.buffId,pcBuffData.leftVal,pcBuffData.curTotalVal) end end end function AttrSystem.EntityCopyPCInfo(entity, targetEntity) local targetPCBuffList = targetEntity.components.attr.PCBuffList local pcBuffList = entity.components.attr.PCBuffList table.clear(pcBuffList) -- 先清理 for i,pcBuffData in ipairs(targetPCBuffList) do table_insert(pcBuffList, { buffId = pcBuffData.buffId, sourceEntityID = pcBuffData.sourceEntityID, leftVal = pcBuffData.leftVal:cloneV1(), --该buff剩余的pc值 curTotalVal = pcBuffData.curTotalVal:cloneV1(), --该buff添加过的总值 }) end end return AttrSystem