diff --git a/game/engine/Actor.lua b/game/engine/Actor.lua index 1b2f1e2da0ec6b34559868274cf4c0fcf996a8c6..e2e5e23ec542ebde8a0f924509452bf4ba99457e 100644 --- a/game/engine/Actor.lua +++ b/game/engine/Actor.lua @@ -21,15 +21,6 @@ function _M:init(t) self.compute_vals = {} end ---- Tells the actor it can act -function _M:act() - if self.changed then self:updateBonus() end -end - ---- Recompute the bonus when something changed -function _M:updateBonus() -end - --- Moves an actor on the map -- *WARNING*: changing x and y properties manualy is *WRONG* and will blow up in your face. Use this method. Always. -- @param map the map to move onto diff --git a/game/engine/DebugConsole.lua b/game/engine/DebugConsole.lua index 31a842429ccc205755c207f5294d9cfd10729f43..e07907acfcd18583b4951fda06302e562c289f99 100644 --- a/game/engine/DebugConsole.lua +++ b/game/engine/DebugConsole.lua @@ -3,13 +3,18 @@ require "engine.Dialog" module(..., package.seeall, class.inherit(engine.Dialog)) +-- Globals to all instances of the console +scroll = 0 +history = {} +line = "" +com_sel = 0 +commands = {} + function _M:init() engine.Dialog.init(self, "Lua Console", core.display.size()) - self.scroll = 0 - self.history = {} - self.line = "" self:keyCommands{ _RETURN = function() + self.commands[#self.commands+1] = self.line table.insert(self.history, 1, self.line) if self.line:match("^=") then self.line = "return "..self.line:sub(2) end local f, err = loadstring(self.line) @@ -26,6 +31,18 @@ function _M:init() self.line = "" self.changed = true end, + _UP = function() + self.com_sel = util.bound(self.com_sel + 1, 1, #self.commands) + if self.commands[self.com_sel] then + self.line = self.commands[self.com_sel] + end + end, + _DOWN = function() + self.com_sel = util.bound(self.com_sel - 1, 1, #self.commands) + if self.commands[self.com_sel] then + self.line = self.commands[self.com_sel] + end + end, _ESCAPE = function() game:unregisterDialog(self) end, diff --git a/game/engine/Object.lua b/game/engine/Object.lua index e3cdaccda4649b089aaccf1ccc3b0f592fff9c6a..ac3170d4b470c0c33ed2026e59a3aef98c9fbe15 100644 --- a/game/engine/Object.lua +++ b/game/engine/Object.lua @@ -22,3 +22,10 @@ end function _M:getDesc() return self.name end + +--- Returns the inventory type an object is worn on +function _M:wornInven() + if not self.slot then return nil end + local invens = require "engine.interface.ActorInventory" + return invens["INVEN_"..self.slot] +end diff --git a/game/engine/dialogs/ShowEquipment.lua b/game/engine/dialogs/ShowEquipment.lua new file mode 100644 index 0000000000000000000000000000000000000000..68f9417df28c9a54f92f6a24d3d9ca910f6334d5 --- /dev/null +++ b/game/engine/dialogs/ShowEquipment.lua @@ -0,0 +1,98 @@ +require "engine.class" +require "engine.Dialog" + +module(..., package.seeall, class.inherit(engine.Dialog)) + +function _M:init(title, actor, filter, action) + self.actor = actor + self.filter = filter + self.action = action + engine.Dialog.init(self, title or "Equipment", game.w * 0.8, game.h * 0.8) + + self:generateList() + + self.sel = 1 + self:keyCommands{ + _UP = function() self.sel = util.boundWrap(self.sel - 1, 1, #self.list) end, + _DOWN = function() self.sel = util.boundWrap(self.sel + 1, 1, #self.list) end, + _RETURN = function() self:use() end, + _ESCAPE = function() game:unregisterDialog(self) end, + __TEXTINPUT = function(c) + if self.chars[c] then + self.sel = self.chars[c] + self:use() + end + end, + } + self:mouseZones{ + { x=2, y=5, w=350, h=self.font_h*#self.list, fct=function(button, x, y, xrel, yrel, tx, ty) + self.sel = 1 + math.floor(ty / self.font_h) + if button == "left" then self:use() + elseif button == "right" then + end + end }, + } +end + +function _M:use() + game:unregisterDialog(self) + if self.list[self.sel] then + self.action(self.list[self.sel].object, self.list[self.sel].inven, self.list[self.sel].item) + end +end + +function _M:generateList() + -- Makes up the list + local list = {} + local chars = {} + local i = 0 + for inven_id = 1, #self.actor.inven_def do + if self.actor.inven[inven_id] and self.actor.inven_def[inven_id].is_worn then + list[#list+1] = { name="#10EF6F#"..self.actor.inven_def[inven_id].name, inven=inven_id } + + for item, o in ipairs(self.actor.inven[inven_id]) do + if not self.filter or self.filter(o) then + local char = string.char(string.byte('a') + i) + list[#list+1] = { name=char..") "..o:getName(), object=o, inven=inven_id, item=item } + chars[char] = #list + i = i + 1 + end + end + end + end + self.list = list + self.chars = chars +end + +function _M:drawDialog(s) + -- Description part + self:drawHBorder(s, self.iw / 2, 2, self.ih - 4) + + local talentshelp = ([[Keyboard: #00FF00#up key/down key#FFFFFF# to select an object; #00FF00#enter#FFFFFF# to use. +Mouse: #00FF00#Left click#FFFFFF# to use. +]]):splitLines(self.iw / 2 - 10, self.font) + + local lines = {} + local h = 2 + for i = 1, #talentshelp do + s:drawColorString(self.font, talentshelp[i], self.iw / 2 + 5, h) + h = h + self.font:lineSkip() + end + + h = h + self.font:lineSkip() + if not self.list[self.sel].item then + lines = self.actor.inven_def[self.list[self.sel].inven].description:splitLines(self.iw / 2 - 10, self.font) + elseif self.list[self.sel] then + lines = self.list[self.sel].object:getDesc():splitLines(self.iw / 2 - 10, self.font) + else + lines = {} + end + self:drawWBorder(s, self.iw / 2 + self.iw / 6, h - 0.5 * self.font:lineSkip(), self.iw / 6) + for i = 1, #lines do + s:drawColorString(self.font, lines[i], self.iw / 2 + 5, 2 + h) + h = h + self.font:lineSkip() + end + + -- Talents + self:drawSelectionList(s, 2, 5, self.font_h, self.list, self.sel, "name") +end diff --git a/game/engine/dialogs/ShowInventory.lua b/game/engine/dialogs/ShowInventory.lua index 9027e4cbae055201f4cdc901d70744962b3d3905..a7cee5f6a40a699794c6d2d1f8485122e7b37a97 100644 --- a/game/engine/dialogs/ShowInventory.lua +++ b/game/engine/dialogs/ShowInventory.lua @@ -3,11 +3,11 @@ require "engine.Dialog" module(..., package.seeall, class.inherit(engine.Dialog)) -function _M:init(inven, filter, action) +function _M:init(title, inven, filter, action) self.inven = inven self.filter = filter self.action = action - engine.Dialog.init(self, "Inventory", game.w * 0.8, game.h * 0.8) + engine.Dialog.init(self, title, "Inventory", game.w * 0.8, game.h * 0.8) self:generateList() @@ -36,7 +36,9 @@ end function _M:use() game:unregisterDialog(self) - self.action(self.list[self.sel].object, self.list[self.sel].item) + if self.list[self.sel] then + self.action(self.list[self.sel].object, self.list[self.sel].item) + end end function _M:generateList() @@ -68,7 +70,11 @@ Mouse: #00FF00#Left click#FFFFFF# to use. end h = h + self.font:lineSkip() - lines = self.list[self.sel].object:getDesc():splitLines(self.iw / 2 - 10, self.font) + if self.list[self.sel] then + lines = self.list[self.sel].object:getDesc():splitLines(self.iw / 2 - 10, self.font) + else + lines = {} + end self:drawWBorder(s, self.iw / 2 + self.iw / 6, h - 0.5 * self.font:lineSkip(), self.iw / 6) for i = 1, #lines do s:drawColorString(self.font, lines[i], self.iw / 2 + 5, 2 + h) diff --git a/game/engine/init.lua b/game/engine/init.lua index 17f1fdfe4be2237bacd30f2e949a76c5e2cec5eb..d7c9739bfc08fe41e47c0b2a95ff556564f5aaec 100644 --- a/game/engine/init.lua +++ b/game/engine/init.lua @@ -32,6 +32,4 @@ key:setCurrent() -- Load the game module game = false -local Menu = require("special.mainmenu.class.Game") -game = Menu.new() -game:run() +util.showMainMenu() diff --git a/game/engine/interface/ActorInventory.lua b/game/engine/interface/ActorInventory.lua index c53a5179c8a1dda363fc717929779c69a0c24b77..d47154216ae3355134808451cd0dc83e5e309c7f 100644 --- a/game/engine/interface/ActorInventory.lua +++ b/game/engine/interface/ActorInventory.lua @@ -1,6 +1,7 @@ require "engine.class" local Map = require "engine.Map" local ShowInventory = require "engine.dialogs.ShowInventory" +local ShowEquipment = require "engine.dialogs.ShowEquipment" --- Handles actors stats module(..., package.seeall, class.make) @@ -44,7 +45,11 @@ end --- Returns the content of an inventory as a table function _M:getInven(id) - return self.inven[id] + if type(id) == "number" then + return self.inven[id] + else + return id + end end --- Adds an object to an inventory @@ -80,6 +85,7 @@ end -- @param item the item id to drop -- @return the object removed or nil if no item existed function _M:removeObject(inven, item) + if type(inven) == "number" then inven = self.inven[inven] end return table.remove(inven, item) end @@ -101,7 +107,43 @@ end -- @param inven the inventory (from self:getInven()) -- @param filter nil or a function that filters the objects to list -- @param action a function called when an object is selected -function _M:showInventory(inven, filter, action) - local d = ShowInventory.new(inven, filter, action) +function _M:showInventory(title, inven, filter, action) + local d = ShowInventory.new(title, inven, filter, action) + game:registerDialog(d) +end + +--- Show equipment dialog +-- @param filter nil or a function that filters the objects to list +-- @param action a function called when an object is selected +function _M:showEquipment(title, filter, action) + local d = ShowEquipment.new(title, self, filter, action) game:registerDialog(d) end + +--- Wear/wield an item +function _M:wearObject(o, replace, vocal) + local inven = o:wornInven() + if not o then + if vocal then game.logSeen(self, "%s is not wearable.", o:getName()) end + return false + end + if self:addObject(inven, o) then + if vocal then game.logSeen(self, "%s wears: %s.", self.name:capitalize(), o:getName()) end + return true + elseif replace then + local ro = self:removeObject(inven, 1) + -- Warning: assume there is now space + self:addObject(inven, o) + return ro + else + if vocal then game.logSeen(self, "%s can not wear: %s.", self.name:capitalize(), o:getName()) end + return false + end +end + +--- Takeoff item +function _M:takeoffObject(inven, item) + inven = self:getInven(inven) + local o = table.remove(inven, item) + return o +end diff --git a/game/engine/utils.lua b/game/engine/utils.lua index e9930339d78a04ba77f72eba77d81750db6f924e..77a6efb0c3a29cd4896cba0835ebd70884c00392 100644 --- a/game/engine/utils.lua +++ b/game/engine/utils.lua @@ -249,3 +249,9 @@ function core.fov.beam_grids(x, y, radius, dir, angle, block) return grids end + +function util.showMainMenu() + local Menu = require("special.mainmenu.class.Game") + game = Menu.new() + game:run() +end diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua index 56f57804dbe19c616366b1af4c7cc343d5835215..1a9bc768413973a97c0c77b585837f8ce0cb7043 100644 --- a/game/modules/tome/class/Actor.lua +++ b/game/modules/tome/class/Actor.lua @@ -26,6 +26,22 @@ module(..., package.seeall, class.inherit( )) function _M:init(t) + -- Define some basic combat stats + self.combat_def = 0 + self.combat_armor = 0 + self.combat_atk = 0 + self.combat_apr = 0 + self.combat_dam = 0 + self.combat_physcrit = 0 + self.combat_physspeed = 0 + self.combat_spellspeed = 0 + self.combat_spellcrit = 0 + self.combat_spellpower = 0 + self.fatigue = 0 + + -- Default melee barehanded damage + self.combat = { dam=1, atk=1, apr=0, dammod={str=1} } + engine.Actor.init(self, t) engine.interface.ActorInventory.init(self, t) engine.interface.ActorTemporaryEffects.init(self, t) @@ -48,16 +64,15 @@ function _M:act() self:regenResources() -- Compute timed effects self:timedEffects() - - engine.Actor.act(self) end function _M:move(x, y, force) local moved = false if force or self:enoughEnergy() then moved = engine.Actor.move(self, game.level.map, x, y, force) - if not force and moved then self:useEnergy() end + if not force and moved and not self.did_energy then self:useEnergy() end end + self.did_energy = nil return moved end @@ -133,11 +148,11 @@ end -- @return true to continue, false to stop function _M:preUseTalent(ab) if not self:enoughEnergy() then return end - if ab.mana and self:getMana() < ab.mana then + if ab.mana and self:getMana() < ab.mana * (100 + self.fatigue) / 100 then game.logPlayer(self, "You do not have enough mana to cast %s.", ab.name) return end - if ab.stamina and self:getStamina() < ab.stamina then + if ab.stamina and self:getStamina() < ab.stamina * (100 + self.fatigue) / 100 then game.logPlayer(self, "You do not have enough stamina to use %s.", ab.name) return end @@ -163,13 +178,20 @@ end -- @return true to continue, false to stop function _M:postUseTalent(ab, ret) if ret == nil then return end - self:useEnergy() + + if ab.type[1]:find("^spell/") then + self:useEnergy(game.energy_to_act * self:combatSpellSpeed()) + elseif ab.type[1]:find("^physical/") then + self:useEnergy(game.energy_to_act * self:combatSpeed()) + else + self:useEnergy() + end if ab.mana then - self:incMana(-ab.mana) + self:incMana(-ab.mana * (100 + self.fatigue) / 100) end if ab.stamina then - self:incStamina(-ab.stamina) + self:incStamina(-ab.stamina * (100 + self.fatigue) / 100) end return true diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua index bfebaa30bf1262d82ec246f442a9b705732420c1..9f3a82184bac9396bc103701335dad8a24e887b1 100644 --- a/game/modules/tome/class/Game.lua +++ b/game/modules/tome/class/Game.lua @@ -294,15 +294,40 @@ function _M:setupCommands() -- Show inventory _i = function() - self.player:showInventory(self.player:getInven(self.player.INVEN_INVEN), nil, function() end) + self.player:showInventory(nil, self.player:getInven(self.player.INVEN_INVEN), nil, function() end) + end, + -- Show equipment + _e = function() + self.player:showEquipment(nil, nil, function() end) end, -- Drop item _d = function() local inven = self.player:getInven(self.player.INVEN_INVEN) - self.player:showInventory(inven, nil, function(o, item) + self.player:showInventory("Drop object", inven, nil, function(o, item) self.player:dropFloor(inven, item) end) end, + -- Wear item + _w = function() + local inven = self.player:getInven(self.player.INVEN_INVEN) + self.player:showInventory("Wield/wear object", inven, function(o) + return o:wornInven() and true or false + end, function(o, item) + local ro = self.player:wearObject(o, true, true) + if ro then + if type(ro) == "table" then self.player:addObject(self.player.INVEN_INVEN, ro) end + self.player:removeObject(self.player.INVEN_INVEN, item) + end + end) + end, + -- Takeoff item + _t = function() + self.player:showEquipment("Take off object", nil, function(o, inven, item) + if self.player:takeoffObject(inven, item) then + self.player:addObject(self.player.INVEN_INVEN, o) + end + end) + end, [{"_g","shift"}] = function() local none = true @@ -345,7 +370,7 @@ function _M:setupCommands() end, _GREATER = {"alias", "_LESS"}, -- Toggle tactical displau - _t = function() + [{"_t","shift"}] = function() if Map.view_faction then self:targetMode(false, true) else @@ -354,7 +379,7 @@ function _M:setupCommands() self.target:scan(5) end end, - -- Toggle tactical displau + -- Show time [{"_t","ctrl"}] = function() self.log(self.calendar:getTimeDate(self.turn)) end, diff --git a/game/modules/tome/class/Player.lua b/game/modules/tome/class/Player.lua index 67dd4c27a74e4976345b6c92ebf184318fc7db08..49d917776a488c46b07a5ec14c3297a15b67f939 100644 --- a/game/modules/tome/class/Player.lua +++ b/game/modules/tome/class/Player.lua @@ -9,8 +9,8 @@ module(..., package.seeall, class.inherit(mod.class.Actor)) function _M:init(t) t.body = { INVEN = 1000, - MAIN_HAND = 1, - OFF_HAND = 1, + MAINHAND = 1, + OFFHAND = 1, FINGER = 2, NECK = 1, LITE = 1, @@ -23,10 +23,12 @@ function _M:init(t) mod.class.Actor.init(self, t) self.player = true self.faction = "players" - self.combat = { dam=10, atk=40, apr=2, def=6, armor=4 } + + -- Default regen self.mana_regen = self.mana_regen or 1 self.stamina_regen = self.stamina_regen or 1 self.life_regen = self.life_regen or 0.5 + self.descriptor = {} self.hotkey = {} end diff --git a/game/modules/tome/class/interface/Combat.lua b/game/modules/tome/class/interface/Combat.lua index 13377b6e6840caec1a51a91c1522e751b0bc4888..a95aa38b44e31cab0b7bd38a951138497a8a524e 100644 --- a/game/modules/tome/class/interface/Combat.lua +++ b/game/modules/tome/class/interface/Combat.lua @@ -32,27 +32,133 @@ end --- Makes the death happen! --[[ The ToME combat system has the following attributes: -- attack power: increases chances to hit against high defence +- attack: 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 + local speed = nil + + -- All weaponsin main hands + 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) + speed = math.max(speed or 0, s) + end + end + end + -- All wpeaons in off hands + if self:getInven(self.INVEN_OFFHAND) then + for i, o in ipairs(self:getInven(self.INVEN_OFFHAND)) do + if o.combat then + local s = self:attackTargetWith(target, o.combat) + speed = math.max(speed or 0, s) + end + end + end + + -- Barehanded ? + if not speed then + speed = self:attackTargetWith(target, self.combat) + end + + -- We use up our own energy + if speed then + self:useEnergy(game.energy_to_act * speed) + self.did_energy = true + end +end + +--- Attacks with one weapon +function _M:attackTargetWith(target, weapon) local damtype = DamageType.PHYSICAL - 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? yes .. complex :/ + local atk, def = self:combatAttack(weapon), target:combatDefense() + local dam, apr, armor = self:combatDamage(weapon), self:combatAPR(weapon), target:combatArmor() + print(atk, def, "::", dam, apr, armor) + if afk == 0 then atk = 1 end + local hit = nil + if atk > def then + hit = math.log10(1 + 5 * (atk - def) / atk) * 100 + 50 + else + hit = -math.log10(1 + 5 * (def - atk) / atk) * 100 + 50 + end + hit = util.bound(hit, 5, 95) + print("hit: ", hit, "from", atk, def) - -- 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) + if rng.percent(hit) then + local dam = dam - math.max(0, armor - apr) DamageType:get(damtype).projector(self, target.x, target.y, damtype, dam) else game.logSeen(target, "%s misses %s.", self.name:capitalize(), target.name) end + + return self:combatSpeed(weapon) +end + +--- Gets the defense +function _M:combatDefense() + return self.combat_def + self:getDex() - 10 +end + +--- Gets the armor +function _M:combatArmor() + return self.combat_armor +end + +--- Gets the attack +function _M:combatAttack(weapon) + weapon = weapon or self.combat + return self.combat_atk + weapon.atk + (self:getStr(50) - 5) + (self:getDex(50) - 5) +end + +--- Gets the armor penetration +function _M:combatAPR(weapon) + weapon = weapon or self.combat + return self.combat_apr + weapon.apr +end + +--- Gets the weapon speed +function _M:combatSpeed(weapon) + weapon = weapon or self.combat + return self.combat_physspeed + (weapon.physspeed or 1) +end + +--- Gets the crit rate +function _M:combatCrit(weapon) + weapon = weapon or self.combat + return self.combat_physcrit + (self:getCun() - 10) * 0.3 + (weapon.physcrit or 1) +end + +--- Gets the damage +function _M:combatDamage(weapon) + weapon = weapon or self.combat + local add = 0 + if weapon.dammod then + for stat, mod in pairs(weapon.dammod) do + add = add + (self:getStat(stat) - 10) * mod + end + end + return self.combat_armor + weapon.dam + add +end + +--- Gets spellpower +function _M:combatSpellpower(mod) + mod = mod or 1 + return (self.combat_spellpower + self:getMag()) * mod +end + +--- Gets spellcrit +function _M:combatSpellCrit() + return self.combat_spellcrit + 1 +end + +--- Gets spellspeed +function _M:combatSpellSpeed() + return self.combat_spellspeed + (self:getCun() - 10) * 0.3 + 1 end diff --git a/game/modules/tome/data/general/objects.lua b/game/modules/tome/data/general/objects.lua index 31354aceb5163e44a1c40c9fc8701341c2c5da1f..d2324b5c9215a3520ecad3c68050726764592e85 100644 --- a/game/modules/tome/data/general/objects.lua +++ b/game/modules/tome/data/general/objects.lua @@ -1,7 +1,8 @@ newEntity{ define_as = "BASE_SWORD", + slot = "MAINHAND", type = "weapon", - display = "\\", color_r=255, + display = "/", color_r=255, encumber = 3, egos_chance = { }, egos = loadList("/data/general/egos.lua"), @@ -12,8 +13,13 @@ newEntity{ name = "& #1#longsword~#2#", level_range = {1, 10}, rarity = 3, + combat = { + dam = resolvers.rngavg(7,11), + atk = 3, + apr = 2, + dammod = {str=1}, + }, wielder = { - combat_dam=resolvers.rngavg(7,11), }, } @@ -24,7 +30,8 @@ newEntity{ rarity = 2, encumber = 6, wielder = { - combat_def=6, + combat_def = 6, + combat_armor = 1, }, } @@ -35,8 +42,13 @@ newEntity{ level_range = {1, 10}, rarity = 2, encumber = 4, + combat = { + dam = 1, + atk = 1, + apr = 0, + dammod = {wil=1}, + }, wielder = { - combat_dam=3, stats = {mag=3, wil=2}, } } @@ -49,8 +61,13 @@ newEntity{ rarity = 15, encumber = 3, unique = "STAFF_OLORIN", + combat = { + dam = 3, + atk = 1, + apr = 0, + dammod = {wil=1}, + }, wielder = { - combat_dam=3, stats = {mag=3, wil=2}, } } diff --git a/game/modules/tome/data/talents/spells/air.lua b/game/modules/tome/data/talents/spells/air.lua index 0d7f37bb757c55c9284570ae1c44b281df5cb940..e9dfe93d308096edbc390a6a1512d89bf58c19b9 100644 --- a/game/modules/tome/data/talents/spells/air.lua +++ b/game/modules/tome/data/talents/spells/air.lua @@ -7,7 +7,7 @@ newTalent{ ATTACKAREA = 10, }, action = function(self) - local duration = 5 + self:getMag(10) + local duration = 5 + self:combatSpellpower(0.1) local radius = 3 local t = {type="ball", range=15, radius=radius} local x, y = self:getTarget(t) @@ -16,7 +16,7 @@ newTalent{ -- Add a lasting map effect game.level.map:addEffect(self, x, y, duration, - DamageType.NATURE, 4 + self:getMag(30), + DamageType.NATURE, 4 + self:combatSpellpower(0.3), radius, 5, nil, engine.Entity.new{alpha=100, display='', color_br=30, color_bg=180, color_bb=60} @@ -27,6 +27,6 @@ newTalent{ info = function(self) return ([[Noxious fumes raises from the ground doing %0.2f nature damage in a radius of 3 each turns for %d turns. Cooldown: 8 turns - The damage and duration will increase with the Magic stat]]):format(4 + self:getMag(30), 5 + self:getMag(10)) + The damage and duration will increase with the Magic stat]]):format(4 + self:combatSpellpower(0.3), 5 + self:combatSpellpower(0.1)) end, } diff --git a/game/modules/tome/data/talents/spells/arcane.lua b/game/modules/tome/data/talents/spells/arcane.lua index 6f317caa2f339bfc530edfc91f5f52acd5e5c6d7..bedf71fbb17348c48b819bfd3606771ac10436ad 100644 --- a/game/modules/tome/data/talents/spells/arcane.lua +++ b/game/modules/tome/data/talents/spells/arcane.lua @@ -9,13 +9,13 @@ newTalent{ local t = {type="bolt", range=20} local x, y = self:getTarget(t) if not x or not y then return nil end - self:project(t, x, y, DamageType.ARCANE, 10 + self:getMag()) + self:project(t, x, y, DamageType.ARCANE, 10 + self:combatSpellpower()) return true end, require = { stat = { mag=10 }, }, info = function(self) return ([[Conjures up mana into a powerful bolt doing %0.2f arcane damage - The damage will increase with the Magic stat]]):format(10 + self:getMag()) + The damage will increase with the Magic stat]]):format(10 + self:combatSpellpower()) end, } newTalent{ @@ -32,7 +32,7 @@ newTalent{ require = { stat = { mag=50 }, }, info = function(self) return ([[Uses mana instead of life to take damage - The damage to mana ratio increases with the Magic stat]]):format(10 + self:getMag()) + The damage to mana ratio increases with the Magic stat]]):format(10 + self:combatSpellpower()) end, } newTalent{ @@ -45,13 +45,13 @@ newTalent{ }, action = function(self) if not self:hasEffect(self.EFF_MANAFLOW) then - self:setEffect(self.EFF_MANAFLOW, 10, {power=5+self:getMag(30)}) + self:setEffect(self.EFF_MANAFLOW, 10, {power=5+self:combatSpellpower(0.3)}) end return true end, require = { stat = { mag=60 }, }, info = function(self) return ([[Engulf yourself into a surge of mana, quickly restoring %d mana every turns for 10 turns. - The mana restored will increase with the Magic stat]]):format(5 + self:getMag(30)) + The mana restored will increase with the Magic stat]]):format(5 + self:combatSpellpower(0.3)) end, } diff --git a/game/modules/tome/data/talents/spells/conveyance.lua b/game/modules/tome/data/talents/spells/conveyance.lua index 6341ab20b97af75ee938e1cac626abb6877c4608..67bf132628bcfebeb1294271fb3167f5789b6d35 100644 --- a/game/modules/tome/data/talents/spells/conveyance.lua +++ b/game/modules/tome/data/talents/spells/conveyance.lua @@ -10,21 +10,21 @@ newTalent{ action = function(self) local x, y = self.x, self.y if self:knowTalent(self.T_TELEPORT_CONTROL) then - x, y = self:getTarget{type="ball", range=10 + self:getMag(10), radius=5 - self:getMag(4)} + x, y = self:getTarget{type="ball", range=10 + self:combatSpellpower(0.1), radius=5 - self:combatSpellpower(0.04)} if not x then return nil end -- Target code doesnot restrict the target coordinates to the range, it lets the poject function do it -- but we cant ... - x, y = game.target:pointAtRange(self.x, self.y, x, y, 10 + self:getMag(10)) - self:teleportRandom(x, y, 5 - self:getMag(4)) + x, y = game.target:pointAtRange(self.x, self.y, x, y, 10 + self:combatSpellpower(0.1)) + self:teleportRandom(x, y, 5 - self:combatSpellpower(0.4)) else - self:teleportRandom(x, y, 10 + self:getMag(10)) + self:teleportRandom(x, y, 10 + self:combatSpellpower(0.1)) end return true end, require = { stat = { mag=12 }, }, info = function(self) return ([[Teleports you randomly on a small scale range (%d) - The range will increase with the Magic stat]]):format(10 + self:getMag(10)) + The range will increase with the Magic stat]]):format(10 + self:combatSpellpower(0.1)) end, } @@ -35,6 +35,6 @@ newTalent{ require = { stat = { mag=38 }, }, info = function(self) return ([[Allows teleport spells to specify a target area. You will blink in this radius randomly. - The radius (%d) of the target area decreases with Magic stat]]):format(5 - self:getMag(4)) + The radius (%d) of the target area decreases with Magic stat]]):format(5 - self:combatSpellpower(0.04)) end, } diff --git a/game/modules/tome/data/talents/spells/earth.lua b/game/modules/tome/data/talents/spells/earth.lua index 259daa2338dc23cc2035cb569e88de80147225cc..94f6b75ba03976b129116f37931f73c2bef04a54 100644 --- a/game/modules/tome/data/talents/spells/earth.lua +++ b/game/modules/tome/data/talents/spells/earth.lua @@ -8,7 +8,7 @@ newTalent{ DEFEND = 10, }, activate = function(self) - local power = 1 + self:getMag(15) + local power = 1 + self:combatSpellpower(0.15) self.combat.armor = self.combat.armor + power return {power=power} end, @@ -18,6 +18,6 @@ newTalent{ require = { stat = { mag=14 }, }, info = function(self) return ([[The caster skin grows as hard as stone, granting %d bonus to armor. - The bonus to armor will increase with the Magic stat]]):format(1 + self:getMag(15)) + The bonus to armor will increase with the Magic stat]]):format(1 + self:combatSpellpower(0.15)) end, } diff --git a/game/modules/tome/data/talents/spells/fire.lua b/game/modules/tome/data/talents/spells/fire.lua index 9568f9e7d4ba9e564e30583c0c2f98b68f924bef..45221b39c77c5bdb06026334ff2a657d3cb27082 100644 --- a/game/modules/tome/data/talents/spells/fire.lua +++ b/game/modules/tome/data/talents/spells/fire.lua @@ -6,14 +6,14 @@ newTalent{ ATTACKAREA = 3, }, action = function(self) - local t = {type="ball", range=0, friendlyfire=false, radius=5 + self:getMag(10)} + local t = {type="ball", range=0, friendlyfire=false, radius=5 + self:combatSpellpower(0.1)} self:project(t, self.x, self.y, DamageType.LIGHT, 1) return true end, require = { stat = { mag=10 }, }, info = function(self) return ([[Creates a globe of pure light with a radius of %d that illuminates the area. - The radius will increase with the Magic stat]]):format(5 + self:getMag(10)) + The radius will increase with the Magic stat]]):format(5 + self:combatSpellpower(0.1)) end, } @@ -26,16 +26,16 @@ newTalent{ ATTACKAREA = 10, }, action = function(self) - local t = {type="ball", range=15, radius=math.min(6, 3 + self:getMag(6))} + local t = {type="ball", range=15, radius=math.min(6, 3 + self:combatSpellpower(0.06))} local x, y = self:getTarget(t) if not x or not y then return nil end - self:project(t, x, y, DamageType.FIRE, 28 + self:getMag(70)) + self:project(t, x, y, DamageType.FIRE, 28 + self:combatSpellpower(0.7)) return true end, require = { stat = { mag=16 }, }, info = function(self) return ([[Conjures up a flash of fire doing %0.2f fire damage in a radius of %d. Cooldown: 6 turns - The damage will increase with the Magic stat]]):format(8 + self:getMag(70), math.min(6, 3 + self:getMag(6))) + The damage will increase with the Magic stat]]):format(8 + self:combatSpellpower(0.7), math.min(6, 3 + self:combatSpellpower(0.06))) end, } diff --git a/game/modules/tome/data/talents/spells/nature.lua b/game/modules/tome/data/talents/spells/nature.lua index 8bb7e4014e888579d60824189891e8460282286b..59067a0856984abc0c7712e0af0760c80c299982 100644 --- a/game/modules/tome/data/talents/spells/nature.lua +++ b/game/modules/tome/data/talents/spells/nature.lua @@ -7,13 +7,13 @@ newTalent{ HEAL = 10, }, action = function(self) - self:setEffect(self.EFF_REGENERATION, 10, {power=5 + self:getMag(35)}) + self:setEffect(self.EFF_REGENERATION, 10, {power=5 + self:combatSpellpower(0.35)}) return true end, require = { stat = { mag=10 }, }, info = function(self) return ([[Call upon the forces of nature to regenerate your body for %d life every turns for 10 turns. - The life healed will increase with the Magic stat]]):format(5 + self:getMag(35)) + The life healed will increase with the Magic stat]]):format(5 + self:combatSpellpower(0.35)) end, } @@ -26,12 +26,12 @@ newTalent{ HEAL = 10, }, action = function(self) - self:heal(10 + self:getMag(200), self) + self:heal(10 + self:combatSpellpower(2), self) return true end, require = { stat = { mag=20 }, }, info = function(self) return ([[Call upon the forces of nature to heal your body for %d life. - The life healed will increase with the Magic stat]]):format(10 + self:getMag(200)) + The life healed will increase with the Magic stat]]):format(10 + self:combatSpellpower(2)) end, } diff --git a/game/modules/tome/dialogs/Quit.lua b/game/modules/tome/dialogs/Quit.lua index bf85b886cbad405c774b407a5df3c785826c4c26..5fbeb63b88d73f6e860735c376850476e562ca14 100644 --- a/game/modules/tome/dialogs/Quit.lua +++ b/game/modules/tome/dialogs/Quit.lua @@ -11,7 +11,7 @@ function _M:init() local save = Savefile.new(game.save_name) save:saveGame(game) save:close() - os.exit() + util.showMainMenu() end, __DEFAULT = function() game:unregisterDialog(self) diff --git a/game/modules/tome/load.lua b/game/modules/tome/load.lua index 495148a573ff7b714b6315633474747b5ed350e0..ee0cd5f41f687f89f8f748b639d01e842c52af10 100644 --- a/game/modules/tome/load.lua +++ b/game/modules/tome/load.lua @@ -32,17 +32,18 @@ dofile("/data/autolevel_schemes.lua") ActorAI:loadDefinition("/engine/ai/") -- Body parts -ActorInventory:defineInventory("MAIN_HAND", "In main hand", true, "") -ActorInventory:defineInventory("OFF_HAND", "In off hand", true, "") -ActorInventory:defineInventory("FINGER", "On fingers", true, "") -ActorInventory:defineInventory("NECK", "Around neck", true, "") -ActorInventory:defineInventory("LITE", "Light source", true, "") -ActorInventory:defineInventory("BODY", "Main armor", true, "") -ActorInventory:defineInventory("CLOAK", "Cloak", true, "") -ActorInventory:defineInventory("HEAD", "On head", true, "") -ActorInventory:defineInventory("HANDS", "On hands", true, "") -ActorInventory:defineInventory("FEET", "On feet", true, "") -ActorInventory:defineInventory("TOOL", "Tool", true, "") +ActorInventory:defineInventory("MAINHAND", "In main hand", true, "Most weapons are wielded in the main hand.") +ActorInventory:defineInventory("OFFHAND", "In off hand", true, "You can use shields or a second weapon in your off hand, if you have the talents for it.") +ActorInventory:defineInventory("FINGER", "On fingers", true, "Rings are worn on fingers.") +ActorInventory:defineInventory("NECK", "Around neck", true, "Amulets are worn around the neck.") +ActorInventory:defineInventory("LITE", "Light source", true, "Light source allows you to see in the dark places of the world.") +ActorInventory:defineInventory("BODY", "Main armor", true, "Armor protects your from physical attacks. The heavier the armor the more it hinders the use of talents and spells.") +ActorInventory:defineInventory("CLOAK", "Cloak", true, "A cloak can simply keep you warn or grant you wonderous powers should you find a magic one.") +ActorInventory:defineInventory("HEAD", "On head", true, "You can wear helmets or crowns on your head") +ActorInventory:defineInventory("BELT", "Around waist", true, "Belts are worn around waist.") +ActorInventory:defineInventory("HANDS", "On hands", true, "Various gloves can be worn on your hands.") +ActorInventory:defineInventory("FEET", "On feet", true, "Sandals or boots can be worn on your feet.") +ActorInventory:defineInventory("TOOL", "Tool", true, "This si your readied tool, always available immediately.") -- Birther descriptor Birther:loadDefinition("/data/birth/descriptors.lua") diff --git a/ideas/combat.ods b/ideas/combat.ods new file mode 100644 index 0000000000000000000000000000000000000000..d2d0636d1ec284b8871dd60e42fa0e900ae377ca Binary files /dev/null and b/ideas/combat.ods differ diff --git a/src/main.c b/src/main.c index afe2cb4c48c9fb6a943c88ce83b515a37f3bb43c..91df877c2bdbac2f4b5804587803748867498937 100644 --- a/src/main.c +++ b/src/main.c @@ -448,8 +448,6 @@ int main(int argc, char *argv[]) /* draw the scene */ on_tick(); -// on_redraw(); - } return 0;