From 10eff649aa2197fd7b984c6d2b8e6a9d759b7578 Mon Sep 17 00:00:00 2001 From: dg <dg@51575b47-30f0-44d4-a5cc-537603b46e54> Date: Mon, 15 Mar 2010 21:27:16 +0000 Subject: [PATCH] unified intentory/equipment git-svn-id: http://svn.net-core.org/repos/t-engine4@424 51575b47-30f0-44d4-a5cc-537603b46e54 --- game/engine/dialogs/ShowEquipInven.lua | 115 ++++++++++++++++++++ game/engine/dialogs/ShowStore.lua | 7 +- game/engine/interface/ActorInventory.lua | 14 +++ game/modules/tome/class/Game.lua | 8 +- game/modules/tome/class/Player.lua | 46 +++++--- game/modules/tome/dialogs/UseItemDialog.lua | 81 ++++++++++++++ ideas/cunning.ods | Bin 14829 -> 14889 bytes 7 files changed, 250 insertions(+), 21 deletions(-) create mode 100644 game/engine/dialogs/ShowEquipInven.lua create mode 100644 game/modules/tome/dialogs/UseItemDialog.lua diff --git a/game/engine/dialogs/ShowEquipInven.lua b/game/engine/dialogs/ShowEquipInven.lua new file mode 100644 index 0000000000..24f9427740 --- /dev/null +++ b/game/engine/dialogs/ShowEquipInven.lua @@ -0,0 +1,115 @@ +require "engine.class" +require "engine.Dialog" + +module(..., package.seeall, class.inherit(engine.Dialog)) + +function _M:init(title, actor, filter, action) + self.action = action + self.filter = filter + self.actor = actor + engine.Dialog.init(self, title or "Inventory", game.w * 0.8, game.h * 0.8, nil, nil, nil, core.display.newFont("/data/font/VeraMono.ttf", 12)) + + self:generateList() + + self.list = self.inven_list + self.sel = 1 + self.scroll = 1 + self.max = math.floor((self.ih * 0.8 - 5) / self.font_h) - 1 + + self:keyCommands({ + __TEXTINPUT = function(c) + if self.list.chars[c] then + self.sel = self.list.chars[c] + self:use() + end + end, + },{ + MOVE_UP = function() self.sel = util.boundWrap(self.sel - 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end, + MOVE_DOWN = function() self.sel = util.boundWrap(self.sel + 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end, + MOVE_LEFT = function() self.list = self.equip_list self.sel = util.bound(self.sel, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end, + MOVE_RIGHT = function() self.list = self.inven_list self.sel = util.bound(self.sel, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end, + ACCEPT = function() self:use() end, + EXIT = function() game:unregisterDialog(self) end, + }) + self:mouseZones{ + { x=2, y=5, w=350, h=self.font_h*self.max, fct=function(button, x, y, xrel, yrel, tx, ty) + self.sel = util.bound(self.scroll + math.floor(ty / self.font_h), 1, #self.list) + if button == "left" then self:use() + elseif button == "right" then + end + end }, + } +end + +function _M:use() + if self.list[self.sel] and self.list[self.sel].item then + if self.action(self.list[self.sel].object, self.list[self.sel].inven, self.list[self.sel].item) then + game:unregisterDialog(self) + end + 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=self.actor.inven_def[inven_id].name, color={0x90, 0x90, 0x90}, 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(), color=o:getDisplayColor(), object=o, inven=inven_id, item=item } + chars[char] = #list + i = i + 1 + end + end + end + end + list.chars = chars + self.equip_list = list + + -- Makes up the list + local list = {} + local chars = {} + local i = 0 + for item, o in ipairs(self.actor:getInven("INVEN")) 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(), color=o:getDisplayColor(), object=o, inven=self.actor.INVEN_INVEN, item=item } + chars[char] = #list + i = i + 1 + end + end + list.chars = chars + self.inven_list = list + self.changed = true + + self.list = self.inven_list + self.sel = 1 + self.scroll = 1 +end + +function _M:drawDialog(s) + 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] and self.list[self.sel].object then + lines = self.list[self.sel].object:getDesc():splitLines(self.iw - 10, self.font) + else + lines = {} + end + + local sh = self.ih - 4 - #lines * self.font:lineSkip() + h = sh + self:drawWBorder(s, 3, sh, self.iw - 6) + for i = 1, #lines do + s:drawColorString(self.font, lines[i], 5, 2 + h) + h = h + self.font:lineSkip() + end + + self:drawSelectionList(s, 2, 5, self.font_h, self.equip_list, self.list == self.equip_list and self.sel or -1, "name", self.scroll, self.max) + self:drawHBorder(s, self.iw / 2, 2, sh - 4) + self:drawSelectionList(s, self.iw / 2 + 5, 5, self.font_h, self.inven_list, self.list == self.inven_list and self.sel or -1, "name", self.scroll, self.max) +end diff --git a/game/engine/dialogs/ShowStore.lua b/game/engine/dialogs/ShowStore.lua index 73392ca187..00add3aeab 100644 --- a/game/engine/dialogs/ShowStore.lua +++ b/game/engine/dialogs/ShowStore.lua @@ -89,20 +89,21 @@ function _M:generateList() end function _M:drawDialog(s) - h = self.ih * 0.80 + 4 if self.list[self.sel] then lines = self.desc(self.list == self.store_list and "buy" or "sell", self.list[self.sel].object):splitLines(self.iw - 10, self.font) else lines = {} end - self:drawWBorder(s, 3, self.ih * 0.80, self.iw - 6) + local sh = self.ih - 4 - #lines * self.font:lineSkip() + h = sh + self:drawWBorder(s, 3, sh, self.iw - 6) for i = 1, #lines do s:drawColorString(self.font, lines[i], 5, 2 + h) h = h + self.font:lineSkip() end self:drawSelectionList(s, 2, 5, self.font_h, self.store_list, self.list == self.store_list and self.sel or -1, "name", self.scroll, self.max) - self:drawHBorder(s, self.iw / 2, 2, self.ih * 0.80 - 4) + self:drawHBorder(s, self.iw / 2, 2, sh - 4) self:drawSelectionList(s, self.iw / 2 + 5, 5, self.font_h, self.actor_list, self.list == self.actor_list and self.sel or -1, "name", self.scroll, self.max) end diff --git a/game/engine/interface/ActorInventory.lua b/game/engine/interface/ActorInventory.lua index 920d501873..3ae2e741bb 100644 --- a/game/engine/interface/ActorInventory.lua +++ b/game/engine/interface/ActorInventory.lua @@ -2,6 +2,7 @@ require "engine.class" local Map = require "engine.Map" local ShowInventory = require "engine.dialogs.ShowInventory" local ShowEquipment = require "engine.dialogs.ShowEquipment" +local ShowEquipInven = require "engine.dialogs.ShowEquipInven" local ShowPickupFloor = require "engine.dialogs.ShowPickupFloor" --- Handles actors stats @@ -157,6 +158,16 @@ function _M:dropFloor(inven, item, vocal, all) return true end +--- Show combined equipment/inventory dialog +-- @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:showEquipInven(title, filter, action, allow_keybind) + local d = ShowEquipInven.new(title, self, filter, action, allow_keybind and self) + game:registerDialog(d) + return d +end + --- Show inventory dialog -- @param inven the inventory (from self:getInven()) -- @param filter nil or a function that filters the objects to list @@ -164,6 +175,7 @@ end function _M:showInventory(title, inven, filter, action, allow_keybind) local d = ShowInventory.new(title, inven, filter, action, allow_keybind and self) game:registerDialog(d) + return d end --- Show equipment dialog @@ -172,6 +184,7 @@ end function _M:showEquipment(title, filter, action, allow_keybind) local d = ShowEquipment.new(title, self, filter, action, allow_keybind and self) game:registerDialog(d) + return d end --- Show floor pickup dialog @@ -180,6 +193,7 @@ end function _M:showPickupFloor(title, filter, action) local d = ShowPickupFloor.new(title, self.x, self.y, filter, action) game:registerDialog(d) + return d end --- Can we wear this item? diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua index 3ec6a511a0..6e49ee8f47 100644 --- a/game/modules/tome/class/Game.lua +++ b/game/modules/tome/class/Game.lua @@ -459,7 +459,13 @@ function _M:setupCommands() self.player:playerDrop() end, SHOW_INVENTORY = function() - self.player:showInventory(nil, self.player:getInven(self.player.INVEN_INVEN), nil, function() end) + local d + d = self.player:showEquipInven(nil, nil, function(o, inven, item) + local ud = require("mod.dialogs.UseItemDialog").new(self.player, o, item, inven, function() + d:generateList() + end) + self:registerDialog(ud) + end) end, SHOW_EQUIPMENT = function() self.player:showEquipment(nil, nil, function() end) diff --git a/game/modules/tome/class/Player.lua b/game/modules/tome/class/Player.lua index 6adcbfb0a0..c99f202e2c 100644 --- a/game/modules/tome/class/Player.lua +++ b/game/modules/tome/class/Player.lua @@ -214,6 +214,32 @@ function _M:runCheck() return engine.interface.PlayerRun.runCheck(self) end +function _M:doDrop(inven, item) + self:dropFloor(inven, item, true, true) + self:sortInven() + self:useEnergy() +end + +function _M:doWear(inven, item, o) + self:removeObject(self.INVEN_INVEN, item, true) + local ro = self:wearObject(o, true, true) + if ro then + if type(ro) == "table" then self:addObject(self.INVEN_INVEN, ro) end + else + self:addObject(self.INVEN_INVEN, o) + end + self:sortInven() + self:useEnergy() +end + +function _M:doTakeoff(inven, item, o) + if self:takeoffObject(inven, item) then + self:addObject(self.INVEN_INVEN, o) + end + self:sortInven() + self:useEnergy() +end + function _M:playerPickup() -- If 2 or more objects, display a pickup dialog, otehrwise just picks up if game.level.map:getObject(self.x, self.y, 2) then @@ -231,9 +257,7 @@ end function _M:playerDrop() local inven = self:getInven(self.INVEN_INVEN) self:showInventory("Drop object", inven, nil, function(o, item) - self:dropFloor(inven, item, true, true) - self:sortInven() - self:useEnergy() + self:doDrop(inven, item) end) end @@ -242,25 +266,13 @@ function _M:playerWear() self:showInventory("Wield/wear object", inven, function(o) return o:wornInven() and true or false end, function(o, item) - self:removeObject(self.INVEN_INVEN, item, true) - local ro = self:wearObject(o, true, true) - if ro then - if type(ro) == "table" then self:addObject(self.INVEN_INVEN, ro) end - else - self:addObject(self.INVEN_INVEN, o) - end - self:sortInven() - self:useEnergy() + self:doWear(inven, item, o) end) end function _M:playerTakeoff() self:showEquipment("Take off object", nil, function(o, inven, item) - if self:takeoffObject(inven, item) then - self:addObject(self.INVEN_INVEN, o) - end - self:sortInven() - self:useEnergy() + self:doTakeoff(inven, item, o) end) end diff --git a/game/modules/tome/dialogs/UseItemDialog.lua b/game/modules/tome/dialogs/UseItemDialog.lua new file mode 100644 index 0000000000..27ddb8d9e8 --- /dev/null +++ b/game/modules/tome/dialogs/UseItemDialog.lua @@ -0,0 +1,81 @@ +require "engine.class" +require "engine.Dialog" +local Savefile = require "engine.Savefile" +local Map = require "engine.Map" + +module(..., package.seeall, class.inherit(engine.Dialog)) + +function _M:init(actor, object, item, inven, onuse) + self.actor = actor + self.object = object + self.inven = inven + self.item = item + self.onuse = onuse + + self.font = core.display.newFont("/data/font/Vera.ttf", 12) + self:generateList() + local name = object:getName() + local nw, nh = self.font:size(name) + engine.Dialog.init(self, name, math.max(nw, self.max) + 10, self.maxh + 10 + 25, nil, nil, nil, self.font) + + self.sel = 1 + self.scroll = 1 + self.max = math.floor((self.ih - 45) / self.font_h) - 1 + + self:keyCommands(nil, { + MOVE_UP = function() self.sel = util.boundWrap(self.sel - 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end, + MOVE_DOWN = function() self.sel = util.boundWrap(self.sel + 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end, + ACCEPT = function() self:use() end, + EXIT = function() game:unregisterDialog(self) end, + }) + self:mouseZones{ + { x=2, y=45, w=350, h=self.font_h*self.max, fct=function(button, x, y, xrel, yrel, tx, ty) + self.changed = true + self.sel = util.bound(self.scroll + math.floor(ty / self.font_h), 1, #self.list) + if button == "left" then self:learn(true) + elseif button == "right" then self:learn(false) + end + self.changed = true + end }, + } +end + +function _M:use() + if not self.list[self.sel] then return end + local act = self.list[self.sel].action + + if act == "use" then self.actor:playerUseItem(self.object, self.item) + elseif act == "drop" then self.actor:doDrop(self.inven, self.item) + elseif act == "wear" then self.actor:doWear(self.inven, self.item, self.object) + elseif act == "takeoff" then self.actor:doTakeoff(self.inven, self.item, self.object) + end + + self.onuse(self.inven, self.item, self.object) + + game:unregisterDialog(self) +end + +function _M:generateList() + local list = {} + + if self.object:canUseObject() then list[#list+1] = {name="Use", action="use"} end + if self.inven == self.actor.INVEN_INVEN and self.object:wornInven() then list[#list+1] = {name="Wield/Wear", action="wear"} end + if self.inven ~= self.actor.INVEN_INVEN and self.object:wornInven() then list[#list+1] = {name="Take off", action="takeoff"} end + if self.inven == self.actor.INVEN_INVEN then list[#list+1] = {name="Drop", action="drop"} end + + self.max = 0 + self.maxh = 0 + for i, v in ipairs(list) do + local w, h = self.font:size(v.name) + self.max = math.max(self.max, w) + self.maxh = self.maxh + h + end + + self.list = list +end + +function _M:drawDialog(s) + local h = 2 + self:drawSelectionList(s, 2, h, self.font_h, self.list, self.sel, "name") + self.changed = false +end diff --git a/ideas/cunning.ods b/ideas/cunning.ods index 4f3b823ab01ac7fe9959d7d006d265c14ab24e8c..fd21ddd66f6c4ce4568cc6e60885ee0ffc5feaca 100644 GIT binary patch delta 6673 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 delta 6569 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 M5@A8#5%@#+KhA?|T>t<8 -- GitLab