Skip to content

Commit

Permalink
Mobs: Traders: Return forgotten money to player or drop int world. Cl…
Browse files Browse the repository at this point in the history
…oses #1156
  • Loading branch information
alek13 committed Oct 3, 2023
1 parent 23f2852 commit ff70a96
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 7 deletions.
11 changes: 8 additions & 3 deletions mods/lord/Entities/lord_traders/src/traders/trader.lua
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,6 @@ local common_trader_definition = {
attack = "default_punch2", -- except elves (mobs_slash_attack)
}
}

------------------------------------------------------------------------------------------------------------------------

--- @param entity LuaEntity
--- @param clicker Player
--- @param race string
Expand Down Expand Up @@ -93,6 +90,14 @@ local function on_rightclick(entity, clicker, race)

end

------------------------------------------------------------------------------------------------------------------------

Form.on_close(function(form)
Inventory.get_by_id(form.inventory_id):return_forgotten()
end)

------------------------------------------------------------------------------------------------------------------------

--- @param name string
--- @param definition table
local function register_trader(name, definition)
Expand Down
77 changes: 74 additions & 3 deletions mods/lord/Entities/lord_traders/src/traders/trader/Form.lua
Original file line number Diff line number Diff line change
@@ -1,19 +1,33 @@
local S = minetest.get_translator("lord_traders")

--- @class traders.trader.Form.Event
local Event = {
CLOSE = "close",
}

---
--- @class traders.trader.Form
---
local Form = {
--- @const
--- @type string
NAME = "trade",
NAME = "lord_traders:trade",
--- @static
--- @private
--- @type table<string,traders.trader.Form>
opened_for = {},
--- @static
--- @type table <string,fun(form:traders.trader.Form)[]>
event_callback = {
["on_"..Event.CLOSE] = {}
},

--- @type string
player_name = nil,
player_name = nil,
--- @type string
inventory_id = nil,
--- @type string
trader_name = nil,
trader_name = nil,
}

--- Constructor
Expand All @@ -32,11 +46,40 @@ function Form:new(player, inventory_id, trader_name)
return setmetatable(self, { __index = class })
end

--- @public
--- @static
--- @param player Player
function Form.get_opened_for(player)
return Form.opened_for[player:get_player_name()]
end

--- @private
--- @param event string
function Form:trigger(event)
for _, callback in pairs(self.event_callback["on_"..event]) do
callback(self)
end
end

--- @public
--- @static
--- @param callback fun(form:traders.trader.Form)
function Form.on_close(callback)
table.insert(Form.event_callback["on_" .. Event.CLOSE], callback)
end

--- @public
function Form:open()
self.opened_for[self.player_name] = self;
minetest.show_formspec(self.player_name, self.NAME, self:get_spec())
end

--- @public
function Form:close()
self.opened_for[self.player_name] = nil
self:trigger(Event.CLOSE)
end

--- @private
--- @return string
function Form:get_spec()
Expand All @@ -62,5 +105,33 @@ function Form:get_spec()
"listring[detached:" .. self.inventory_id .. ";goods]"
end

--- @public
--- @static
--- @param player Player
--- @param form_name string
--- @param fields table
function Form.handler(player, form_name, fields)
if form_name ~= Form.NAME then
return
end

local form = Form.get_opened_for(player)
if not form then return end

if fields.quit then
form:close()
end
end

minetest.register_on_player_receive_fields(Form.handler)

--- @param player Player
minetest.register_on_leaveplayer(function(player, timed_out)
local form = Form.get_opened_for(player);
if form then
form:close()
end
end)


return Form
30 changes: 29 additions & 1 deletion mods/lord/Entities/lord_traders/src/traders/trader/Inventory.lua
Original file line number Diff line number Diff line change
Expand Up @@ -254,12 +254,21 @@ function Inventory:new(player, entity, goods_config, same_race)
end

--- @static
--- @private
--- @param inv InvRef
--- @return traders.trader.Inventory|nil
function Inventory.get_by_invRef(inv)
return inventories_by_id[inv:get_location().name]
end

--- @static
--- @public
--- @param id string
--- @return traders.trader.Inventory|nil
function Inventory.get_by_id(id)
return inventories_by_id[id]
end

--- @private
--- @param inventory_id string
--- @return InvRef
Expand All @@ -281,7 +290,7 @@ function Inventory:get_or_create_detached_inventory()
self.detached_inv_id = self.player_name.."_trader_".. self.entity_id:gsub(":", "_")
inventories_by_id[self.detached_inv_id] = self

local trader_inventory = minetest.get_inventory({ type ="detached", name = self.detached_inv_id })
local trader_inventory = minetest.get_inventory({ type = "detached", name = self.detached_inv_id })
if trader_inventory ~= nil then
return trader_inventory
end
Expand All @@ -299,4 +308,23 @@ function Inventory:get_id()
return self.detached_inv_id
end

--- Returns forgotten money into player's inventory or drops into world.
--- @public
function Inventory:return_forgotten()
local player_inventory = minetest.get_inventory({ type = "player", name = self.player_name })
local trader_inventory = minetest.get_inventory({ type = "detached", name = self.detached_inv_id })

if trader_inventory:is_empty("payment") then return end

local stack = trader_inventory:get_stack("payment", 1)
trader_inventory:set_stack("payment", 1, nil)
trader_inventory:set_stack("takeaway", 1, nil)
if player_inventory:room_for_item("main", stack) then
player_inventory:add_item("main", stack)
else
local player = minetest.get_player_by_name(self.player_name)
minetest.item_drop(stack, player, player:get_pos())
end
end

return Inventory
6 changes: 6 additions & 0 deletions util/mt-ide-helper/minetest_types.lua
Original file line number Diff line number Diff line change
Expand Up @@ -992,6 +992,8 @@ function minetest.add_item(pos, item) end
--- Get an `ObjectRef` to a player
---
--- [View in lua_api.txt](https://github.com/minetest/minetest/blob/5.4.1/doc/lua_api.txt#L4913-L4913)
--- @param name string
--- @return Player
function minetest.get_player_by_name(name) end
--- Returns a list of
--- ObjectRefs.
Expand Down Expand Up @@ -1634,6 +1636,10 @@ function minetest.item_place(itemstack, placer, pointed_thing, param2) end
--- * returns the leftover itemstack
---
--- [View in lua_api.txt](https://github.com/minetest/minetest/blob/5.4.1/doc/lua_api.txt#L5376-L5378)
--- @param itemstack ItemStack
--- @param dropper Player|ObjectRef
--- @param pos Position
--- @return ItemStack
function minetest.item_drop(itemstack, dropper, pos) end
--- * Returns `function(itemstack, user, pointed_thing)` as a
--- function wrapper for `minetest.do_item_eat`.
Expand Down

0 comments on commit ff70a96

Please sign in to comment.