Skip to content
Snippets Groups Projects
Commit 860bc594 authored by dg's avatar dg
Browse files

store

git-svn-id: http://svn.net-core.org/repos/t-engine4@376 51575b47-30f0-44d4-a5cc-537603b46e54
parent 94f8c272
No related branches found
No related tags found
No related merge requests found
Showing with 274 additions and 85 deletions
......@@ -128,22 +128,24 @@ end
function _M:drawSelectionList(s, x, y, hskip, list, sel, prop, scroll, max, color, selcolor)
selcolor = selcolor or {0,255,255}
color = color or {255,255,255}
scroll = scroll or 1
scroll = util.bound(scroll or 1, 1, max)
max = max or 99999
for i = scroll, math.min(#list, scroll + max - 1) do
local v = list[i]
local vc = nil
if type(v) == "table" then vc = v.color end
if prop and type(v[prop]) == "string" then v = tostring(v[prop])
elseif prop and type(v[prop]) == "function" then v = tostring(v[prop](v))
else v = tostring(v) end
if sel == i then
s:drawColorString(self.font, v, x, y + (i-scroll) * hskip, selcolor[1], selcolor[2], selcolor[3])
else
local r, g, b = color[1], color[2], color[3]
if vc then r, g, b = vc[1], vc[2], vc[3] end
s:drawColorString(self.font, v, x, y + (i-scroll) * hskip, r, g, b)
if v then
if type(v) == "table" then vc = v.color end
if prop and type(v[prop]) == "string" then v = tostring(v[prop])
elseif prop and type(v[prop]) == "function" then v = tostring(v[prop](v))
else v = tostring(v) end
if sel == i then
s:drawColorString(self.font, v, x, y + (i-scroll) * hskip, selcolor[1], selcolor[2], selcolor[3])
else
local r, g, b = color[1], color[2], color[3]
if vc then r, g, b = vc[1], vc[2], vc[3] end
s:drawColorString(self.font, v, x, y + (i-scroll) * hskip, r, g, b)
end
end
end
end
require "engine.class"
local Entity = require "engine.Entity"
local Inventory = require "engine.interface.ActorInventory"
local ShowStore = require "engine.dialogs.ShowStore"
local GetQuantity = require "engine.dialogs.GetQuantity"
module(..., package.seeall, class.inherit(Entity, Inventory))
function _M:init(t, no_default)
t = t or {}
t.body = {INVEN=10000}
Entity.init(self, t, no_default)
Inventory.init(self, t, no_default)
end
--- Fill the store with goods
-- @param level the level to generate for (inctance of type engine.Level)
-- @param zone the zone to generate for
function _M:loadup(level, zone)
local s = self.store
if not s then error("Store without a store field") end
if self.last_filled and game.turn and self.last_filled >= game.turn - s.restock_after then
print("[STORE] not restocking yet", game.turn, s.restock_after, self.last_filled)
return
end
local inven = self:getInven("INVEN")
for i = 1, rng.range(s.min_fill, s.max_fill) - #inven do
local filter = rng.table(s.filters)
local e = zone:makeEntity(level, "object", filter)
if e then
if filter.id then e:identify(filter.id) end
self:addObject(inven, e)
print("[STORE] stocking up: ", e.name)
end
end
self:sortInven(inven)
self.last_filled = game.turn
end
--- Actor interacts with the store
-- @param who the actor who interracts
function _M:interact(who)
local store, inven = self:getInven("INVEN"), who:getInven("INVEN")
local d; d = ShowStore.new("Store: "..self.name, store, inven, nil, nil, function(what, o, item)
if what == "buy" then
if o:getNumber() > 1 then
local q = GetQuantity.new(nil, nil, function(qty) self:doBuy(who, o, item, qty) print(d) d:updateStore() end)
q.qty = o:getNumber()
game:registerDialog(q)
else
self:doBuy(who, o, item, 1)
end
else
if o:getNumber() > 1 then
local q
q = GetQuantity.new(nil, nil, function(qty) self:doSell(who, o, item, qty) d:updateStore() end)
q.qty = o:getNumber()
game:registerDialog(q)
else
self:doSell(who, o, item, 1)
end
end
end, function(what, o)
return self:descObject(who, what, o)
end)
game:registerDialog(d)
end
function _M:doBuy(who, o, item, nb)
local max_nb = o:getNumber()
nb = math.min(nb, max_nb)
nb = self:onBuy(who, o, item, nb)
if nb then
local store, inven = self:getInven("INVEN"), who:getInven("INVEN")
for i = 1, nb do
local o = self:removeObject(store, item)
who:addObject(inven, o)
end
self:sortInven(store)
who:sortInven(inven)
self.changed = true
who.changed = true
end
end
function _M:doSell(who, o, item, nb)
local max_nb = o:getNumber()
nb = math.min(nb, max_nb)
nb = self:onSell(who, o, item)
if nb then
local store, inven = self:getInven("INVEN"), who:getInven("INVEN")
for i = 1, nb do
local o = who:removeObject(inven, item)
self:addObject(store, o)
end
self:sortInven(store)
who:sortInven(inven)
self.changed = true
who.changed = true
end
end
--- Called on object purchase
-- @param who the actor buying
-- @param o the object trying to be purchased
-- @param item the index in the inventory
-- @param nb number of items (if stacked) to buy
-- @return a number (or nil) if allowed to buy, giving the number of objects to buy
function _M:onBuy(who, o, item, nb)
return nb
end
--- Called on object sale
-- @param who the actor selling
-- @param o the object trying to be sold
-- @param item the index in the inventory
-- @param nb number of items (if stacked) to sell
-- @return a number (or nil) if allowed to sell, giving the number of objects to sell
function _M:onSell(who, o, item, nb)
return nb
end
--- Called to describe an object, being to sell or to buy
-- @param who the actor
-- @param what either "sell" or "buy"
-- @param o the object
-- @return a string (possibly multiline) describing the object
function _M:descObject(what, o)
return o:getDesc()
end
require "engine.class"
require "engine.Dialog"
module(..., package.seeall, class.inherit(engine.Dialog))
function _M:init(title, prompt, act)
engine.Dialog.init(self, title or "Quantity?", 300, 100)
self.prompt = prompt
self.act = act
self.qty = 0
self:keyCommands{
_RETURN = function()
game:unregisterDialog(self)
act(self.qty)
end,
_BACKSPACE = function()
local b = tostring(self.qty)
b = b:sub(1, b:len() - 1)
if b == '' then self.qty = 0
else self.qty = tonumber(b)
end
end,
__TEXTINPUT = function(c)
if not (c == '0' or c == '1' or c == '2' or c == '3' or c == '4' or c == '5' or c == '6' or c == '7' or c == '8' or c == '9') then return end
if self.qty >= 10000000 then return end
local b = tostring(self.qty)
if self.qty == 0 then b = "" end
self.qty = tonumber(b .. c)
self.changed = true
end,
}
end
function _M:drawDialog(s, w, h)
s:drawColorStringCentered(self.font, self.prompt or "Quantity:", 2, 2, self.iw - 2, self.ih - 2 - self.font:lineSkip())
s:drawColorStringCentered(self.font, tostring(self.qty), 2, 2 + self.font:lineSkip(), self.iw - 2, self.ih - 2 - self.font:lineSkip())
end
......@@ -3,7 +3,9 @@ require "engine.Dialog"
module(..., package.seeall, class.inherit(engine.Dialog))
function _M:init(title, store_inven, actor_inven, store_filter, actor_filter, action)
function _M:init(title, store_inven, actor_inven, store_filter, actor_filter, action, desc)
self.action = action
self.desc = desc
self.store_inven = store_inven
self.actor_inven = actor_inven
self.store_filter = store_filter
......@@ -25,10 +27,10 @@ function _M:init(title, store_inven, actor_inven, store_filter, actor_filter, ac
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) end,
MOVE_DOWN = function() self.sel = util.boundWrap(self.sel + 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) end,
MOVE_LEFT = function() end,
MOVE_RIGHT = function() 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.store_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.actor_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,
})
......@@ -42,10 +44,23 @@ function _M:init(title, store_inven, actor_inven, store_filter, actor_filter, ac
}
end
function _M:updateStore()
self:generateList()
self.list = #self.store_list > 0 and self.store_list or self.actor_list
self.sel = util.bound(self.sel, 1, #self.list)
self.scroll = util.scroll(self.sel, self.scroll, self.max)
self.changed = true
end
function _M:use()
game:unregisterDialog(self)
if self.list[self.sel] then
self.action(self.list[self.sel].object, self.list[self.sel].item)
if self.list == self.store_list then
self.action("buy", self.list[self.sel].object, self.list[self.sel].item)
self:updateStore()
else
self.action("sell", self.list[self.sel].object, self.list[self.sel].item)
self:updateStore()
end
end
end
......@@ -74,33 +89,20 @@ function _M:generateList()
end
function _M:drawDialog(s)
-- Description part
self:drawHBorder(s, self.iw / 2, 2, self.ih - 4)
local help = [[Keyboard: #00FF00#up key/down key#FFFFFF# to select an object; #00FF00#enter#FFFFFF# to use.
Mouse: #00FF00#Left click#FFFFFF# to use.
]]
local talentshelp = help: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 = 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
-- h = h + self.font:lineSkip()
-- if self.store_list[self.store_sel] then
-- lines = self.store_list[self.store_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
self:drawWBorder(s, 3, self.ih * 0.80, 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.sel, "name", self.scroll, self.max)
self:drawSelectionList(s, self.iw / 2 + 5, 5, self.font_h, self.actor_list, self.sel, "name", self.scroll, self.max)
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: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
......@@ -145,7 +145,7 @@ function _M:setupDisplayMode()
end
function _M:save()
return class.save(self, self:defaultSavedFields{}, true)
return class.save(self, self:defaultSavedFields{stores_def=true}, true)
end
function _M:getSaveDescription()
......
......@@ -228,3 +228,8 @@ end
function _M:getSubtypeOrder()
return self.subtype or ""
end
--- Get item cost
function _M:getPrice()
return self.cost
end
require "engine.class"
local Entity = require "engine.Entity"
local Inventory = require "engine.interface.ActorInventory"
local Store = require "engine.Store"
local Dialog = require "engine.Dialog"
module(..., package.seeall, class.inherit(Entity, Inventory))
module(..., package.seeall, class.inherit(Store))
_M.stores_def = {}
function _M:init(t, no_default)
t = t or {}
t.body = {INVEN=10000}
Entity.init(self, t, no_default)
Inventory.init(self, t, no_default)
Store.init(self, t, no_default)
end
--- Fill the store with goods
function _M:loadup(level, zone)
local s = self.store
if not s then error("Store without a store field") end
if self.last_filled and game.turn and self.last_filled >= game.turn - s.restock_after then
print("[STORE] not restocking yet", game.turn, s.restock_after, self.last_filled)
return
--- Called on object purchase
-- @param who the actor buying
-- @param o the object trying to be purchased
-- @param item the index in the inventory
-- @param nb number of items (if stacked) to buy
-- @return true if allowed to buy
function _M:onBuy(who, o, item, nb)
local price = o:getPrice()
if who.money >= price * nb then
who.money = who.money - price * nb
return nb
else
Dialog:simplePopup("Not enough gold", "You do not have enough gold!")
end
local inven = self:getInven("INVEN")
end
for i = 1, rng.range(s.min_fill, s.max_fill) - #inven do
local filter = rng.table(s.filters)
local e = zone:makeEntity(level, "object", filter)
if e then
if filter.id then e:identify(filter.id) end
self:addObject(inven, e)
print("[STORE] stocking up: ", e.name)
end
end
self:sortInven(inven)
self.last_filled = game.turn
--- Called on object sale
-- @param who the actor selling
-- @param o the object trying to be sold
-- @param item the index in the inventory
-- @param nb number of items (if stacked) to sell
-- @return true if allowed to sell
function _M:onSell(who, o, item, nb)
local price = o:getPrice() / 10
if price <= 0 then return end
who.money = who.money + price * nb
return nb
end
function _M:interact(who)
local D = require "engine.dialogs.ShowStore"
local d = D.new("Store: "..self.name, self:getInven("INVEN"), who:getInven("INVEN"), nil, nil, function() end)
game:registerDialog(d)
--- Called to describe an object, being to sell or to buy
-- @param who the actor
-- @param what either "sell" or "buy"
-- @param o the object
-- @return a string (possibly multiline) describing the object
function _M:descObject(who, what, o)
local desc = ([[Price: %0.2f gold (You have %0.2f gold)
]]):format(o:getPrice(), who.money)
desc = desc .. o:getDesc()
return desc
end
......@@ -11,6 +11,14 @@ quickEntity('.', {name='road', display='.', color=colors.WHITE})
quickEntity(',', {name='dirt', display='.', color=colors.LIGHT_UMBER})
quickEntity('-', {name='grass', display='.', color=colors.LIGHT_GREEN})
quickEntity('1', {name="General Store", display='1', color={r=0, g=255, b=255},
on_move = function(self, x, y, who)
self.store:loadup(game.level, game.zone)
self.store:interact(who)
end,
store = game.stores_def[1]:clone(),
})
startx = 131
starty = 33
......
......@@ -23,13 +23,7 @@ quickEntity('D', {name="A path into the Old Forest", display='>', color={r=0,
quickEntity('E', {name="A mysterious hole in the beach", display='>', color={r=200, g=255, b=55}, change_level=1, change_zone="sandworm-lair"})
quickEntity('F', {name="The entry to the old tower of Tol Falas",display='>', color={r=0, g=255, b=255}, change_level=1, change_zone="tol-falas"})
quickEntity('1', {name="General Store", display='1', color={r=0, g=255, b=255},
on_move = function(self, x, y, who)
self.store:loadup(game.level, game.zone)
self.store:interact(who)
end,
store = game.stores_def[1]:clone(),
})
quickEntity('1', {name="Bree (Town)", display='*', color={r=255, g=255, b=255}, change_level=1, change_zone="town-bree"})
return {
[[========q=qqqqqqqqqgggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg]],
......
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