HeroPlugin.lua 12.1 KB
local HeroPlugin = {}


function HeroPlugin.bind(Hero)

	function Hero:mylog(contents)
		contents = contents or {}
		if contents["cint1"] or contents["cint2"] or contents["cint3"] then
			print("heroLog error log have cint1 or cint2 or cint3 ", debug.traceback())
		end
		contents["cint1"] = self:getProperty("id")
		contents["cint2"] = self:getProperty("type")

		self.owner:mylog("hero_action", contents)
	end

	function Hero:getMaxLevel()
		return math.min(#csvdb["unit_expCsv"], csvdb["unit_breakCsv"][self:getProperty("breakL")].levelLimit)
	end


	-- 纯% 的属性
	local PercentAttr = {
		crit = 6, 			-- 暴击
		critHurt = 8, 		-- 暴伤
		vampire = 9, 		-- 吸血
		pierce = 10, 		-- 穿透
	}
	-- base 原, add 增加值 ,atype 增加类型(0 值 1%)
	local function addAttr(base, add, atype, attrName)
		base = base or 0
		add = add or 0
		if PercentAttr[attrName] then
			atype = 0
		end
		if atype == 1 then
			return base * add / 100
		else
			return add
		end
	end

	--角色自身 = 初始 *(1+升级)*(1+突破)*(1+觉醒)+ 天赋升级 + 天赋阶段
	function Hero:getBaseAttrs(params)
		params = params or {}
		local unitData  = csvdb["unitCsv"][self:getProperty("type")]
		local level = params.level or self:getProperty("level")
		local breakL = params.breakL or self:getProperty("breakL")
		local wakeL = params.wakeL or self:getProperty("wakeL")
		local talent = params.talent or self:getProperty("talent")
		local heroCfgId = self:getProperty("type")
		--天赋
		local talentAttrS = {}

		-- 四个基础属性
		local cfgName = "unit_talent_"..heroCfgId.."Csv"
		local curRank = talent:getv(0, 1)
		local curLv = talent:getv(1,1) - 1
		for i, value in ipairs(csvdb[cfgName]) do
			if i <= curRank then
				for lv, cfg in ipairs(value) do
					if i < curRank or lv <= curLv then
						if cfg.effect ~= 99 then
							if not talentAttrS[cfg.effect] then
								talentAttrS[AttsEnumEx[cfg.effect]] = 0
							end
							talentAttrS[AttsEnumEx[cfg.effect]] = cfg.strength
						end
					else
						break
					end
				end
			else
				break
			end
		end
		
		for _, attrName in pairs(AttsEnumEx) do
			if talentAttrS[attrName] then
				talentAttrS[attrName] = addAttr(unitData[attrName], talentAttrS[attrName], 1, attrName)
			end
		end

		-- 信赖属性
		local faithAttr = {}
		local faith = self:getProperty("faith")
		local faithConfig = csvdb["unit_trustCsv"]
		for lvl = 1, #faithConfig do
			if faith >= faithConfig[lvl].exp then
				local add = faithConfig[lvl]["position_"..unitData.position]:toArray(true, "=")
				faithAttr[AttsEnumEx[add[1]]] = (faithAttr[AttsEnumEx[add[1]]] or 0) + add[2]
			end
		end
		for _, attrName in pairs(AttsEnumEx) do
			if faithAttr[attrName] then
				faithAttr[attrName] = addAttr(unitData[attrName], faithAttr[attrName], 1, attrName)
			end
		end

		local attrs = {}
		for _, attName in pairs(AttsEnumEx) do
			attrs[attName] = unitData[attName] or 0
		end
		--升级、突破、觉醒
		local lData = csvdb["unit_expCsv"][level]
		local blData = csvdb["unit_breakCsv"][breakL]
		local wData = csvdb["unit_wakeCsv"][wakeL]
		for attr, value in pairs(attrs) do
			attrs[attr] = attrs[attr] + addAttr(attrs[attr], lData[attr .. "Level"], 1, attr)
			attrs[attr] = attrs[attr] + addAttr(attrs[attr], blData[attr .. "Level"], 1, attr)
			attrs[attr] = attrs[attr] + addAttr(attrs[attr], wData[attr .. "Level"], 1, attr) + (talentAttrS[attr] or 0) + (faithAttr[attr] or 0)
		end

		return attrs
	end


	--当前属性 = 角色属性值 * (1 + 装备套装(百分比) + 铭文套装(百分比))+ (装备(固定)+ 铭文(固定))
	function Hero:getTotalAttrs(params)
		params = params or {}
		local attrs = self:getBaseAttrs()
		-- 装备零件
		local equipAttrs = self:getRuneEquipAttrs()

		for _, attName in pairs(AttsEnumEx) do
			attrs[attName] = attrs[attName] or 0
			attrs[attName] = attrs[attName] + addAttr(attrs[attName], equipAttrs.percent[attName], 1, attName)
			attrs[attName] = attrs[attName] + addAttr(attrs[attName], equipAttrs.value[attName], 0, attName)
		end

		-- 羁绊加成
	   --  if params.activeRelation then
	   --      for k, attName in pairs(AttsEnumEx) do
				-- attrs[attName] = attrs[attName] + addAttr(attrs[attName], params.activeRelation[attName], 1, attName)
	   --      end
	   --  end
		return attrs
	end

	-- 当前零件和装备增加属性
	function Hero:getRuneEquipAttrs()
		local attrs = {value = {}, percent = {}}
		for _, attName in pairs(AttsEnumEx) do
			attrs.value[attName] = 0
			attrs.percent[attName] = 0
		end
		local equipSuits = {}
		-- 装备效果
		for typ,level in pairs(self:getProperty("equip"):toNumMap()) do
			if level > 0 then
				local data = csvdb["equipCsv"][typ][level]
				for k,v in pairs(data.attr1:toNumMap()) do
					attrs.value[AttsEnumEx[k]] = attrs.value[AttsEnumEx[k]] + v
				end
				for k,v in pairs(data.attr2:toNumMap()) do
					attrs.value[AttsEnumEx[k]] = attrs.value[AttsEnumEx[k]] + v
				end
				if data.suit ~= "" then
					if not equipSuits[data.suit] then equipSuits[data.suit] = {} end
					table.insert(equipSuits[data.suit], data)
				end
			end
		end
		-- 装备套装效果
		for suitId,eDatas in pairs(equipSuits) do
			local suitCsv = csvdb["equip_suitCsv"][tonumber(suitId)]
			if suitCsv then 
				local effects = suitCsv.effect:toTableArray(true)
				local count = #eDatas
				if count >= 2 then
					attrs.percent[AttsEnumEx[effects[1][1]]] = attrs.percent[AttsEnumEx[effects[1][1]]] + effects[1][2]
				end
				if count >= 3 then
					attrs.percent[AttsEnumEx[effects[2][1]]] = attrs.percent[AttsEnumEx[effects[2][1]]] + effects[1][2]
				end
				if count >= 4 then
					attrs.percent[AttsEnumEx[effects[3][1]]] = attrs.percent[AttsEnumEx[effects[3][1]]] + effects[3][2]
				end
			end
		end
		-- 零件效果
	    local suits = {}
	    for _, uid in pairs(self:getProperty("rune"):toNumMap()) do
	        if uid > 0 then
	            local rune = self.owner.runeBag[uid]
	            local csvData = csvdb["runeCsv"][rune:getProperty("type")][rune:getProperty("id")]
	            local runeRareData = csvdb["rune_rareCsv"][csvData.rarity]
	            local buildData = csvdb["rune_buildCsv"][rune:getProperty("level")]
	            for k, v in pairs(rune:getProperty("attrs"):toNumMap()) do
	                local attName = AttsEnumEx[k]
	                --零件的加成属性有特殊需求 填的是 10倍的值
	                --rare的effect不影响 特殊属性

	                --铭文单件普通属性=attr*(1+[rune_build表effect]/100*[rune_rare表effect]/100)
					--铭文单件特殊属性=attr+[rune_build表effect]

	                local effect = buildData[attName]
	                if not PercentAttr[attName] then
	                    effect = buildData[attName] * runeRareData.effect / 100
	                end
	                attrs.value[attName] = attrs.value[attName] + (v / 100) + addAttr(v / 100, effect, 1, attName)
	            end
	            
	            if not suits[csvData.suit] then suits[csvData.suit] = {} end
	            table.insert(suits[csvData.suit],csvData)
	        end
	    end
		-- 零件套装效果
		for suitId,runeDatas in pairs(suits) do
			local suitCsv = csvdb["rune_suitCsv"][tonumber(suitId)]
			if suitCsv then
				local effects = suitCsv.effect:toTableArray(true)
				local count = #runeDatas
				if count >= 2 and AttsEnumEx[effects[1][1]]then
					attrs.percent[AttsEnumEx[effects[1][1]]] = attrs.percent[AttsEnumEx[effects[1][1]]] + effects[1][2]
				end
				if count >= 4 and AttsEnumEx[effects[2][1]] then
					attrs.percent[AttsEnumEx[effects[2][1]]] = attrs.percent[AttsEnumEx[effects[2][1]]] + effects[2][2]
				end
				if count >= 6 and AttsEnumEx[effects[3][1]] then
					attrs.percent[AttsEnumEx[effects[3][1]]] = attrs.percent[AttsEnumEx[effects[3][1]]] + effects[3][2]
				end
			end
		end
		return attrs
	end


	-- 战斗力(当前属性)= POWER[(生命 + 防御 * 7 + 闪避 * 4)*(攻击*4 + 命中 * 2)*(1 + 暴击几率/100 * 暴击伤害/100)* 攻击速度 / 60000 ,0.8 ]
	-- function Hero:getBattleValue(activeRelation) -- isReal包括队伍加成
	function Hero:getBattleValue() -- isReal包括队伍加成
	    -- local attrs = self:getTotalAttrs({activeRelation = activeRelation})
	    local attrs = self:getTotalAttrs()
	    local battleValue = ((attrs["hp"] + attrs["def"] * 7 + attrs["miss"] * 4) * (attrs["atk"] * 4 + attrs["hit"] * 2) * (1 + attrs["crit"]/100 * attrs["critHurt"]/100) * attrs["atkSpeed"] / 600000) ^ 0.8
	    return math.floor(battleValue)
	end

	function Hero:saveBattleValue()
		local battleValue = self:getBattleValue()
		if battleValue ~= self:getProperty("battleV") then
			self:setProperty("battleV", battleValue)
		end
		return battleValue
	end

	-- 技能1234 对应必杀技,冒险技,被动技,战斗技
	function Hero:getSkillLevel(idx)
		local level = 1
		for wakeL = 1, self:getProperty("wakeL") do
			local wakeData = csvdb["unit_wakeCsv"][wakeL]
			for _, slot in ipairs(wakeData.skill:toArray(true,"=")) do
				if slot == idx then
					level = level + 1
				end
			end
		end
		return level
	end

	-- 天赋获得的技能
	function Hero:getTalentSkill()
		local TalentEnum = {
			[1] = 1,			-- 血量
			[2] = 2,			-- 攻击
			[3] = 3,			-- 物理防御
			[4] = 4,			-- 命中
			[5] = 5, 			-- 闪避
		}
	    local talentCsv = csvdb["unit_talent_" .. self:getProperty("type") .. "Csv"]
	    local curLv = self:getProperty("talent"):getv(1,1) - 1
	    local curRan = self:getProperty("talent"):getv(0,1)
	    local skills = {}
	    for ran, data in ipairs(talentCsv) do
	        if ran <= curRan then
	            for lv, value in ipairs(data) do
	                if ran < curRan or lv <= curLv then
	                    if not TalentEnum[value.effect] then
	                        skills[value.strength] = true
	                    end
	                else
	                    break
	                end
	            end
	        else
	            break
	        end
	    end
	    return skills
	end

	function Hero:getSkillData(idx)
		local unitData = csvdb["unitCsv"][self:getProperty("type")]
		if idx == 1 then
			return csvdb["skill_specialCsv"][unitData.special]
		elseif idx == 2 then
			return csvdb["adv_battle_specialCsv"][unitData.adv]
		elseif idx == 3 then
			return csvdb["skill_passiveCsv"][unitData.passive]
		elseif idx == 4 then
			return csvdb["skill_blockCsv"][unitData.block]
		end
		return {}
	end

	function Hero:getRunes()
	    local rune = self:getProperty("rune")
	    if not rune or rune == "" then
	        rune = "1=0 2=0 3=0 4=0 5=0 6=0"
	    end
	    local result = rune:toNumMap()
	    for i = 1, 6 do
	        if not result[i] then
	            result[i] = 0
	        end
	    end
	    return result
	end

	-- 101 冒险战斗被动技
	-- 102 挂机战斗被动技
	function Hero:getRuneSkill(skillType)
	    local suits = {}
	    for _,uid in pairs(self:getRunes()) do
	        if uid > 0 then
	            local runeData = self.owner.runeBag[uid]
	            if not runeData then return  end
	            local csvData = csvdb["runeCsv"][runeData:getProperty("type")][runeData:getProperty("id")]
	            if not suits[csvData.suit] then suits[csvData.suit] = {} end
	            table.insert(suits[csvData.suit],csvData)
	        end
	    end

	    for suitId,runes in pairs(suits) do
	        local suitCsv = csvdb["rune_suitCsv"][tonumber(suitId)]
	        if not suitCsv then return  end
	        local effects = suitCsv.effect:toTableArray(true)
	        local count = #runes
	        if count >= 2 and effects[1][1] == skillType then
	            return effects[1][2]
	        end
	        if count >= 4 and effects[2][1] == skillType then
	            return effects[2][2]
	        end
	        if count >= 6 and effects[3][1] == skillType then
	            return effects[3][2]
	        end
	    end
	    return
	end

	-- 添加英雄信赖
	function Hero:addHeroFaith(exp)
		local faith = self:getProperty("faith")
		local config = csvdb["unit_trustCsv"]
		local star = self:getProperty("wakeL")
		local tmpExp = faith + exp
		for lvl = 1, #config do
			if star < config[lvl].star then
				break
			end
			if tmpExp < config[lvl].exp then
				faith = tmpExp
				break
			else
				faith = config[lvl].exp
			end
		end
		self:setProperty("faith", faith)
	end

end


return HeroPlugin