diff --git a/mods/builtin_falling/init.lua b/mods/builtin_falling/init.lua new file mode 100644 index 00000000..10d32e5a --- /dev/null +++ b/mods/builtin_falling/init.lua @@ -0,0 +1,239 @@ + +-- +-- Falling stuff custom for protected area +-- + +core.register_entity(":__builtin:falling_node", { + initial_properties = { + physical = true, + collide_with_objects = false, + collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5}, + visual = "wielditem", + textures = {}, + visual_size = {x=0.667, y=0.667}, + owner = "falling", + }, + + node = {}, + + set_node = function(self, node) + self.node = node + local stack = ItemStack(node.name) + 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 core.registered_items[itemname] then + item_texture = core.registered_items[itemname].inventory_image + item_type = core.registered_items[itemname].type + end + prop = { + is_visible = true, + textures = {node.name}, + } + self.object:set_properties(prop) + end, + + set_owner = function(self, owner) + self.owner = owner + end, + + get_staticdata = function(self) + return self.node.name + end, + + on_activate = function(self, staticdata) + self.object:set_armor_groups({immortal=1}) + self:set_node({name=staticdata}) + end, + + on_step = function(self, dtime) + -- Set gravity + self.object:setacceleration({x=0, y=-10, z=0}) + -- Turn to actual sand when collides to ground or just move + local pos = self.object:getpos() + local bcp = {x=pos.x, y=pos.y-0.7, z=pos.z} -- Position of bottom center point + local bcn = core.get_node(bcp) + local bcd = core.registered_nodes[bcn.name] + -- Note: walkable is in the node definition, not in item groups + if not bcd or + (bcd.walkable or + (core.get_item_group(self.node.name, "float") ~= 0 and + bcd.liquidtype ~= "none")) then + if bcd and bcd.leveled and + bcn.name == self.node.name then + local addlevel = self.node.level + if addlevel == nil or addlevel <= 0 then + addlevel = bcd.leveled + end + if core.add_node_level(bcp, addlevel) == 0 then + self.object:remove() + return + end + elseif bcd and bcd.buildable_to and + (core.get_item_group(self.node.name, "float") == 0 or + bcd.liquidtype == "none") then + core.remove_node(bcp) + return + end + local np = {x=bcp.x, y=bcp.y+1, z=bcp.z} + -- Check what's here + local n2 = core.get_node(np) + -- If it's not air or liquid, remove node and replace it with + -- it's drops + if n2.name ~= "air" and (not core.registered_nodes[n2.name] or + core.registered_nodes[n2.name].liquidtype == "none") then + core.remove_node(np) + if core.registered_nodes[n2.name].buildable_to == false then + -- Add dropped items + local drops = core.get_node_drops(n2.name, "") + local _, dropped_item + for _, dropped_item in ipairs(drops) do + core.add_item(np, dropped_item) + end + end + -- Run script hook + local _, callback + for _, callback in ipairs(core.registered_on_dignodes) do + callback(np, n2, nil) + end + end + -- Create node and remove entity + if self.owner == nil or self.owner == "falling" then + core.add_item(np, self.node) + else + if not minetest.is_protected(pos,self.owner) then + core.add_node(np, self.node) + else + core.add_item(np, self.node) + end + end + self.object:remove() + nodeupdate(np) + return + end + local vel = self.object:getvelocity() + if vector.equals(vel, {x=0,y=0,z=0}) then + local npos = self.object:getpos() + self.object:setpos(vector.round(npos)) + end + end +}) + +function spawn_falling_node(p, node, owners) + obj = core.add_entity(p, "__builtin:falling_node") + obj:get_luaentity():set_node(node) + obj:get_luaentity():set_owner(owners) +end + +function drop_attached_node(p) + local nn = core.get_node(p).name + core.remove_node(p) + for _,item in ipairs(core.get_node_drops(nn, "")) do + local pos = { + x = p.x + math.random()/2 - 0.25, + y = p.y + math.random()/2 - 0.25, + z = p.z + math.random()/2 - 0.25, + } + core.add_item(pos, item) + end +end + +function check_attached_node(p, n) + local def = core.registered_nodes[n.name] + local d = {x=0, y=0, z=0} + if def.paramtype2 == "wallmounted" then + if n.param2 == 0 then + d.y = 1 + elseif n.param2 == 1 then + d.y = -1 + elseif n.param2 == 2 then + d.x = 1 + elseif n.param2 == 3 then + d.x = -1 + elseif n.param2 == 4 then + d.z = 1 + elseif n.param2 == 5 then + d.z = -1 + end + else + d.y = -1 + end + local p2 = {x=p.x+d.x, y=p.y+d.y, z=p.z+d.z} + local nn = core.get_node(p2).name + local def2 = core.registered_nodes[nn] + if def2 and not def2.walkable then + return false + end + return true +end + +-- +-- Some common functions +-- + +function nodeupdate_single(p, delay) + n = core.get_node(p) + if core.get_item_group(n.name, "falling_node") ~= 0 then + p_bottom = {x=p.x, y=p.y-1, z=p.z} + n_bottom = core.get_node(p_bottom) + -- Note: walkable is in the node definition, not in item groups + if core.registered_nodes[n_bottom.name] and + (core.get_item_group(n.name, "float") == 0 or + core.registered_nodes[n_bottom.name].liquidtype == "none") and + (n.name ~= n_bottom.name or (core.registered_nodes[n_bottom.name].leveled and + core.get_node_level(p_bottom) < core.get_node_max_level(p_bottom))) and + (not core.registered_nodes[n_bottom.name].walkable or + core.registered_nodes[n_bottom.name].buildable_to) then + if delay then + core.after(0.1, nodeupdate_single, {x=p.x, y=p.y, z=p.z}, false) + else + n.level = core.get_node_level(p) + local meta = minetest.env:get_meta(p) + --print('get owner '.. meta:get_string("owner")) + spawn_falling_node(p, n, meta:get_string("owner")) + core.remove_node(p) + nodeupdate(p) + end + end + end + + if core.get_item_group(n.name, "attached_node") ~= 0 then + if not check_attached_node(p, n) then + drop_attached_node(p) + nodeupdate(p) + end + end +end + +function nodeupdate(p, delay) + -- Round p to prevent falling entities to get stuck + p.x = math.floor(p.x+0.5) + p.y = math.floor(p.y+0.5) + p.z = math.floor(p.z+0.5) + + for x = -1,1 do + for y = -1,1 do + for z = -1,1 do + nodeupdate_single({x=p.x+x, y=p.y+y, z=p.z+z}, delay or not (x==0 and y==0 and z==0)) + end + end + end +end + +-- +-- Global callbacks +-- + +function on_placenode(p, node) + nodeupdate(p) +end +core.register_on_placenode(on_placenode) + +function on_dignode(p, node) + nodeupdate(p) +end +core.register_on_dignode(on_dignode) diff --git a/mods/builtin_falling/init.lua~ b/mods/builtin_falling/init.lua~ new file mode 100644 index 00000000..a2ff9419 --- /dev/null +++ b/mods/builtin_falling/init.lua~ @@ -0,0 +1,237 @@ + +-- +-- Falling stuff custom for protected area +-- + +core.register_entity(":__builtin:falling_node", { + initial_properties = { + physical = true, + collide_with_objects = false, + collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5}, + visual = "wielditem", + textures = {}, + visual_size = {x=0.667, y=0.667}, + owner = "falling", + }, + + node = {}, + + set_node = function(self, node) + self.node = node + local stack = ItemStack(node.name) + 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 core.registered_items[itemname] then + item_texture = core.registered_items[itemname].inventory_image + item_type = core.registered_items[itemname].type + end + prop = { + is_visible = true, + textures = {node.name}, + } + self.object:set_properties(prop) + end, + + set_owner = function(self, owner) + self.owner = owner + end, + + get_staticdata = function(self) + return self.node.name + end, + + on_activate = function(self, staticdata) + self.object:set_armor_groups({immortal=1}) + self:set_node({name=staticdata}) + end, + + on_step = function(self, dtime) + -- Set gravity + self.object:setacceleration({x=0, y=-10, z=0}) + -- Turn to actual sand when collides to ground or just move + local pos = self.object:getpos() + local bcp = {x=pos.x, y=pos.y-0.7, z=pos.z} -- Position of bottom center point + local bcn = core.get_node(bcp) + local bcd = core.registered_nodes[bcn.name] + -- Note: walkable is in the node definition, not in item groups + if not bcd or + (bcd.walkable or + (core.get_item_group(self.node.name, "float") ~= 0 and + bcd.liquidtype ~= "none")) then + if bcd and bcd.leveled and + bcn.name == self.node.name then + local addlevel = self.node.level + if addlevel == nil or addlevel <= 0 then + addlevel = bcd.leveled + end + if core.add_node_level(bcp, addlevel) == 0 then + self.object:remove() + return + end + elseif bcd and bcd.buildable_to and + (core.get_item_group(self.node.name, "float") == 0 or + bcd.liquidtype == "none") then + core.remove_node(bcp) + return + end + local np = {x=bcp.x, y=bcp.y+1, z=bcp.z} + -- Check what's here + local n2 = core.get_node(np) + -- If it's not air or liquid, remove node and replace it with + -- it's drops + if n2.name ~= "air" and (not core.registered_nodes[n2.name] or + core.registered_nodes[n2.name].liquidtype == "none") then + core.remove_node(np) + if core.registered_nodes[n2.name].buildable_to == false then + -- Add dropped items + local drops = core.get_node_drops(n2.name, "") + local _, dropped_item + for _, dropped_item in ipairs(drops) do + core.add_item(np, dropped_item) + end + end + -- Run script hook + local _, callback + for _, callback in ipairs(core.registered_on_dignodes) do + callback(np, n2, nil) + end + end + -- Create node and remove entity + + if not minetest.is_protected(pos,self.owner) then + core.add_node(np, self.node) + else + core.add_item(np, self.node) + end + + self.object:remove() + nodeupdate(np) + return + end + local vel = self.object:getvelocity() + if vector.equals(vel, {x=0,y=0,z=0}) then + local npos = self.object:getpos() + self.object:setpos(vector.round(npos)) + end + end +}) + +function spawn_falling_node(p, node, owners) + obj = core.add_entity(p, "__builtin:falling_node") + obj:get_luaentity():set_node(node) + obj:get_luaentity():set_owner(owners) +end + +function drop_attached_node(p) + local nn = core.get_node(p).name + core.remove_node(p) + for _,item in ipairs(core.get_node_drops(nn, "")) do + local pos = { + x = p.x + math.random()/2 - 0.25, + y = p.y + math.random()/2 - 0.25, + z = p.z + math.random()/2 - 0.25, + } + core.add_item(pos, item) + end +end + +function check_attached_node(p, n) + local def = core.registered_nodes[n.name] + local d = {x=0, y=0, z=0} + if def.paramtype2 == "wallmounted" then + if n.param2 == 0 then + d.y = 1 + elseif n.param2 == 1 then + d.y = -1 + elseif n.param2 == 2 then + d.x = 1 + elseif n.param2 == 3 then + d.x = -1 + elseif n.param2 == 4 then + d.z = 1 + elseif n.param2 == 5 then + d.z = -1 + end + else + d.y = -1 + end + local p2 = {x=p.x+d.x, y=p.y+d.y, z=p.z+d.z} + local nn = core.get_node(p2).name + local def2 = core.registered_nodes[nn] + if def2 and not def2.walkable then + return false + end + return true +end + +-- +-- Some common functions +-- + +function nodeupdate_single(p, delay) + n = core.get_node(p) + if core.get_item_group(n.name, "falling_node") ~= 0 then + p_bottom = {x=p.x, y=p.y-1, z=p.z} + n_bottom = core.get_node(p_bottom) + -- Note: walkable is in the node definition, not in item groups + if core.registered_nodes[n_bottom.name] and + (core.get_item_group(n.name, "float") == 0 or + core.registered_nodes[n_bottom.name].liquidtype == "none") and + (n.name ~= n_bottom.name or (core.registered_nodes[n_bottom.name].leveled and + core.get_node_level(p_bottom) < core.get_node_max_level(p_bottom))) and + (not core.registered_nodes[n_bottom.name].walkable or + core.registered_nodes[n_bottom.name].buildable_to) then + if delay then + core.after(0.1, nodeupdate_single, {x=p.x, y=p.y, z=p.z}, false) + else + n.level = core.get_node_level(p) + local meta = minetest.env:get_meta(p) + --print('get owner '.. meta:get_string("owner")) + spawn_falling_node(p, n, meta:get_string("owner")) + core.remove_node(p) + nodeupdate(p) + end + end + end + + if core.get_item_group(n.name, "attached_node") ~= 0 then + if not check_attached_node(p, n) then + drop_attached_node(p) + nodeupdate(p) + end + end +end + +function nodeupdate(p, delay) + -- Round p to prevent falling entities to get stuck + p.x = math.floor(p.x+0.5) + p.y = math.floor(p.y+0.5) + p.z = math.floor(p.z+0.5) + + for x = -1,1 do + for y = -1,1 do + for z = -1,1 do + nodeupdate_single({x=p.x+x, y=p.y+y, z=p.z+z}, delay or not (x==0 and y==0 and z==0)) + end + end + end +end + +-- +-- Global callbacks +-- + +function on_placenode(p, node) + nodeupdate(p) +end +core.register_on_placenode(on_placenode) + +function on_dignode(p, node) + nodeupdate(p) +end +core.register_on_dignode(on_dignode) diff --git a/mods/homedecor_modpack/itemframes/depends.txt b/mods/homedecor_modpack/itemframes/depends.txt deleted file mode 100755 index 4ad96d51..00000000 --- a/mods/homedecor_modpack/itemframes/depends.txt +++ /dev/null @@ -1 +0,0 @@ -default diff --git a/mods/homedecor_modpack/itemframes/init.lua b/mods/homedecor_modpack/itemframes/init.lua deleted file mode 100755 index f5c8ce06..00000000 --- a/mods/homedecor_modpack/itemframes/init.lua +++ /dev/null @@ -1,216 +0,0 @@ -local tmp = {} - -minetest.register_entity("itemframes:item",{ - hp_max = 1, - visual="wielditem", - visual_size={x=.33,y=.33}, - collisionbox = {0,0,0,0,0,0}, - physical=false, - textures={"air"}, - on_activate = function(self, staticdata) - if tmp.nodename ~= nil and tmp.texture ~= nil then - self.nodename = tmp.nodename - tmp.nodename = nil - self.texture = tmp.texture - tmp.texture = nil - else - if staticdata ~= nil and staticdata ~= "" then - local data = staticdata:split(';') - if data and data[1] and data[2] then - self.nodename = data[1] - self.texture = data[2] - end - end - end - if self.texture ~= nil then - self.object:set_properties({textures={self.texture}}) - end - if self.nodename == "itemframes:pedestal" then - self.object:set_properties({automatic_rotate=1}) - end - end, - get_staticdata = function(self) - if self.nodename ~= nil and self.texture ~= nil then - return self.nodename .. ';' .. self.texture - end - return "" - end, -}) - - -local facedir = {} -facedir[0] = {x=0,y=0,z=1} -facedir[1] = {x=1,y=0,z=0} -facedir[2] = {x=0,y=0,z=-1} -facedir[3] = {x=-1,y=0,z=0} - -local remove_item = function(pos, node) - local objs = nil - if node.name == "itemframes:frame" then - objs = minetest.env:get_objects_inside_radius(pos, .5) - elseif node.name == "itemframes:pedestal" then - objs = minetest.env:get_objects_inside_radius({x=pos.x,y=pos.y+1,z=pos.z}, .5) - end - if objs then - for _, obj in ipairs(objs) do - if obj and obj:get_luaentity() and obj:get_luaentity().name == "itemframes:item" then - obj:remove() - end - end - end -end - -local update_item = function(pos, node) - remove_item(pos, node) - local meta = minetest.env:get_meta(pos) - if meta:get_string("item") ~= "" then - if node.name == "itemframes:frame" then - local posad = facedir[node.param2] - if not posad then return end - pos.x = pos.x + posad.x*6.5/16 - pos.y = pos.y + posad.y*6.5/16 - pos.z = pos.z + posad.z*6.5/16 - elseif node.name == "itemframes:pedestal" then - pos.y = pos.y + 12/16+.33 - end - tmp.nodename = node.name - tmp.texture = ItemStack(meta:get_string("item")):get_name() - local e = minetest.env:add_entity(pos,"itemframes:item") - if node.name == "itemframes:frame" then - local yaw = math.pi*2 - node.param2 * math.pi/2 - e:setyaw(yaw) - end - end -end - -local drop_item = function(pos, node) - local meta = minetest.env:get_meta(pos) - if meta:get_string("item") ~= "" then - if node.name == "itemframes:frame" then - minetest.env:add_item(pos, meta:get_string("item")) - elseif node.name == "itemframes:pedestal" then - minetest.env:add_item({x=pos.x,y=pos.y+1,z=pos.z}, meta:get_string("item")) - end - meta:set_string("item","") - end - remove_item(pos, node) -end - -minetest.register_node("itemframes:frame",{ - description = "Item frame", - drawtype = "nodebox", - node_box = { type = "fixed", fixed = {-0.5, -0.5, 7/16, 0.5, 0.5, 0.5} }, - selection_box = { type = "fixed", fixed = {-0.5, -0.5, 7/16, 0.5, 0.5, 0.5} }, - tiles = {"itemframes_frame.png"}, - inventory_image = "itemframes_frame.png", - wield_image = "itemframes_frame.png", - paramtype = "light", - paramtype2 = "facedir", - sunlight_propagates = true, - groups = { choppy=2,dig_immediate=2 }, - legacy_wallmounted = true, - sounds = default.node_sound_defaults(), - after_place_node = function(pos, placer, itemstack) - local meta = minetest.env:get_meta(pos) - meta:set_string("owner",placer:get_player_name()) - meta:set_string("infotext","Item frame (owned by "..placer:get_player_name()..")") - end, - on_rightclick = function(pos, node, clicker, itemstack) - if not itemstack then return end - local meta = minetest.env:get_meta(pos) - if clicker:get_player_name() == meta:get_string("owner") then - drop_item(pos,node) - local s = itemstack:take_item() - meta:set_string("item",s:to_string()) - update_item(pos,node) - end - return itemstack - end, - on_punch = function(pos,node,puncher) - local meta = minetest.env:get_meta(pos) - if puncher:get_player_name() == meta:get_string("owner") then - drop_item(pos, node) - end - end, - can_dig = function(pos,player) - - local meta = minetest.env:get_meta(pos) - return player:get_player_name() == meta:get_string("owner") - end, -}) - - -minetest.register_node("itemframes:pedestal",{ - description = "Pedestal", - drawtype = "nodebox", - node_box = { type = "fixed", fixed = { - {-7/16, -8/16, -7/16, 7/16, -7/16, 7/16}, -- bottom plate - {-6/16, -7/16, -6/16, 6/16, -6/16, 6/16}, -- bottom plate (upper) - {-0.25, -6/16, -0.25, 0.25, 11/16, 0.25}, -- pillar - {-7/16, 11/16, -7/16, 7/16, 12/16, 7/16}, -- top plate - } }, - --selection_box = { type = "fixed", fixed = {-7/16, -0.5, -7/16, 7/16, 12/16, 7/16} }, - tiles = {"itemframes_pedestal.png"}, - paramtype = "light", - groups = { cracky=3 }, - sounds = default.node_sound_defaults(), - after_place_node = function(pos, placer, itemstack) - local meta = minetest.env:get_meta(pos) - meta:set_string("owner",placer:get_player_name()) - meta:set_string("infotext","Pedestal (owned by "..placer:get_player_name()..")") - end, - on_rightclick = function(pos, node, clicker, itemstack) - if not itemstack then return end - local meta = minetest.env:get_meta(pos) - if clicker:get_player_name() == meta:get_string("owner") then - drop_item(pos,node) - local s = itemstack:take_item() - meta:set_string("item",s:to_string()) - update_item(pos,node) - end - return itemstack - end, - on_punch = function(pos,node,puncher) - local meta = minetest.env:get_meta(pos) - if puncher:get_player_name() == meta:get_string("owner") then - drop_item(pos,node) - end - end, - can_dig = function(pos,player) - - local meta = minetest.env:get_meta(pos) - return player:get_player_name() == meta:get_string("owner") - end, -}) - --- automatically restore entities lost from frames/pedestals --- due to /clearobjects or similar - -minetest.register_abm({ - nodenames = { "itemframes:frame", "itemframes:pedestal" }, - interval = 15, - chance = 1, - action = function(pos, node, active_object_count, active_object_count_wider) - if #minetest.get_objects_inside_radius(pos, 0.5) > 0 then return end - update_item(pos, node) - end -}) - --- crafts - -minetest.register_craft({ - output = 'itemframes:frame', - recipe = { - {'default:stick', 'default:stick', 'default:stick'}, - {'default:stick', 'default:paper', 'default:stick'}, - {'default:stick', 'default:stick', 'default:stick'}, - } -}) -minetest.register_craft({ - output = 'itemframes:pedestal', - recipe = { - {'default:stone', 'default:stone', 'default:stone'}, - {'', 'default:stone', ''}, - {'default:stone', 'default:stone', 'default:stone'}, - } -}) diff --git a/mods/homedecor_modpack/itemframes/textures/itemframes_frame.png b/mods/homedecor_modpack/itemframes/textures/itemframes_frame.png deleted file mode 100755 index 9ea9a302..00000000 Binary files a/mods/homedecor_modpack/itemframes/textures/itemframes_frame.png and /dev/null differ diff --git a/mods/homedecor_modpack/itemframes/textures/itemframes_pedestal.png b/mods/homedecor_modpack/itemframes/textures/itemframes_pedestal.png deleted file mode 100755 index e39abd30..00000000 Binary files a/mods/homedecor_modpack/itemframes/textures/itemframes_pedestal.png and /dev/null differ diff --git a/mods/irc/init.lua b/mods/irc/init.lua index 8a6ab85f..8232c245 100644 --- a/mods/irc/init.lua +++ b/mods/irc/init.lua @@ -17,8 +17,9 @@ if not jit and package.config:sub(1, 1) == "/" then package.path = package.path.. ";/usr/share/lua/5.1/?.lua".. ";/usr/share/lua/5.1/?/init.lua" - package.cpath = package.cpath.. - ";/usr/lib/lua/5.1/?.so" + package.cpath = package.cpath.. + -- ";/usr/lib/lua/5.1/?.so" + ";/usr/lib/x86_64-linux-gnu/lua/5.1/?.so" end irc = { diff --git a/mods/mobs/api.lua b/mods/mobs/api.lua index 90179778..fe21ef5e 100644 --- a/mods/mobs/api.lua +++ b/mods/mobs/api.lua @@ -19,7 +19,7 @@ function mobs:register_mob(name, def) light_damage = def.light_damage, water_damage = def.water_damage, lava_damage = def.lava_damage, - disable_fall_damage = def.disable_fall_damage, + fall_damage = def.fall_damage or true, drops = def.drops, armor = def.armor, drawtype = def.drawtype, @@ -88,7 +88,7 @@ function mobs:register_mob(name, def) local v = self.object:getvelocity() return (v.x^2 + v.z^2)^(0.5) end, - +--[[ in_fov = function(self,pos) -- checks if POS is in self's FOV local yaw = self.object:getyaw() @@ -112,7 +112,7 @@ function mobs:register_mob(name, def) return true end end, - +]] set_animation = function(self, type) if not self.animation then return @@ -194,7 +194,7 @@ function mobs:register_mob(name, def) -- drop egg if self.animaltype == "clucky" then - if math.random(1, 1000) <= 1 + if math.random(1, 1500) < 2 and minetest.get_node(self.object:getpos()).name == "air" and self.state == "stand" then minetest.set_node(self.object:getpos(), {name="mobs:egg"}) @@ -208,12 +208,26 @@ function mobs:register_mob(name, def) end local x = math.sin(yaw) * -2 local z = math.cos(yaw) * 2 - self.object:setacceleration({x=x, y=-10, z=z}) +-- self.object:setacceleration({x=x, y=-10, z=z}) +-- else +-- self.object:setacceleration({x=0, y=-10, z=0}) +-- end +-- Mobs float in water now, to revert uncomment previous 4 lines and remove following block of 12 + if minetest.get_item_group(minetest.get_node(self.object:getpos()).name, "water") ~= 0 then + self.object:setacceleration({x = x, y = 1.5, z = z}) + else + self.object:setacceleration({x = x, y = -10, z = z}) -- 14.5 + end else - self.object:setacceleration({x=0, y=-10, z=0}) + if minetest.get_item_group(minetest.get_node(self.object:getpos()).name, "water") ~= 0 then + self.object:setacceleration({x = 0, y = 1.5, z = 0}) + else + self.object:setacceleration({x = 0, y = -10, z = 0}) -- 14.5 + end end - - if self.disable_fall_damage and self.object:getvelocity().y == 0 then + + -- fall damage + if self.fall_damage and self.object:getvelocity().y == 0 then if not self.old_y then self.old_y = self.object:getpos().y else @@ -246,7 +260,7 @@ function mobs:register_mob(name, def) end self.timer = 0 end - + if self.sounds and self.sounds.random and math.random(1, 100) <= 1 then minetest.sound_play(self.sounds.random, {object = self.object}) end @@ -254,7 +268,7 @@ function mobs:register_mob(name, def) local do_env_damage = function(self) local pos = self.object:getpos() local n = minetest.get_node(pos) - + if self.light_damage and self.light_damage ~= 0 and pos.y>0 and minetest.get_node_light(pos) @@ -263,16 +277,16 @@ function mobs:register_mob(name, def) and minetest.get_timeofday() < 0.8 then self.object:set_hp(self.object:get_hp()-self.light_damage) - if self.object:get_hp() == 0 then + if self.object:get_hp() < 1 then self.object:remove() end end - + if self.water_damage and self.water_damage ~= 0 and minetest.get_item_group(n.name, "water") ~= 0 then self.object:set_hp(self.object:get_hp()-self.water_damage) - if self.object:get_hp() == 0 then + if self.object:get_hp() < 1 then self.object:remove() end end @@ -281,7 +295,7 @@ function mobs:register_mob(name, def) minetest.get_item_group(n.name, "lava") ~= 0 then self.object:set_hp(self.object:get_hp()-self.lava_damage) - if self.object:get_hp() == 0 then + if self.object:get_hp() < 1 then self.object:remove() end end @@ -320,7 +334,7 @@ function mobs:register_mob(name, def) p.y = p.y + 1 sp.y = sp.y + 1 -- aim higher to make looking up hills more realistic local dist = ((p.x-s.x)^2 + (p.y-s.y)^2 + (p.z-s.z)^2)^0.5 - if dist < self.view_range and self.in_fov(self,p) then + if dist < self.view_range then -- and self.in_fov(self,p) then if minetest.line_of_sight(sp,p,2) == true then self.do_attack(self,player,dist) break @@ -442,7 +456,7 @@ function mobs:register_mob(name, def) self.set_animation(self, "walk") end elseif self.state == "walk" then - if math.random(1, 100) <= 30 then + if math.random(1, 100) < 31 then self.object:setyaw(self.object:getyaw()+((math.random(0,360)-180)/180*math.pi)) end if self.jump and self.get_velocity(self) <= 0.5 and self.object:getvelocity().y == 0 then @@ -452,7 +466,7 @@ function mobs:register_mob(name, def) end self:set_animation("walk") self.set_velocity(self, self.walk_velocity) - if math.random(1, 100) <= 30 then + if math.random(1, 100) < 31 then self.set_velocity(self, 0) self.state = "stand" self:set_animation("stand") @@ -518,7 +532,7 @@ function mobs:register_mob(name, def) full_punch_interval=1.0, damage_groups = {fleshy=self.damage} }, vec) - if self.attack.player:get_hp() <= 0 then + if self.attack.player:get_hp() < 1 then self.state = "stand" self:set_animation("stand") end @@ -560,7 +574,7 @@ function mobs:register_mob(name, def) self.object:setyaw(yaw) self.set_velocity(self, 0) - if self.timer > self.shoot_interval and math.random(1, 100) <= 60 then + if self.timer > self.shoot_interval and math.random(1, 100) < 61 then self.timer = 0 self:set_animation("punch") @@ -574,7 +588,7 @@ function mobs:register_mob(name, def) local obj = minetest.add_entity(p, self.arrow) local amount = (vec.x^2+vec.y^2+vec.z^2)^0.5 local v = obj:get_luaentity().velocity - vec.y = vec.y + self.shoot_offset -- 2 + vec.y = vec.y + self.shoot_offset -- was +1, this way shoot aim is accurate vec.x = vec.x*v/amount vec.y = vec.y*v/amount vec.z = vec.z*v/amount @@ -613,7 +627,7 @@ function mobs:register_mob(name, def) self.object:set_properties(tmp.textures) end]] end - if self.lifetimer <= 0 and not self.tamed and self.type ~= "npc" then + if self.lifetimer < 1 and not self.tamed and self.type ~= "npc" then self.object:remove() end end, @@ -632,8 +646,8 @@ function mobs:register_mob(name, def) process_weapon(hitter,tflp,tool_capabilities) local pos = self.object:getpos() - if self.object:get_hp() <= 0 then - if hitter and hitter:is_player() and hitter:get_inventory() then + if self.object:get_hp() < 1 then + if hitter and hitter:is_player() then -- and hitter:get_inventory() then for _,drop in ipairs(self.drops) do if math.random(1, drop.chance) == 1 then local d = ItemStack(drop.name.." "..math.random(drop.min, drop.max)) @@ -697,7 +711,7 @@ function mobs:register_mob(name, def) end --blood_particles - +--[[ if self.blood_amount > 0 and pos then local p = pos p.y = p.y + self.blood_offset @@ -719,7 +733,7 @@ function mobs:register_mob(name, def) self.blood_texture --texture ) end - +]]-- -- knock back effect, adapted from blockmen's pyramids mod -- https://github.com/BlockMen/pyramids local kb = self.knock_back @@ -738,7 +752,7 @@ function mobs:register_mob(name, def) self.object:setvelocity({x=dir.x*kb,y=ykb,z=dir.z*kb}) self.pause_timer = r - +--[[ -- attack puncher and call other mobs for help if self.passive == false then if self.state ~= "attack" then @@ -755,6 +769,7 @@ function mobs:register_mob(name, def) end end end +]]-- end, }) @@ -777,15 +792,14 @@ function mobs:register_spawn(name, nodes, max_light, min_light, chance, active_o end pos.y = pos.y+1 - if not minetest.get_node_light(pos) then - return - end - if minetest.get_node_light(pos) > max_light then - return - end - if minetest.get_node_light(pos) < min_light then + + if not minetest.get_node_light(pos) + or minetest.get_node_light(pos) > max_light + or minetest.get_node_light(pos) < min_light then + --print ("LIGHT", name) return end + if pos.y > max_height then return end @@ -805,11 +819,8 @@ function mobs:register_spawn(name, nodes, max_light, min_light, chance, active_o max_dist = {x=33000,z=33000} end - if math.abs(pos.x) < min_dist.x or math.abs(pos.z) < min_dist.z then - return - end - - if math.abs(pos.x) > max_dist.x or math.abs(pos.z) > max_dist.z then + if math.abs(pos.x) < min_dist.x or math.abs(pos.z) < min_dist.z + or math.abs(pos.x) > max_dist.x or math.abs(pos.z) > max_dist.z then return end @@ -846,6 +857,7 @@ function mobs:register_arrow(name, def) on_step = function(self, dtime) local pos = self.object:getpos() + --if minetest.get_node(self.object:getpos()).name ~= "air" then if minetest.registered_nodes[minetest.get_node(self.object:getpos()).name].walkable then self.hit_node(self, pos, node) self.object:remove() diff --git a/mods/mobs/dungeonmaster.lua b/mods/mobs/dungeonmaster.lua index d496a2f4..bf614fe2 100644 --- a/mods/mobs/dungeonmaster.lua +++ b/mods/mobs/dungeonmaster.lua @@ -61,6 +61,7 @@ mobs:register_mob("mobs:dungeon_master", { }, jump = true, step = 0.5, + shoot_offset = 0, blood_texture = "mobs_blood.png", }) mobs:register_spawn("mobs:dungeon_master", {"default:stone"}, 2, -1, 6000, 1, -70) diff --git a/mods/mobs/dungeonmaster.lua~ b/mods/mobs/dungeonmaster.lua~ new file mode 100644 index 00000000..d496a2f4 --- /dev/null +++ b/mods/mobs/dungeonmaster.lua~ @@ -0,0 +1,105 @@ + +-- Dungeon Master (This one spits out fireballs at you) + +mobs:register_mob("mobs:dungeon_master", { + type = "monster", + hp_min = 45, + hp_max = 55, + collisionbox = {-0.7, -0.01, -0.7, 0.7, 2.6, 0.7}, + visual = "mesh", + mesh = "mobs_dungeon_master.x", + textures = {"mobs_dungeon_master.png"}, + visual_size = {x=8, y=8}, + makes_footstep_sound = true, + view_range = 16, + walk_velocity = 1, + run_velocity = 3, + damage = 12, + drops = { + {name = "default:mese_crystal_fragment", + chance = 1, + min = 1, + max = 3,}, + {name = "default:diamond", + chance = 5, + min = 1, + max = 3,}, + {name = "default:mese_crystal", + chance = 2, + min = 1, + max = 3,}, + {name = "default:diamond_block", + chance = 30, + min = 1, + max = 1,}, + {name = "maptools:silver_coin", + chance = 1, + min = 1, + max = 5,}, + }, + armor = 60, + drawtype = "front", + water_damage = 1, + lava_damage = 1, + light_damage = 0, + on_rightclick = nil, + attack_type = "shoot", + arrow = "mobs:fireball", + shoot_interval = 2.5, + sounds = { + attack = "mobs_fireball", + }, + animation = { + stand_start = 0, + stand_end = 19, + walk_start = 20, + walk_end = 35, + punch_start = 36, + punch_end = 48, + speed_normal = 15, + speed_run = 15, + }, + jump = true, + step = 0.5, + blood_texture = "mobs_blood.png", +}) +mobs:register_spawn("mobs:dungeon_master", {"default:stone"}, 2, -1, 6000, 1, -70) + +-- Fireball (weapon) + +mobs:register_arrow("mobs:fireball", { + visual = "sprite", + visual_size = {x=1, y=1}, + textures = {"mobs_fireball.png"}, + velocity = 5, + + -- direct hit, no fire... just plenty of pain + hit_player = function(self, player) + local s = self.object:getpos() + local p = player:getpos() + player:punch(self.object, 1.0, { + full_punch_interval=1.0, + damage_groups = {fleshy=8}, + }, 0) -- {x=s.x-p.x, y=s.y-p.y, z=s.z-p.z}) + end, + + -- node hit, bursts into flame (cannot blast through obsidian) + hit_node = function(self, pos, node) + + for dx=-1,1 do + for dy=-1,1 do + for dz=-1,1 do + local p = {x=pos.x+dx, y=pos.y+dy, z=pos.z+dz} + local n = minetest.env:get_node(p).name + if n ~= "default:obsidian" and n ~= "ethereal:obsidian_brick" then + if minetest.registered_nodes[n].groups.flammable or math.random(1, 100) <= 30 then + minetest.env:set_node(p, {name="fire:basic_flame"}) + else + minetest.env:set_node(p, {name="air"}) + end + end + end + end + end + end +}) diff --git a/mods/mobs/init.lua b/mods/mobs/init.lua index 798cc84c..56837fb9 100644 --- a/mods/mobs/init.lua +++ b/mods/mobs/init.lua @@ -1,4 +1,4 @@ --- Mob Api (5th Sep 2014) +-- Mob Api (15th Oct 2014) dofile(minetest.get_modpath("mobs").."/api.lua") diff --git a/mods/mobs/mese_monster.lua b/mods/mobs/mese_monster.lua index c8ce6809..a149317b 100644 --- a/mods/mobs/mese_monster.lua +++ b/mods/mobs/mese_monster.lua @@ -63,6 +63,7 @@ mobs:register_mob("mobs:mese_monster", { }, jump = true, step = 1, + shoot_offset = 2, blood_texture = "default_mese_crystal_fragment.png", }) mobs:register_spawn("mobs:mese_monster", {"default:stone", "nether:netherrack"}, 3, -1, 4000, 1, -20) diff --git a/mods/mobs/mese_monster.lua~ b/mods/mobs/mese_monster.lua~ new file mode 100644 index 00000000..c8ce6809 --- /dev/null +++ b/mods/mobs/mese_monster.lua~ @@ -0,0 +1,90 @@ + +--= Mese Monster by Zeg9 + +-- 9 mese crystal fragments = 1 mese crystal +minetest.register_craft({ + output = "default:mese_crystal", + recipe = { + {"default:mese_crystal_fragment", "default:mese_crystal_fragment", "default:mese_crystal_fragment"}, + {"default:mese_crystal_fragment", "default:mese_crystal_fragment", "default:mese_crystal_fragment"}, + {"default:mese_crystal_fragment", "default:mese_crystal_fragment", "default:mese_crystal_fragment"}, + } +}) + +-- Mese Monster +mobs:register_mob("mobs:mese_monster", { + type = "monster", + hp_min = 15, + hp_max = 30, + collisionbox = {-0.5, -1.5, -0.5, 0.5, 0.5, 0.5}, + visual = "mesh", + mesh = "zmobs_mese_monster.x", + textures = {"zmobs_mese_monster.png"}, + visual_size = {x=1, y=1}, + makes_footstep_sound = true, + view_range = 16, + walk_velocity = 1, + run_velocity = 3, + damage = 7, + drops = { + {name = "default:mese_crystal", + chance = 9, + min = 1, + max = 3,}, + {name = "default:mese_crystal_fragment", + chance = 1, + min = 1, + max = 9,}, + {name = "maptools:silver_coin", + chance = 2, + min = 1, + max = 2,}, + }, + light_resistant = true, + armor = 80, + drawtype = "front", + water_damage = 0, + lava_damage = 0, + light_damage = 0, + attack_type = "shoot", + arrow = "mobs:mese_arrow", + shoot_interval = .5, + animation = { + speed_normal = 15, + speed_run = 15, + stand_start = 0, + stand_end = 14, + walk_start = 15, + walk_end = 38, + run_start = 40, + run_end = 63, + punch_start = 15, -- 40 + punch_end = 38, -- 63 + }, + jump = true, + step = 1, + blood_texture = "default_mese_crystal_fragment.png", +}) +mobs:register_spawn("mobs:mese_monster", {"default:stone", "nether:netherrack"}, 3, -1, 4000, 1, -20) + +-- Mese Monster Crystal Shards (weapon) + +mobs:register_arrow("mobs:mese_arrow", { + visual = "sprite", + visual_size = {x=.5, y=.5}, + textures = {"default_mese_crystal_fragment.png"}, + velocity = 5, + + hit_player = function(self, player) + local s = self.object:getpos() + local p = player:getpos() + + player:punch(self.object, 1.0, { + full_punch_interval=1.0, + damage_groups = {fleshy=1}, + }, 0) -- {x=s.x-p.x, y=s.y-p.y, z=s.z-p.z}) + end, + + hit_node = function(self, pos, node) + end +})