mirror of
https://git.minetest.land/VoxeLibre/VoxeLibre.git
synced 2024-11-28 05:21:05 +01:00
Correct crashes/item duplication with dropping carts, start API documentation
This commit is contained in:
parent
5c351ae258
commit
49ef40aa3c
3 changed files with 89 additions and 28 deletions
44
mods/ENTITIES/mcl_minecarts/API.md
Normal file
44
mods/ENTITIES/mcl_minecarts/API.md
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
== Cart-Node interactions
|
||||||
|
|
||||||
|
As the cart moves thru the environment, it can interact with the surrounding blocks
|
||||||
|
thru a number of handlers in the block definitions. All these handlers are defined
|
||||||
|
as:
|
||||||
|
|
||||||
|
`function(node_position, cart_luaentity, cart_direction, cart_position)`
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
`node_position` - position of the node the cart is interacting with
|
||||||
|
`cart_luaentity` - The luaentity of the cart that is entering this block. Will
|
||||||
|
be nil for minecarts moving thru unloaded blocks
|
||||||
|
`cart_direction` - The direction the cart is moving
|
||||||
|
`cart_position` - The location of the cart
|
||||||
|
`cart_data` - Information about the cart. This will always be defined.
|
||||||
|
|
||||||
|
There are several variants of this handler:
|
||||||
|
`_mcl_minecarts_on_enter` - The cart enters this block
|
||||||
|
`_mcl_minecarts_on_enter_below` - The cart enters above this block
|
||||||
|
`_mcl_minecarts_on_enter_above` - The cart enters below this block
|
||||||
|
`_mcl_minecarts_on_enter_side` - The cart enters beside this block
|
||||||
|
|
||||||
|
Mods can also define global handlers that are called for every node. These
|
||||||
|
handlers are defined as:
|
||||||
|
|
||||||
|
`function(node_position, cart_luaentity, cart_direction, node_definition, cart_data)`
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
`node_position` - position of the node the cart is interacting with
|
||||||
|
`cart_luaentity` - The luaentity of the cart that is entering this block. Will
|
||||||
|
be nil for minecarts moving thru unloaded blocks
|
||||||
|
`cart_direction` - The direction the cart is moving
|
||||||
|
`cart_position` - The location of the cart
|
||||||
|
`cart_data` - Information about the cart. This will always be defined.
|
||||||
|
`node_definition` - The definition of the node at `node_position`
|
||||||
|
|
||||||
|
The available hooks are:
|
||||||
|
`_mcl_minecarts.on_enter` - The cart enters this block
|
||||||
|
`_mcl_minecarts.on_enter_below` - The cart enters above this block
|
||||||
|
`_mcl_minecarts.on_enter_above` - The cart enters below this block
|
||||||
|
`_mcl_minecarts.on_enter_side` - The cart enters beside this block
|
||||||
|
|
||||||
|
Only a single function can be installed in each of these handlers. Before installing,
|
||||||
|
preserve the existing handler and call it from inside your handler if not `nil`.
|
|
@ -249,18 +249,10 @@ function DEFAULT_CART_DEF:on_step(dtime)
|
||||||
mod.update_cart_orientation(self)
|
mod.update_cart_orientation(self)
|
||||||
|
|
||||||
end
|
end
|
||||||
function DEFAULT_CART_DEF:on_death(killer)
|
local function kill_cart(staticdata)
|
||||||
local staticdata = self._staticdata
|
local pos
|
||||||
minetest.log("action", "cart #"..staticdata.uuid.." was killed")
|
minetest.log("action", "cart #"..staticdata.uuid.." was killed")
|
||||||
|
|
||||||
detach_driver(self)
|
|
||||||
|
|
||||||
-- Detach passenger
|
|
||||||
if self._passenger then
|
|
||||||
local mob = self._passenger.object
|
|
||||||
mob:set_detach()
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Leave nodes
|
-- Leave nodes
|
||||||
if staticdata.attached_at then
|
if staticdata.attached_at then
|
||||||
handle_cart_leave(self, staticdata.attached_at, staticdata.dir )
|
handle_cart_leave(self, staticdata.attached_at, staticdata.dir )
|
||||||
|
@ -268,23 +260,42 @@ function DEFAULT_CART_DEF:on_death(killer)
|
||||||
mcl_log("TODO: handle detatched minecart death")
|
mcl_log("TODO: handle detatched minecart death")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Handle entity-related items
|
||||||
|
local le = mcl_util.get_luaentity_from_uuid(staticdata.uuid)
|
||||||
|
if le then
|
||||||
|
pos = le.object:get_pos()
|
||||||
|
|
||||||
|
detach_driver(le)
|
||||||
|
|
||||||
|
-- Detach passenger
|
||||||
|
if le._passenger then
|
||||||
|
local mob = le._passenger.object
|
||||||
|
mob:set_detach()
|
||||||
|
end
|
||||||
|
else
|
||||||
|
pos = mod.get_cart_position(staticdata)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Drop items
|
||||||
|
if not staticdata.dropped then
|
||||||
|
local entity_def = minetest.registered_entities[staticdata.cart_type]
|
||||||
|
if entity_def then
|
||||||
|
local drop = entity_def.drop
|
||||||
|
for d=1, #drop do
|
||||||
|
minetest.add_item(pos, drop[d])
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Prevent item duplication
|
||||||
|
staticdata.dropped = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Remove data
|
-- Remove data
|
||||||
destroy_cart_data(staticdata.uuid)
|
destroy_cart_data(staticdata.uuid)
|
||||||
|
|
||||||
-- Drop items
|
|
||||||
local drop = self.drop
|
|
||||||
if not killer or not minetest.is_creative_enabled(killer:get_player_name()) then
|
|
||||||
for d=1, #drop do
|
|
||||||
minetest.add_item(self.object:get_pos(), drop[d])
|
|
||||||
end
|
|
||||||
elseif killer and killer:is_player() then
|
|
||||||
local inv = killer:get_inventory()
|
|
||||||
for d=1, #drop do
|
|
||||||
if not inv:contains_item("main", drop[d]) then
|
|
||||||
inv:add_item("main", drop[d])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
function DEFAULT_CART_DEF:on_death(killer)
|
||||||
|
kill_cart(self._staticdata)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Place a minecart at pointed_thing
|
-- Place a minecart at pointed_thing
|
||||||
|
@ -558,8 +569,14 @@ minetest.register_globalstep(function(dtime)
|
||||||
local r = 0.6
|
local r = 0.6
|
||||||
for _, node_pos in pairs({{r, 0}, {0, r}, {-r, 0}, {0, -r}}) do
|
for _, node_pos in pairs({{r, 0}, {0, r}, {-r, 0}, {0, -r}}) do
|
||||||
if minetest.get_node(vector.offset(pos, node_pos[1], 0, node_pos[2])).name == "mcl_core:cactus" then
|
if minetest.get_node(vector.offset(pos, node_pos[1], 0, node_pos[2])).name == "mcl_core:cactus" then
|
||||||
self:on_death()
|
kill_cart(staticdata)
|
||||||
self.object:remove()
|
local le = mcl_util.get_luaentity_from_uuid(staticdata.uuid)
|
||||||
|
if le then
|
||||||
|
le:on_death()
|
||||||
|
le.object:remove()
|
||||||
|
else
|
||||||
|
kill_cart(staticdata)
|
||||||
|
end
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -62,11 +62,11 @@ local function handle_cart_enter_exit(staticdata, pos, next_dir, event)
|
||||||
-- node-specific hook
|
-- node-specific hook
|
||||||
local hook_name = "_mcl_minecarts_"..event..check[4]
|
local hook_name = "_mcl_minecarts_"..event..check[4]
|
||||||
local hook = node_def[hook_name]
|
local hook = node_def[hook_name]
|
||||||
if hook then hook(check_pos, luaentity, next_dir, pos) end
|
if hook then hook(check_pos, luaentity, next_dir, pos, staticdata) end
|
||||||
|
|
||||||
-- global minecart hook
|
-- global minecart hook
|
||||||
hook = mcl_minecarts[event..check[4]]
|
hook = mcl_minecarts[event..check[4]]
|
||||||
if hook then hook(check_pos, luaentity, next_dir, node_def) end
|
if hook then hook(check_pos, luaentity, next_dir, pos, staticdata, node_def) end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue