Compare commits

27 Commits

Author SHA1 Message Date
c4a8ed4cd3 depends.txt -> mod.conf 2021-10-10 13:05:47 +02:00
0f81edd278 Remove unused code and file, and add a .luacheckrc 2020-10-11 13:29:29 +02:00
4f85670e78 Simplify the flow code and allow diagonal directions 2020-10-10 18:07:58 +02:00
66c222e93b Fix liquid flowing down ledges 2020-10-10 17:46:06 +02:00
5636a2bb94 Remove item burn code
Something like this is in the default mod now.
2020-10-10 16:39:33 +02:00
89f02386bc Simplify the code and change behaviour a bit
Example: accelerate instead of setting velocities
2020-10-08 20:29:39 +02:00
14f985a62b General code cleanup 2020-10-08 19:35:12 +02:00
ff43812fcf Change the license 2020-10-08 18:41:18 +02:00
c475185ea4 Replace some deprecated function calls 2020-08-01 21:12:28 +02:00
e6dfd9dce8 Support Minetest 5.3.0-dev
The on_step now has a moveresult parameter
2020-05-09 17:42:51 +02:00
aa1b3a7142 Remove old README 2019-11-08 08:47:51 +01:00
1c7473dc54 Use new underscore in set_acceleration and set_velocity 2018-10-03 17:37:29 +02:00
143ab1f8dd Use new settings interface 2017-06-11 09:18:46 +02:00
2cea32d4d7 2017-06-11 08:59:50 +02:00
19c8b65f67 🐈
M  init.lua
2017-03-07 10:41:37 +01:00
bb90a38c2e 🐈 2016-05-26 12:17:00 +02:00
bd97071dc6 🐈 2016-02-21 12:31:33 +01:00
72f75d0417 🐈 2016-02-18 18:45:59 +01:00
08935daaf4 🐈 2015-06-05 11:30:34 +02:00
f43e39bbdf add smoke 2015-04-09 22:31:21 +02:00
3ba5c899cb Update init.lua
I've added the particle effect when items drop in lava. Tell me what you think.
2015-04-09 22:17:31 +02:00
c41e61e346 always search nodes if lots of objects are pushed by water 2014-08-31 14:59:40 +02:00
f6629da1ba use get_node more selden 2014-08-31 14:49:25 +02:00
06cfcc90fe use get_node more selden 2014-08-31 14:44:42 +02:00
13aecb026d add gitignore 2014-08-31 14:13:12 +02:00
50176917f9 · 2014-08-31 14:12:47 +02:00
64e2561c60 dont override the whole item 2014-08-31 14:12:32 +02:00
8 changed files with 142 additions and 248 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
## Generic ignorable patterns and files
*~
.*.swp
debug.txt

12
.luacheckrc Normal file
View File

@ -0,0 +1,12 @@
read_globals = {
minetest = {
fields = {
registered_entities = {
read_only = false,
other_fields = true
}
},
other_fields = true
},
"vector"
}

2
LICENSE.txt Normal file
View File

@ -0,0 +1,2 @@
MIT for the code
The original mod was licensed under WTFPL.

2
README.md Normal file
View File

@ -0,0 +1,2 @@
For a description of this Minetest mod, see
https://forum.minetest.net/viewtopic.php?f=9&t=10271.

View File

@ -1,38 +0,0 @@
=== BUILTIN_ITEM MOD for MINETEST-C55 ===
by PilzAdam
Features:
This mod adds some new features to the builtin items:
- The items are pushed by flowing water
- The items are destroyed by lava
- The items are removed after 300 seconds or the time that is specified by
remove_items in minetest.conf (0 disables it)
How to install:
Unzip the archive an place it in minetest-base-directory/mods/minetest/
if you have a windows client or a linux run-in-place client. If you have
a linux system-wide instalation place it in ~/.minetest/mods/minetest/.
If you want to install this mod only in one world create the folder
worldmods/ in your worlddirectory.
For further information or help see:
http://wiki.minetest.com/wiki/Installing_Mods
License:
WTFPL (see below)
See also:
http://minetest.net/
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.

331
init.lua Executable file → Normal file
View File

