diff --git a/game/engines/default/engine/Entity.lua b/game/engines/default/engine/Entity.lua index 2b318a01e8a984b59d90bd47fcb5a6ab75643ece..ca0bf1223be89b7c1bc49bed23216ce5884e2218 100644 --- a/game/engines/default/engine/Entity.lua +++ b/game/engines/default/engine/Entity.lua @@ -741,24 +741,9 @@ function _M:loadList(file, no_default, res, mod, loaded) newEntity = function(t) -- Do we inherit things ? if t.base then - -- Append array part - for i = 1, #res[t.base] do - local b = res[t.base][i] - if type(b) == "table" and not b.__CLASSNAME then b = table.clone(b, true) - elseif type(b) == "table" and b.__CLASSNAME then b = b:clone() - end - table.insert(t, b) - end - - for k, e in pairs(res[t.base]) do - if k ~= "define_as" and type(k) ~= "number" then - if type(t[k]) == "table" and type(e) == "table" then - copy_recurs(t[k], e) - elseif not t[k] and type(t[k]) ~= "boolean" then - t[k] = e - end - end - end + local temp = table.clone(res[t.base], true, {define_as = true}) + table.mergeAppendArray(temp, t, true) + t = temp t.base = nil end diff --git a/game/engines/default/engine/utils.lua b/game/engines/default/engine/utils.lua index 5c5cc62cd1ea5745fa1626a74c399bf61f34637b..7f4b09e88af4fb5f3a8bdd7b442bb0c873b079a7 100644 --- a/game/engines/default/engine/utils.lua +++ b/game/engines/default/engine/utils.lua @@ -37,14 +37,19 @@ function table.print(src, offset) end end -function table.clone(tbl, deep, k_filter) +--- Returns a clone of a table +-- @param tbl The original table to be cloned +-- @param deep Boolean to determine if recursive cloning occurs +-- @param k_skip A table containing key values set to true if you want to skip them. +-- @return The cloned table. +function table.clone(tbl, deep, k_skip) local n = {} - k_filter = k_filter or {} + k_skip = k_skip or {} for k, e in pairs(tbl) do - if not k_filter[k] then + if not k_skip[k] then -- Deep copy subtables, but not objects! if deep and type(e) == "table" and not e.__CLASSNAME then - n[k] = table.clone(e, true, k_filter) + n[k] = table.clone(e, true, k_skip) else n[k] = e end @@ -53,14 +58,34 @@ function table.clone(tbl, deep, k_filter) return n end -function table.merge(dst, src, deep, k_filter) - k_filter = k_filter or {} +table.NIL_MERGE = {} + +--- Merges two tables in-place. +-- The table.NIL_MERGE is a special value that will nil out the corresponding dst key. +-- @param dst The destination table, which will have all merged values. +-- @param src The source table, supplying values to be merged. +-- @param deep Boolean that determines if tables will be recursively merged. +-- @param k_skip A table containing key values set to true if you want to skip them. +-- @param k_skip_deep Like k_skip, except this table is passed on to the deep recursions. +-- @param addnumbers Boolean that determines if two numbers will be added rather than replaced. +function table.merge(dst, src, deep, k_skip, k_skip_deep, addnumbers) + k_skip = k_skip or {} + k_skip_deep = k_skip_deep or {} for k, e in pairs(src) do - if not k_filter[k] then + if not k_skip[k] and not k_skip_deep[k] then + -- Recursively merge tables if deep and dst[k] and type(e) == "table" and type(dst[k]) == "table" and not e.__CLASSNAME then - table.merge(dst[k], e, true, k_filter) + table.merge(dst[k], e, deep, nil, k_skip_deep, addnumbers) + -- Clone tables if into the destination elseif deep and not dst[k] and type(e) == "table" and not e.__CLASSNAME then - dst[k] = table.clone(e, true, k_filter) + dst[k] = table.clone(e, deep, nil, k_skip_deep) + -- Nil out any NIL_MERGE entries + elseif e == table.NIL_MERGE then + dst[k] = nil + -- Add number entries if "add" is set + elseif addnumbers and dst[k] and type(dst[k]) == "number" and type(e) == "number" then + dst[k] = dst[k] + e + -- Or simply replace/set with the src value else dst[k] = e end @@ -69,49 +94,33 @@ function table.merge(dst, src, deep, k_filter) return dst end -function table.mergeAdd(dst, src, deep) - for k, e in pairs(src) do - if deep and dst[k] and type(e) == "table" and type(dst[k]) == "table" and not e.__CLASSNAME then - table.mergeAdd(dst[k], e, true) - elseif deep and not dst[k] and type(e) == "table" and not e.__CLASSNAME then - dst[k] = table.clone(e, true) - elseif dst[k] and type(e) == "number" then - dst[k] = dst[k] + e - else - dst[k] = e - end - end - return dst -end - ---- Merges additively the named fields and append the array part --- Yes this is weird and you'll probably not need it, but the engine does :) -function table.mergeAddAppendArray(dst, src, deep) +function table.mergeAppendArray(dst, src, deep, k_skip, k_skip_deep, addnumbers) -- Append the array part + k_skip = k_skip or {} for i = 1, #src do + k_skip[i] = true local b = src[i] - if deep and type(b) == "table" and not b.__CLASSNAME then b = table.clone(b, true) - elseif deep and type(b) == "table" and b.__CLASSNAME then b = b:clone() - end - table.insert(dst, b) - end - - -- Copy the table part - for k, e in pairs(src) do - if type(k) ~= "number" then - if deep and dst[k] and type(e) == "table" and type(dst[k]) == "table" and not e.__CLASSNAME then - -- WARNING we do not recurse on ourself but instead of the simple mergeAdd, we do not want to do the array stuff for subtables - -- yes I warned you this is weird - table.mergeAdd(dst[k], e, true) - elseif deep and not dst[k] and type(e) == "table" and not e.__CLASSNAME then - dst[k] = table.clone(e, true) - elseif dst[k] and type(e) == "number" then - dst[k] = dst[k] + e + if deep and type(b) == "table" then + if b.__CLASSNAME then + b = b:clone() else - dst[k] = e + b = table.clone(b, true) end end + table.insert(dst, b) end + -- Copy the table part + return table.merge(dst, src, deep, k_skip, k_skip_deep, addnumbers) +end + +function table.mergeAdd(dst, src, deep, k_skip, k_skip_deep) + return table.merge(dst, src, deep, k_skip, k_skip_deep, true) +end + +--- Merges additively the named fields and append the array part +-- Yes this is weird and you'll probably not need it, but the engine does :) +function table.mergeAddAppendArray(dst, src, deep, k_skip, k_skip_deep) + return table.mergeAppendArray(dst, src, deep, k_skip, k_skip_deep, true) end function table.append(dst, src) @@ -153,13 +162,16 @@ function table.from_list(t, k, v) for i, e in ipairs(t) do tt[e[k or 1]] = e[v or 2] end return tt end - +--- Adds missing keys from the src table to the dst table. +-- @param dst The destination table, which will have all merged values. +-- @param src The source table, supplying values to be merged. +-- @param deep Boolean that determines if tables will be recursively merged. function table.update(dst, src, deep) for k, e in pairs(src) do if deep and dst[k] and type(e) == "table" and type(dst[k]) == "table" and not e.__CLASSNAME then - table.update(dst[k], e, true) + table.update(dst[k], e, deep) elseif deep and not dst[k] and type(e) == "table" and not e.__CLASSNAME then - dst[k] = table.clone(e, true) + dst[k] = table.clone(e, deep) elseif not dst[k] and type(dst[k]) ~= "boolean" then dst[k] = e end @@ -1531,11 +1543,11 @@ end function util.browserOpenUrl(url) local tries = { - "rundll32 url.dll,FileProtocolHandler %s", -- Windows - "open %s", -- OSX - "xdg-open %s", -- Linux - portable way + "rundll32 url.dll,FileProtocolHandler %s", -- Windows + "open %s", -- OSX + "xdg-open %s", -- Linux - portable way "gnome-open %s", -- Linux - Gnome - "kde-open %s", -- Linux - Kde + "kde-open %s", -- Linux - Kde "firefox %s", -- Linux - try to find something "mozilla-firefox %s", -- Linux - try to find something } diff --git a/game/modules/tome/ai/shadow.lua b/game/modules/tome/ai/shadow.lua index b7465549a3ce37495321de10a53ef39cb4958e45..01858fc53fd340506b0b834a1f5ec12b778fc680 100644 --- a/game/modules/tome/ai/shadow.lua +++ b/game/modules/tome/ai/shadow.lua @@ -168,9 +168,9 @@ local function shadowMoveToLocationTarget(self) -- try to move around actors..if we fail we will just try a a new target if not self:canMove(tx, ty, false) then local dir = util.getDir(tx, ty, self.x, self.y) - tx, ty = util.coordAddDir(self.x, self.y, dir_sides[dir].left) + tx, ty = util.coordAddDir(self.x, self.y, util.dirSides(dir, self.x, self.y).left) if not self:canMove(tx, ty, false) then - tx, ty = util.coordAddDir(self.x, self.y, dir_sides[dir].right) + tx, ty = util.coordAddDir(self.x, self.y, util.dirSides(dir, self.x, self.y).right) if not self:canMove(tx, ty, false) then --game.logPlayer(self.summoner, "#PINK#%s move fails", self.name:capitalize()) return false diff --git a/game/modules/tome/class/interface/Combat.lua b/game/modules/tome/class/interface/Combat.lua index 7c13562791c881f1f3499364f6e93a55943984b7..2e9a9ead6e716f12a1acda160380cd73a2a351a4 100644 --- a/game/modules/tome/class/interface/Combat.lua +++ b/game/modules/tome/class/interface/Combat.lua @@ -483,9 +483,9 @@ function _M:attackTargetWith(target, weapon, damtype, mult, force_dam) -- Onslaught if hitted and self:attr("onslaught") then - local dir = util.getDir(target.x, target.y, self.x, self.y) - local lx, ly = util.coordAddDir(self.x, self.y, dir_sides[dir or 6].left) - local rx, ry = util.coordAddDir(self.x, self.y, dir_sides[dir or 6].right) + local dir = util.getDir(target.x, target.y, self.x, self.y) or 6 + local lx, ly = util.coordAddDir(self.x, self.y, util.dirSides(dir, self.x, self.y).left) + local rx, ry = util.coordAddDir(self.x, self.y, util.dirSides(dir, self.x, self.y).right) local lt, rt = game.level.map(lx, ly, Map.ACTOR), game.level.map(rx, ry, Map.ACTOR) if target:checkHit(self:combatAttack(weapon), target:combatPhysicalResist(), 0, 95, 10) and target:canBe("knockback") then @@ -1070,7 +1070,7 @@ function _M:physicalCrit(dam, weapon, target, atk, def) if target:hasHeavyArmor() and target:knowTalent(target.T_ARMOUR_TRAINING) then chance = chance - target:getTalentLevel(target.T_ARMOUR_TRAINING) * 1.9 end - + if target:attr("combat_critreduction") then chance = chance - target:attr("combat_critreduction") end diff --git a/game/modules/tome/data/talents/techniques/dualweapon.lua b/game/modules/tome/data/talents/techniques/dualweapon.lua index 93ce71c14144ea71a2517cfbc97459c60e0857d3..7395b54f5a8125f726ca1522960ab5ff60f16773 100644 --- a/game/modules/tome/data/talents/techniques/dualweapon.lua +++ b/game/modules/tome/data/talents/techniques/dualweapon.lua @@ -214,8 +214,8 @@ newTalent{ local dir = util.getDir(x, y, self.x, self.y) if dir == 5 then return nil end - local lx, ly = util.coordAddDir(self.x, self.y, dir_sides[dir].left) - local rx, ry = util.coordAddDir(self.x, self.y, dir_sides[dir].right) + local lx, ly = util.coordAddDir(self.x, self.y, util.dirSides(dir, self.x, self.y).left) + local rx, ry = util.coordAddDir(self.x, self.y, util.dirSides(dir, self.x, self.y).right) local lt, rt = game.level.map(lx, ly, Map.ACTOR), game.level.map(rx, ry, Map.ACTOR) local hit diff --git a/game/modules/tome/data/talents/techniques/pugilism.lua b/game/modules/tome/data/talents/techniques/pugilism.lua index 9ce5f6b464895a2a51bf4fbfac3b86cc4c051c61..007c6fb0c628ed24a4882f99fc0dbab22dd86e03 100644 --- a/game/modules/tome/data/talents/techniques/pugilism.lua +++ b/game/modules/tome/data/talents/techniques/pugilism.lua @@ -201,8 +201,8 @@ newTalent{ if core.fov.distance(self.x, self.y, x, y) == 1 then -- get left and right side local dir = util.getDir(x, y, self.x, self.y) - local lx, ly = util.coordAddDir(self.x, self.y, dir_sides[dir].left) - local rx, ry = util.coordAddDir(self.x, self.y, dir_sides[dir].right) + local lx, ly = util.coordAddDir(self.x, self.y, util.dirSides(dir, self.x, self.y).left) + local rx, ry = util.coordAddDir(self.x, self.y, util.dirSides(dir, self.x, self.y).right) local lt, rt = game.level.map(lx, ly, Map.ACTOR), game.level.map(rx, ry, Map.ACTOR) hit1 = self:attackTarget(target, nil, damage, true) diff --git a/game/modules/tome/dialogs/ArenaFinish.lua b/game/modules/tome/dialogs/ArenaFinish.lua index 954c637e6b83c3c7e84b5e4bc3feeada66f084f5..a23a4f7d303bd5e130f4b91f98d6d14f512c296f 100644 --- a/game/modules/tome/dialogs/ArenaFinish.lua +++ b/game/modules/tome/dialogs/ArenaFinish.lua @@ -149,7 +149,7 @@ function _M:use(item) elseif act == "dump" then game:registerDialog(require("mod.dialogs.CharacterSheet").new(self.actor)) elseif act == "log" then - game:registerDialog(require("mod.dialogs.ShowChatLog").new("Message Log", 0.6, game.logdisplay, profile.chat)) + game:registerDialog(require("mod.dialogs.ShowChatLog").new("Message Log", 0.6, game.uiset.logdisplay, profile.chat)) end end diff --git a/game/modules/tome/dialogs/DeathDialog.lua b/game/modules/tome/dialogs/DeathDialog.lua index a5b40917134c0afc5ce33f1f53590466727c25a1..10099a4ddd5ca78cb0f52c7e3a0563fc081f4234 100644 --- a/game/modules/tome/dialogs/DeathDialog.lua +++ b/game/modules/tome/dialogs/DeathDialog.lua @@ -109,13 +109,13 @@ function _M:resurrectBasic(actor) game:unregisterDialog(self) game.level.map:redisplay() actor.energy.value = game.energy_to_act - + -- apply cursed equipment if actor.hasTalent and actor.hasTalent(actor.T_DEFILING_TOUCH) then local t = self:getTalentFromId(self.T_DEFILING_TOUCH) t.updateCurses(self, t, true) end - + actor.changed = true game.paused = true end @@ -195,7 +195,7 @@ function _M:use(item) elseif act == "dump" then game:registerDialog(require("mod.dialogs.CharacterSheet").new(self.actor)) elseif act == "log" then - game:registerDialog(require("mod.dialogs.ShowChatLog").new("Message Log", 0.6, game.logdisplay, profile.chat)) + game:registerDialog(require("mod.dialogs.ShowChatLog").new("Message Log", 0.6, game.uiset.logdisplay, profile.chat)) elseif act == "cheat" then game.logPlayer(self.actor, "#LIGHT_BLUE#You resurrect! CHEATER!") @@ -247,7 +247,7 @@ end function _M:generateList() local list = {} local allow_res = true - + -- Pause the game game:onTickEnd(function() game.paused = true diff --git a/src/map.c b/src/map.c index 6ef9442aac3fb5de921e17ecc55059aea8cfbd9e..69ed2b6d9c466780d77a17b4b1f0d1ba08b8b8ef 100644 --- a/src/map.c +++ b/src/map.c @@ -957,8 +957,8 @@ static void map_update_seen_texture(map_type *map) for (ii = 0; ii < map->w+10; ii++) { int i = ii, j = jj; - ptr = (((1+f)*j + (i & f)) * map->seens_map_w + (1+f)*i) * 4; int ri = i-5, rj = j-5; + ptr = (((1+f)*j + (ri & f)) * map->seens_map_w + (1+f)*i) * 4; ri = (ri < 0) ? 0 : (ri >= map->w) ? map->w-1 : ri; rj = (rj < 0) ? 0 : (rj >= map->h) ? map->h-1 : rj; if ((i < 0) || (j < 0) || (i >= map->w+10) || (j >= map->h+10))