forked from VoxeLibre/VoxeLibre
Correct crashes/item duplication with dropping carts, start API documentation
This commit is contained in:
parent
5c351ae258
commit
49ef40aa3c
|
@ -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)
|
||||
|
||||
end
|
||||
function DEFAULT_CART_DEF:on_death(killer)
|
||||
local staticdata = self._staticdata
|
||||
local function kill_cart(staticdata)
|
||||
local pos
|
||||
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
|
||||
if staticdata.attached_at then
|
||||
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")
|
||||
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
|
||||
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
|
||||
|
||||
-- Place a minecart at pointed_thing
|
||||
|
@ -558,8 +569,14 @@ minetest.register_globalstep(function(dtime)
|
|||
local r = 0.6
|
||||
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
|
||||
self:on_death()
|
||||
self.object:remove()
|
||||
kill_cart(staticdata)
|
||||
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
|
||||
end
|
||||
end
|
||||
|
|
|
@ -62,11 +62,11 @@ local function handle_cart_enter_exit(staticdata, pos, next_dir, event)
|
|||
-- node-specific hook
|
||||
local hook_name = "_mcl_minecarts_"..event..check[4]
|
||||
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
|
||||
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
|
||||
|
||||
|
|
Loading…
Reference in New Issue