|
|
--[[
This file demonstrates how attributes are getting calculated and how they can
be linked to each other.
See http://doc.manasource.org/attributes.xml for more info.
--]]
local function recalculate_base_attribute(being, attribute_name)
local old_base = being:base_attribute(attribute_name)
local new_base = old_base
if attribute == "Accuracy" then
-- Provisional
new_base = being:modified_attribute("Dexterity")
elseif attribute == "Defense" then
new_base = 0.3 * being:modified_attribute("Vitality")
elseif attribute == "Dodge" then
-- Provisional
new_base = being:modified_attribute("Agility")
elseif attribute == "M. dodge" then
-- TODO
new_base = 1
elseif attribute == "M. defense" then
-- TODO
new_base = 0
elseif attribute == "Bonus att. speed" then
-- TODO
new_base = 0
elseif attribute == "HP regeneration" then
local hp_per_sec = being:modified_attribute("Vitality") * 0.05
new_base = hp_per_sec * TICKS_PER_HP_REGENERATION / 10
elseif attribute == "HP" then
local hp = being:modified_attribute("HP")
local max_hp = being:modified_attribute("Max HP")
if hp > max_hp then
new_base = new_base - hp - max_hp
end
elseif attribute == "Max HP" then
local vit = being:modified_attribute("Vitality")
new_base = (vit + 3) * (vit + 20) * 0.125
elseif attribute == "Movement speed" then
-- Provisional
new_base = 3.0 + being:modified_attribute("Agility") * 0.08
elseif attribute == "Capacity" then
-- Provisional
new_base = 2000 + being:modified_attribute("Strength") * 180
elseif attribute == "Global ability cooldown" then
-- Provisional
new_base = 100 - being:modified_attribute("Willpower")
elseif attribute == "Level" then
-- Provisional
--new_base = 100 - 100 * math.pow(0.99999, being:base_attribute("XP"))
new_base = being:base_attribute("XP") / 20
end
if new_base ~= old_base then
being:set_base_attribute(attribute_name, new_base)
end
end
local function update_derived_attributes(being, attribute)
local attribute_name = attribute:name()
if attribute_name == "Strength" then
recalculate_base_attribute(being, "Capacity")
elseif attribute_name == "Agility" then
recalculate_base_attribute(being, "Dodge")
elseif attribute_name == "Vitality" then
recalculate_base_attribute(being, "Max HP")
recalculate_base_attribute(being, "HP regeneration")
recalculate_base_attribute(being, "Defense")
elseif attribute_name == "Intelligence" then
-- unimplemented
elseif attribute_name == "Willpower" then
recalculate_base_attribute(being, "Global ability cooldown")
elseif attribute_name == "XP" then
recalculate_base_attribute(being, "Level")
end
end
on_recalculate_base_attribute(recalculate_base_attribute)
on_update_derived_attribute(update_derived_attributes)
function Entity:level()
return math.floor(self:base_attribute("Level"))
end
function Entity:give_experience(experience)
local old_experience = self:base_attribute("XP")
local old_level = self:level()
self:set_base_attribute("XP", old_experience + experience)
if self:level() > old_level then
self:say("LEVELUP!!! " .. self:level())
self:set_attribute_points(self:attribute_points() + 1)
self:set_correction_points(self:correction_points() + 1)
end
end
local mobs_config = require "scripts/monster/settings"
local exp_receiver = {}
-- Give EXP for monster kills
local function monster_damaged(mob, source, damage)
local receiver = exp_receiver[mob] or { chars = {}, total = 0 }
exp_receiver[mob] = receiver
if source and source:type() == TYPE_CHARACTER then
mob:change_anger(source, damage)
local current_damage = receiver.chars[source]
if not current_damage then
on_remove(source, function(removed_being)
receiver[removed_being] = nil
end)
on_death(source, function(removed_being)
receiver[removed_being] = nil
end)
end
current_damage = (current_damage or 0) + damage
receiver.chars[source] = current_damage
receiver.total = receiver.total + damage
end
if mob:base_attribute("HP") == 0 then
local mob_config = mobs_config[mob:name()]
local experience = mob_config.experience or 0
for char, damage in pairs(receiver.chars) do
local gained_exp = damage / receiver.total * experience
char:give_experience(gained_exp)
end
end
end
for _, monsterclass in pairs(get_monster_classes()) do
monsterclass:on_damaged(monster_damaged)
end
|