diff --git a/game/engine/Actor.lua b/game/engine/Actor.lua index f85048b24df973604fcd1c9f0a7a83a6fdf1cbca..3c65b1fc4f5993f9bd1d2b02f26d4a16c4e5edd0 100644 --- a/game/engine/Actor.lua +++ b/game/engine/Actor.lua @@ -107,7 +107,7 @@ function _M:teleportRandom(x, y, dist) end --- Knock back the actor -function _M:knockBack(srcx, srcy, dist) +function _M:knockback(srcx, srcy, dist) local l = line.new(srcx, srcy, self.x, self.y, true) local lx, ly = l(true) dist = dist - 1 diff --git a/game/engine/Entity.lua b/game/engine/Entity.lua index 607736f5a152cb8d3cc1972b09d18252abed5370..7e70cd75231fd7040c41466572558f0e10f4cd4c 100644 --- a/game/engine/Entity.lua +++ b/game/engine/Entity.lua @@ -199,8 +199,17 @@ function _M:loadList(file, no_default, res, mod) newEntity = function(t) -- Do we inherit things ? if t.base then + -- Append array part + for i = 1, #t.base do + local b = 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" then + if k ~= "define_as" and type(k) ~= "number" then if not t[k] then t[k] = e elseif type(t[k]) == "table" and type(e) == "table" then diff --git a/game/engine/generator/map/Roomer.lua b/game/engine/generator/map/Roomer.lua index 487f5b40099d62ed59ed93008823ef69bd7e478e..46a2a24f19ce8a3fb6f2ce12ed54149537dad8a0 100644 --- a/game/engine/generator/map/Roomer.lua +++ b/game/engine/generator/map/Roomer.lua @@ -142,6 +142,9 @@ local mark_dirs = { } --- Marks a tunnel as a tunnel and the space behind it function _M:markTunnel(x, y, xdir, ydir, id) + -- Disable the many prints of tunnelling + local print = function()end + x, y = x - xdir, y - ydir local dir = coord_to_dir[xdir][ydir] for i, d in ipairs(mark_dirs[dir]) do @@ -155,6 +158,7 @@ end function _M:tunnel(x1, y1, x2, y2, id) -- Disable the many prints of tunnelling local print = function()end + local xdir, ydir = self:tunnelDir(x1, y1, x2, y2) print("tunneling from",x1, y1, "to", x2, y2, "initial dir", xdir, ydir) diff --git a/game/engine/resolvers.lua b/game/engine/resolvers.lua index 7535de819cffc2431ba70ea79a2ced6aa8f68d99..db2fce38fad9119fa582ae6f48ef5302754cb91e 100644 --- a/game/engine/resolvers.lua +++ b/game/engine/resolvers.lua @@ -31,7 +31,7 @@ function resolvers.talents(list) return {__resolver="talents", list} end function resolvers.calc.talents(t, e) - for tid, level in pairs(t[1]) do print(level) e:learnTalent(tid, true, level) end + for tid, level in pairs(t[1]) do e:learnTalent(tid, true, level) end return nil end diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua index 115a38d8c2bc5e660df4ede65e37060835d91409..e1611ed52c6d0f7e3f3809dd4d7857a308c0e139 100644 --- a/game/modules/tome/class/Actor.lua +++ b/game/modules/tome/class/Actor.lua @@ -87,9 +87,9 @@ function _M:init(t, no_default) engine.interface.ActorInventory.init(self, t) engine.interface.ActorTemporaryEffects.init(self, t) engine.interface.ActorLife.init(self, t) - engine.interface.ActorStats.init(self, t) engine.interface.ActorTalents.init(self, t) engine.interface.ActorResource.init(self, t) + engine.interface.ActorStats.init(self, t) engine.interface.ActorLevel.init(self, t) engine.interface.ActorFOV.init(self, t) end diff --git a/game/modules/tome/class/Player.lua b/game/modules/tome/class/Player.lua index c99f202e2c104006a9103877edcf46bd7efeffce..bca75df3f1feb0442250eb7e224e758db8491f37 100644 --- a/game/modules/tome/class/Player.lua +++ b/game/modules/tome/class/Player.lua @@ -111,6 +111,7 @@ function _M:onTakeHit(value, src) end function _M:die() + game.paused = true game:registerDialog(DeathDialog.new(self)) end diff --git a/game/modules/tome/data/autolevel_schemes.lua b/game/modules/tome/data/autolevel_schemes.lua index 2250c5707400ffdee1aed9d89f61f87c90d50490..f433eef58b61669316dfd0bcd498bfb6d4ddff14 100644 --- a/game/modules/tome/data/autolevel_schemes.lua +++ b/game/modules/tome/data/autolevel_schemes.lua @@ -9,6 +9,9 @@ local function learnStats(self, statorder) end end +Autolevel:registerScheme{ name = "none", levelup = function(self) +end} + Autolevel:registerScheme{ name = "warrior", levelup = function(self) learnStats(self, { self.STAT_STR, self.STAT_STR, self.STAT_DEX }) end} diff --git a/game/modules/tome/data/damage_types.lua b/game/modules/tome/data/damage_types.lua index 8d34bfebf9e00eea5882fc27c6ecaa58cb99ef13..7762a8a570702161c02957e6dfc092ee2f0e9e80 100644 --- a/game/modules/tome/data/damage_types.lua +++ b/game/modules/tome/data/damage_types.lua @@ -197,7 +197,7 @@ newDamageType{ local target = game.level.map(x, y, Map.ACTOR) if target then if target:checkHit(src:combatSpellpower(), target:combatPhysicalResist(), 0, 95, 15) and target:canBe("knockback") then - target:knockBack(src.x, src.y, 1) + target:knockback(src.x, src.y, 1) game.logSeen(target, "%s is knocked back!", target.name:capitalize()) else game.logSeen(target, "%s resists the wave!", target.name:capitalize()) @@ -214,7 +214,7 @@ newDamageType{ local target = game.level.map(x, y, Map.ACTOR) if target then if target:checkHit(src:combatSpellpower(), target:combatPhysicalResist(), 0, 95, 15) and target:canBe("knockback") then - target:knockBack(src.x, src.y, 2) + target:knockback(src.x, src.y, 2) game.logSeen(target, "%s is knocked back!", target.name:capitalize()) else game.logSeen(target, "%s resists the punch!", target.name:capitalize()) diff --git a/game/modules/tome/data/general/npcs/minotaur.lua b/game/modules/tome/data/general/npcs/minotaur.lua index d64d753bf8a17d136ec90e79409157caaa2b499f..c74e7450e6b072fdf875808262b4198f1fbfbfe4 100644 --- a/game/modules/tome/data/general/npcs/minotaur.lua +++ b/game/modules/tome/data/general/npcs/minotaur.lua @@ -26,7 +26,7 @@ newEntity{ newEntity{ base = "BASE_NPC_MINOTAUR", name = "minotaur", color=colors.UMBER, desc = [[It is a cross between a human and a bull.]], - equipment = resolvers.equip{ {type="weapon", subtype="greataxe"}, }, + equipment = resolvers.equip{ {type="weapon", subtype="battleaxe"}, }, level_range = {10, 50}, exp_worth = 1, rarity = 9, combat_armor = 13, combat_def = 8, diff --git a/game/modules/tome/data/general/objects/egos/shield.lua b/game/modules/tome/data/general/objects/egos/shield.lua index acab141bbec2808c51f2067923ae8a5d5692ce17..722a2ef6431ee170fadd027ca14a8f01e2cd1add 100644 --- a/game/modules/tome/data/general/objects/egos/shield.lua +++ b/game/modules/tome/data/general/objects/egos/shield.lua @@ -51,7 +51,7 @@ newEntity{ rarity = 8, cost = 8, wielder = { - resists={[DamageType.FIRE] = resolvers.mbonus(7, 3)}, + on_melee_hit={[DamageType.FIRE] = resolvers.mbonus(7, 3)}, }, } newEntity{ diff --git a/game/modules/tome/data/general/objects/world-artifacts.lua b/game/modules/tome/data/general/objects/world-artifacts.lua index 40971f4a94d60d387861f7f9dd7d7865fa47e0c4..a1f4f27920126100ff8c6b775b2e20f87adeb663 100644 --- a/game/modules/tome/data/general/objects/world-artifacts.lua +++ b/game/modules/tome/data/general/objects/world-artifacts.lua @@ -172,5 +172,6 @@ newEntity{ game.logPlayer(who, "The Blood of Life seems to have no effect on you.") end game.logSeen(who, "%s quaffs the %s!", who.name:capitalize(), self:getName()) + return "destroy", true end}, } diff --git a/game/modules/tome/data/talents/gifts/summon-distance.lua b/game/modules/tome/data/talents/gifts/summon-distance.lua index 0d2769a4fd1cbd1b2a2948bdb284c09111dce8f7..3e5455ef7089a36cc2b9ea1ca4d7fb3cf7eca63f 100644 --- a/game/modules/tome/data/talents/gifts/summon-distance.lua +++ b/game/modules/tome/data/talents/gifts/summon-distance.lua @@ -6,15 +6,15 @@ newTalent{ short_name = "FIRE_IMP_BOLT", range = 20, reflectable = true, action = function(self, t) - local tg = {type="bolt", range=self:getTalentRange(t), talent=t} + local tg = {type="hit", range=self:getTalentRange(t), talent=t} local x, y = self:getTarget(tg) if not x or not y then return nil end - self:project(tg, x, y, DamageType.FIRE, self:spellCrit(12 + self:combatSpellpower(0.8) * self:getTalentLevel(t)), {type="flame"}) + self:project(tg, x, y, DamageType.FIRE, self:spellCrit(12 + self:combatSpellpower(0.3) * self:getTalentLevel(t)), {type="flame"}) return true end, info = function(self, t) return ([[Conjures up a bolt of fire doing %0.2f fire damage. - The damage will increase with the Magic stat]]):format(12 + self:combatSpellpower(0.8) * self:getTalentLevel(t)) + The damage will increase with the Magic stat]]):format(12 + self:combatSpellpower(0.3) * self:getTalentLevel(t)) end, } @@ -48,9 +48,9 @@ newTalent{ display = "u", color=colors.RED, name = "fire imp", faction = self.faction, desc = [[]], - autolevel = "caster", + autolevel = "none", ai = "summoned", ai_real = "dumb_talented_simple", ai_state = { talent_in=1, }, - stats = { str=5, dex=5, mag=15, wil=15, con=7 }, + stats = { mag=15 + self:getWil() * self:getTalentLevel(t) / 5, wil=18, con=10 + self:getTalentLevel(t) * 2, }, level_range = {self.level, self.level}, exp_worth = 0, max_life = resolvers.rngavg(5,10), @@ -62,7 +62,7 @@ newTalent{ max_mana = 150, resolvers.talents{ [self.T_MANA_POOL]=1, - [self.T_FIRE_IMP_BOLT]=self:getTalentLevelRaw() + [self.T_FIRE_IMP_BOLT]=self:getTalentLevelRaw(t), }, summoner = self, summoner_gain_exp=true, @@ -78,6 +78,7 @@ newTalent{ return true end, info = function(self, t) - return ([[Summon a Fire Imp to burn your foes to death.]]) + return ([[Summon a Fire Imp to burn your foes to death. Fire Imps are really weak in melee and die easily, but they can burn your foes from afar. + It will get %d magic and %d willpower.]]):format(15 + self:getWil() * self:getTalentLevel(t) / 5, 10 + self:getTalentLevel(t) * 2) end, } diff --git a/game/modules/tome/data/talents/gifts/summon-melee.lua b/game/modules/tome/data/talents/gifts/summon-melee.lua index 318b998cdb397b915273d36977cf00ead1860984..8467d6cce0e8e042e42f1711b90218e90b2aff64 100644 --- a/game/modules/tome/data/talents/gifts/summon-melee.lua +++ b/game/modules/tome/data/talents/gifts/summon-melee.lua @@ -4,8 +4,8 @@ newTalent{ require = gifts_req1, points = 5, message = "@Source@ summons a War Hound!", - equilibrium = 2, - cooldown = 10, + equilibrium = 3, + cooldown = 15, range = 20, action = function(self, t) local tg = {type="bolt", range=self:getTalentRange(t), nolock=true, talent=t} @@ -29,11 +29,11 @@ newTalent{ desc = [[]], autolevel = "warrior", ai = "summoned", ai_real = "dumb_talented_simple", ai_state = { talent_in=5, }, - stats = { str=18, dex=13, mag=5, con=15 }, + stats = { str=10 + self:getWil() * self:getTalentLevel(t) / 5, dex=10 + self:getTalentLevel(t) * 2, mag=5, con=15 }, level_range = {self.level, self.level}, exp_worth = 0, max_life = resolvers.rngavg(25,50), - life_rating = 10, + life_rating = 4, combat_armor = 2, combat_def = 4, combat = { dam=resolvers.rngavg(12,25), atk=10, apr=10, dammod={str=0.8} }, @@ -51,7 +51,8 @@ newTalent{ return true end, info = function(self, t) - return ([[Summon a War Hound to attack your foes.]]) + return ([[Summon a War Hound to attack your foes. War hounds are good basic melee attackers. + It will get %d strength and %d dexterity.]]):format(10 + self:getWil() * self:getTalentLevel(t) / 5, 10 + self:getTalentLevel(t) * 2) end, } @@ -61,7 +62,7 @@ newTalent{ require = gifts_req2, points = 5, message = "@Source@ summons a Jelly!", - equilibrium = 4, + equilibrium = 5, cooldown = 10, range = 20, action = function(self, t) @@ -84,8 +85,8 @@ newTalent{ display = "j", color=colors.BLACK, desc = "A strange blob on the dungeon floor.", name = "black jelly", - autolevel = "tank", faction=self.faction, - stats = { str=12, dex=15, mag=3, con=15 }, + autolevel = "none", faction=self.faction, + stats = { con=10 + self:getWil() * self:getTalentLevel(t) / 5, str=10 + self:getTalentLevel(t) * 2 }, resists = { [DamageType.LIGHT] = -50 }, ai = "summoned", ai_real = "dumb_talented_simple", ai_state = { talent_in=5, }, level_range = {self.level, self.level}, exp_worth = 0, @@ -96,7 +97,7 @@ newTalent{ combat_armor = 1, combat_def = 1, never_move = 1, - combat = { dam=8, atk=15, apr=5, damtype=DamageType.POISON, dammod={str=0.8} }, + combat = { dam=8, atk=15, apr=5, damtype=DamageType.ACID, dammod={str=0.7} }, summoner = self, summoner_gain_exp=true, summon_time = math.ceil(self:getTalentLevel(t)) + 5, @@ -111,8 +112,9 @@ newTalent{ return true end, info = function(self, t) - return ([[Summon a Jelly to attack your foes. Jellies do not move, but are great to block a passage.]]) - end, + return ([[Summon a Jelly to attack your foes. Jellies do not move, but are great to block a passage. + It will get %d constitution and %d strength.]]):format(10 + self:getWil() * self:getTalentLevel(t) / 5, 10 + self:getTalentLevel(t) * 2) + end, } newTalent{ @@ -140,26 +142,32 @@ newTalent{ local NPC = require "mod.class.NPC" local m = NPC.new{ - type = "immovable", subtype = "jelly", - display = "j", color=colors.BLACK, - desc = "A strange blob on the dungeon floor.", - name = "black jelly", - autolevel = "tank", faction=self.faction, - stats = { str=12, dex=15, mag=3, con=15 }, - resists = { [DamageType.LIGHT] = -50 }, - ai = "summoned", ai_real = "dumb_talented_simple", ai_state = { talent_in=5, }, - level_range = {self.level, self.level}, exp_worth = 0, + type = "giant", subtype = "minotaur", + display = "H", + name = "minotaur", color=colors.UMBER, - max_life = resolvers.rngavg(25,50), - life_rating = 10, + body = { INVEN = 10, MAINHAND=1, OFFHAND=1, BODY=1 }, - combat_armor = 1, combat_def = 1, - never_move = 1, + max_stamina = 100, + life_rating = 13, + max_life = resolvers.rngavg(50,80), - combat = { dam=8, atk=15, apr=5, damtype=DamageType.POISON, dammod={str=0.8} }, + autolevel = "none", + ai = "summoned", ai_real = "dumb_talented_simple", ai_state = { talent_in=5, }, + energy = { mod=1.2 }, + stats = { str=25 + self:getWil() * self:getTalentLevel(t) / 5, dex=18, con=10 + self:getTalentLevel(t) * 2, }, + resolvers.tmasteries{ ["technique/2hweapon-offense"]=0.3, ["technique/2hweapon-cripple"]=0.3, ["technique/combat-training"]=0.3, }, + desc = [[It is a cross between a human and a bull.]], + equipment = resolvers.equip{ {type="weapon", subtype="battleaxe"}, }, + level_range = {self.level, self.level}, exp_worth = 0, + + combat_armor = 13, combat_def = 8, + resolvers.talents{ [Talents.T_WARSHOUT]=3, [Talents.T_STUNNING_BLOW]=3, [Talents.T_SUNDER_ARMOUR]=2, [Talents.T_SUNDER_ARMS]=2, }, + + faction = self.faction, summoner = self, summoner_gain_exp=true, - summon_time = math.ceil(self:getTalentLevel(t)) + 5, + summon_time = math.ceil(self:getTalentLevel(t)) + 2, ai_target = {actor=target} } @@ -171,6 +179,7 @@ newTalent{ return true end, info = function(self, t) - return ([[Summon a Minotaur to attack your foes. Minotaurs can not stay summoned for long but they deal lots of damage.]]) + return ([[Summon a Minotaur to attack your foes. Minotaurs can not stay summoned for long but they deal lots of damage. + It will get %d strength and %d constitution.]]):format(25 + self:getWil() * self:getTalentLevel(t) / 5, 10 + self:getTalentLevel(t) * 2) end, } diff --git a/game/modules/tome/data/talents/techniques/sling.lua b/game/modules/tome/data/talents/techniques/sling.lua index fd5c6e4b9e37eba3af1138a260d3ce47dfd4b68d..f11efe8990aea8442a39d40857b26283434f59c7 100644 --- a/game/modules/tome/data/talents/techniques/sling.lua +++ b/game/modules/tome/data/talents/techniques/sling.lua @@ -43,7 +43,7 @@ newTalent{ action = function(self, t) self:archeryShoot(nil, 1.2 + self:getTalentLevel(t) / 5, function(target, x, y) if target:checkHit(self:combatAttackDex(), target:combatPhysicalResist(), 0, 95, 15) and target:canBe("knockback") then - target:knockBack(self.x, self.y, 4) + target:knockback(self.x, self.y, 4) game.logSeen(target, "%s is knocked back!", target.name:capitalize()) else game.logSeen(target, "%s resists the wave!", target.name:capitalize()) diff --git a/game/modules/tome/data/talents/techniques/weaponshield.lua b/game/modules/tome/data/talents/techniques/weaponshield.lua index ef1e13e2040efc77d7da59c4ae6fa9657f3abf34..98bb278ed77d6cf51e8c133d5f8e6579abd7b8ce 100644 --- a/game/modules/tome/data/talents/techniques/weaponshield.lua +++ b/game/modules/tome/data/talents/techniques/weaponshield.lua @@ -80,7 +80,7 @@ newTalent{ -- Try to stun ! if hit then if target:checkHit(self:combatAttack(shield.special_combat), target:combatPhysicalResist(), 0, 95, 5 - self:getTalentLevel(t) / 2) and target:canBe("knockback") then - target:knockBack(self.x, self.y, 4) + target:knockback(self.x, self.y, 4) else game.logSeen(target, "%s resists the knockback!", target.name:capitalize()) end @@ -202,7 +202,7 @@ newTalent{ if (self.x ~= x or self.y ~= y) and game.level.map:isBound(x, y) and game.level.map(x, y, Map.ACTOR) then local target = game.level.map(x, y, Map.ACTOR) if target:checkHit(self:combatAttack(shield.special_combat), target:combatPhysicalResist(), 0, 95, 5 - self:getTalentLevel(t) / 2) and target:canBe("knockback") then - target:knockBack(self.x, self.y, 1 + self:getTalentLevel(t)) + target:knockback(self.x, self.y, 1 + self:getTalentLevel(t)) else game.logSeen(target, "%s resists the knockback!", target.name:capitalize()) end diff --git a/game/modules/tome/init.lua b/game/modules/tome/init.lua index 970460e57d5961c6179dc01a0722bc840b81c686..b22187d4158da56b9dddf7c1b19e670ec9fa7453 100644 --- a/game/modules/tome/init.lua +++ b/game/modules/tome/init.lua @@ -1,7 +1,7 @@ name = "T.o.M.E" long_name = "Tales of Middle Earth: The Fourth Age" short_name = "tome" -author = { "DarkGod", "darkgod@t-o-m-e.net" } +author = { "DarkGod", "darkgod@te4.org" } homepage = "http://tome.te4.org/" version = {4,0,0} engine = {1,0,0}