diff --git a/game/engine/interface/BloodyDeath.lua b/game/engine/interface/BloodyDeath.lua index 7d7794ec04de0524ba4fb7b1c9126abf19010e37..167c84f70fcb13ca9691c724f971fe55423a0f57 100644 --- a/game/engine/interface/BloodyDeath.lua +++ b/game/engine/interface/BloodyDeath.lua @@ -1,6 +1,6 @@ require "engine.class" ---- Interface to add a bloodyDeath() method to actords +--- Interface to add a bloodyDeath() method to actors -- When this method is called, the floor or walls around the late actor is covered in blood module(..., package.seeall, class.make) diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua index e917a5cac3b989750e066d1b2fa8a60be13f452d..9a7782c18082d105ceb3704ec00e83affe1ef92a 100644 --- a/game/modules/tome/class/Actor.lua +++ b/game/modules/tome/class/Actor.lua @@ -3,8 +3,16 @@ require "engine.Actor" require "engine.interface.ActorLife" require "engine.interface.ActorLevel" require "engine.interface.BloodyDeath" +require "mod.class.interface.Combat" -module(..., package.seeall, class.inherit(engine.Actor, engine.interface.ActorLife, engine.interface.ActorLevel, engine.interface.BloodyDeath)) +module(..., package.seeall, class.inherit( + -- a ToME actor is a complex beast it uses may inetrfaces + engine.Actor, + engine.interface.ActorLife, + engine.interface.ActorLevel, + engine.interface.BloodyDeath, + mod.class.interface.Combat +)) function _M:init(t) engine.Actor.init(self, t) @@ -36,3 +44,7 @@ end function _M:levelup() end + +function _M:attack(target) + self:attackTarget(target) +end diff --git a/game/modules/tome/class/NPC.lua b/game/modules/tome/class/NPC.lua index 2b1a4ee9bc780a0622ab34c8240a890d9e3cf1d6..4d5a760265c6cb2a190016dbbed97c70e9fdf9aa 100644 --- a/game/modules/tome/class/NPC.lua +++ b/game/modules/tome/class/NPC.lua @@ -8,5 +8,5 @@ function _M:init(t) end function _M:act() - self:move(self.x + 1, self.y) +-- self:move(self.x + 1, self.y) end diff --git a/game/modules/tome/class/Player.lua b/game/modules/tome/class/Player.lua index 0acc88ce9dd35d6d64f39f3af0a98d9dbb498663..96187d5245368fe1116108cf7484843322855aad 100644 --- a/game/modules/tome/class/Player.lua +++ b/game/modules/tome/class/Player.lua @@ -5,6 +5,8 @@ module(..., package.seeall, class.inherit(mod.class.Actor)) function _M:init(t) mod.class.Actor.init(self, t) + + self.combat = { dam=10, atk=4, apr=2, def=6, armor=4 } end function _M:move(x, y, force) diff --git a/game/modules/tome/class/interface/Combat.lua b/game/modules/tome/class/interface/Combat.lua new file mode 100644 index 0000000000000000000000000000000000000000..77c09ca209a6b1621db2ebc9bc09dc80d726d632 --- /dev/null +++ b/game/modules/tome/class/interface/Combat.lua @@ -0,0 +1,32 @@ +require "engine.class" + +--- Interface to add ToME combat system +module(..., package.seeall, class.make) + +--- Makes the bloody death happen +--[[ +The ToME combat system has the following attributes: +- attack power: increases chances to hit against high defence +- defence: increases chances to miss against high attack power +- armor: direct reduction of damage done +- armor penetration: reduction of target's armor +- damage: raw damage done +]] +function _M:attackTarget(target) + local sc = self.combat + local tc = target.combat + + if not sc then sc = {dam=0, atk=0, apr=0, def=0, armor=0} end + if not tc then tc = {dam=0, atk=0, apr=0, def=0, armor=0} end + + -- Does the blow connect? + local hit = rng.avg(sc.atk * 2 / 3, sc.atk) - tc.def + -- If hit is over 0 it connects, if it is 0 we still have 50% chance + if hit > 0 or (hit == 0 and rng.percent(50)) then + local dam = rng.avg(sc.dam * 2 / 3, sc.dam) - math.max(0, tc.armor - sc.apr) + game.logSeen(target, "%s hits %s for #aaaaaa#%0.2f physical damage#ffffff#.", self.name:capitalize(), target.name, dam) + target:takeHit(dam, self) + else + game.logSeen(target, "%s misses %s.", self.name:capitalize(), target.name) + end +end diff --git a/game/modules/tome/data/zones/ancient_ruins/npcs.lua b/game/modules/tome/data/zones/ancient_ruins/npcs.lua index 282723bc1dfdfb860f7c1025ef5d6b7e5bdb54f7..cfcb18663e12328ea884022bac6bf774700c159f 100644 --- a/game/modules/tome/data/zones/ancient_ruins/npcs.lua +++ b/game/modules/tome/data/zones/ancient_ruins/npcs.lua @@ -8,6 +8,7 @@ return { mana = 1000, energy = { mod=0.8 }, has_blood = true, + combat = { dam=8, atk=10, apr=2, def=4, armor=6}, }, { name = "baby dragon", @@ -17,6 +18,7 @@ return { mana = 1000, energy = { mod=0.3 }, has_blood = true, + combat = { dam=5, atk=6, def=2, apr=1, armor=2}, }, } \ No newline at end of file diff --git a/game/modules/tome/data/zones/ancient_ruins/zone.lua b/game/modules/tome/data/zones/ancient_ruins/zone.lua index d3e90f78ab0e9936b6f963f1631e97f40f464aff..716a0e70c5421b0bb384327330a6303a9e9a8827 100644 --- a/game/modules/tome/data/zones/ancient_ruins/zone.lua +++ b/game/modules/tome/data/zones/ancient_ruins/zone.lua @@ -7,7 +7,7 @@ return { level_npcs = {5, 10}, generator = { map = { - class= "engine.generator.map.Rooms", + class= "engine.generator.map.Empty", floor = "FLOOR", wall = "WALL", up = "UP", diff --git a/src/core_lua.c b/src/core_lua.c index 864ac034194c0daa31ef41041eaf89d44946450b..f66d8c8264d674740a493f0af6e7d32d0db38aad 100644 --- a/src/core_lua.c +++ b/src/core_lua.c @@ -419,6 +419,20 @@ static int rng_range(lua_State *L) return 1; } +static int rng_avg(lua_State *L) +{ + int x = luaL_checknumber(L, 1); + int y = luaL_checknumber(L, 2); + int nb = 2; + double res = 0; + int i; + if (lua_isnumber(L, 3)) nb = luaL_checknumber(L, 3); + for (i = 0; i < nb; i++) + res += x + rand_div(1 + y - x); + lua_pushnumber(L, res / nb); + return 1; +} + static int rng_call(lua_State *L) { int x = luaL_checknumber(L, 1); @@ -462,6 +476,7 @@ static const struct luaL_reg rnglib[] = { {"__call", rng_call}, {"range", rng_range}, + {"avg", rng_avg}, {"dice", rng_dice}, {"seed", rng_seed}, {"chance", rng_chance},