Skip to content
Snippets Groups Projects
Commit 13dbd5d1 authored by dg's avatar dg
Browse files

drops; multi-floor pickup dialog

git-svn-id: http://svn.net-core.org/repos/t-engine4@145 51575b47-30f0-44d4-a5cc-537603b46e54
parent 8bc1baff
No related branches found
No related tags found
No related merge requests found
......@@ -460,4 +460,31 @@ function _M:addObject(x, y, o)
while self(x, y, i) do i = i + 1 end
-- Fill it
self(x, y, i, o)
return true
end
function _M:getObject(x, y, i)
-- Compute the map stack position
i = i - 1 + self.OBJECT
return self(x, y, i)
end
function _M:removeObject(x, y, i)
-- Compute the map stack position
i = i - 1 + self.OBJECT
if not self(x, y, i) then return false end
-- Remove it
self:remove(x, y, i)
-- Move the last one to its position, to never get a "hole"
local j = i + 1
while self(x, y, j) do j = j + 1 end
j = j - 1
-- If the removed one was not the last
if j > i then
local o = self(x, y, j)
self:remove(x, y, j)
self(x, y, i, o)
end
return true
end
......@@ -142,18 +142,18 @@ function _M:makeEntity(level, type, filter)
end
if tries == 0 then return nil end
e = self:finishEntity(level, type, e)
e = self:finishEntity(level, type, e, filter and filter.ego_chance)
return e
end
--- Finishes generating an entity
function _M:finishEntity(level, type, e)
function _M:finishEntity(level, type, e, ego_chance)
e = e:clone()
e:resolve()
-- Add "ego" properties, sometimes
if e.egos and e.egos_chance and rng.percent(e.egos_chance) then
if e.egos and e.egos_chance and rng.percent(e.egos_chance + (ego_chance or 0)) then
local egos = self:getEgosList(level, type, e.egos, e.__CLASSNAME)
local ego = self:pickEntity(egos)
if ego then
......@@ -169,6 +169,7 @@ function _M:finishEntity(level, type, e)
print("applying ego", ego.name, "to ", e.name, "::", newname)
table.merge(e, ego, true)
e.name = newname
e.egoed = true
end
end
return e
......
require "engine.class"
require "engine.Dialog"
module(..., package.seeall, class.inherit(engine.Dialog))
function _M:init(title, x, y, filter, action)
self.x, self.y = x, y
self.filter = filter
self.action = action
engine.Dialog.init(self, title or "Pickup", 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,
_ASTERISK = function() while self:use() do end end,
__TEXTINPUT = function(c)
if c:find("^[a-z]$") then
self.sel = util.bound(1 + string.byte(c) - string.byte('a'), 1, #self.list)
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 = util.bound(1 + 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] then
self.action(self.list[self.sel].object, self.list[self.sel].item)
end
self:generateList()
if #self.list == 0 then
game:unregisterDialog(self)
return false
end
return true
end
function _M:generateList()
-- Makes up the list
local list = {}
local idx = 1
local i = 1
while true do
local o = game.level.map:getObject(self.x, self.y, idx)
if not o then break end
if not self.filter or self.filter(o) then
list[#list+1] = { name=string.char(string.byte('a') + i)..") "..o:getName(), object=o, item=idx }
i = i + 1
end
idx = idx + 1
end
self.list = list
self.sel = 1
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 pickup.
]]):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 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
......@@ -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 ShowPickupFloor = require "engine.dialogs.ShowPickupFloor"
--- Handles actors stats
module(..., package.seeall, class.make)
......@@ -69,11 +70,10 @@ end
--- Picks an object from the floor
function _M:pickupFloor(i, vocal)
i = i - 1 + Map.OBJECT
local o = game.level.map(self.x, self.y, i)
local o = game.level.map:getObject(self.x, self.y, i)
if o then
if self:addObject(self.INVEN_INVEN, o) then
game.level.map:remove(self.x, self.y, i)
game.level.map:removeObject(self.x, self.y, i)
if vocal then game.logSeen(self, "%s picks up: %s.", self.name:capitalize(), o:getName()) end
else
......@@ -130,6 +130,14 @@ function _M:showEquipment(title, filter, action)
game:registerDialog(d)
end
--- Show floor pickup 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:showPickupFloor(title, filter, action)
local d = ShowPickupFloor.new(title, self.x, self.y, filter, action)
game:registerDialog(d)
end
--- Wear/wield an item
function _M:wearObject(o, replace, vocal)
local inven = o:wornInven()
......
......@@ -125,6 +125,17 @@ function _M:die(src)
end
-- Do we get a blooooooody death ?
if rng.percent(33) then self:bloodyDeath() end
-- Drop stuff
for inven_id, inven in pairs(self.inven) do
for i, o in ipairs(inven) do
if not o.no_drop then
game.level.map:addObject(self.x, self.y, o)
end
end
end
self.inven = {}
return true
end
......
......@@ -295,7 +295,14 @@ function _M:setupCommands()
-- Pickup object
_g = function()
self.player:pickupFloor(1, true)
-- If 2 or more objects, display a pickup dialog, otehrwise just picks up
if self.level.map:getObject(self.player.x, self.player.y, 2) then
self.player:showPickupFloor(nil, nil, function(o, item)
self.player:pickupFloor(item, true)
end)
else
self.player:pickupFloor(1, true)
end
end,
-- Show inventory
......
......@@ -72,7 +72,8 @@ newEntity{
BODY = 1, HEAD = 1, HANDS = 1, FEET = 1,
TOOL = 1,
},
equipment = resolvers.equip{ {type="weapon", subtype="longsword"}, {type="armor", subtype="massive"}, {type="armor", subtype="shield"}, },
equipment = resolvers.equip{ {type="weapon", subtype="longsword"}, {type="armor", subtype="massive"}, {type="armor", subtype="shield"}, },
drops = resolvers.drops{chance=100, nb=3, {ego_chance=100} },
stats = { str=14, dex=12, mag=8, con=13 },
talents = { },
......
......@@ -11,6 +11,32 @@ function resolvers.calc.equip(t, e)
if o then
print("Zone made us an equipment according to filter!", o:getName())
e:wearObject(o, true, false)
-- Do not drop it unless it is an ego or better
if not o.egoed and not o.unique then o.no_drop = true end
end
end
-- Delete the origin field
return nil
end
--- Resolves drops creation for an actor
function resolvers.drops(t)
return {__resolver="drops", t}
end
--- Actually resolve the drops creation
function resolvers.calc.drops(t, e)
t = t[1]
if not rng.percent(t.chance) then return nil end
-- Iterate of object requests, try to create them and drops them
for i = 1, (t.nb or 1) do
local filter = t[rng.range(1, #t)]
print("Drops resolver", filter.type, filter.subtype)
local o = game.zone:makeEntity(game.level, "object", filter)
if o then
print("Zone made us an drop according to filter!", o:getName())
e:addObject(e.INVEN_INVEN, o)
end
end
-- Delete the origin field
......
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