summaryrefslogtreecommitdiff
path: root/example/scripts/attributes.lua
blob: 7a3f6098cffc65764c7314384f8fb1ff863d0675 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
--[[

 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