Guns4d.registered_items = {} local old_spawn_item = core.spawn_item --didnt know if I had to use core instead of minetest or if they are the same reference, not chancing it though. core.spawn_item = function(pos, item, ...) if item then --if it doesnt exist, let it handle itself... local stack = ItemStack(item) local name = stack:get_name() local def = Guns4d.registered_items[name] if def then local obj = minetest.add_entity(pos, "guns4d:item") if obj then obj:get_luaentity():set_item(stack:to_string()) end return obj end end return old_spawn_item(pos, item, ...) end local defaults = { --light_source = 0, visual_size = 1, realistic = Guns4d.config.realistic_items, backface_culling = false, --animation = {x=0,y=0, speed=15, loop=true, blend=nil}, selectionbox = {-.2,-.2,-.2, .2,.2,.2}, collisionbox = (Guns4d.config.realistic_items and {-.2,-.05,-.2, .2,.15,.2}) or {-.2,-.2,-.2, .2,.2,.2} } function Guns4d.register_item(itemstring, def) assert(minetest.registered_items[itemstring], "item: `"..tostring(itemstring).."` not registered by minetest") assert(type(def)=="table", "definition is not a table") def = Guns4d.table.fill(defaults, def) Guns4d.registered_items[itemstring] = def end local def = table.copy(minetest.registered_entities["__builtin:item"]) def.visual = "mesh" def.visual_size = {x=1,y=1,z=1} def.set_item = function(self, item) local stack = ItemStack(item or self.itemstring) self.itemstring = stack:to_string() if self.itemstring == "" then return end --[[local a = item_def.collisionbox_size local o = item_def.collisionbox_offset local b = item_def.selectionbox if item_def.realistic == true then cbox = {(-a-o.x)/20, 0-(o.y/20), (-a-o.z)/20, (a-o.x)/20, (a-o.y)/10, (a-o.z)/20} --we want the collision_box to sit above it. sbox = {(-b.x-o.x)/20, (-b.y/20), (-b.z-o.z)/20, (b.x-o.x)/20, (b.y/20), (b.z-o.z)/20, rotate=true} else cbox = {(-a-o.x)/20, (-a-o.y)/20, (-a-o.z)/20, (a-o.x)/20, (a-o.y)/20, (a-o.z)/20} sbox = {(-b.x-o.x)/20, (-b.y-o.y)/20, (-b.z-o.z)/20, (b.x-o.x)/20, (b.y-o.y)/20, (b.z-o.z)/20} end]] local item_def = Guns4d.registered_items[stack:get_name()] local cbox = item_def.collisionbox local sbox = item_def.selectionbox self.object:set_properties({ is_visible = true, visual = "mesh", mesh = item_def.mesh, textures = item_def.textures, collisionbox = cbox, selectionbox = {sbox[1], sbox[2], sbox[3], sbox[4], sbox[5], sbox[6], rotate=true}, glow = item_def and item_def.light_source and math.floor(def.light_source/2+0.5), backface_culling = item_def.backface_culling, visual_size = {x=item_def.visual_size,y=item_def.visual_size,z=item_def.visual_size}, automatic_rotate = ((not item_def.realistic) and math.pi * 0.5 * 0.2 / 5) or nil, infotext = stack:get_description(), }) --self._collisionbox = cbox end local old = def.on_step def._respawn = function(self) minetest.add_item(self.object:get_pos(), self.itemstring) end def.on_step = function(self, dt, mr, ...) old(self, dt, mr, ...) --icky nesting. local item_def if not self._guns4d_animation_set then item_def = Guns4d.registered_items[ItemStack(self.itemstring):get_name()] if item_def then local anim = item_def.animation if anim then self.object:set_animation({x=anim.x, y=anim.y}, anim.speed, anim.blend, anim.loop) end else self:_respawn() end end if mr and mr.touching_ground then item_def = item_def or Guns4d.registered_items[ItemStack(self.itemstring):get_name()] if item_def and not self._4dguns_rotated then if item_def.realistic then self.object:set_properties({ automatic_rotate = nil }) local rot = self.object:get_rotation() self.object:set_rotation({y=rot.y, x=rot.x, z=math.pi*.5}) self._4dguns_rotated = true else self.object:set_properties({ automatic_rotate = math.pi * 0.5 * 0.2, }) local rot = self.object:get_rotation() self.object:set_rotation({y=rot.y, x=0, z=0}) self._4dguns_rotated = true end end if not item_def then self:_respawn() end else if self._4dguns_rotated then self.object:set_properties({ automatic_rotate = 0, }) self._4dguns_rotated = false end end end minetest.register_entity("guns4d:item", def)