@ -1,216 +1,127 @@
local time = tonumber(minetest.setting_get("remove_items"))
if not time then
time = 1800 -- set to 30 minutes the time before remove a dropped item
end
-- Use the movement gravity for the downwards acceleration.
-- The setting may change in-game but for simplicity we don't support this.
local movement_gravity = tonumber(minetest.settings:get("movement_gravity"))
or 9.81
unwalkable_nodes = {}
minetest.after(0, function()
for itemname, node in pairs(minetest.registered_nodes) do
if node.walkable == false then
table.insert(unwalkable_nodes, 1, itemname)
end
end
end)
local get_flowing_dir = function(self)
local pos = self.object:getpos()
-- get_flow_raw determines the horizontal flow vector for a flowing liquid node,
-- or returns nothing if the flow is zero
local neighbour_offsets = {
{x=-1, y=0, z=0},
{x=1, y=0, z=0},
{x=0, y=0, z=-1},
{x=0, y=0, z=1}
}
local function get_flow_raw(pos)
-- FIXME: Do we need to treat nodes with special liquid_range differently?
local param2 = minetest.get_node(pos).param2
for i,d in ipairs({-1, 1, -1, 1}) do
if i<3 then
pos.x = pos.x+d
else
pos.z = pos.z+d
end
local name = minetest.get_node(pos).name
local par2 = minetest.get_node(pos).param2
if name == "default:water_flowing" and par2 < param2 then
return pos
end
if i<3 then
pos.x = pos.x-d
else
pos.z = pos.z-d
end
if param2 == 15 then
-- The liquid has full height and flows downwards
return
end
return nil
local flow = {x = 0, y = 0, z = 0}
local height = param2 % 8
for n = 1, 4 do
local node = minetest.get_node(vector.add(pos, neighbour_offsets[n]))
local def = minetest.registered_nodes[node.name]
local height_other
if not def or def.walkable then
-- A solid node, so no flow happens
height_other = height
elseif def.liquidtype == "source" then
-- Assume that relevant liquid comes from this source
height_other = 8
elseif def.liquidtype == "flowing" then
-- This neighbour is also a flowing liquid
height_other = node.param2 % 8
else
-- There is a free space, e.g. air or a plant
height_other = 0
end
local fl = vector.multiply(neighbour_offsets[n], height - height_other)
flow = vector.add(flow, fl)
end
if vector.equals(flow, {x = 0, y = 0, z = 0}) then
return
end
return vector.normalize(flow)
end
minetest.register_entity(":__builtin:item", {
initial_properties = {
hp_max = 1,
physical = true,
collisionbox = {-0.175, -0.175, -0.175, 0.175, 0.175, 0.175},
collide_with_objects = false,
visual = "sprite",
visual_size = {x=0.5, y=0.5},
textures = {""},
spritediv = {x=1, y=1},
initial_sprite_basepos = {x=0, y=0},
is_visible = false,
timer = 0,
},
itemstring = "",
physical_state = true,
set_item = function(self, itemstring)
self.itemstring = itemstring
local stack = ItemStack(itemstring)
local itemtable = stack:to_table()
local itemname = nil
if itemtable then
itemname = stack:to_table().name
end
local item_texture = nil
local item_type = ""
if minetest.registered_items[itemname] then
item_texture = minetest.registered_items[itemname].inventory_image
item_type = minetest.registered_items[itemname].type
end
local prop = {
is_visible = true,
visual = "wielditem",
textures = {(itemname or "unknown_item.png")},
visual_size = {x=0.175, y=0.175},
automatic_rotate = math.pi * 0.5,
}
self.object:set_properties(prop)
end,
get_staticdata = function(self)
--return self.itemstring
return minetest.serialize({
itemstring = self.itemstring,
always_collect = self.always_collect,
timer = self.timer,
})
end,
on_activate = function(self, staticdata, dtime_s)
if string.sub(staticdata, 1, string.len("return")) == "return" then
local data = minetest.deserialize(staticdata)
if data and type(data) == "table" then
self.itemstring = data.itemstring
self.always_collect = data.always_collect
self.timer = data.timer
if not self.timer then
self.timer = 0
end
self.timer = self.timer+dtime_s
end
else
self.itemstring = staticdata
end
self.object:set_armor_groups({immortal=1})
self.object:setvelocity({x=0, y=2, z=0})
self.object:setacceleration({x=0, y=-10, z=0})
self:set_item(self.itemstring)
end,
on_step = function(self, dtime)
if not self.timer then
self.timer = 0
end
self.timer = self.timer + dtime
if self.itemstring == "" or (time ~= 0 and (self.timer > time)) then
self.object:remove()
return
end
local p = self.object:getpos()
local name = minetest.get_node(p).name
if not minetest.registered_nodes[name] then return end
if minetest.registered_nodes[name].damage_per_second > 0 or name == "maptools:igniter" then
minetest.sound_play("builtin_item_lava", {pos = p, gain = 0.5})
self.object:remove()
return
end
--[[ if name == "default:water_source" then
self.object:setacceleration({x = 0, y = 4, z = 0})
else
self.object:setacceleration({x = 0, y = -10, z = 0})
end
--]]
if minetest.registered_nodes[name].liquidtype == "flowing" then
local vec = get_flowing_dir(self)
if vec then
local v = self.object:getvelocity()
if v and vec.x-p.x > 0 then
self.object:setacceleration({x = 0, y = 0, z = 0})
self.object:setvelocity({x = 1, y = -0.22, z = 0})
elseif v and vec.x-p.x < 0 then
self.object:setacceleration({x = 0, y = 0, z = 0})
self.object:setvelocity({x = -1, y = -0.22, z = 0})
elseif v and vec.z-p.z > 0 then
self.object:setacceleration({x = 0, y = 0, z = 0})
self.object:setvelocity({x = 0, y = -0.22, z = 1})
elseif v and vec.z-p.z < 0 then
self.object:setacceleration({x = 0, y = 0, z = 0})
self.object:setvelocity({x = 0, y = -0.22, z = -1})
end
self.object:setacceleration({x = 0, y = -10, z = 0})
self.physical_state = true
self.object:set_properties({
physical = true
})
return
end
end
p.y = p.y - 0.3
local nn = minetest.get_node(p).name
-- If node is not registered or node is walkably solid.
if not minetest.registered_nodes[nn] or minetest.registered_nodes[nn].walkable then
if self.physical_state then
self.object:setvelocity({x=0,y=0,z=0})
self.object:setacceleration({x=0, y=0, z=0})
self.physical_state = false
self.object:set_properties({
physical = false
})
end
else
if not self.physical_state then
self.object:setvelocity({x=0,y=0,z=0})
self.object:setacceleration({x=0, y=-10, z=0})
self.physical_state = true
self.object:set_properties({
physical = true
})
end
end
-- Eject if not walkable
local upnode = minetest.get_node({x = p.x, y = math.ceil(p.y), z = p.z}).name
if minetest.registered_nodes[upnode] and minetest.registered_nodes[upnode].walkable then
local minp, maxp = {x=p.x-1, y=math.ceil(p.y), z=p.z-1}, {x=p.x+1, y=math.ceil(p.y)+1, z=p.z+1}
local nodes = minetest.find_nodes_in_area(minp, maxp, unwalkable_nodes)
if table.getn(nodes) > 0 then
self.object:setpos(nodes[math.random(1,#nodes)])
end
end
end,
--[[ This causes a duplication glitch if a player walks upon an item and clicks on it at the same time.
on_punch = function(self, hitter)
if self.itemstring ~= "" then
local left = hitter:get_inventory():add_item("main", self.itemstring)
if not left:is_empty() then
self.itemstring = left:to_string()
return
end
end
self.object:remove()
end,
--]]
})
if minetest.setting_get("log_mods") then
minetest.log("action", "[builtin_item] loaded.")
-- get_flow caches the results from get_flow_raw for 10 s
local flow_cache = {}
setmetatable(flow_cache, {__mode = "kv"})
local function get_flow(pos)
local vi = minetest.hash_node_position(pos)
local t = minetest.get_us_time()
if flow_cache[vi]
and t - flow_cache[vi][1] < 10 * 1000000 then
return flow_cache[vi][2]
end
local flow = get_flow_raw(pos)
flow_cache[vi] = {t, flow}
return flow
end
local item_entity = minetest.registered_entities["__builtin:item"]
local old_on_step = item_entity.on_step
item_entity.makes_footstep_sound = true
-- The "bt_" prefix shows that the value comes from builtin_item
item_entity.bt_timer = 0
item_entity.on_step = function(self, dtime, ...)
-- Remember the velocity before an original on_step can change it
local vel_desired
if self.bt_reset_velocity then
vel_desired = self.object:get_velocity()
end
old_on_step(self, dtime, ...)
-- Ignore the item if it should not interact with physics
if not self.physical_state then
return
end
-- Reset the velocity if needed
if vel_desired
and not vector.equals(self.object:get_velocity(), vel_desired) then
self.object:set_velocity(vel_desired)
end
-- For performance reasons, skip the remaining code in frequent steps
self.bt_timer = self.bt_timer + dtime
if self.bt_timer < 0.1 then
return
end
self.bt_timer = 0
local p = self.object:get_pos()
local pos = vector.round(p)
local nodename = minetest.get_node(pos).name
if self.bt_reset_velocity then
-- Set the item acceleration to its default (changed again below)
self.object:set_acceleration({x=0, y=-movement_gravity, z=0})
self.bt_reset_velocity = nil
end
local def = minetest.registered_nodes[nodename]
if not def or not def.liquidtype or def.liquidtype ~= "flowing" then
return
end
local flow = get_flow(pos)
if not flow then
return
end
local vel_current = vel_desired or self.object:get_velocity()
local acc
if vector.dot(vel_current, flow) < 1.0 then
acc = vector.multiply(flow, 2.0)
else
-- The item is already accelerated by the fluids
acc = {x = 0, y = 0, z = 0}
end
acc.y = -movement_gravity
self.object:set_acceleration(acc)
self.bt_reset_velocity = true
end
minetest.register_entity(":__builtin:item", item_entity)

1
mod.conf Normal file
View File

@ -0,0 +1 @@
name = builtin_item

Binary file not shown.