Skip to content
Snippets Groups Projects
Commit 15824ba9 authored by dg's avatar dg
Browse files

recursive object savefile handler

trollshaws population


git-svn-id: http://svn.net-core.org/repos/t-engine4@209 51575b47-30f0-44d4-a5cc-537603b46e54
parent 6d57454c
No related branches found
No related tags found
No related merge requests found
......@@ -100,6 +100,20 @@ function _M:saveLevel(level)
zip:close()
end
local function resolveSelf(o, base, allow_object)
if o.__CLASSNAME and not allow_object then return end
local change = {}
for k, e in pairs(o) do
if type(e) == "table" then
if e == class.LOAD_SELF then change[#change+1] = k
else resolveSelf(e, base, false)
end
end
end
for i, k in ipairs(change) do o[k] = base end
end
function _M:loadReal(load)
if self.loaded[load] then return self.loaded[load] end
local f = fs.open(self.load_dir..load, "r")
......@@ -112,6 +126,10 @@ function _M:loadReal(load)
end
f:close()
local o = class.load(table.concat(lines), load)
-- Resolve self referencing tables now
resolveSelf(o, o, true)
self.loaded[load] = o
return o
end
......
......@@ -153,21 +153,26 @@ function _M:save(filter, allow, savefile)
return res
end
local function deserialize(string)
_M.LOAD_SELF = {}
local function deserialize(string, src)
local f, err = loadstring(string)
if err then print("error deserializing", string, err) end
setfenv(f, {
loadstring = loadstring,
loadObject = function(n)
-- print("wants to load",n)
return engine.Savefile.current_save:loadReal(n)
if n == src then
return _M.LOAD_SELF
else
return engine.Savefile.current_save:loadReal(n)
end
end,
})
return f()
end
function load(str, delayloading)
local obj = deserialize(str)
local obj = deserialize(str, delayloading)
if obj then
-- print("setting obj class", obj.__CLASSNAME)
setmetatable(obj, {__index=require(obj.__CLASSNAME)})
......
......@@ -40,7 +40,7 @@ The ToME combat system has the following attributes:
- damage: raw damage done
]]
function _M:attackTarget(target, damtype, mult, noenergy)
local speed = nil
local speed, hit = nil, false
-- Cancel stealth early if we are noticed
if self:isTalentActive(self.T_STEALTH) and target:canSee(self) then
......@@ -53,8 +53,9 @@ function _M:attackTarget(target, damtype, mult, noenergy)
if self:getInven(self.INVEN_MAINHAND) then
for i, o in ipairs(self:getInven(self.INVEN_MAINHAND)) do
if o.combat then
local s = self:attackTargetWith(target, o.combat, damtype, mult)
local s, h = self:attackTargetWith(target, o.combat, damtype, mult)
speed = math.max(speed or 0, s)
hit = hit or h
end
end
end
......@@ -67,8 +68,9 @@ function _M:attackTarget(target, damtype, mult, noenergy)
end
for i, o in ipairs(self:getInven(self.INVEN_OFFHAND)) do
if o.combat then
local s = self:attackTargetWith(target, o.combat, damtype, offmult)
local s, h = self:attackTargetWith(target, o.combat, damtype, offmult)
speed = math.max(speed or 0, s)
hit = hit or h
end
end
end
......@@ -89,6 +91,7 @@ function _M:attackTarget(target, damtype, mult, noenergy)
self:useTalent(self.T_STEALTH)
self.changed = true
end
return hit
end
--- Computes a logarithmic chance to hit, opposing chance to hit to chance to miss
......
......@@ -4,8 +4,8 @@ setDefaultProjector(function(src, x, y, type, dam)
if target then
-- Reduce damage with resistance
local res = target.resists[type] or 0
if res == 10 then dam = 0
else dam = dam * (100 / (100 - res))
if res >= 100 then dam = 0
else dam = dam / (100 * (100 - res))
end
local flash = game.flash.NEUTRAL
......
local Talents = require("engine.interface.ActorTalents")
newEntity{
define_as = "BASE_NPC_TROLL",
type = "giant", subtype = "troll",
display = "T", color=colors.UMBER,
combat = { dam=resolvers.rngavg(15,25), atk=3, apr=6, physspeed=1.2 },
body = { INVEN = 10, MAINHAND=1, OFFHAND=1, BODY=1 },
equipment = resolvers.equip{ {type="weapon", subtype="greatsword"} },
drops = resolvers.drops{chance=20, nb=1, {} },
life_rating = 15,
life_regen = 2,
max_stamina = 90,
autolevel = "warrior",
ai = "dumb_talented_simple", ai_state = { talent_in=5, },
energy = { mod=1 },
stats = { str=20, dex=8, mag=6, con=16 },
resists = { [DamageType.FIRE] = -50 },
}
newEntity{ base = "BASE_NPC_TROLL",
name = "forest troll", color=colors.YELLOW_GREEN,
desc = [[Green-skinned and ugly, this massive humanoid glares at you, clenching wart-covered green fists.]],
level_range = {1, 50}, exp_worth = 1,
rarity = 6,
max_life = resolvers.rngavg(100,120),
combat_armor = 4, combat_def = 0,
}
newEntity{ base = "BASE_NPC_TROLL",
name = "stone troll", color=colors.DARK_SLATE_GRAY,
desc = [[A giant troll with scabrous black skin. With a shudder, you notice the belt of dwarf skulls around his massive waist.]],
level_range = {3, 50}, exp_worth = 1,
rarity = 7,
max_life = resolvers.rngavg(120,140),
combat_armor = 7, combat_def = 0,
talents = resolvers.talents{ [Talents.T_STAMINA_POOL]=1, [Talents.T_STUN]=1, },
}
newEntity{ base = "BASE_NPC_TROLL",
name = "cave troll", color=colors.SLATE,
desc = [[This huge troll wields a massive spear and has a disturbingly intelligent look in its piggy eyes.]],
level_range = {7, 50}, exp_worth = 1,
rarity = 7,
max_life = resolvers.rngavg(120,140),
combat_armor = 9, combat_def = 3,
talents = resolvers.talents{ [Talents.T_STAMINA_POOL]=1, [Talents.T_STUN]=1, [Talents.T_KNOCKBACK]=1,},
}
newEntity{ base = "BASE_NPC_TROLL",
name = "mountain troll", color=colors.UMBER,
desc = [[A large and athletic troll with an extremely tough and warty hide.]],
level_range = {12, 50}, exp_worth = 1,
rarity = 7,
max_life = resolvers.rngavg(120,140),
combat_armor = 12, combat_def = 4,
talents = resolvers.talents{ [Talents.T_STAMINA_POOL]=1, [Talents.T_STUN]=1, [Talents.T_KNOCKBACK]=1, },
}
......@@ -122,3 +122,63 @@ newTalent{
return ([[Releases poisonous spores at the target.]])
end,
}
newTalent{
name = "Stun",
type = {"physical/other", 1},
points = 5,
cooldown = 6,
stamina = 8,
require = { stat = { str=12 }, },
action = function(self, t)
local t = {type="hit", range=self:getTalentRange(t)}
local x, y, target = self:getTarget(t)
if not x or not y or not target then return nil end
if math.floor(core.fov.distance(self.x, self.y, x, y)) > 1 then return nil end
local hit = self:attackTarget(target, 0.5 + self:getTalentLevel(t) / 10, true)
-- Try to stun !
if hit then
if target:checkHit(self:combatAttackStr(weapon.combat), target:combatPhysicalResist(), 0, 95, 5 - self:getTalentLevel(t) / 2) and target:canBe("stun") then
target:setEffect(target.EFF_STUNNED, 2 + self:getTalentLevel(t), {})
else
game.logSeen(target, "%s resists the stunning blow!", target.name:capitalize())
end
end
return true
end,
info = function(self, t)
return ([[Hits the target with your weapon doing %d%% damage, if the atatck hits, the target is stunned.]]):format(100 * (0.5 + self:getTalentLevel(t) / 10))
end,
}
newTalent{
name = "Knockback",
type = {"physical/other", 1},
points = 5,
cooldown = 6,
stamina = 8,
require = { stat = { str=12 }, },
action = function(self, t)
local t = {type="hit", range=self:getTalentRange(t)}
local x, y, target = self:getTarget(t)
if not x or not y or not target then return nil end
if math.floor(core.fov.distance(self.x, self.y, x, y)) > 1 then return nil end
local hit = self:attackTarget(target, nil, 1.5 + self:getTalentLevel(t) / 10, true)
-- Try to knockback !
if hit then
if target:checkHit(self:combatAttackStr(weapon.combat), target:combatPhysicalResist(), 0, 95, 5 - self:getTalentLevel(t) / 2) and target:canBe("knockback") then
target:knockback(4)
else
game.logSeen(target, "%s resists the knockback!", target.name:capitalize())
end
end
return true
end,
info = function(self, t)
return ([[Hits the target with your weapon doing %d%% damage, if the atatck hits, the target is knocked back.]]):format(100 * (1.5 + self:getTalentLevel(t) / 10))
end,
}
load("/data/general/npcs/vermin.lua")
load("/data/general/npcs/molds.lua")
load("/data/general/npcs/skeleton.lua")
load("/data/general/npcs/wolf.lua")
load("/data/general/npcs/troll.lua")
local Talents = require("engine.interface.ActorTalents")
......@@ -22,7 +22,7 @@ newEntity{ define_as = "TROLL_BILL",
drops = resolvers.drops{chance=100, nb=3, {ego_chance=100} },
talents = resolvers.talents{
[Talents.T_STAMINA_POOL]=1, [Talents.T_STUNNING_BLOW]=1,
[Talents.T_STAMINA_POOL]=1, [Talents.T_STUN]=2, [Talents.T_KNOCKBACK]=1,
},
autolevel = "warrior",
......
......@@ -14,4 +14,7 @@ newEntity{ base = "BASE_GREATMAUL",
dammod = {str=1.3},
damrange = 1.7,
},
wielder = {
},
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment