local function isLevelUp(inst,gexp)
--击杀5个蜘蛛可以升1级，此后每级需多击杀5个
	local NowLevel = inst.components.level.lv
	local NowExp = inst.components.level.exp + gexp
	local NeedExp = NowLevel*25 - NowExp 
	if NeedExp >0 then
		return false
	elseif NeedExp == 0 then
		return 0
	else
		return -NeedExp
	end
end
local function OnGetExp (inst,data)
	if inst.components.level.lv >=18 then --18级以后不再获取任何经验
		return	
	elseif data and data.GetExp then
		local gexp = data.GetExp	
		--判断是否升级
		--print("获取经验"..gexp)
		local surplus = isLevelUp(inst,gexp)
		if surplus then
			--print("剩余经验为"..surplus)
			local nlevel = inst.components.level.lv +1	
			inst.components.level.exp = 0 --经验在升级时要清零，余下的经验会通过GetExp事件再次获得
			inst.components.level.lv = nlevel--在这部分完成升级，是为了兼顾其他部分
			inst:PushEvent("levelup",{level = nlevel,surplus = surplus }) --一旦升级，就触发升级事件
		else
			--print("没有升级")
		
			local nexp = inst.components.level.exp + gexp
			--print("当前经验为"..nexp)
			inst.components.level.exp = nexp
			if gexp >0 then
				inst:PushEvent("HUDChanged",{tag = "Level",tag2 = "exp",nexp = nexp})
			end
		end

	end
end
local function OnLevelUp(inst,data)
	if data and data.level then
		local newlevel = data.level
		local surplus = data.surplus
		--print("触发升级:Lv"..newlevel)
		if inst.components.level.onlevelupfn then
			inst.components.level.onlevelupfn(inst,newlevel)
		end
		inst:PushEvent("HUDChanged",{tag = "Level",tag2 = "level",surplus = surplus,level = newlevel})
		--剩余的经验，用获取经验的事件再次触发，如果能升级则继续升级。
		inst:PushEvent("getexp",{GetExp = surplus})
	end
end




local level = Class(function(self, inst)
    self.inst = inst
	---需要保存的数据
	self.lv = 1
	self.exp = 0
	---其他
	self.inst:ListenForEvent("getexp",OnGetExp)--监听获得经验
	self.inst:ListenForEvent("levelup",OnLevelUp)--监听是否升级
end)



function level:SetLv(lv)
	self.lv = lv
end
function level:SetExp(nexp)
	self.exp = nexp
end

--用于给出击杀的经验获取
local function expcompute(victim)	
	if victim and not victim:HasTag("deciduoustree") then --限定不计算桦树精		
		local health = victim.components.health.maxhealth
		local damage = victim.components.combat.defaultdamage
		local period = victim.components.combat.min_attack_period
		local exprience = health*damage/period*3/400 --以蜘蛛为标准，1个蜘蛛5经验
		return exprience
	end
	return 0
end
local function OnKill(inst,data)--这个函数的重要作用在于推动事件发展
	local gexp = 0
	if data and data.victim then
		local victim = data.victim
		gexp = expcompute(victim)
	end
	if gexp >0 then
		inst:PushEvent("getexp",{GetExp = gexp})
	end
end
--初始化,获取组件生物初始数据，用于后续与等级相关的内容
function level:Init(nokill)
	local inst = self.inst
	if inst.components.hunger then
		self.hunger = inst.components.hunger.max
	end
	if inst.components.sanity then
		self.sanity = inst.components.sanity.max
	end
	if inst.components.health then
		self.health = inst.components.health.maxhealth
	end	
	--默认在击杀后获得经验,经验值采用内定形式：击杀怪物获得经验
	if nokill==nil or false then
		print("通过击杀获取经验")
		inst:ListenForEvent("killed",OnKill)
	end
end


--读取存档后对三围进行初始化
function level:LoadPostInit()
	local inst = self.inst
	local lv = self.lv
	if self.LvState then
		self.LvState(inst,lv)
	end
end
--设置与等级相关的三围属性变化，一般用于读取存档时的修改。
function level:SetLvStateFn(fn)
	self.LvState = fn
end

---直接调用此函数可以获取经验并触发相应事件
function level:GetExp(gexp)
	self.inst:PushEvent("getexp",{GetExp = gexp})
end
--获取等级和经验状态
function level:GetState()
	return self.lv,self.exp
end

--设置升级时的额外奖励
function level:SetOnLevelUpFn(fn)
	self.onlevelupfn = fn
end

---返回值直接返回到data里
function level:OnSave()
	return
	{
		level = self.lv,
		exprience = self.exp
	}
end
function level:OnLoad(data)
	if data then
		if data.level then
			self.lv = data.level
		end
		if data.exprience then
			self.exp = data.exprience
		end
	end
end

function level:test()
	--print("当前等级"..self.lv)
	--print("当前经验"..self.exp)
end



return level