Botete spits corrosive goo
parent
f92259eac7
commit
33c5834474
|
@ -2,6 +2,7 @@ defense.director = {}
|
|||
local director = defense.director
|
||||
director.call_interval = 1.0
|
||||
director.intensity_decay = 0.92
|
||||
director.max_entities = 50
|
||||
director.spawn_list = {
|
||||
{
|
||||
description = "Unggoy group",
|
||||
|
@ -84,7 +85,7 @@ function director:on_interval()
|
|||
end
|
||||
|
||||
if self.cooldown_timer <= 0 then
|
||||
if defense:is_dark() then
|
||||
if defense:is_dark() and #minetest.luaentities < self.max_entities then
|
||||
self:spawn_monsters()
|
||||
end
|
||||
|
||||
|
|
|
@ -122,7 +122,7 @@ function mobs.default_prototype:hunt()
|
|||
self:do_attack(nearest.player)
|
||||
end
|
||||
if nearest.distance > self.attack_range or nearest.distance < self.attack_range/2-1 then
|
||||
local r = math.max(0, self.attack_range - 1.0)
|
||||
local r = math.max(0, self.attack_range - 2)
|
||||
self.destination = vector.add(nearest.position, vector.multiply(dir, r))
|
||||
end
|
||||
end
|
||||
|
|
|
@ -17,11 +17,15 @@ defense.mobs.register_mob("defense:botete", {
|
|||
move_speed = 4,
|
||||
attack_damage = 0,
|
||||
attack_range = 8,
|
||||
attack_interval = 3.4,
|
||||
attack_interval = 16,
|
||||
|
||||
on_step = function(self, dtime)
|
||||
defense.mobs.default_prototype.on_step(self, dtime)
|
||||
self:hunt()
|
||||
if self.last_attack_time + self.attack_interval * 0.8 < 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)})
|
||||
end
|
||||
end,
|
||||
|
||||
attack = function(self, obj, dir)
|
||||
|
@ -57,14 +61,10 @@ defense.mobs.register_mob("defense:botete", {
|
|||
-- Launch projectile
|
||||
local projectile = minetest.add_entity(pos, "defense:gooball")
|
||||
projectile:setvelocity(v)
|
||||
self.object:setvelocity(vector.multiply(v, -0.5))
|
||||
self.object:setvelocity(vector.multiply(v, -0.4))
|
||||
|
||||
if math.random() < 0.1 then
|
||||
if self.attack_range < 4 then
|
||||
self.attack_range = 8
|
||||
else
|
||||
self.attack_range = self.attack_range - 1
|
||||
end
|
||||
self.attack_range = 4 + math.random() * 4
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
@ -82,59 +82,139 @@ minetest.register_entity("defense:gooball", {
|
|||
|
||||
on_step = function(self, dtime)
|
||||
local pos = self.object:getpos()
|
||||
if minetest.get_node(pos).name ~= "air" then
|
||||
local node = minetest.get_node(pos)
|
||||
if node.name ~= "air" and node.name ~= "defense:goo" then
|
||||
local space = pos
|
||||
local back = vector.multiply(vector.normalize(self.object:getvelocity()), -1)
|
||||
local node
|
||||
local nvel = vector.normalize(self.object:getvelocity())
|
||||
local back = vector.multiply(nvel, -1)
|
||||
local bnode
|
||||
repeat
|
||||
space = vector.add(space, back)
|
||||
node = minetest.get_node_or_nil(space)
|
||||
until not node or node.name == "air" or node.name == "defense:goo"
|
||||
self:hit(space)
|
||||
bnode = minetest.get_node_or_nil(space)
|
||||
until not bnode or bnode.name == "air"
|
||||
self:hit(space, nvel)
|
||||
self.object:remove()
|
||||
end
|
||||
end,
|
||||
|
||||
hit = function(self, pos)
|
||||
minetest.set_node(pos, {name="defense:goo"})
|
||||
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
|
||||
minetest.register_node("defense:goo", {
|
||||
description = "Caustic Goo",
|
||||
tiles = {"defense_goo.png"},
|
||||
tiles = {{
|
||||
name="defense_goo.png",
|
||||
animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=0.7}
|
||||
}},
|
||||
inventory_image = "defense_gooball.png",
|
||||
drop = "",
|
||||
groups = {crumbly=3},
|
||||
walkable = false,
|
||||
buildable_to = false,
|
||||
damage_per_second = 1,
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {-0.5, -0.5, -0.5, 0.5, -0.5+2/16, 0.5},
|
||||
fixed = {-0.5, -0.5, 0.5-2/16, 0.5, 0.5, 0.5},
|
||||
},
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
liquid_viscosity = 4,
|
||||
liquidtype = "source",
|
||||
liquid_alternative_flowing = "defense:goo",
|
||||
liquid_alternative_source = "defense:goo",
|
||||
liquid_renewable = false,
|
||||
liquid_range = 0,
|
||||
groups = {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)
|
||||
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
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_node("defense:goo_block", {
|
||||
description = "Caustic Goo Block",
|
||||
tiles = {"defense_goo.png"},
|
||||
-- inventory_image = "defense_goo.png",
|
||||
tiles = {{
|
||||
name="defense_goo.png",
|
||||
animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=0.7}
|
||||
}},
|
||||
drawtype = "glasslike",
|
||||
paramtype = "light",
|
||||
liquid_viscosity = 8,
|
||||
liquidtype = "source",
|
||||
liquid_alternative_flowing = "defense:goo_block",
|
||||
liquid_alternative_source = "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},
|
||||
drop = "",
|
||||
groups = {crumbly=3},
|
||||
walkable = false,
|
||||
buildable_to = false,
|
||||
damage_per_second = 1,
|
||||
})
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = {"defense:goo", "defense:goo_block"},
|
||||
interval = 1,
|
||||
chance = 30,
|
||||
action = function(pos, node)
|
||||
minetest.remove_node(pos)
|
||||
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)
|
||||
end
|
||||
end,
|
||||
})
|
||||
})
|
||||
|
|
|
@ -56,9 +56,8 @@ defense.mobs.register_mob("defense:sarangay", {
|
|||
local v = self.object:getvelocity()
|
||||
v.y = 0
|
||||
pos = vector.add(pos, vector.multiply(vector.normalize(v), 1.5))
|
||||
local blocks = self:crash_blocks(pos, 4)
|
||||
local entities = self:crash_entities(pos, 3)
|
||||
self.charge_power = self.charge_power - blocks * 0.2 - entities * 0.05
|
||||
self.charge_power = self:crash_blocks(pos, 4, self.charge_power/2) * 2
|
||||
self.charge_power = self:crash_entities(pos, 3, self.charge_power/3) * 3
|
||||
|
||||
if self.charge_power < 0 or (self.charge_power > 1 and vector.length(self.object:getvelocity()) < self.move_speed/4) then
|
||||
self:set_charging_state(false)
|
||||
|
@ -73,7 +72,7 @@ defense.mobs.register_mob("defense:sarangay", {
|
|||
if math.random() < 0.1 then
|
||||
self:set_charging_state(true)
|
||||
self.destination = nil
|
||||
elseif nearest.distance < 6 then
|
||||
elseif nearest.distance < 4 then
|
||||
self:hunt()
|
||||
elseif not self.destination then
|
||||
local nearest_pos = nearest.player:getpos()
|
||||
|
@ -101,8 +100,7 @@ defense.mobs.register_mob("defense:sarangay", {
|
|||
end
|
||||
end,
|
||||
|
||||
crash_blocks = function(self, pos, radius)
|
||||
local hit_count = 0
|
||||
crash_blocks = function(self, pos, radius, maxwear)
|
||||
local p = {x=0, y=0, z=pos.z - radius}
|
||||
for z = -radius, radius do
|
||||
p.y = pos.y - radius
|
||||
|
@ -110,9 +108,13 @@ defense.mobs.register_mob("defense:sarangay", {
|
|||
p.x = pos.x - radius
|
||||
for x = -radius, radius do
|
||||
if x*x + y*y + z*z <= radius then
|
||||
if self:can_destroy_node(p) then
|
||||
local wear = self:get_node_wear(p)
|
||||
if wear > 0 then
|
||||
minetest.dig_node(p)
|
||||
hit_count = hit_count + 1
|
||||
maxwear = maxwear - wear
|
||||
if maxwear <= 0 then
|
||||
return 0
|
||||
end
|
||||
end
|
||||
end
|
||||
p.x = p.x + 1
|
||||
|
@ -122,11 +124,10 @@ defense.mobs.register_mob("defense:sarangay", {
|
|||
p.z = p.z + 1
|
||||
end
|
||||
|
||||
return hit_count
|
||||
return maxwear
|
||||
end,
|
||||
|
||||
crash_entities = function(self, pos, radius)
|
||||
local weight_count = 0
|
||||
crash_entities = function(self, pos, radius, maxweight)
|
||||
local myv = self.object:getvelocity()
|
||||
for _,o in pairs(minetest.get_objects_inside_radius(pos, radius)) do
|
||||
if o ~= self.object then
|
||||
|
@ -145,19 +146,37 @@ defense.mobs.register_mob("defense:sarangay", {
|
|||
o:setvelocity(vector.add(v, vector.multiply(dir, 3/m)))
|
||||
end
|
||||
|
||||
weight_count = weight_count + m
|
||||
maxweight = maxweight - m
|
||||
if maxweight <= 0 then
|
||||
return 0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return weight_count
|
||||
|
||||
return maxweight
|
||||
end,
|
||||
|
||||
can_destroy_node = function(self, pos)
|
||||
get_node_wear = function(self, pos)
|
||||
local node = minetest.get_node_or_nil(pos)
|
||||
if not node or minetest.registered_nodes[node.name].walkable then
|
||||
return true
|
||||
local groupwear = {
|
||||
crumbly = {[1]=0.5, [2]=0.1, [3]=0.1},
|
||||
fleshy = {[1]=1, [2]=0.5, [3]=0.1},
|
||||
snappy = {[1]=1.5, [2]=1, [3]=0.5},
|
||||
choppy = {[1]=2, [2]=1, [3]=0.5},
|
||||
cracky = {[1]=4, [2]=2, [3]=1},
|
||||
}
|
||||
if node then
|
||||
local wear = 0
|
||||
for k,v in pairs(groupwear) do
|
||||
local rating = minetest.get_item_group(node.name, k)
|
||||
if v[rating] and v[rating] > wear then
|
||||
wear = v[rating]
|
||||
end
|
||||
end
|
||||
return wear
|
||||
else
|
||||
return false
|
||||
return 0
|
||||
end
|
||||
end,
|
||||
})
|
Binary file not shown.
Before Width: | Height: | Size: 545 B After Width: | Height: | Size: 2.0 KiB |
Loading…
Reference in New Issue