From 85fa36b08a69227051ea40a34ef31dd5ed371af0 Mon Sep 17 00:00:00 2001 From: Tai Kedzierski Date: Thu, 27 Dec 2018 18:48:37 +0000 Subject: [PATCH] preliminary investigation of special weapons axes and swords --- api/main_api.lua | 180 +++++++++++++++++----------------------- materials/materials.lua | 88 +++++++++++++------- mobs/lava_titan.lua | 8 +- todo.txt | 3 +- 4 files changed, 143 insertions(+), 136 deletions(-) diff --git a/api/main_api.lua b/api/main_api.lua index 25ec72f..845b6b5 100644 --- a/api/main_api.lua +++ b/api/main_api.lua @@ -5,22 +5,41 @@ local c_obsidian = minetest.get_content_id("default:obsidian") local c_brick = minetest.get_content_id("default:obsidianbrick") local c_chest = minetest.get_content_id("default:chest_locked") -nssm.lessvirulent = minetest.settings:get_bool("nssm.lessvirulent") -nssm.safebones = minetest.settings:get_bool("nssm.safebones") -nssm.cryosave = minetest.settings:get_bool("nssm.cryosave") +local no_swap_nodes = { + "bones:bones", + "air", + "ignore", + "default:chest_locked", +} -function nssm:virulence(mobe) - if not nssm.lessvirulent then - return 0 +nssm.unswappable_node = function (pos, node_list) + -- Return true if the original_node should not be swapped + + local _, node, original_node + original_node = minetest.env:get_node(pos).name + + if minetest.get_item_group(original_node) == "unbreakable" then + return true end - return math.ceil(100 / mobe.hp_max) + + if minetest.is_protected(pos, "") then + return true + end + + if node_list then + for _,node in pairs(node_list) do + if node == original_node then return true end + end + end + + for _,node in pairs(no_swap_nodes) do + if node == original_node then return true end + end + + return false end -function nssm:affectbones(mobe) -- as function for adaptable heuristic - return not nssm.safebones -end - -function drops(drop) +nssm.drops = function(drop) if drop then drop:setvelocity({ x = math.random(-10, 10) / 9, @@ -83,32 +102,6 @@ function dist_pos(p, s) return r end ---check_for_death functions customized for monsters who respawns (Masticone) -function check_for_death_hydra(self) - local hp = self.object:get_hp() - if hp > 0 then - self.health = hp - if self.sounds.damage ~= nil then - minetest.sound_play(self.sounds.damage,{ - object = self.object, - max_hear_distance = self.sounds.distance - }) - end - return false - end - local pos = self.object:getpos() - local obj = nil - if self.sounds.death ~= nil then - minetest.sound_play(self.sounds.death,{ - object = self.object, - max_hear_distance = self.sounds.distance - }) - end - self.object:remove() - return true -end - - function round(n) if (n>0) then return n % 1 >= 0.5 and math.ceil(n) or math.floor(n) @@ -145,7 +138,6 @@ function digging_attack( dim --vector representing the dimensions of the mob ) - --if math.random(1,nssm:virulence(self)) ~= 1 then return end if self.attack and self.attack:is_player() then local s = self.object:getpos() local p = self.attack:getpos() @@ -155,53 +147,42 @@ function digging_attack( local per = perpendicular_vector(dir) local posp = vector.add(s,dir) - - --minetest.chat_send_all("La mia posizione:"..minetest.pos_to_string(s)) - --minetest.chat_send_all("La posizione davanti:"..minetest.pos_to_string(posp)) posp = vector.subtract(posp,per) + if nssm.unswappable_node(posp) then + return + end + local j for j = 1,3 do - --minetest.chat_send_all("pos1:"..minetest.pos_to_string(posp).." per.y= "..dim.y) - if minetest.is_protected(posp, "") then - return - end - local pos1 = posp + local pos_to_dig = posp - for i = 0,dim.y do - - --minetest.chat_send_all("pos2:"..minetest.pos_to_string(posp).." per.y= "..per.y) - - local n = minetest.env:get_node(pos1).name - --local up = {x=pos.x+dx, y=pos.y+dy, z=pos.z+dz} - if group == nil then - if minetest.get_item_group(n, "unbreakable") == 1 or minetest.is_protected(pos1, "") or (n == "bones:bones" and not nssm:affectbones(self) ) then - else - --minetest.env:set_node(p, {name="air"}) - minetest.remove_node(pos1) - end - else - if ((minetest.get_item_group(n, group)==1) and (minetest.get_item_group(n, "unbreakable") ~= 1) and (n ~= "bones:bones") and not (minetest.is_protected(pos1, "")) ) then - --minetest.env:set_node(p, {name="air"}) - minetest.remove_node(pos1) - end + for i = 0,dim.y do -- from 0 to dy between mob and player altitude? + local target_node = minetest.env:get_node(pos_to_dig).name + if not nssm.unswappable_node(pos_to_dig) then + minetest.remove_node(pos_to_dig) end - pos1.y = pos1.y+1 + pos_to_dig.y = pos_to_dig.y+1 end + posp.y=s.y posp=vector.add(posp,per) - --minetest.chat_send_all("pos3:"..minetest.pos_to_string(posp).." per.y= "..per.y) end end end +local function safely_put_block(self, pos_under_mob, original_node, putting_block) + minetest.debug("Set node "..putting_block.." under "..minetest.pos_to_string(pos_under_mob)) + if not nssm.unswappable_node(pos_under_mob, {putting_block}) then + minetest.env:set_node(pos_under_mob, {name = putting_block}) + end +end -function putting_ability( --puts under the mob the block defined as 'p_block' - self, --the entity of the mob - p_block, --definition of the block to use - max_vel --max velocity of the mob +function putting_ability( --sets 'putting_block' under the mob, as well as in front + self, -- the entity of the mob + putting_block, -- itemstring of block to put + max_vel -- max velocity of the mob ) - --if math.random(1,nssm:virulence(self)) ~= 1 then return end local v = self.object:getvelocity() @@ -222,31 +203,27 @@ function putting_ability( --puts under the mob the block defined as 'p_bl end end - local pos = self.object:getpos() - local pos1 - pos.y=pos.y-1 - pos1 = {x = pos.x+dx, y = pos.y, z = pos.z+dz} - local n = minetest.env:get_node(pos).name - local n1 = minetest.env:get_node(pos1).name - local oldmetainf = {minetest.get_meta(pos):to_table(),minetest.get_meta(pos1):to_table() } - if n~=p_block and not minetest.is_protected(pos, "") and (n == "bones:bones" and nssm:affectbones(self) ) and n~="air" then - minetest.env:set_node(pos, {name=p_block}) - if nssm.cryosave then - local metai = minetest.get_meta(pos) - metai:from_table(oldmetainf[1]) -- this is enough to save the meta - metai:set_string("nssm",n) - end - end - if n1~=p_block and not minetest.is_protected(pos1, "") and (n == "bones:bones" and nssm:affectbones(self) ) and n~="air" then - minetest.env:set_node(pos1, {name=p_block}) - if nssm.cryosave then - local metai = minetest.get_meta(pos1) - metai:from_table(oldmetainf[2]) -- this is enough to save the meta - metai:set_string("nssm",n1) - end - end -end + local pos_under_mob = self.object:getpos() + local pos_under_frontof_mob + pos_under_mob.y=pos_under_mob.y - 1 + pos_under_frontof_mob = { + x = pos_under_mob.x + dx, + y = pos_under_mob.y, + z = pos_under_mob.z + dz + } + + local node_under_mob = minetest.env:get_node(pos_under_mob).name + local node_under_frontof_mob = minetest.env:get_node(pos_under_frontof_mob).name + + local oldmetainf = { + minetest.get_meta(pos_under_mob):to_table(), + minetest.get_meta(pos_under_frontof_mob):to_table() + } + + safely_put_block(self, pos_under_mob, node_under_mob, putting_block) + safely_put_block(self, pos_under_frontof_mob, node_under_frontof_mob, putting_block) +end function webber_ability( --puts randomly around the block defined as w_block self, --the entity of the mob @@ -254,8 +231,6 @@ function webber_ability( --puts randomly around the block defined as w_bl radius --max distance the block can be put ) - if (nssm:virulence(self)~=0) and (math.random(1,nssm:virulence(self)) ~= 1) then return end - local pos = self.object:getpos() if (math.random(1,55)==1) then local dx=math.random(1,radius) @@ -264,7 +239,7 @@ function webber_ability( --puts randomly around the block defined as w_bl local t = {x=pos.x+dx, y=pos.y, z=pos.z+dz} local n = minetest.env:get_node(p).name local k = minetest.env:get_node(t).name - if ((n~="air")and(k=="air")) and not minetest.is_protected(t, "") then + if not unswappable_node(p) then minetest.env:set_node(t, {name=w_block}) end end @@ -278,15 +253,13 @@ function midas_ability( --ability to transform every blocks it touches in height --height of the mob ) - if math.random(1,nssm:virulence(self)) ~= 1 then return end - local v = self.object:getvelocity() local pos = self.object:getpos() - +--[[ if minetest.is_protected(pos, "") then return end - +--]] local max = 0 local yaw = (self.object:getyaw() + self.rotate) or 0 local x = math.sin(yaw)*-1 @@ -317,8 +290,7 @@ function midas_ability( --ability to transform every blocks it touches in local p = {x=pos.x+dx, y=pos.y+dy, z=pos.z+dz} local n = minetest.env:get_node(p).name - if minetest.get_item_group(n, "unbreakable") == 1 or minetest.is_protected(p, "") or n=="air" or (n == "bones:bones" and not nssm:affectbones(self)) then - else + if not unswappable_noed(p) then minetest.env:set_node(p, {name=m_block}) end end diff --git a/materials/materials.lua b/materials/materials.lua index 753d69c..ee74755 100644 --- a/materials/materials.lua +++ b/materials/materials.lua @@ -598,6 +598,7 @@ minetest.register_tool("nssm:tarantula_warhammer", { }) minetest.register_tool("nssm:axe_of_pride", { + -- Damage enemy, heal user by the same amount description = "Axe of Pride", inventory_image = "axe_of_pride.png", wield_scale= {x=2,y=2,z=1.5}, @@ -605,7 +606,7 @@ minetest.register_tool("nssm:axe_of_pride", { full_punch_interval =1.3 , max_drop_level=1, groupcaps={ - snappy={times={[1]=0.6, [2]=0.5, [3]=0.4}, uses=100, maxlevel=1}, + choppy={times={[1]=0.6, [2]=0.5, [3]=0.4}, uses=100, maxlevel=1}, fleshy={times={[2]=0.8, [3]=0.4}, uses=400, maxlevel=1} }, damage_groups = {fleshy=16}, @@ -652,7 +653,10 @@ minetest.register_tool("nssm:axe_of_pride", { if (obj:get_luaentity().health) then --minetest.chat_send_all("Entity") obj:get_luaentity().health = obj:get_luaentity().health -10 - check_for_death(obj:get_luaentity()) + + if obj:get_luaentity().check_for_death then + obj:get_luaentity():check_for_death({type = "punch"}) + end dropper:set_hp(dropper:get_hp()+10) --flag = 1 @@ -693,6 +697,7 @@ minetest.register_tool("nssm:axe_of_pride", { }) minetest.register_tool("nssm:gratuitousness_battleaxe", { + -- aka Battleaxe of Boom - causes and explosion at nodes from player description = "Gratuitousness Battleaxe", inventory_image = "gratuitousness_battleaxe.png", wield_scale= {x=2.2,y=2.2,z=1.5}, @@ -706,13 +711,14 @@ minetest.register_tool("nssm:gratuitousness_battleaxe", { damage_groups = {fleshy=18}, }, on_drop = function(itemstack, dropper, pos) + local epicenter_distance = 10 local objects = minetest.env:get_objects_inside_radius(pos, 10) local flag = 0 local vec = dropper:get_look_dir() local pos = dropper:getpos() --vec.y = 0 - for i=1,10 do + for i=1,epicenter_distance do pos = vector.add(pos, vec) end @@ -740,6 +746,7 @@ minetest.register_tool("nssm:gratuitousness_battleaxe", { }) minetest.register_tool("nssm:sword_of_eagerness", { + -- Cause enemies to be sent upwards y+20 description = "Sword of Eagerness", inventory_image = "sword_of_eagerness.png", wield_scale= {x=2,y=2,z=1}, @@ -829,6 +836,7 @@ minetest.register_tool("nssm:sword_of_eagerness", { }) minetest.register_tool("nssm:falchion_of_eagerness", { + -- Sends player 16m in the direction in which they are pointing... description = "Falchion of Eagerness", inventory_image = "falchion_of_eagerness.png", wield_scale= {x=2,y=2,z=1}, @@ -843,11 +851,11 @@ minetest.register_tool("nssm:falchion_of_eagerness", { }, on_drop = function(itemstack, dropper, pos) local vec = dropper:get_look_dir() - local pos = dropper:getpos() + local pos_destination = dropper:getpos() --vec.y = 0 for i=1,16 do - pos = vector.add(pos, vec) + pos_destination = vector.add(pos_destination, vec) end local pname = dropper:get_player_name() @@ -868,15 +876,20 @@ minetest.register_tool("nssm:falchion_of_eagerness", { end end if found == 0 then - minetest.chat_send_player(pname, "You haven't got enough life_energy!") + minetest.chat_send_player(pname, "You do not have enough life energy!") return + + elseif minetest.is_protected(pos_destination, pname) or nssm.unswappable_node(pos_destination) then + minetest.chat_send_player(pname, "You cannot go to that protected space!") + return + else - local s = dropper:getpos() + local pos_particles = dropper:getpos() minetest.add_particlespawner( 25, --amount 0.3, --time - vector.subtract(s, 0.5), --minpos - vector.add(s, 0.5), --maxpos + vector.subtract(pos_particles, 0.5), --minpos + vector.add(pos_particles, 0.5), --maxpos {x=0, y=10, z=0}, --minvel {x=0.1, y=11, z=0.1}, --maxvel {x=0,y=1,z=0}, --minacc @@ -888,19 +901,24 @@ minetest.register_tool("nssm:falchion_of_eagerness", { false, --collisiondetection "slothful_soul_fragment.png" --texture ) - minetest.remove_node(pos) - pos.y=pos.y+1 - minetest.remove_node(pos) - pos.y=pos.y-2 - minetest.remove_node(pos) - dropper:setpos(pos) - s = pos - s.y = s.y+10 + + local dy, digpos + for dy = -1,1 do + digpos = pos_destination + dy + if not nssm.unswappable_node(digpos) then + minetest.remove_node(digpos) + end + end + + dropper:setpos(pos_destination) + + pos_particles = pos_destination + pos_particles.y = pos_particles.y+10 minetest.add_particlespawner( 25, --amount 0.3, --time - vector.subtract(s, 0.5), --minpos - vector.add(s, 0.5), --maxpos + vector.subtract(pos_particles, 0.5), --minpos + vector.add(pos_particles, 0.5), --maxpos {x=0, y=-10, z=0}, --minvel {x=0.1, y=-11, z=0.1}, --maxvel {x=0,y=-1,z=0}, --minacc @@ -912,6 +930,7 @@ minetest.register_tool("nssm:falchion_of_eagerness", { false, --collisiondetection "slothful_soul_fragment.png" --texture ) + local items = player_inv:get_stack('main', found) items:set_count(items:get_count()-5) player_inv:set_stack('main', found, items) @@ -921,6 +940,8 @@ minetest.register_tool("nssm:falchion_of_eagerness", { }) minetest.register_tool("nssm:sword_of_envy", { + -- Switch the health of the enemy with the health of the player + -- Particularly useful when enemy's health is over 20 description = "Sword of Envy", inventory_image = "sword_of_envy.png", wield_scale= {x=2,y=2,z=1}, @@ -971,14 +992,18 @@ minetest.register_tool("nssm:sword_of_envy", { end else if (obj:get_luaentity().health) then - local hpp = obj:get_luaentity().health + local obj_health = obj:get_luaentity().health obj:get_luaentity().health = dropper:get_hp() - if hpp > 20 then + + if obj_health > 20 then dropper:set_hp(20) else - dropper:set_hp(hpp) + dropper:set_hp(obj_health) + end + + if obj:get_luaentity().check_for_death then + obj:get_luaentity():check_for_death({type = "punch"}) end - check_for_death(obj:get_luaentity()) flag = 1 local items = player_inv:get_stack('main', found) @@ -994,6 +1019,7 @@ minetest.register_tool("nssm:sword_of_envy", { }) minetest.register_tool("nssm:sword_of_gluttony", { + -- Kills nearby monsters and causes them to drop roasted duck legs! :D description = "Sword of Gluttony", inventory_image = "sword_of_gluttony.png", wield_scale= {x=2,y=2,z=1}, @@ -1046,6 +1072,8 @@ minetest.register_tool("nssm:sword_of_gluttony", { local pos = obj:getpos() obj:remove() + -- We don't use check_for_death, as that would cause it to put regular drops + -- (FIXME - this means hydra hobs do not respawn...) --check_for_death(obj:get_luaentity()) --flag = 1 --take energy globe from inventory: @@ -1055,7 +1083,7 @@ minetest.register_tool("nssm:sword_of_gluttony", { for i = 1,math.random(1,4) do drop = minetest.add_item(pos, "nssm:roasted_duck_legs 1") - drops(drop) + nssm.drops(drop) end local s = obj:getpos() @@ -1089,6 +1117,8 @@ minetest.register_tool("nssm:sword_of_gluttony", { }) minetest.register_tool("nssm:death_scythe", { + -- Kills everything around it + -- Casues dry grass, dry shrubs, and dead leaves, dropping lots of life eergy to drop too description = "Death Scythe", wield_scale= {x=3,y=3,z=1.3}, inventory_image = "death_scythe.png", @@ -1116,7 +1146,9 @@ minetest.register_tool("nssm:death_scythe", { else if (obj:get_luaentity().health) then obj:get_luaentity().health = obj:get_luaentity().health -40 - check_for_death(obj:get_luaentity()) + if obj:get_luaentity().check_for_death then + obj:get_luaentity():check_for_death({type = "punch"}) + end flag = 1 end end @@ -1143,7 +1175,7 @@ minetest.register_tool("nssm:death_scythe", { if math.random(1,3)==1 then v.y = v.y +2 drop = minetest.add_item(v, "nssm:life_energy 1") - drops(drop) + nssm.drops(drop) end end @@ -1154,7 +1186,7 @@ minetest.register_tool("nssm:death_scythe", { if math.random(1,3)==1 then v.y = v.y +2 drop = minetest.add_item(v, "nssm:life_energy 1") - drops(drop) + nssm.drops(drop) end end @@ -1165,7 +1197,7 @@ minetest.register_tool("nssm:death_scythe", { if math.random(1,3)==1 then v.y = v.y +2 drop = minetest.add_item(v, "nssm:life_energy 1") - drops(drop) + nssm.drops(drop) end end end, diff --git a/mobs/lava_titan.lua b/mobs/lava_titan.lua index 6841f91..b4e52c3 100644 --- a/mobs/lava_titan.lua +++ b/mobs/lava_titan.lua @@ -82,12 +82,16 @@ mobs:register_mob("nssm:lava_titan", { }, do_custom = function (self) digging_attack(self, nil, self.run_velocity, {x=0, y=4, z=0}) + + -- Deactivated because... non existent ? --digging_ability(self, nil, self.run_velocity, {x=0, y=5, z=0}) + + -- For now deactivate - it places lava under it, sinks, then places lava under it, sinks, etc ... --putting_ability(self, "default:lava_source", self.run_velocity) end, --[[ custom_attack = function (self) - digging_attack + -- digging_attack mobs:set_animation(self, "punch") local p2 = p local s2 = s @@ -113,5 +117,5 @@ mobs:register_mob("nssm:lava_titan", { }, nil) end end, - ]]-- + --]] }) diff --git a/todo.txt b/todo.txt index 6fa85b2..9b6df28 100644 --- a/todo.txt +++ b/todo.txt @@ -1,7 +1,6 @@ Mobs bugs + changes -* Check why ice snake and snow biter are not placing ice -* Check why lava titan is not placing lava +* Ensure phoenix cannot burn through unswappable Server-oriented changes