Update goo

master
Lean Rada 2015-01-25 02:52:49 +08:00
parent 2e895b2be2
commit 35dc377191
1 changed files with 122 additions and 70 deletions

View File

@ -1,3 +1,94 @@
local function place_goo(pos, origin)
if not origin then
origin = pos
end
local node = minetest.get_node_or_nil(pos)
if not node or node.name ~= "air" and not minetest.registered_nodes[node.name].buildable_to then
return false
end
if node.name == "defense:goo" then
-- minetest.place_node(pos, {name="defense:goo_block"})
-- minetest.get_meta(pos):set_string("origin", minetest.pos_to_string(origin))
return true
else
local dirs = {
{x = 0, y =-1, z = 0},
{x =-1, y = 0, z = 0},
{x = 0, y = 0, z = 1},
{x = 0, y = 0, z =-1},
{x = 1, y = 0, z = 0},
{x = 0, y = 1, z = 0},
}
local dir = nil
for _,d in ipairs(dirs) do
local wall_pos = vector.add(pos, d)
local wall = minetest.get_node_or_nil(wall_pos)
if wall and wall.name ~= "air" and minetest.get_item_group(wall.name, "caustic_goo") == 0 then
dir = d
break
end
end
if dir then
local facedir = minetest.dir_to_facedir(dir, true)
if minetest.registered_nodes[node.name].buildable_to then
-- minetest.set_node(pos, {name="defense:goo", param2=facedir})
-- minetest.get_meta(pos):set_string("origin", minetest.pos_to_string(origin))
return true
end
end
end
return false
end
local function spread_goo(pos, origin)
if origin and vector.distance(pos, origin) > 2 then
return
end
local node = minetest.get_node_or_nil(pos)
if node then
local dirs = {
{x = 1, y = 0, z = 0},
{x =-1, y = 0, z = 0},
{x = 0, y = 1, z = 0},
{x = 0, y =-1, z = 0},
{x = 0, y = 0, z = 1},
{x = 0, y = 0, z =-1},
}
if node.name == "defense:goo" then
local dir = minetest.facedir_to_dir(node.param2)
for _,d in ipairs(dirs) do
local dot_product = d.x * dir.x + d.y * dir.y + d.z * dir.z
if dot_product == 0 then
if math.random() < 0.25 then
local npos = vector.add(pos, d)
if not place_goo(vector.add(npos, dir), origin) then
if not place_goo(npos, origin) then
place_goo(vector.subtract(npos, dir), origin)
end
end
end
end
end
else
for _,d in ipairs(dirs) do
if math.random() < 0.17 then
local npos = vector.add(pos, d)
minetest.dig_node(npos)
place_goo(npos, origin)
end
end
end
if math.random() < 0.1 then
minetest.dig_node(pos)
end
end
end
defense.mobs.register_mob("defense:botete", {
hp_max = 2,
collisionbox = {-0.6,-0.7,-0.6, 0.6,0.4,0.6},
@ -21,10 +112,10 @@ defense.mobs.register_mob("defense:botete", {
on_step = function(self, dtime)
defense.mobs.default_prototype.on_step(self, dtime)
if self.last_attack_time + self.attack_interval * 0.8 < self.timer then
if self.last_attack_time + self.attack_interval * 0.5 < self.timer then
self:hunt()
elseif not self.destination then
self.destination = vector.add(self.object:getpos(), {x=math.random(-10,10), y=math.random(-5,5), z=math.random(-10,10)})
self.destination = vector.add(self.object:getpos(), {x=math.random(-10,10), y=math.random(-5,6), z=math.random(-10,10)})
end
end,
@ -38,7 +129,6 @@ defense.mobs.register_mob("defense:botete", {
-- Calculate launch angle
local angle
local delta = vector.subtract(obj:getpos(), pos)
delta.y = delta.y + 1
local x2 = delta.x*delta.x + delta.z*delta.z
local s2 = s*s
local r = s2*s2 - g * (g*x2 + 2*delta.y*s2)
@ -83,7 +173,9 @@ minetest.register_entity("defense:gooball", {
on_step = function(self, dtime)
local pos = self.object:getpos()
local node = minetest.get_node(pos)
if node.name ~= "air" and node.name ~= "defense:goo" then
if minetest.get_item_group(node.name, "caustic_goo") > 0 then
self.object:remove()
elseif node.name ~= "air" then
local space = pos
local nvel = vector.normalize(self.object:getvelocity())
local back = vector.multiply(nvel, -1)
@ -92,39 +184,10 @@ minetest.register_entity("defense:gooball", {
space = vector.add(space, back)
bnode = minetest.get_node_or_nil(space)
until not bnode or bnode.name == "air"
self:hit(space, nvel)
place_goo(space)
self.object:remove()
end
end,
hit = function(self, pos, dir)
local xmag = math.abs(dir.x)
local ymag = math.abs(dir.y)
local zmag = math.abs(dir.z)
if xmag > ymag then
if xmag > zmag then
dir.x = dir.x/xmag
dir.y = 0
dir.z = 0
else
dir.x = 0
dir.y = 0
dir.z = dir.z/zmag
end
else
if ymag > zmag then
dir.x = 0
dir.y = dir.y/ymag
dir.z = 0
else
dir.x = 0
dir.y = 0
dir.z = dir.z/zmag
end
end
local facedir = minetest.dir_to_facedir(dir, true)
minetest.set_node(pos, {name="defense:goo", param2=facedir})
end,
})
-- Goo node
@ -148,29 +211,29 @@ minetest.register_node("defense:goo", {
liquid_alternative_source = "defense:goo",
liquid_renewable = false,
liquid_range = 0,
groups = {crumbly=3, dig_immediate=3, liquid=3, disable_jump=1},
groups = {caustic_goo=1, crumbly=3, dig_immediate=3, liquid=3, disable_jump=1},
drop = "",
walkable = false,
buildable_to = false,
damage_per_second = 1,
on_construct = function(pos)
minetest.get_node_timer(pos):start(1 + math.random() * 5)
minetest.get_node_timer(pos):start(1 + math.random() * 9)
local meta = minetest.get_meta(pos)
local origin = meta:get_string("origin")
if not origin then
meta:set_string("origin", minetest.pos_to_string(pos))
end
end,
on_timer = function(pos, elapsed)
local dir = minetest.facedir_to_dir(minetest.get_node(pos).param2)
local under = vector.add(pos, dir)
local node = minetest.get_node_or_nil(under)
if node and node.name ~= "air" then
minetest.remove_node(under)
minetest.place_node(under, {name="defense:goo_block"})
end
minetest.dig_node(pos)
return false
local meta = minetest.get_meta(pos)
spread_goo(pos, minetest.string_to_pos(meta:get_string("origin")))
return true
end,
})
-- Goo block
minetest.register_node("defense:goo_block", {
description = "Caustic Goo Block",
tiles = {{
@ -186,35 +249,24 @@ minetest.register_node("defense:goo_block", {
liquid_renewable = false,
liquid_range = 0,
post_effect_color = {r=100, g=240, b=0, a=240},
groups = {crumbly=3, dig_immediate=3, falling_node=1, liquid=3, disable_jump=1},
groups = {caustic_goo=1, crumbly=3, dig_immediate=3, liquid=3, disable_jump=1},
drop = "",
walkable = false,
buildable_to = false,
damage_per_second = 1,
})
minetest.register_abm({
nodenames = {"defense:goo_block"},
interval = 1.5,
chance = 2,
action = function(pos, _, _, _)
if math.random() < 0.5 then
minetest.dig_node(pos)
else
local neighbor = vector.new(pos)
if math.random() < 1.0/3.0 then
neighbor.y = pos.y - 1
elseif math.random() < 0.5 then
neighbor.x = pos.x + math.random(0,1) * 2 - 1
else
neighbor.z = pos.z + math.random(0,1) * 2 - 1
end
local node = minetest.get_node_or_nil(neighbor)
if node and node.name ~= "air" then
minetest.remove_node(neighbor)
minetest.place_node(neighbor, {name="defense:goo_block"})
end
minetest.dig_node(pos)
on_construct = function(pos)
minetest.get_node_timer(pos):start(1 + math.random() * 15)
local meta = minetest.get_meta(pos)
local origin = meta:get_string("origin")
if not origin then
meta:set_string("origin", minetest.pos_to_string(pos))
end
end,
})
on_timer = function(pos, elapsed)
local meta = minetest.get_meta(pos)
spread_goo(pos, minetest.string_to_pos(meta:get_string("origin")))
return true
end,
})