Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Minetest: builtin/item.lua (override falling entity with new features)
- local builtin_shared = ...
- -- override falling nodes to add damage
- local function add_fall_damage(node, damage)
- if core.registered_nodes[node] then
- local group = core.registered_nodes[node].groups
- group.falling_node_damage = damage
- core.override_item(node, {groups = group})
- else
- print (node .. " not found to add fall_damage to")
- end
- end
- add_fall_damage("default:sand", 2)
- add_fall_damage("default:desert_sand", 2)
- add_fall_damage("default:silver_sand", 2)
- add_fall_damage("caverealms:coal_dust", 3)
- add_fall_damage("tnt:tnt_burning", 4)
- --
- -- Falling stuff
- --
- local node_fall_hurt = minetest.setting_getbool("node_fall_hurt") ~= false
- local delay = 0.25
- local function fall_hurt_check(self, pos, dtime)
- if not node_fall_hurt then return end
- if self.hurt_timer > 0 then
- self.hurt_timer = self.hurt_timer - (dtime * delay)
- else
- -- Get damage level from falling_node_damage group
- local damage = core.registered_nodes[self.node.name] and
- core.registered_nodes[self.node.name].groups.falling_node_damage
- if damage then
- local all_objects = minetest.get_objects_inside_radius(pos, 0.7)
- for _,obj in ipairs(all_objects) do
- local name = obj:get_luaentity() and
- obj:get_luaentity().name or ""
- if name ~= "__builtin:item"
- and name ~= "__builtin:falling_node" then
- obj:punch(obj, 4.0, {
- full_punch_interval = 4.0,
- damage_groups = {fleshy = damage}})
- self.hurt_timer = 0.2
- end
- end
- end
- end
- end
- core.register_entity(":__builtin:falling_node", {
- initial_properties = {
- visual = "wielditem",
- visual_size = {x = 0.667, y = 0.667},
- textures = {},
- physical = true,
- is_visible = false,
- collide_with_objects = false,
- collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
- },
- node = {},
- meta = {},
- set_node = function(self, node, meta)
- self.node = node
- self.meta = meta or {}
- self.hurt_timer = 0
- self.object:set_properties({
- is_visible = true,
- textures = {node.name},
- })
- end,
- get_staticdata = function(self)
- local ds = {node = self.node, meta = self.meta}
- return core.serialize(ds)
- end,
- on_activate = function(self, staticdata)
- self.object:set_armor_groups({immortal = 1})
- local ds = core.deserialize(staticdata)
- if ds and ds.node then
- self:set_node(ds.node, ds.meta)
- elseif ds then
- self:set_node(ds)
- elseif staticdata ~= "" then
- self:set_node({name = staticdata})
- end
- end,
- on_step = function(self, dtime)
- self.timer = (self.timer or 0) + dtime
- if self.timer < delay then
- return
- end
- self.timer = 0
- -- Set gravity
- local acceleration = self.object:getacceleration()
- if not vector.equals(acceleration, {x = 0, y = -10, z = 0}) then
- self.object:setacceleration({x = 0, y = -10, z = 0})
- end
- -- Turn to actual node when colliding with ground, or continue to move
- local pos = self.object:get_pos()
- -- Position of bottom center point
- local below_pos = {x = pos.x, y = pos.y - 0.7, z = pos.z}
- -- Check for player/mobs below falling node and hurt them >:D
- fall_hurt_check(self, below_pos, dtime)
- -- Avoid bugs caused by an unloaded node below
- local below_node = core.get_node_or_nil(below_pos)
- -- Delete on contact with ignore at world edges
- if below_node and below_node.name == "ignore" then
- self.object:remove()
- return
- end
- local below_nodef = below_node and
- core.registered_nodes[below_node.name]
- -- Is below node walkable, or liquid that node floats on?
- if below_node and
- (not below_nodef or below_nodef.walkable or
- (core.get_item_group(self.node.name, "float") ~= 0 and
- below_nodef.liquidtype ~= "none")) then
- -- Is it a level node we can add to?
- if below_nodef and below_nodef.leveled and
- below_node.name == self.node.name then
- local addlevel = self.node.level
- if not addlevel or addlevel <= 0 then
- addlevel = below_nodef.leveled
- end
- if core.add_node_level(below_pos, addlevel) == 0 then
- self.object:remove()
- return
- end
- -- Remove node below if buildable_to and not liquid?
- elseif below_nodef and below_nodef.buildable_to and
- (core.get_item_group(self.node.name, "float") == 0 or
- below_nodef.liquidtype == "none") then
- core.remove_node(below_pos)
- return
- end
- -- Get falling node position and see what's there
- -- local np = {x = below_pos.x, y = below_pos.y + 1, z = below_pos.z}
- local np = self.object:get_pos()
- local nod = core.get_node(np)
- local nodef = core.registered_nodes[nod.name]
- local unbreak = nodef and
- core.get_item_group(nod.name, "unbreakable") ~= 0
- -- If not air or liquid or has unbreakable group set,
- -- remove node and replace with it's drops
- if nod.name ~= "air" and not unbreak and
- (not nodef or nodef.liquidtype == "none") then
- core.remove_node(np)
- if nodef.buildable_to == false then
- -- Add dropped items
- local drops = core.get_node_drops(nod, "")
- for _, dropped_item in pairs(drops) do
- core.add_item(np, dropped_item)
- end
- end
- -- Run script hook
- for _, callback in pairs(core.registered_on_dignodes) do
- callback(np, nod)
- end
- end
- -- Create node and remove entity
- local def = core.registered_nodes[self.node.name]
- if def then
- -- If the node below has unbreakable group set
- -- then move the Y position up 1
- if unbreak then
- np.y = np.y + 1
- end
- core.add_node(np, self.node)
- if self.meta then
- local meta = core.get_meta(np)
- meta:from_table(self.meta)
- end
- if def.sounds and def.sounds.place and def.sounds.place.name then
- core.sound_play(def.sounds.place, {pos = np})
- end
- end
- self.object:remove()
- core.check_for_falling(np)
- return
- end
- local vel = self.object:getvelocity()
- if vector.equals(vel, {x = 0, y = 0, z = 0}) then
- local npos = self.object:get_pos()
- self.object:setpos(vector.round(npos))
- end
- end
- })
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement