Botete spits corrosive goo

master
Lean Rada 2015-01-24 02:05:11 +08:00
parent f92259eac7
commit 33c5834474
5 changed files with 153 additions and 53 deletions

View File

@ -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

View File

@ -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

View File

@ -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,
})
})

View File

@ -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