Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ---
- game/engines/default/engine/Object.lua | 7 ++
- game/engines/default/engine/Zone.lua | 8 +--
- game/engines/default/engine/utils.lua | 96 ++++++++++++++++++++++++++++
- game/modules/tome/class/Object.lua | 73 ++++++++++++++++-----
- game/modules/tome/class/interface/Combat.lua | 12 +++-
- 5 files changed, 172 insertions(+), 24 deletions(-)
- diff --git a/game/engines/default/engine/Object.lua b/game/engines/default/engine/Object.lua
- index 4dff64c..594c6e2 100644
- --- a/game/engines/default/engine/Object.lua
- +++ b/game/engines/default/engine/Object.lua
- @@ -244,3 +244,10 @@ end
- function _M:getEntityKind()
- return "object"
- end
- +
- +--- List of ego rules to be applied.
- +_M.ego_rules = {}
- +
- +function _M:addEgoRule(rule)
- + table.insert(self.ego_rules, rule)
- +end
- diff --git a/game/engines/default/engine/Zone.lua b/game/engines/default/engine/Zone.lua
- index 8f612c0..005c48d 100644
- --- a/game/engines/default/engine/Zone.lua
- +++ b/game/engines/default/engine/Zone.lua
- @@ -475,8 +475,8 @@ function _M:finishEntity(level, type, e, ego_filter)
- ego.instant_resolve = nil
- -- Void the uid, we dont want to erase the base entity's one
- ego.uid = nil
- - -- Merge additively but with array appending, so that nameless resolvers are not lost
- - table.mergeAddAppendArray(e, ego, true)
- + -- Merge with Object's ego merge rules.
- + table.ruleMergeAppendAdd(e, ego, self.object_class.ego_rules)
- e.name = newname
- e.egoed = true
- end
- @@ -563,8 +563,8 @@ function _M:finishEntity(level, type, e, ego_filter)
- ego.instant_resolve = nil
- -- Void the uid, we dont want to erase the base entity's one
- ego.uid = nil
- - -- Merge additively but with array appending, so that nameless resolvers are not lost
- - table.mergeAddAppendArray(e, ego, true)
- + -- Merge with Object's ego merge rules.
- + table.ruleMergeAppendAdd(e, ego, self.object_class.ego_rules)
- e.name = newname
- e.egoed = true
- end
- diff --git a/game/engines/default/engine/utils.lua b/game/engines/default/engine/utils.lua
- index 4b633ab..dbaeca9 100644
- --- a/game/engines/default/engine/utils.lua
- +++ b/game/engines/default/engine/utils.lua
- @@ -173,6 +173,102 @@ function table.merge(dst, src, deep, k_skip, k_skip_deep, addnumbers)
- return dst
- end
- +
- +table.rules = {}
- +
- +-- Turns any rule names into the actual rules. rules should be an
- +-- integer-key only list of functions and rule names. rule_defs is a
- +-- lookup table for rule definitions, defaulting to table.rules.
- +function table.parseRules(rules, rule_defs)
- + if rules.__parsed then return end
- + rule_defs = rule_defs or table.rules
- + for i, r in ipairs(rules) do
- + if type(r) == 'string' then
- + rules[i] = rule_defs[r]
- + end
- + end
- + rules.__parsed = true
- +end
- +
- +--[[
- +Applies a series of rules to a pair of tables. rules should be a list of functions
- +to be applied, in order, until one returns true.
- +
- +All keys in the table src are looped through, starting with array
- +indices, and then the rest of the keys. The rules are given the
- +following arguments:
- +The dst table's value for the current key.
- +The src table's value for the current key.
- +The current key.
- +The dst table.
- +The src table.
- +The list of rules.
- +A state table which the rules are free to modify.
- +--]]
- +function table.applyRules(dst, src, rules, state)
- + if not dst or not src then return end
- + state = state or {}
- + local used_keys = {}
- + -- First loop through with ipairs so we get the numbers in order.
- + for k, v in ipairs(src) do
- + for _, rule in ipairs(rules) do
- + if rule(dst[k], src[k], k, dst, src, rules, state) then
- + used_keys[k] = true
- + break
- + end
- + end
- + end
- + -- Then loop through with pairs, skipping the ones we got with ipairs.
- + for k, v in pairs(src) do
- + if not used_keys[k] then
- + for _, rule in ipairs(rules) do
- + if rule(dst[k], src[k], k, dst, src, rules, state) then
- + break
- + end
- + end
- + end
- + end
- +end
- +
- +-- Simply overwrites the value.
- +table.rules.overwrite = function(dvalue, svalue, key, dst)
- + dst[key] = svalue
- + return true
- +end
- +-- Does the recursion.
- +table.rules.recurse = function(dvalue, svalue, key, dst, src, rules, state)
- + if type(dvalue) ~= 'table' or type(svalue) ~= 'table' then return end
- + state = table.clone(state)
- + state.path = table.clone(state.path) or {}
- + table.insert(state.path, key)
- + table.applyRules(dvalue, svalue, rules, state)
- + return true
- +end
- +-- Appends indices.
- +table.rules.append = function(dvalue, svalue, key, dst, src, rules, state)
- + if type(key) ~= 'number' then return end
- + table.insert(dst, svalue)
- + return true
- +end
- +-- Adds numbers
- +table.rules.add = function(dvalue, svalue, key, dst)
- + if type(dvalue) ~= 'number' or type(svalue) ~= 'number' then return end
- + dst[key] = dvalue + svalue
- + return true
- +end
- +
- +--[[
- +A convenience method for merging tables, appending numeric indices,
- +and adding number values in addition to other rules.
- +--]]
- +function table.ruleMergeAppendAdd(dst, src, rules)
- + rules = table.clone(rules)
- + for _, rule in pairs {'append', 'recurse', 'add', 'overwrite'} do
- + table.insert(rules, table.rules[rule])
- + end
- + table.applyRules(dst, src, rules)
- +end
- +
- function table.mergeAppendArray(dst, src, deep, k_skip, k_skip_deep, addnumbers)
- -- Append the array part
- k_skip = k_skip or {}
- diff --git a/game/modules/tome/class/Object.lua b/game/modules/tome/class/Object.lua
- index ea4fc1d..9dc4562 100644
- --- a/game/modules/tome/class/Object.lua
- +++ b/game/modules/tome/class/Object.lua
- @@ -605,23 +605,43 @@ function _M:getTextualDesc(compare_with, use_actor)
- desc:add(found and {"color","WHITE"} or {"color","GREEN"}, "Special effect when this weapon hits: "..special, {"color","LAST"}, true)
- end
- - special = ""
- - if combat.special_on_crit then
- - special = combat.special_on_crit.desc
- - end
- - found = false
- - for i, v in ipairs(compare_with or {}) do
- - if v[field] and v[field].special_on_crit then
- - if special ~= v[field].special_on_crit.desc then
- - desc:add({"color","RED"}, "Special effect when this weapon crits: "..v[field].special_on_crit.desc, {"color","LAST"}, true)
- - else
- - found = true
- - end
- - end
- - end
- - if special ~= "" then
- - desc:add(found and {"color","WHITE"} or {"color","GREEN"}, "Special effect when this weapon crits: "..special, {"color","LAST"}, true)
- - end
- + -- Special on crit
- + local have_list = combat.special_on_crit or {}
- + if have_list and have_list.desc then have_list = {have_list} end
- + local lose_list = {}
- + for i, v in pairs(compare_with or {}) do
- + if v[field] and v[field].special_on_crit then
- + lose_list = v[field].special_on_crit
- + break
- + end
- + end
- + if lose_list and lose_list.desc then lose_list = {lose_list} end
- + local have_descs, lose_descs = {}, {}
- + for i, v in ipairs(have_list) do
- + have_descs[v.desc] = true
- + end
- + for i, v in ipairs(lose_list) do
- + lose_descs[v.desc] = true
- + end
- + -- kept specials
- + for i, v in ipairs(lose_list) do
- + if have_descs[v.desc] then
- + desc:add({"color","WHITE"}, "Special effect when this weapon crits: "..v.desc, {"color","LAST"}, true)
- + end
- + end
- + -- gained specials
- + for i, v in ipairs(have_list) do
- + if not lose_descs[v.desc] then
- + desc:add({"color","GREEN"}, "Special effect when this weapon crits: "..v.desc, {"color","LAST"}, true)
- + end
- + end
- + -- lost specials
- + for i, v in ipairs(lose_list) do
- + if not have_descs[v.desc] then
- + desc:add({"color","RED"}, "Special effect when this weapon crits: "..v.desc, {"color","LAST"}, true)
- + end
- + end
- +
- local special = ""
- if combat.special_on_kill then
- @@ -1672,3 +1692,22 @@ function _M:addedToLevel(level, x, y)
- self.__price_level_mod = util.getval(level.data.objects_cost_modifier, self)
- end
- end
- +
- +-- Merge special_on_crit values.
- +_M:addEgoRule(
- + function(dvalue, svalue, key, dst, src, rules, state)
- + -- Only work on the special_on_crit key.
- + if key ~= 'special_on_crit' then return end
- + -- If the special isn't a table, make it an empty one.
- + if type(dvalue) ~= 'table' then dvalue = {} end
- + if type(svalue) ~= 'table' then svalue = {} end
- + -- If the special is a single special, wrap it to allow multiple.
- + if dvalue.fct then dvalue = {dvalue} end
- + if svalue.fct then svalue = {svalue} end
- + -- Save changes to the specials.
- + dst[key] = dvalue
- + src[key] = svalue
- + -- Return false so we can let the normal table merge take care of
- + -- the rest.
- + return false
- +end)
- diff --git a/game/modules/tome/class/interface/Combat.lua b/game/modules/tome/class/interface/Combat.lua
- index d0ee9fa..36b4a83 100644
- --- a/game/modules/tome/class/interface/Combat.lua
- +++ b/game/modules/tome/class/interface/Combat.lua
- @@ -751,9 +751,15 @@ function _M:attackTargetWith(target, weapon, damtype, mult, force_dam)
- weapon.special_on_hit.fct(weapon, self, target, dam)
- end
- - if hitted and crit and weapon and weapon.special_on_crit and weapon.special_on_crit.fct and (not target.dead or weapon.special_on_crit.on_kill) then
- - weapon.special_on_crit.fct(weapon, self, target, dam)
- - end
- + if hitted and crit and weapon and weapon.special_on_crit then
- + local specials = weapon.special_on_crit
- + if specials.fct then specials = {specials} end
- + for _, special in ipairs(specials) do
- + if special.fct and (not target.dead or special.on_kill) then
- + special.fct(weapon, self, target, dam)
- + end
- + end
- + end
- if hitted and weapon and weapon.special_on_kill and weapon.special_on_kill.fct and target.dead then
- weapon.special_on_kill.fct(weapon, self, target, dam)
- --
- 1.8.3.1
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement