3129 lines
88 KiB
Lua
3129 lines
88 KiB
Lua
aliveai_threats={c4={},debris={},n=0,tox_obs={},stopacidplayer={}}
|
|
|
|
dofile(minetest.get_modpath("aliveai_threats") .. "/eyes.lua")
|
|
dofile(minetest.get_modpath("aliveai_threats") .. "/sec.lua")
|
|
dofile(minetest.get_modpath("aliveai_threats") .. "/lab.lua")
|
|
dofile(minetest.get_modpath("aliveai_threats") .. "/flowerattack.lua")
|
|
dofile(minetest.get_modpath("aliveai_threats") .. "/crystal.lua")
|
|
dofile(minetest.get_modpath("aliveai_threats") .. "/tree.lua")
|
|
dofile(minetest.get_modpath("aliveai_threats") .. "/fort.lua")
|
|
dofile(minetest.get_modpath("aliveai_threats") .. "/spider.lua")
|
|
|
|
aliveai_threats.tox=function(ob)
|
|
|
|
if not ob or not ob:get_pos() or aliveai.gethp(ob,1)<1 or aliveai.team(ob)=="nuke" then
|
|
if ob and ob:is_player() then
|
|
if aliveai_threats.tox_obs[ob:get_player_name()]==2 then return end
|
|
aliveai_threats.tox_obs[ob:get_player_name()]=nil
|
|
end
|
|
return
|
|
end
|
|
if ob:is_player() then
|
|
if aliveai_threats.tox_obs[ob:get_player_name()]==2 then return end
|
|
aliveai_threats.tox_obs[ob:get_player_name()]=1
|
|
elseif ob:get_luaentity() then
|
|
ob:get_luaentity().aliveai_threats_tox=1
|
|
end
|
|
|
|
local pos=ob:get_pos()
|
|
for _, obs in ipairs(minetest.get_objects_inside_radius(pos, 4)) do
|
|
if aliveai.visiable(pos,obs:get_pos()) and not ((ob:get_luaentity() and ob:get_luaentity().aliveai_threats_tox) or (ob:is_player() and aliveai_threats.tox_obs[ob:get_player_name()])) then aliveai_threats.tox(obs) end
|
|
end
|
|
aliveai.punchdmg(ob)
|
|
if aliveai.gethp(ob,1)<1 or math.random(1,40)==1 then
|
|
if ob and ob:is_player() then
|
|
local name=ob:get_player_name()
|
|
aliveai_threats.tox_obs[name]=2
|
|
minetest.after(5, function(name)
|
|
aliveai_threats.tox_obs[name]=nil
|
|
end,name)
|
|
elseif ob:get_luaentity() then
|
|
ob:get_luaentity().aliveai_threats_tox=nil
|
|
end
|
|
return
|
|
end
|
|
|
|
minetest.after(math.random(1,2), function(ob)
|
|
aliveai_threats.tox(ob)
|
|
end,ob)
|
|
end
|
|
aliveai.create_bot({
|
|
description="The toxic gassman is constantly hunting someone to envenom and destroy civilizations",
|
|
attack_players=1,
|
|
name="toxic_gassman",
|
|
team="nuke",
|
|
texture="aliveai_threats_gassman.png^[colorize:#00ff0055",
|
|
attacking=1,
|
|
talking=0,
|
|
light=0,
|
|
building=0,
|
|
escape=0,
|
|
type="monster",
|
|
dmg=0,
|
|
hp=100,
|
|
name_color="",
|
|
arm=2,
|
|
coming=0,
|
|
smartfight=0,
|
|
spawn_on={"group:sand","group:spreading_dirt_type","default:gravel","default:stone"},
|
|
attack_chance=5,
|
|
on_punching=function(self,target)
|
|
aliveai_threats.tox(target)
|
|
end,
|
|
on_blow=function(self)
|
|
aliveai.kill(self)
|
|
self.death(self,self.object,self.object:get_pos())
|
|
end,
|
|
death=function(self,puncher,pos)
|
|
if not self.ex then
|
|
self.ex=true
|
|
aliveai_nitroglycerine.explode(pos,{
|
|
radius=1,
|
|
set="air",
|
|
blow_nodes=0,
|
|
hurt=0
|
|
})
|
|
for _, ob in ipairs(minetest.get_objects_inside_radius(pos, 4)) do
|
|
if aliveai.visiable(pos,ob:get_pos()) then aliveai_threats.tox(ob,1) end
|
|
end
|
|
end
|
|
return self
|
|
end,
|
|
on_punched=function(self,puncher)
|
|
local pos=self.object:get_pos()
|
|
aliveai_threats.tox(puncher)
|
|
minetest.add_particlespawner({
|
|
amount = 5,
|
|
time=0.2,
|
|
minpos = pos,
|
|
maxpos = pos,
|
|
minvel = {x=-0.1, y=-0.1, z=-0.1},
|
|
maxvel = {x=0.1, y=0.1, z=0.1},
|
|
minacc = {x=0, y=0, z=0},
|
|
maxacc = {x=0, y=0, z=0},
|
|
minexptime = 0.5,
|
|
maxexptime = 1,
|
|
minsize = 0.5,
|
|
maxsize = 2,
|
|
texture = "default_grass.png^[colorize:#00ff0055",
|
|
})
|
|
end
|
|
})
|
|
|
|
|
|
|
|
if minetest.get_modpath("aliveai_nitroglycerine")~=nil then
|
|
|
|
minetest.register_craft({
|
|
output = "aliveai_threats:c4 2",
|
|
recipe = {
|
|
{"default:steel_ingot","default:coal_lump","default:steel_ingot"},
|
|
{"default:steel_ingot","default:mese_crystal_fragment","default:steel_ingot"},
|
|
{"default:steel_ingot","default:copper_ingot","default:steel_ingot"},
|
|
}
|
|
})
|
|
|
|
|
|
minetest.register_craftitem("aliveai_threats:c4", {
|
|
description = "C4 bomb",
|
|
inventory_image = "aliveai_threats_c4.png",
|
|
on_use = function(itemstack, user, pointed_thing)
|
|
local name=user:get_player_name()
|
|
local c=aliveai_threats.c4[name]
|
|
if not c and pointed_thing.type=="object" then
|
|
local ob=pointed_thing.ref
|
|
aliveai_threats.c4[user:get_player_name()]=ob
|
|
user:get_inventory():add_item("main","aliveai_threats:c4_controler")
|
|
itemstack:take_item()
|
|
elseif not c then
|
|
aliveai_threats.c4[name]=nil
|
|
end
|
|
return itemstack
|
|
end
|
|
})
|
|
|
|
minetest.register_craftitem("aliveai_threats:c4_controler", {
|
|
description = "C4 controller",
|
|
inventory_image = "aliveai_threats_c4_controller.png",
|
|
groups = {not_in_creative_inventory=1},
|
|
on_use = function(itemstack, user, pointed_thing)
|
|
local name=user:get_player_name()
|
|
local ob=aliveai_threats.c4[name]
|
|
if ob and ob:get_pos() and ob:get_pos().x then
|
|
local pos=ob:get_pos()
|
|
for _, ob in ipairs(minetest.get_objects_inside_radius(pos, 3)) do
|
|
local en=ob:get_luaentity()
|
|
if en and en.aliveai then en.drop_dead_body=0 end
|
|
ob:punch(ob,1,{full_punch_interval=1,damage_groups={fleshy=200}})
|
|
end
|
|
aliveai_nitroglycerine.explode(pos,{
|
|
radius=3,
|
|
set="air",
|
|
})
|
|
else
|
|
user:get_inventory():add_item("main","aliveai_threats:c4")
|
|
end
|
|
aliveai_threats.c4[name]=nil
|
|
itemstack:take_item()
|
|
return itemstack
|
|
end
|
|
})
|
|
|
|
|
|
aliveai.create_bot({
|
|
description="The nitrogen is provoking you to fight him, but only leads to your own damage",
|
|
drop_dead_body=0,
|
|
attack_players=1,
|
|
name="nitrogen",
|
|
team="ice",
|
|
texture="aliveai_threats_nitrogen.png",
|
|
stealing=1,
|
|
steal_chanse=2,
|
|
attacking=1,
|
|
talking=0,
|
|
light=0,
|
|
building=0,
|
|
escape=0,
|
|
start_with_items={["default:snowblock"]=1,["default:ice"]=4},
|
|
type="monster",
|
|
dmg=1,
|
|
hp=40,
|
|
name_color="",
|
|
arm=2,
|
|
spawn_on={"default:silver_sand","default:dirt_with_snow","default:snow","default:snowblock","default:ice"},
|
|
on_step=function(self,dtime)
|
|
local pos=self.object:get_pos()
|
|
pos.y=pos.y-1.5
|
|
local node=minetest.get_node(pos)
|
|
if node and node.name and minetest.is_protected(pos,"")==false then
|
|
if minetest.get_item_group(node.name, "soil")>0 then
|
|
minetest.set_node(pos,{name="default:dirt_with_snow"})
|
|
elseif minetest.get_item_group(node.name, "sand")>0 and minetest.registered_nodes["default:silver_sand"] then
|
|
minetest.set_node(pos,{name="default:silver_sand"})
|
|
elseif minetest.get_item_group(node.name, "water")>0 then
|
|
minetest.set_node(pos,{name="default:ice"})
|
|
pos.y=pos.y+1
|
|
if minetest.get_item_group(minetest.get_node(pos).name, "water")>1 then
|
|
minetest.set_node(pos,{name="default:ice"})
|
|
end
|
|
elseif minetest.get_item_group(node.name, "lava")>0 then
|
|
minetest.set_node(pos,{name="default:ice"})
|
|
pos.y=pos.y+1
|
|
if minetest.get_item_group(minetest.get_node(pos).name, "lava")>1 then
|
|
minetest.set_node(pos,{name="default:ice"})
|
|
end
|
|
end
|
|
end
|
|
end,
|
|
on_punching=function(self,target)
|
|
if aliveai.gethp(target)<=self.dmg+5 then
|
|
aliveai_nitroglycerine.freeze(target)
|
|
else
|
|
target:punch(self.object,1,{full_punch_interval=1,damage_groups={fleshy=self.dmg}},nil)
|
|
end
|
|
end,
|
|
death=function(self,puncher,pos)
|
|
minetest.sound_play("default_break_glass", {pos=pos, gain = 1.0, max_hear_distance = 5,})
|
|
aliveai_nitroglycerine.crush(pos)
|
|
end,
|
|
})
|
|
|
|
aliveai.create_bot({
|
|
description="The gassman is provoking everyone, in order to get the opportunity to trigger its powerful explosion",
|
|
drop_dead_body=0,
|
|
attack_players=1,
|
|
name="gassman",
|
|
team="nuke",
|
|
texture="aliveai_threats_gassman.png",
|
|
attacking=1,
|
|
talking=0,
|
|
light=0,
|
|
building=0,
|
|
escape=0,
|
|
type="monster",
|
|
dmg=0,
|
|
hp=100,
|
|
name_color="",
|
|
arm=2,
|
|
coming=0,
|
|
smartfight=0,
|
|
spawn_on={"group:sand","group:spreading_dirt_type","default:gravel","group:stone"},
|
|
attack_chance=5,
|
|
on_fighting=function(self,target)
|
|
if not self.ti then self.ti={t=1,s=0} end
|
|
self.temper=10
|
|
self.ti.s=self.ti.s-1
|
|
if self.ti.s<=0 then
|
|
self.ti.t=self.ti.t-1
|
|
if self.ti.t>=0 then
|
|
self.ti.s=99
|
|
end
|
|
end
|
|
if self.ti.t<0 then
|
|
local pos=self.object:get_pos()
|
|
self.ex=true
|
|
aliveai.kill(self)
|
|
aliveai_nitroglycerine.explode(pos,{
|
|
radius=10,
|
|
set="air",
|
|
drops=0,
|
|
})
|
|
return self
|
|
end
|
|
|
|
local tag=self.ti.t ..":" .. self.ti.s
|
|
self.object:set_properties({nametag=tag,nametag_color="#ff0000aa"})
|
|
end,
|
|
on_blow=function(self)
|
|
aliveai.kill(self)
|
|
self.death(self,self.object,self.object:get_pos())
|
|
end,
|
|
death=function(self,puncher,pos)
|
|
if not self.ex then
|
|
self.hp=0
|
|
self.ex=true
|
|
aliveai_nitroglycerine.explode(pos,{
|
|
radius=2,
|
|
set="air",
|
|
})
|
|
end
|
|
return self
|
|
end,
|
|
})
|
|
|
|
|
|
|
|
aliveai.create_bot({
|
|
description="In contrast to the nitrogen monster it provokes you to get a chance to explode and freeze you",
|
|
drop_dead_body=0,
|
|
attack_players=1,
|
|
name="nitrogenblow",
|
|
team="ice",
|
|
texture="aliveai_threats_nitrogenblow.png",
|
|
attacking=1,
|
|
talking=0,
|
|
light=0,
|
|
building=0,
|
|
escape=0,
|
|
start_with_items={["default:snowblock"]=10,["default:ice"]=2},
|
|
spawn_on={"default:silver_sand","default:dirt_with_snow","default:snow","default:snowblock","default:ice"},
|
|
type="monster",
|
|
dmg=1,
|
|
hp=30,
|
|
name_color="",
|
|
arm=2,
|
|
coming=0,
|
|
smartfight=0,
|
|
spawn_on={"group:sand","group:spreading_dirt_type","default:gravel","group:stone"},
|
|
attack_chance=5,
|
|
on_fighting=function(self,target)
|
|
if aliveai.gethp(target)<=self.dmg+5 then
|
|
aliveai_nitroglycerine.freeze(target)
|
|
elseif math.random(1,10)==1 then
|
|
target:punch(self.object,1,{full_punch_interval=1,damage_groups={fleshy=self.dmg}},nil)
|
|
end
|
|
if not self.ti then self.ti={t=5,s=9} end
|
|
self.temper=10
|
|
self.ti.s=self.ti.s-1
|
|
if self.ti.s<=0 then
|
|
self.ti.t=self.ti.t-1
|
|
if self.ti.t>=0 then
|
|
self.ti.s=9
|
|
end
|
|
end
|
|
if self.ti.t<0 then
|
|
self.ex=true
|
|
if aliveai.gethp(target)<=11 then
|
|
aliveai_nitroglycerine.freeze(target)
|
|
else
|
|
target:punch(self.object,1,{full_punch_interval=1,damage_groups={fleshy=10}},nil)
|
|
end
|
|
aliveai_nitroglycerine.crush(self.object:get_pos())
|
|
aliveai.kill(self)
|
|
return self
|
|
end
|
|
local tag=self.ti.t ..":" .. self.ti.s
|
|
self.object:set_properties({nametag=tag,nametag_color="#ff0000aa"})
|
|
end,
|
|
death=function(self,puncher,pos)
|
|
minetest.sound_play("default_break_glass", {pos=pos, gain = 1.0, max_hear_distance = 5,})
|
|
if not self.ex then
|
|
self.ex=true
|
|
self.aliveai_ice=1
|
|
local radius=10
|
|
aliveai_nitroglycerine.explode(pos,{
|
|
radius=radius,
|
|
hurt=0,
|
|
place={"default:snowblock","default:ice","default:snowblock"},
|
|
place_chance=2,
|
|
})
|
|
for _, ob in ipairs(minetest.get_objects_inside_radius(pos, radius*2)) do
|
|
local pos2=ob:get_pos()
|
|
local d=math.max(1,vector.distance(pos,pos2))
|
|
local dmg=(8/d)*radius
|
|
local en=ob:get_luaentity()
|
|
if ob:is_player() or not (en and en.name=="aliveai_nitroglycerine:ice" or en.aliveai_ice) then
|
|
if ob:get_hp()<=dmg+5 then
|
|
aliveai_nitroglycerine.freeze(ob)
|
|
else
|
|
ob:punch(self.object,1,{full_punch_interval=1,damage_groups={fleshy=dmg}})
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return self
|
|
end,
|
|
})
|
|
|
|
aliveai.create_bot({
|
|
description="Its provokes you to get a chance to explode it self and creats heavy gass.\nBlast a part of the gas to remove it",
|
|
drop_dead_body=0,
|
|
attack_players=1,
|
|
name="heavygassman",
|
|
team="nuke",
|
|
texture="aliveai_threats_gassman2.png",
|
|
attacking=1,
|
|
talking=0,
|
|
light=0,
|
|
building=0,
|
|
escape=0,
|
|
start_with_items={["default:coal_lump"]=4},
|
|
type="monster",
|
|
dmg=0,
|
|
hp=20,
|
|
name_color="",
|
|
arm=2,
|
|
coming=1,
|
|
smartfight=0,
|
|
attack_chance=1,
|
|
on_fighting=function(self,target)
|
|
if not self.t then self.t=20 end
|
|
self.temper=10
|
|
self.t=self.t-1
|
|
if self.t<0 then
|
|
aliveai.kill(self)
|
|
return self
|
|
end
|
|
self.object:set_properties({nametag=self.t,nametag_color="#ff0000aa"})
|
|
end,
|
|
on_blow=function(self)
|
|
aliveai.kill(self)
|
|
self.death(self,self.object,self.object:get_pos())
|
|
end,
|
|
death=function(self,puncher,pos)
|
|
if not self.ex then
|
|
self.ex=true
|
|
local radius=10
|
|
aliveai_nitroglycerine.explode(pos,{
|
|
radius=radius,
|
|
place={"aliveai_threats:gass","aliveai_threats:gass"},
|
|
set="aliveai_threats:gass",
|
|
place_chance=1,
|
|
})
|
|
end
|
|
return self
|
|
end,
|
|
})
|
|
|
|
minetest.register_node("aliveai_threats:gass", {
|
|
description = "Gass",
|
|
inventory_image = "bubble.png",
|
|
tiles = {"aliveai_air.png"},
|
|
walkable = false,
|
|
pointable = false,
|
|
drowning = 1,
|
|
buildable_to = true,
|
|
drawtype = "glasslike",
|
|
post_effect_color = {a = 248, r =0, g = 0, b = 0},
|
|
damage_per_second = 1,
|
|
paramtype = "light",
|
|
liquid_viscosity = 15,
|
|
liquidtype = "source",
|
|
liquid_range = 0,
|
|
liquid_alternative_flowing = "aliveai_threats:gass",
|
|
liquid_alternative_source = "aliveai_threats:gass",
|
|
groups = {liquid = 4,crumbly = 1,not_in_creative_inventory=1},
|
|
on_blast=function(pos)
|
|
minetest.after(0, function(pos)
|
|
local np=minetest.find_node_near(pos, 3,"aliveai_threats:gass")
|
|
if np then
|
|
aliveai_nitroglycerine.cons({pos=pos,max=5000,replace={["aliveai_threats:gass"]="air"}})
|
|
end
|
|
end,pos)
|
|
end,
|
|
})
|
|
|
|
if minetest.get_modpath("fire")~=nil then
|
|
|
|
aliveai.create_bot({
|
|
description="Powerfull lavamonster, yourself away from it!",
|
|
drop_dead_body=0,
|
|
attack_players=1,
|
|
name="lava",
|
|
team="lava",
|
|
texture="default_lava.png",
|
|
attacking=1,
|
|
talking=0,
|
|
light=0,
|
|
building=0,
|
|
start_with_items={["default:obsidian"]=1,["default:obsidian_shard"]=3},
|
|
type="monster",
|
|
hp=50,
|
|
dmg=8,
|
|
escape=0,
|
|
name_color="",
|
|
attack_chance=2,
|
|
damage_by_blocks=0,
|
|
spawn_on={"default:lava_source","default:lava_flowing"},
|
|
spawn_in="default:lava_source",
|
|
mindamage=5,
|
|
on_step=function(self,dtime)
|
|
if (self.fight and math.random(1,3)==1) or math.random(1,10)==1 then
|
|
local pos=self.object:get_pos()
|
|
for y=-2,4,1 do
|
|
for x=-2,4,1 do
|
|
for z=-2,4,1 do
|
|
local p1={x=pos.x+x,y=pos.y+y,z=pos.z+z}
|
|
local p2={x=pos.x+x,y=pos.y+y-1,z=pos.z+z}
|
|
local no1=minetest.get_node(p1).name
|
|
local no2=minetest.get_node(p2).name
|
|
if not (minetest.registered_nodes[no1] and minetest.registered_nodes[no2]) then return end
|
|
if minetest.get_item_group(no1, "igniter")==0 and minetest.registered_nodes[no1].buildable_to and minetest.registered_nodes[no2].walkable and aliveai.visiable(pos,p1) then
|
|
minetest.set_node(p1, {name = "fire:basic_flame"})
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end,
|
|
on_punched=function(self,puncher)
|
|
local pos=self.object:get_pos()
|
|
minetest.add_particlespawner({
|
|
amount = 5,
|
|
time =0.05,
|
|
minpos = pos,
|
|
maxpos = pos,
|
|
minvel = {x=-2, y=-2, z=-2},
|
|
maxvel = {x=1, y=0.5, z=1},
|
|
minacc = {x=0, y=-8, z=0},
|
|
maxacc = {x=0, y=-10, z=0},
|
|
minexptime = 2,
|
|
maxexptime = 1,
|
|
minsize = 0.1,
|
|
maxsize = 2,
|
|
texture = "default_lava.png",
|
|
collisiondetection = true,
|
|
})
|
|
end,
|
|
death=function(self,puncher,pos)
|
|
if not self.ex then
|
|
self.ex=true
|
|
aliveai_nitroglycerine.explode(pos,{
|
|
radius=7,
|
|
place={"fire:basic_flame","fire:basic_flame"},
|
|
})
|
|
end
|
|
return self
|
|
end,
|
|
})
|
|
|
|
|
|
aliveai.create_bot({
|
|
description="Born in fire, add more fire and rages around",
|
|
drop_dead_body=0,
|
|
attack_players=1,
|
|
name="fire",
|
|
team="lava",
|
|
texture="fire_basic_flame.png",
|
|
attacking=1,
|
|
talking=0,
|
|
light=0,
|
|
building=0,
|
|
start_with_items={["default:obsidian"]=1,["default:obsidian_shard"]=3},
|
|
type="monster",
|
|
hp=30,
|
|
name_color="",
|
|
attack_chance=2,
|
|
damage_by_blocks=0,
|
|
spawn_on={"fire:basic_flame"},
|
|
dmg=5,
|
|
escape=0,
|
|
mindamage=5,
|
|
spawn_chance=100,
|
|
on_step=function(self,dtime)
|
|
if (self.fight and math.random(1,3)==1) or math.random(1,10)==1 then
|
|
local pos=self.object:get_pos()
|
|
for y=-1,1,1 do
|
|
for x=-1,1,1 do
|
|
for z=-1,1,1 do
|
|
local p1={x=pos.x+x,y=pos.y+y,z=pos.z+z}
|
|
local p2={x=pos.x+x,y=pos.y+y-1,z=pos.z+z}
|
|
local no1=minetest.get_node(p1).name
|
|
local no2=minetest.get_node(p2).name
|
|
if not (minetest.registered_nodes[no1] and minetest.registered_nodes[no2]) then return end
|
|
if minetest.get_item_group(no1, "igniter")==0 and minetest.registered_nodes[no1].buildable_to and minetest.registered_nodes[no2].walkable and aliveai.visiable(pos,p1) then
|
|
minetest.set_node(p1, {name = "fire:basic_flame"})
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end,
|
|
on_punched=function(self,puncher)
|
|
local pos=self.object:get_pos()
|
|
minetest.add_particlespawner({
|
|
amount = 5,
|
|
time =0.05,
|
|
minpos = pos,
|
|
maxpos = pos,
|
|
minvel = {x=-2, y=-2, z=-2},
|
|
maxvel = {x=1, y=0.5, z=1},
|
|
minacc = {x=0, y=-8, z=0},
|
|
maxacc = {x=0, y=-10, z=0},
|
|
minexptime = 2,
|
|
maxexptime = 1,
|
|
minsize = 0.1,
|
|
maxsize = 2,
|
|
texture = "fire_basic_flame.png",
|
|
collisiondetection = true,
|
|
})
|
|
end,
|
|
death=function(self,puncher,pos)
|
|
if not self.ex then
|
|
self.ex=true
|
|
aliveai_nitroglycerine.explode(pos,{
|
|
radius=5,
|
|
place={"fire:basic_flame","fire:basic_flame"},
|
|
})
|
|
end
|
|
return self
|
|
end,
|
|
})
|
|
end
|
|
|
|
|
|
end
|
|
|
|
aliveai.create_bot({
|
|
description="Terminator the murder machine is constantly hunting to destroy civilizations",
|
|
attack_players=1,
|
|
name="terminator",
|
|
team="nuke",
|
|
texture="aliveai_threats_terminator.png",
|
|
attacking=1,
|
|
talking=0,
|
|
building=0,
|
|
escape=0,
|
|
start_with_items={["default:steel_ingot"]=4,["default:steelblock"]=1},
|
|
type="monster",
|
|
dmg=0,
|
|
hp=200,
|
|
arm=3,
|
|
name_color="",
|
|
spawn_on={"group:sand","group:spreading_dirt_type","default:gravel","group:stone"},
|
|
attack_chance=5,
|
|
mindamage=5,
|
|
on_punching=function(self,target)
|
|
local pos=self.object:get_pos()
|
|
pos.y=pos.y-0.5
|
|
local radius=self.arm
|
|
for _, ob in ipairs(minetest.get_objects_inside_radius(pos, radius)) do
|
|
local pos2=ob:get_pos()
|
|
local d=math.max(1,vector.distance(pos,pos2))
|
|
local dmg=(8/d)*radius
|
|
local en=ob:get_luaentity()
|
|
if ob:is_player() or not (en and en.team==self.team or ob.itemstring) then
|
|
if en and en.object then
|
|
if en.type~="" then ob:punch(self.object,1,{full_punch_interval=1,damage_groups={fleshy=dmg}},nil) end
|
|
dmg=dmg*2
|
|
ob:set_velocity({x=(pos2.x-pos.x)*dmg, y=((pos2.y-pos.y)*dmg)+2, z=(pos2.z-pos.z)*dmg})
|
|
elseif ob:is_player() then
|
|
ob:punch(self.object,1,{full_punch_interval=1,damage_groups={fleshy=dmg}},nil)
|
|
local d=dmg/2
|
|
local v=0
|
|
local dd=0
|
|
local p2={x=pos.x-pos2.x, y=pos.y-pos2.y, z=pos.z-pos2.z}
|
|
local tmp
|
|
for i=0,10,1 do
|
|
dd=d*v
|
|
tmp={x=pos.x+(p2.x*dd), y=pos.y+(p2.y*dd)+2, z=pos.z+(p2.z*dd)}
|
|
local n=minetest.get_node(tmp)
|
|
if n and n.name and minetest.registered_nodes[n.name].walkable then
|
|
if minetest.is_protected(tmp,"")==false and minetest.dig_node(tmp) then
|
|
for _, item in pairs(minetest.get_node_drops(n.name, "")) do
|
|
if item then
|
|
local it=minetest.add_item(tmp, item)
|
|
it:get_luaentity().age=890
|
|
it:set_velocity({x = math.random(-1, 1),y=math.random(-1, 1),z = math.random(-1, 1)})
|
|
end
|
|
end
|
|
else
|
|
break
|
|
end
|
|
end
|
|
v=v-0.1
|
|
end
|
|
d=d*v
|
|
ob:set_pos({x=pos.x+(p2.x*d), y=pos.y+(p2.y*d)+2, z=pos.z+(p2.z*d)})
|
|
end
|
|
end
|
|
end
|
|
end,
|
|
on_punched=function(self,puncher)
|
|
local pos=self.object:get_pos()
|
|
minetest.add_particlespawner({
|
|
amount = 5,
|
|
time =0.05,
|
|
minpos = pos,
|
|
maxpos = pos,
|
|
minvel = {x=-2, y=-2, z=-2},
|
|
maxvel = {x=1, y=0.5, z=1},
|
|
minacc = {x=0, y=-8, z=0},
|
|
maxacc = {x=0, y=-10, z=0},
|
|
minexptime = 2,
|
|
maxexptime = 1,
|
|
minsize = 0.1,
|
|
maxsize = 2,
|
|
texture = "default_steel_block.png",
|
|
collisiondetection = true,
|
|
spawn_chance=100,
|
|
})
|
|
end
|
|
})
|
|
|
|
|
|
|
|
aliveai.create_bot({
|
|
description="The pull monsters pulls down all its enemies in the ground, it even hides itself in the underground",
|
|
attack_players=1,
|
|
name="pull_monster",
|
|
team="pull",
|
|
texture="aliveai_threats_pull.png",
|
|
visual_size={x=0.8,y=1.4},
|
|
collisionbox={-0.33,-1.3,-0.33,0.33,1.5,0.33},
|
|
attacking=1,
|
|
talking=0,
|
|
light=-1,
|
|
lowest_light=9,
|
|
building=0,
|
|
smartfight=0,
|
|
escape=0,
|
|
type="monster",
|
|
dmg=0,
|
|
hp=80,
|
|
arm=2,
|
|
name_color="",
|
|
spawn_on={"group:sand","group:spreading_dirt_type","group:stone","default:snow"},
|
|
attack_chance=3,
|
|
spawn_chance=200,
|
|
spawn_y=1,
|
|
on_punching=function(self,target)
|
|
if not self.pull_down then
|
|
local pos=aliveai.roundpos(target:get_pos())
|
|
local n=minetest.get_node(pos)
|
|
if minetest.registered_nodes[n.name] and minetest.registered_nodes[n.name].walkable then return end
|
|
pos.y=pos.y-1
|
|
self.pull_down={pos={pos0=pos}}
|
|
local p
|
|
for i=1,3,1 do
|
|
p={x=pos.x,y=pos.y-i,z=pos.z}
|
|
n=minetest.get_node(p)
|
|
self.pull_down.pos["pos" .. i]=p
|
|
if minetest.registered_nodes[n.name] and minetest.registered_nodes[n.name].walkable==false then
|
|
self.pull_down=nil
|
|
return
|
|
end
|
|
end
|
|
self.pull_down.target=target
|
|
end
|
|
end,
|
|
on_detect_enemy=function(self,target)
|
|
self.object:set_properties({
|
|
mesh = aliveai.character_model,
|
|
textures = {"aliveai_threats_pull.png"},
|
|
})
|
|
end,
|
|
on_load=function(self)
|
|
self.move.speed=0.5
|
|
local pos=aliveai.roundpos(self.object:get_pos())
|
|
local n=minetest.get_node(pos)
|
|
if minetest.registered_nodes[n.name] and minetest.registered_nodes[n.name].walkable then
|
|
pos.y=pos.y+3
|
|
local l=minetest.get_node_light(pos)
|
|
if not l then return end
|
|
local n=minetest.get_node(pos)
|
|
if minetest.registered_nodes[n.name] and minetest.registered_nodes[n.name].walkable then
|
|
self.domovefromslp=true
|
|
return self
|
|
elseif l>9 then
|
|
self.sleep={ground=pos}
|
|
return self
|
|
else
|
|
self.domovefromslp=true
|
|
return self
|
|
end
|
|
end
|
|
end,
|
|
on_step=function(self,dtime)
|
|
if self.movefromslp then
|
|
aliveai.rndwalk(self,false)
|
|
aliveai.stand(self)
|
|
for i, v in pairs(self.movefromslp) do
|
|
self.object:move_to(v)
|
|
table.remove(self.movefromslp,i)
|
|
return self
|
|
end
|
|
self.movefromslp=nil
|
|
return self
|
|
end
|
|
if self.domovefromslp then
|
|
self.domovefromslp=nil
|
|
local pos=self.object:get_pos()
|
|
local gpos={x=pos.x,y=pos.y+3,z=pos.z}
|
|
local n=minetest.get_node(gpos)
|
|
if minetest.registered_nodes[n.name] and minetest.registered_nodes[n.name].walkable then
|
|
self.movefromslp={} -- move up from stuck sleep pos
|
|
local p3=0
|
|
for i=1,103,1 do
|
|
local p={x=gpos.x,y=gpos.y+i,z=gpos.z}
|
|
local n=minetest.get_node(p)
|
|
self.movefromslp[i]=p
|
|
if minetest.registered_nodes[n.name] and minetest.registered_nodes[n.name].walkable==false then
|
|
p3=p3+1
|
|
if p3>2 then
|
|
self.sleep=nil
|
|
return self
|
|
end
|
|
else
|
|
p3=0
|
|
end
|
|
end
|
|
aliveai.kill(self)
|
|
return self
|
|
end
|
|
end
|
|
if self.sleep then
|
|
local pos=aliveai.roundpos(self.object:get_pos())
|
|
if self.sleep.pos then
|
|
if self.sleep.pos.pos0 then
|
|
self.object:move_to(self.sleep.pos.pos0)
|
|
self.sleep.pos.pos0=nil
|
|
elseif self.sleep.pos.pos1 then
|
|
self.object:move_to(self.sleep.pos.pos1)
|
|
self.sleep.pos.pos1=nil
|
|
elseif self.sleep.pos.pos2 then
|
|
self.object:move_to(self.sleep.pos.pos2)
|
|
self.sleep.pos=nil
|
|
end
|
|
if not self.pull_down then return self end
|
|
end
|
|
if self.pull_down then
|
|
if self.pull_down.target and self.pull_down.pos then
|
|
if self.pull_down.pos.pos0 and not (self.sleep.pos and self.sleep.pos.pos2) then
|
|
self.pull_down=nil
|
|
self.sleep=nil
|
|
return
|
|
end
|
|
if self.pull_down.pos.pos0 then
|
|
self.pull_down.target:move_to(self.pull_down.pos.pos0)
|
|
self.pull_down.pos.pos0=nil
|
|
elseif self.pull_down.pos.pos1 then
|
|
self.pull_down.target:move_to(self.pull_down.pos.pos1)
|
|
self.pull_down.pos.pos1=nil
|
|
elseif self.pull_down.pos.pos2 then
|
|
self.pull_down.target:move_to(self.pull_down.pos.pos2)
|
|
self.pull_down.pos=nil
|
|
end
|
|
return self
|
|
end
|
|
if self.pull_down.target and aliveai.gethp(self.pull_down.target)>0 and aliveai.distance(self,self.pull_down.target:get_pos())<=self.arm+1 then
|
|
aliveai.punch(self,self.pull_down.target,1)
|
|
if aliveai.gethp(self.pull_down.target)<=0 then
|
|
self.object:set_hp(self.hp_max)
|
|
aliveai.showhp(self,true)
|
|
self.domovefromslp=true
|
|
end
|
|
return self
|
|
else
|
|
self.sleep=nil
|
|
self.pull_down=nil
|
|
return
|
|
end
|
|
end
|
|
if self.hide then
|
|
self.time=self.otime
|
|
if math.random(1,2)==1 then
|
|
if not self.abortsleep then
|
|
for _, ob in ipairs(minetest.get_objects_inside_radius(self.sleep.ground, 10)) do
|
|
local en=ob:get_luaentity()
|
|
if not (en and en.aliveai and en.team==self.team) then
|
|
return self
|
|
end
|
|
end
|
|
end
|
|
self.hide=nil
|
|
self.pull_down=nil
|
|
self.domovefromslp=true
|
|
end
|
|
if self.hide then return self end
|
|
end
|
|
local l=minetest.get_node_light(self.sleep.ground)
|
|
if not l then
|
|
aliveai.kill(self)
|
|
self.sleep=nil
|
|
self.domovefromslp=true
|
|
return self
|
|
elseif l<=9 or self.abortsleep then
|
|
self.domovefromslp=true
|
|
else
|
|
if math.random(1,10)==1 then
|
|
for _, ob in ipairs(minetest.get_objects_inside_radius(self.sleep.ground, self.distance)) do
|
|
local en=ob:get_luaentity()
|
|
if not (en and en.aliveai and en.team==self.team) then
|
|
return self
|
|
end
|
|
end
|
|
aliveai.kill(self)
|
|
end
|
|
return self
|
|
end
|
|
elseif math.random(1,10)==1 or self.pull_down or self.hide then
|
|
local pos=aliveai.roundpos(self.object:get_pos())
|
|
pos.y=pos.y-1
|
|
local l=minetest.get_node_light(pos)
|
|
if not l then return end
|
|
if l>9 or self.pull_down or self.hide then
|
|
local p
|
|
self.sleep={ground=pos,pos={pos0=pos}}
|
|
for i=1,3,1 do
|
|
p={x=pos.x,y=pos.y-i,z=pos.z}
|
|
local n=minetest.get_node(p)
|
|
self.sleep.pos["pos" .. i]=p
|
|
if minetest.registered_nodes[n.name] and minetest.registered_nodes[n.name].walkable==false then
|
|
self.sleep=nil
|
|
self.pull_down=nil
|
|
return
|
|
end
|
|
end
|
|
aliveai.rndwalk(self,false)
|
|
aliveai.stand(self)
|
|
return self
|
|
end
|
|
elseif math.random(1,10)==1 then
|
|
local pos=self.object:get_pos()
|
|
pos.y=pos.y-1.5
|
|
local n=minetest.get_node(pos)
|
|
if minetest.registered_nodes[n.name] and minetest.registered_nodes[n.name].tiles then
|
|
local tiles=minetest.registered_nodes[n.name].tiles
|
|
if type(tiles)=="table" and type(tiles[1])=="string" then
|
|
self.tex=tiles[1]
|
|
self.object:set_properties({
|
|
mesh = aliveai.character_model,
|
|
textures = {tiles[1]},
|
|
})
|
|
end
|
|
end
|
|
end
|
|
end,
|
|
on_punched=function(self,puncher)
|
|
self.object:set_properties({
|
|
mesh = aliveai.character_model,
|
|
textures = {"aliveai_threats_pull.png"},
|
|
})
|
|
local pos=self.object:get_pos()
|
|
minetest.add_particlespawner({
|
|
amount = 5,
|
|
time =0.05,
|
|
minpos = pos,
|
|
maxpos = pos,
|
|
minvel = {x=-2, y=-2, z=-2},
|
|
maxvel = {x=1, y=0.5, z=1},
|
|
minacc = {x=0, y=-8, z=0},
|
|
maxacc = {x=0, y=-10, z=0},
|
|
minexptime = 2,
|
|
maxexptime = 1,
|
|
minsize = 0.1,
|
|
maxsize = 2,
|
|
texture = self.tex or "default_dirt.png",
|
|
collisiondetection = true,
|
|
})
|
|
self.tex=nil
|
|
if self.sleep or self.hide then self.abortsleep=true end
|
|
if self.hide or not self.fight then return end
|
|
if not self.ohp then self.ohp=self.object:get_hp()*0.8 return end
|
|
if self.ohp>self.object:get_hp() then
|
|
local pos=self.object:get_pos()
|
|
local n=minetest.get_node(pos)
|
|
if minetest.registered_nodes[n.name] and minetest.registered_nodes[n.name].walkable then return end
|
|
self.hide=true
|
|
self.ohp=nil
|
|
self.time=0.2
|
|
self.pull_down=nil
|
|
return self
|
|
end
|
|
end
|
|
})
|
|
|
|
minetest.register_craft({
|
|
output = "aliveai_threats:mind_manipulator",
|
|
recipe = {
|
|
{"default:steel_ingot", "default:papyrus"},
|
|
{"default:steel_ingot", "default:mese_crystal"},
|
|
{"default:steel_ingot", "default:obsidian_glass"},
|
|
}
|
|
})
|
|
|
|
minetest.register_tool("aliveai_threats:mind_manipulator", {
|
|
description = "Mind manipulator",
|
|
inventory_image = "aliveai_threats_mind_manipulator.png",
|
|
on_use = function(itemstack, user, pointed_thing)
|
|
if pointed_thing.type=="object" then
|
|
local ob=pointed_thing.ref
|
|
if ob:get_luaentity() and ob:get_luaentity().type and ob:get_luaentity().type=="monster" then
|
|
ob:get_luaentity().team="mind_manipulator" .. math.random(1,100)
|
|
elseif ob:get_luaentity() then
|
|
ob:get_luaentity().type="monster"
|
|
ob:get_luaentity().team="mind_manipulator" .. math.random(1,100)
|
|
ob:get_luaentity().attack_players=1
|
|
ob:get_luaentity().attacking=1
|
|
ob:get_luaentity().talking=0
|
|
ob:get_luaentity().light=0
|
|
ob:get_luaentity().building=0
|
|
ob:get_luaentity().fighting=1
|
|
ob:get_luaentity().attack_chance=2
|
|
ob:get_luaentity().temper=3
|
|
--support for other mobs
|
|
ob:get_luaentity().attack_type="dogfight"
|
|
ob:get_luaentity().reach=2
|
|
ob:get_luaentity().damage=3
|
|
ob:get_luaentity().view_range=10
|
|
ob:get_luaentity().walk_velocity= ob:get_luaentity().walk_velocity or 2
|
|
ob:get_luaentity().run_velocity= ob:get_luaentity().run_velocity or 2
|
|
elseif ob:is_player() then
|
|
ob:punch(ob,1,{full_punch_interval=1,damage_groups={fleshy=5}},nil)
|
|
ob:set_properties({
|
|
mesh = aliveai.character_model,
|
|
textures = {"aliveai_threats_mind_manipulator.png"}
|
|
})
|
|
if ob:get_hp()<=0 and aliveai.registered_bots["bot"] and aliveai.registered_bots["bot"].bot=="aliveai:bot" then
|
|
local tex=ob:get_properties().textures
|
|
local pos=ob:get_pos()
|
|
local m=minetest.add_entity(pos, "aliveai:bot")
|
|
m:get_luaentity().attack_chance=2
|
|
m:get_luaentity().type="monster"
|
|
m:get_luaentity().team="mind_manipulator" .. math.random(1,100)
|
|
m:get_luaentity().attack_players=1
|
|
m:get_luaentity().attacking=1
|
|
m:get_luaentity().talking=0
|
|
m:get_luaentity().light=0
|
|
m:get_luaentity().building=0
|
|
m:get_luaentity().fighting=1
|
|
m:set_yaw(math.random(0,6.28))
|
|
m:set_properties({
|
|
mesh = aliveai.character_model,
|
|
textures = tex
|
|
})
|
|
end
|
|
end
|
|
itemstack:add_wear(65536/10)
|
|
return itemstack
|
|
end
|
|
end
|
|
})
|
|
|
|
|
|
|
|
aliveai.create_bot({
|
|
description="The cloning bug, cloning itself and becomes a group, is very hard to eliminate.\nKeep youself away from them!",
|
|
drop_dead_body=0,
|
|
attack_players=1,
|
|
name="cockroach",
|
|
team="bug",
|
|
texture={"aliveai_threats_cockroach.png","aliveai_threats_cockroach.png","aliveai_threats_cockroach.png","aliveai_threats_cockroach.png","aliveai_threats_cockroach.png","aliveai_threats_cockroach.png"},
|
|
attacking=1,
|
|
talking=0,
|
|
light=0,
|
|
building=0,
|
|
escape=0,
|
|
type="monster",
|
|
dmg=1,
|
|
hp=4,
|
|
name_color="",
|
|
arm=2,
|
|
coming=0,
|
|
smartfight=0,
|
|
spawn_on={"group:sand","group:spreading_dirt_type","default:gravel","group:stone"},
|
|
attack_chance=2,
|
|
visual="cube",
|
|
visual_size={x=0.4,y=0.001},
|
|
collisionbox={-0.1,0,-0.1,0.2,0.1,0.2},
|
|
basey=0,
|
|
distance=10,
|
|
spawn_y=2,
|
|
on_load=function(self)
|
|
if self.save__clone then
|
|
self.object:remove()
|
|
end
|
|
end,
|
|
on_step=function(self,dtime)
|
|
if self.fight then
|
|
local pos=aliveai.roundpos(self.object:get_pos())
|
|
local n=0
|
|
for _, ob in ipairs(minetest.get_objects_inside_radius(pos, 20)) do
|
|
local en=ob:get_luaentity()
|
|
if en and en.name=="aliveai_threats:cockroach" then
|
|
n=n+1
|
|
end
|
|
end
|
|
if n<10 then
|
|
for y=-2,5,1 do
|
|
for x=-2,2,1 do
|
|
for z=-2,2,1 do
|
|
local p1={x=pos.x+x,y=pos.y+y,z=pos.z+z}
|
|
local p2={x=pos.x+x,y=pos.y+y-1,z=pos.z+z}
|
|
local no1=minetest.get_node(p1).name
|
|
local no2=minetest.get_node(p2).name
|
|
if not (minetest.registered_nodes[no1] and minetest.registered_nodes[no2]) then return end
|
|
if minetest.registered_nodes[no1].walkable==false and minetest.registered_nodes[no2].walkable
|
|
and aliveai.visiable(pos,p1) then
|
|
local e=minetest.add_entity(p1,"aliveai_threats:cockroach")
|
|
e:get_luaentity().save__clone=1
|
|
e:get_luaentity().fight=self.fight
|
|
e:get_luaentity().temper=3
|
|
e:set_yaw(math.random(0,6.28))
|
|
n=n+1
|
|
if n>=10 then
|
|
return
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
elseif self.save__clone and not self.fight then
|
|
aliveai.kill(self)
|
|
end
|
|
end,
|
|
click=function(self,clicker)
|
|
clicker:punch(self.object,1,{full_punch_interval=1,damage_groups={fleshy=self.object:get_hp()*2}},nil)
|
|
end,
|
|
death=function(self,puncher,pos)
|
|
local pos=self.object:get_pos()
|
|
minetest.add_particlespawner({
|
|
amount = 5,
|
|
time =0.05,
|
|
minpos = pos,
|
|
maxpos = pos,
|
|
minvel = {x=-2, y=-2, z=-2},
|
|
maxvel = {x=1, y=0.5, z=1},
|
|
minacc = {x=0, y=-8, z=0},
|
|
maxacc = {x=0, y=-10, z=0},
|
|
minexptime = 2,
|
|
maxexptime = 1,
|
|
minsize = 0.1,
|
|
maxsize = 1,
|
|
texture = "default_dirt.png^[colorize:#000000cc",
|
|
collisiondetection = true,
|
|
})
|
|
return self
|
|
end,
|
|
})
|
|
|
|
|
|
aliveai.create_bot({
|
|
description="Black ninjas always keeping its sword ready and makes it self invisible",
|
|
attack_players=1,
|
|
name="ninja",
|
|
team="bug",
|
|
texture="aliveai_threats_ninja.png",
|
|
attacking=1,
|
|
talking=0,
|
|
light=0,
|
|
building=0,
|
|
start_with_items={["default:sword_steel"]=1},
|
|
type="",
|
|
hp=30,
|
|
name_color="",
|
|
attack_chance=2,
|
|
on_step=function(self,dtime)
|
|
if not self.finvist and (self.fight or self.fly) then
|
|
self.finvist=true
|
|
self.object:set_properties({
|
|
is_visible=false,
|
|
makes_footstep_sound=false,
|
|
textures={"aliveai_threats_i.png","aliveai_threats_i.png","aliveai_threats_i.png"}
|
|
})
|
|
elseif self.finvist and not (self.fight or self.fight) then
|
|
self.finvist=nil
|
|
self.object:set_properties({
|
|
is_visible=true,
|
|
makes_footstep_sound=true,
|
|
textures={"aliveai_threats_ninja.png","aliveai_threats_i.png","aliveai_threats_i.png"}
|
|
})
|
|
elseif self.finvist and self.fight then
|
|
if math.random(1,10)<3 then
|
|
self.object:set_properties({is_visible=true})
|
|
else
|
|
self.object:set_properties({is_visible=false})
|
|
|
|
if math.random(1,5)==1 then
|
|
local pos=self.object:get_pos()
|
|
for _, ob in ipairs(minetest.get_objects_inside_radius(pos, self.distance/2)) do
|
|
local en=ob:get_luaentity()
|
|
if en and en.aliveai and en.fight and en.fight:get_luaentity() and en.fight:get_luaentity().aliveai and en.fight:get_luaentity().botname==self.botname then
|
|
ob:get_luaentity().fight=nil
|
|
end
|
|
end
|
|
end
|
|
|
|
end
|
|
end
|
|
end,
|
|
on_punched=function(self,puncher)
|
|
local pos=self.object:get_pos()
|
|
if self.finvist then
|
|
self.finvist=nil
|
|
self.object:set_properties({
|
|
is_visible=true,
|
|
makes_footstep_sound=true,
|
|
textures={"aliveai_threats_ninja.png","aliveai_threats_i.png","aliveai_threats_i.png"},
|
|
})
|
|
end
|
|
minetest.add_particlespawner({
|
|
amount = 5,
|
|
time =0.05,
|
|
minpos = pos,
|
|
maxpos = pos,
|
|
minvel = {x=-2, y=-2, z=-2},
|
|
maxvel = {x=1, y=0.5, z=1},
|
|
minacc = {x=0, y=-8, z=0},
|
|
maxacc = {x=0, y=-10, z=0},
|
|
minexptime = 2,
|
|
maxexptime = 1,
|
|
minsize = 0.1,
|
|
maxsize = 2,
|
|
texture = "default_dirt.png^[colorize:#000000cc",
|
|
collisiondetection = true,
|
|
})
|
|
end
|
|
})
|
|
|
|
minetest.register_tool("aliveai_threats:quantumcore", {
|
|
description = "Quantum core",
|
|
inventory_image = "aliveai_threats_quantumcore.png",
|
|
range = 15,
|
|
on_use=function(itemstack, user, pointed_thing)
|
|
if user:get_luaentity() then user=user:get_luaentity() end
|
|
local type=pointed_thing.type
|
|
if type=="node" or type=="object" then
|
|
local pos=pointed_thing.above
|
|
if type=="object" then
|
|
pos=pointed_thing.ref:get_pos()
|
|
end
|
|
local n1=minetest.registered_nodes[minetest.get_node(pos).name]
|
|
pos.y=pos.y+1
|
|
local n2=minetest.registered_nodes[minetest.get_node(pos).name]
|
|
if n1 and n2 and not (n1.walkable and n2.walkable) then
|
|
user:set_pos(pos)
|
|
end
|
|
else
|
|
local p=aliveai.random_pos(user:get_pos(),15)
|
|
if p then user:set_pos(p) end
|
|
end
|
|
|
|
end,
|
|
on_place=function(itemstack, user, pointed_thing)
|
|
local p=aliveai.random_pos(user:get_pos(),15)
|
|
if p then user:set_pos(p) end
|
|
end
|
|
})
|
|
|
|
aliveai.create_bot({
|
|
description="Teleporting monster that is hard to fight with",
|
|
attack_players=1,
|
|
name="quantum_monster",
|
|
team="bug",
|
|
texture="aliveai_threats_quantum_monster.png",
|
|
attacking=1,
|
|
talking=0,
|
|
light=0,
|
|
building=0,
|
|
start_with_items={["aliveai_threats:quantumcore"]=1},
|
|
type="",
|
|
hp=40,
|
|
name_color="",
|
|
visual_size={x=1,y=1.4},
|
|
collisionbox={-0.33,-1.3,-0.33,0.33,1.2,0.33},
|
|
spawn_y=1,
|
|
on_step=function(self,dtime)
|
|
if self.fight and not self.fly and (math.random(1,5)==1 or self.epunched) then
|
|
self.epunched=nil
|
|
local p=aliveai.roundpos(self.fight:get_pos())
|
|
if not p then self.fight=nil return end
|
|
local pos={x=p.x+math.random(-1,4),y=p.y,z=p.z+math.random(-1,4)}
|
|
for i=-2,2,1 do
|
|
local pos1={x=pos.x,y=pos.y+i,z=pos.z}
|
|
local pos2={x=pos.x,y=pos.y+i+1,z=pos.z}
|
|
local pos3={x=pos.x,y=pos.y+i+2,z=pos.z}
|
|
local pos4={x=pos.x,y=pos.y+i+3,z=pos.z}
|
|
|
|
local n1=minetest.registered_nodes[minetest.get_node(pos1).name]
|
|
local n2=minetest.registered_nodes[minetest.get_node(pos2).name]
|
|
local n3=minetest.registered_nodes[minetest.get_node(pos3).name]
|
|
local n4=minetest.registered_nodes[minetest.get_node(pos4).name]
|
|
|
|
if n2 and n2.walkable==false and n1 and n3 and n4 and n1.walkable and not (n3.walkable and n4.walkable) then
|
|
pos2.y=pos2.y+1
|
|
self.object:set_pos(pos2)
|
|
end
|
|
end
|
|
elseif self.fly and (self.epunched or aliveai.distance(self,self.fly:get_pos())<self.distance) then
|
|
self.epunched=nil
|
|
local p=aliveai.random_pos(self.fly:get_pos(),15)
|
|
if p then self.object:set_pos(p) end
|
|
end
|
|
|
|
local p=self.object:get_pos()
|
|
minetest.add_particlespawner({
|
|
amount = 20,
|
|
time =1,
|
|
minpos = {x=p.x+1,y=p.y+1,z=p.z+1},
|
|
maxpos = {x=p.x-1,y=p.y-1,z=p.z-1},
|
|
minvel = {x=0, y=0, z=0},
|
|
maxvel = {x=0, y=0, z=0},
|
|
minacc = {x=0, y=0, z=0},
|
|
maxacc = {x=0, y=0, z=0},
|
|
minexptime = 0.5,
|
|
maxexptime = 1,
|
|
minsize = 0.4,
|
|
maxsize = 0.8,
|
|
glow=13,
|
|
texture = "aliveai_threats_quantum_monster_lights.png",
|
|
})
|
|
|
|
end,
|
|
on_punched=function(self,puncher)
|
|
local pos=self.object:get_pos()
|
|
self.epunched=true
|
|
minetest.add_particlespawner({
|
|
amount = 5,
|
|
time =0.05,
|
|
minpos = pos,
|
|
maxpos = pos,
|
|
minvel = {x=-2, y=-2, z=-2},
|
|
maxvel = {x=1, y=0.5, z=1},
|
|
minacc = {x=0, y=-8, z=0},
|
|
maxacc = {x=0, y=-10, z=0},
|
|
minexptime = 2,
|
|
maxexptime = 1,
|
|
minsize = 0.1,
|
|
maxsize = 2,
|
|
texture = "default_dirt.png^[colorize:#000000cc",
|
|
collisiondetection = true,
|
|
})
|
|
end
|
|
})
|
|
|
|
minetest.register_globalstep(function(dtime)
|
|
for i, o in pairs(aliveai_threats.debris) do
|
|
if o.ob and o.ob:get_luaentity() and o.ob:get_hp()>0 and o.ob:get_velocity().y~=0 then
|
|
for ii, ob in pairs(minetest.get_objects_inside_radius(o.ob:get_pos(), 1.5)) do
|
|
local en=ob:get_luaentity()
|
|
if not en or (en.name~="__builtin:item" and not (en.aliveai and en.botname==o.n) ) then
|
|
ob:punch(o.ob,1,{full_punch_interval=1,damage_groups={fleshy=1}})
|
|
o.ob:set_velocity({x=0, y=0, z=0})
|
|
if o.on_hit_object then
|
|
o.on_hit_object(o.ob:get_luaentity(),o.ob:get_pos(),ob)
|
|
end
|
|
table.remove(aliveai_threats.debris,i)
|
|
break
|
|
end
|
|
end
|
|
else
|
|
|
|
if o and o.on_hit_ground and o.ob:get_velocity() and o.ob:get_velocity().y==0 then
|
|
o.on_hit_ground(o.ob:get_luaentity(),o.ob:get_pos())
|
|
end
|
|
table.remove(aliveai_threats.debris,i)
|
|
end
|
|
end
|
|
end)
|
|
|
|
|
|
aliveai.create_bot({
|
|
description="Camouflage monster, nodes become wherever it is",
|
|
attack_players=1,
|
|
name="natural_monster",
|
|
team="natural",
|
|
texture="aliveai_threats_natural_monster.png",
|
|
attacking=1,
|
|
talking=0,
|
|
light=0,
|
|
building=0,
|
|
type="monster",
|
|
hp=10,
|
|
name_color="",
|
|
collisionbox={-0.5,-0.5,-0.5,0.5,0.5,0.5},
|
|
visual="cube",
|
|
basey=-0.5,
|
|
drop_dead_body=0,
|
|
escape=0,
|
|
spawn_on={"group:sand","group:soil","default:snow","default:snowblock","default:ice","group:leaves","group:tree","group:stone","group:cracky","group:level","group:crumbly","group:choppy"},
|
|
attack_chance=2,
|
|
spawn_y=0,
|
|
spawn=function(self)
|
|
local pos=self.object:get_pos()
|
|
pos.y=pos.y-1.5
|
|
if minetest.get_node(pos).name=="aliveai:spawner" then pos.y=pos.y-1 end
|
|
local drop=minetest.get_node_drops(minetest.get_node(pos).name)[1]
|
|
local n=minetest.registered_nodes[minetest.get_node(pos).name]
|
|
if not (n and n.walkable) or drop=="" or type(drop)~="string" then self.object:remove() return self end
|
|
local t=n.tiles
|
|
if not t[1] then self.object:remove() return self end
|
|
local tx={}
|
|
self.save__t1=t[1]
|
|
self.save__t2=t[1]
|
|
self.save__t3=t[1]
|
|
self.save__natural_monster=1
|
|
self.save__consists=drop
|
|
self.team=self.save__consists
|
|
if t[2] then self.save__t2=t[2] self.save__t3=t[2] end
|
|
if t[3] and t[3].name then self.save__t3=t[3].name
|
|
elseif t[3] then self.save__t3=t[3]
|
|
end
|
|
if type(self.save__t3)=="table" then return end
|
|
tx[1]=self.save__t1
|
|
tx[2]=self.save__t2
|
|
tx[3]=self.save__t3
|
|
tx[4]=self.save__t3
|
|
tx[5]=self.save__t3 .."^aliveai_threats_natural_monster.png"
|
|
tx[6]=self.save__t3
|
|
self.object:set_properties({textures=tx})
|
|
self.cctime=0
|
|
end,
|
|
on_load=function(self)
|
|
if self.save__natural_monster then
|
|
local tx={}
|
|
tx[1]=self.save__t1
|
|
tx[2]=self.save__t2
|
|
tx[3]=self.save__t3
|
|
tx[4]=self.save__t3
|
|
tx[5]=self.save__t3 .."^aliveai_threats_natural_monster.png"
|
|
tx[6]=self.save__t3
|
|
self.object:set_properties({textures=tx})
|
|
self.team=self.save__consists
|
|
self.cctime=0
|
|
else
|
|
self.object:remove()
|
|
end
|
|
end,
|
|
on_step=function(self,dtime)
|
|
if self.fight and (self.cctime<1 or self.time==self.otime) then
|
|
self.cctime=5
|
|
local d=aliveai.distance(self,self.fight:get_pos())
|
|
if not (d>4 and d<self.distance and aliveai.viewfield(self,self.fight) and aliveai.visiable(self,self.fight:get_pos())) then return end
|
|
local pos=self.object:get_pos()
|
|
local ta=self.fight:get_pos()
|
|
if not (ta and pos) then return end
|
|
aliveai.stand(self)
|
|
aliveai.lookat(self,ta)
|
|
|
|
local e=minetest.add_item({x=pos.x,y=pos.y,z=pos.z},self.save__consists)
|
|
local dir=aliveai.get_dir(self,ta)
|
|
local vc = {x = dir.x*30, y = dir.y*30, z = dir.z*30}
|
|
e:set_velocity(vc)
|
|
|
|
e:get_luaentity().age=(tonumber(minetest.settings:get("item_entity_ttl")) or 900)-2
|
|
table.insert(aliveai_threats.debris,{ob=e,n=self.botname})
|
|
return self
|
|
elseif self.fight and self.cctime>1 then
|
|
self.cctime=self.cctime-1
|
|
end
|
|
end,
|
|
death=function(self,puncher,pos)
|
|
aliveai.invadd(self,self.save__consists,math.random(1, 4),false)
|
|
end,
|
|
on_punched=function(self,puncher)
|
|
local pos=self.object:get_pos()
|
|
aliveai.lookat(self,pos)
|
|
minetest.add_particlespawner({
|
|
amount = 5,
|
|
time =0.05,
|
|
minpos = pos,
|
|
maxpos = pos,
|
|
minvel = {x=-2, y=-2, z=-2},
|
|
maxvel = {x=1, y=0.5, z=1},
|
|
minacc = {x=0, y=-8, z=0},
|
|
maxacc = {x=0, y=-10, z=0},
|
|
minexptime = 2,
|
|
maxexptime = 1,
|
|
minsize = 0.2,
|
|
maxsize = 4,
|
|
texture = self.save__t1,
|
|
collisiondetection = true,
|
|
})
|
|
end
|
|
})
|
|
|
|
aliveai.create_bot({
|
|
description="This monster is stubborn more than the limit, it can be killed but survive many times",
|
|
type="monster",
|
|
name="stubborn_monster",
|
|
texture="aliveai_threats_stubborn_monster.png",
|
|
hp=20,
|
|
drop_dead_body=0,
|
|
usearmor=0,
|
|
on_load=function(self)
|
|
self.save__hp_max=self.save__hp_max or 20
|
|
if not self.save__body or self.save__killed then self.spawn(self) return self end
|
|
local s={}
|
|
local c=""
|
|
local t=""
|
|
for i,v in ipairs(self.save__body) do
|
|
s["s"..v]=v
|
|
if i>1 then c="^" end
|
|
t=t .. c.. "aliveai_threats_stubborn_monster" .. v ..".png"
|
|
end
|
|
self.object:set_properties({
|
|
mesh = aliveai.character_model,
|
|
textures = {t,"aliveai_threats_i.png","aliveai_threats_i.png"},
|
|
})
|
|
if not s["s3"] then self.nhead=true end
|
|
self.spawn(self)
|
|
end,
|
|
spawn=function(self)
|
|
if not self.save__body then
|
|
self.save__body={1,2,3}
|
|
end
|
|
self.save__hp_max=self.save__hp_max or 20
|
|
self.hp2=self.object:get_hp()
|
|
self.deadtimer=10
|
|
self.hurted=0
|
|
if self.save__killed then
|
|
self.attack_players=1
|
|
self.attacking=1
|
|
self.team="stubborn"
|
|
self.talking=0
|
|
self.light=0
|
|
self.building=0
|
|
self.type="monster"
|
|
self.escape=0
|
|
self.attack_chance=1
|
|
self.smartfight=0
|
|
end
|
|
|
|
end,
|
|
on_step=function(self,dtime)
|
|
if self.dead1 then
|
|
self.time=self.otime
|
|
self.deadtimer=self.deadtimer-1
|
|
if self.deadtimer<0 then
|
|
self.object:punch(self.object,1,{full_punch_interval=1,damage_groups={fleshy=self.hp*2}},nil)
|
|
end
|
|
return self
|
|
end
|
|
if self.lay then
|
|
self.time=self.otime
|
|
if math.random(0,5)==1 then
|
|
aliveai.anim(self,"stand")
|
|
self.lay=nil
|
|
end
|
|
return self
|
|
end
|
|
if self.nhead then
|
|
self.fight=nil
|
|
self.fly=nil
|
|
self.temper=0
|
|
self.come=nil
|
|
end
|
|
end,
|
|
on_punched=function(self,puncher,h)
|
|
self.hurted=h
|
|
end,
|
|
death=function(self,puncher,pos)
|
|
local r=math.random(1,5)
|
|
if r>3 then
|
|
if self.basey==-0.5 then local pos=self.object:get_pos() self.object:set_pos({x=pos.x,y=pos.y+1,z=pos.z}) end
|
|
aliveai.anim(self,"lay")
|
|
self.lay=true
|
|
end
|
|
if r<3 or not self.save__killed then
|
|
r=math.random(1,3)
|
|
table.remove(self.save__body,r)
|
|
local t=""
|
|
local c=""
|
|
local c2=0
|
|
for i,v in ipairs(self.save__body) do
|
|
if i>1 then c="^" end
|
|
t=t .. c.. "aliveai_threats_stubborn_monster" .. v ..".png"
|
|
c2=i
|
|
end
|
|
self.object:set_properties({
|
|
mesh = aliveai.character_model,
|
|
textures = {t,"aliveai_threats_i.png","aliveai_threats_i.png"},
|
|
})
|
|
if r==1 or c2==1 or self.hurted>self.save__hp_max then
|
|
if self.basey==-0.5 then self.object:set_properties({mesh = aliveai.character_model}) local pos=self.object:get_pos() self.object:set_pos({x=pos.x,y=pos.y+1,z=pos.z}) end
|
|
aliveai.anim(self,"lay")
|
|
self.object:set_hp(self.save__hp_max)
|
|
self.hp=self.save__hp_max
|
|
self.dead1=true
|
|
return self
|
|
end
|
|
if r==3 then self.nhead=true end
|
|
if not self.save__killed then
|
|
self.save__killed=1
|
|
self.spawn(self)
|
|
end
|
|
end
|
|
if not self.dead1 then
|
|
self.save__hp_max=self.save__hp_max-2
|
|
self.object:set_hp(self.save__hp_max)
|
|
self.hp=self.save__hp_max
|
|
end
|
|
end
|
|
})
|
|
|
|
|
|
aliveai.create_bot({
|
|
description="Slim monsters is killing eveything and thrive in them, spreads quickly",
|
|
drop_dead_body=0,
|
|
attack_players=1,
|
|
name="slime",
|
|
team="slime",
|
|
texture="aliveai_threats_slime.png",
|
|
attacking=1,
|
|
talking=0,
|
|
light=0,
|
|
building=0,
|
|
escape=0,
|
|
start_with_items={["aliveai_threats:slime"]=2},
|
|
type="monster",
|
|
dmg=2,
|
|
hp=10,
|
|
name_color="",
|
|
on_punch_hit=function(self,target)
|
|
if self.setslime and aliveai.gethp(target)<1 then
|
|
local e=minetest.add_entity(self.setslime, "aliveai_threats:slime")
|
|
if self.fight and self.fight:get_luaentity() then
|
|
e:set_properties({
|
|
visual_size=target:get_properties().visual_size,
|
|
collisionbox=target:get_properties().collisionbox
|
|
})
|
|
if aliveai.is_bot(self.fight) then
|
|
aliveai.anim(self.fight:get_luaentity(),"lay")
|
|
end
|
|
self.setslime=nil
|
|
self.fight:remove()
|
|
self.fight=nil
|
|
end
|
|
end
|
|
end,
|
|
on_punching=function(self,target)
|
|
self.setslime=target:get_pos()
|
|
end,
|
|
death=function(self,puncher,pos)
|
|
minetest.add_particlespawner({
|
|
amount = 15,
|
|
time =0.1,
|
|
minpos = pos,
|
|
maxpos = pos,
|
|
minvel = {x=-2, y=-2, z=-2},
|
|
maxvel = {x=2, y=2, z=2},
|
|
minacc = {x=0, y=-8, z=0},
|
|
maxacc = {x=0, y=-10, z=0},
|
|
minexptime = 2,
|
|
maxexptime = 1,
|
|
minsize = 0.1,
|
|
maxsize = 3,
|
|
texture = "default_dirt.png^[colorize:#00aa00aa",
|
|
collisiondetection = true,
|
|
})
|
|
end,
|
|
})
|
|
|
|
minetest.register_node("aliveai_threats:slime", {
|
|
description = "Slime",
|
|
tiles = {"default_river_water.png^[colorize:#00aa00aa"},
|
|
alpha = 200,
|
|
walkable = false,
|
|
pointable = true,
|
|
drowning = 1,
|
|
buildable_to = true,
|
|
drawtype = "glasslike",
|
|
post_effect_color = {a = 248, r =0, g = 255, b = 0},
|
|
damage_per_second = 1,
|
|
paramtype = "light",
|
|
liquid_viscosity = 15,
|
|
liquidtype = "source",
|
|
liquid_range = 0,
|
|
liquid_alternative_flowing = "aliveai_threats:slime",
|
|
liquid_alternative_source = "aliveai_threats:slime",
|
|
groups = {liquid = 4,crumbly = 1,not_in_creative_inventory=1}
|
|
})
|
|
|
|
aliveai.create_bot({
|
|
description="A block who is catching everything reachable",
|
|
name="killerplant",
|
|
type="node",
|
|
team="killerplants",
|
|
hp=1,
|
|
mindamage=1,
|
|
texture="default_grass_5.png^[colorize:#00ff0022",
|
|
talking=0,
|
|
light=0,
|
|
building=0,
|
|
name_color="",
|
|
collisionbox={-0.5,-0.5,-0.5,0.5,0.5,0.5},
|
|
visual="cube",
|
|
basey=-0.5,
|
|
drop_dead_body=0,
|
|
spawn_on={"group:sand","group:soil","group:stone","group:cracky","group:level","group:crumbly","group:choppy"},
|
|
spawn_y=0,
|
|
spawn=function(self)
|
|
local pos=self.object:get_pos()
|
|
if pos then
|
|
local opos=pos
|
|
for i=0,10,1 do
|
|
if aliveai.def({x=pos.x,y=pos.y-i,z=pos.z,},"walkable") and not minetest.is_protected(opos,"") then
|
|
minetest.set_node(opos,{name="aliveai_threats:killerplant"})
|
|
aliveai.kill(self)
|
|
return
|
|
end
|
|
opos={x=pos.x,y=pos.y-i,z=pos.z,}
|
|
end
|
|
end
|
|
aliveai.kill(self)
|
|
end,
|
|
})
|
|
|
|
|
|
minetest.register_node("aliveai_threats:killerplant", {
|
|
description = "Killerplant",
|
|
groups = {attached_node=1,choppy = 1,aliveai=1,not_in_creative_inventory=1},
|
|
tiles = {"default_grass_5.png^[colorize:#00ff0022"},
|
|
paramtype="light",
|
|
walkable=false,
|
|
sounds = default.node_sound_leaves_defaults(),
|
|
drawtype = "plantlike",
|
|
selection_box = {
|
|
type = "fixed",
|
|
fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5}
|
|
},
|
|
on_construct = function(pos)
|
|
local meta=minetest.get_meta(pos)
|
|
meta:set_string("owner","plant")
|
|
minetest.get_node_timer(pos):start(3)
|
|
end,
|
|
on_timer = function (pos, elapsed)
|
|
for i, ob in pairs(minetest.get_objects_inside_radius({x=pos.x,y=pos.y-2.5,z=pos.z}, 2)) do
|
|
ob:punch(ob,1,{full_punch_interval=1,damage_groups={fleshy=1}})
|
|
end
|
|
for i, ob in pairs(minetest.get_objects_inside_radius(pos, 1.5)) do
|
|
minetest.sound_play("default_grass_footstep", {pos=pos,max_hear_distance = 10, gain = 0.5})
|
|
ob:move_to({x=pos.x,y=pos.y-3,z=pos.z})
|
|
end
|
|
return true
|
|
end,
|
|
})
|
|
|
|
|
|
aliveai.create_bot({
|
|
description="Aggressive bee",
|
|
attack_players=1,
|
|
name="bee",
|
|
team="bug",
|
|
floating=1,
|
|
texture={"aliveai_threats_bee.png","aliveai_threats_bee.png","aliveai_threats_bee.png","aliveai_threats_bee.png","aliveai_threats_bee.png","aliveai_threats_bee.png"},
|
|
attacking=1,
|
|
talking=0,
|
|
light=0,
|
|
building=0,
|
|
type="monster",
|
|
hp=2,
|
|
name_color="",
|
|
collisionbox={-0.2,-0.2,-0.2,0.2,0.2,0.2},
|
|
visual_size={x=0.1,y=0.1},
|
|
visual="cube",
|
|
basey=-0.5,
|
|
drop_dead_body=0,
|
|
escape=0,
|
|
spawn_on={"group:sand","group:soil","default:snow","default:snowblock","default:ice","group:leaves","group:tree","group:stone","group:cracky","group:level","group:crumbly","group:choppy"},
|
|
attack_chance=2,
|
|
spawn_y=0,
|
|
death=function(self,puncher,pos)
|
|
minetest.add_particlespawner({
|
|
amount = 5,
|
|
time =0.05,
|
|
minpos = pos,
|
|
maxpos = pos,
|
|
minvel = {x=-2, y=-2, z=-2},
|
|
maxvel = {x=1, y=0.5, z=1},
|
|
minacc = {x=0, y=-8, z=0},
|
|
maxacc = {x=0, y=-10, z=0},
|
|
minexptime = 2,
|
|
maxexptime = 1,
|
|
minsize = 0.2,
|
|
maxsize = 1,
|
|
texture ="aliveai_threats_bee.png",
|
|
collisiondetection = true,
|
|
})
|
|
end
|
|
})
|
|
|
|
|
|
|
|
|
|
minetest.register_tool("aliveai_threats:quake_core", {
|
|
description = "Quake core",
|
|
inventory_image = "default_dirt.png",
|
|
on_use=function(itemstack, user, pointed_thing)
|
|
if user:get_luaentity() then user=user:get_luaentity() end
|
|
local type=pointed_thing.type
|
|
local pos1=user:get_pos()
|
|
pos1.y=pos1.y+1.5
|
|
local pos2
|
|
if type=="object" then
|
|
pos2=pointed_thing.ref:get_pos()
|
|
elseif type=="node" then
|
|
pos2=pointed_thing.under
|
|
elseif type=="nothing" then
|
|
local dir
|
|
if user:get_luaentity() then
|
|
if user:get_luaentity().aliveai and user:get_luaentity().fight then
|
|
local dir=aliveai.get_dir(user:get_luaentity(),user:get_luaentity().fight)
|
|
pos2={x=pos1.x+(dir.x*15),y=pos1.y+(dir.y*15),z=pos1.z+(dir.z*15)}
|
|
else
|
|
pos2=aliveai.pointat(user:get_luaentity(),15)
|
|
end
|
|
else
|
|
local dir=user:get_look_dir()
|
|
pos2={x=pos1.x+(dir.x*15),y=pos1.y+(dir.y*15),z=pos1.z+(dir.z*15)}
|
|
end
|
|
else
|
|
return itemstack
|
|
end
|
|
|
|
local n=minetest.get_node(pos1).name
|
|
if minetest.registered_nodes[n] and minetest.registered_nodes[n].walkable then return end
|
|
aliveai_threats.quake(pos1,pos2)
|
|
itemstack:add_wear(65535/50)
|
|
return itemstack
|
|
end,
|
|
})
|
|
|
|
|
|
aliveai_threats.quake=function(pos1,pos2)
|
|
if aliveai_threats.n>20 then return end
|
|
aliveai_threats.n=aliveai_threats.n+1
|
|
local d=math.floor(aliveai.distance(pos1,pos2)+0.5)
|
|
local dir={x=(pos1.x-pos2.x)/-d,y=(pos1.y-pos2.y)/-d,z=(pos1.z-pos2.z)/-d}
|
|
local p1
|
|
local p2
|
|
local i1=1
|
|
local ii=15
|
|
for i=1,d,1 do
|
|
ii=i
|
|
p1={x=pos1.x+(dir.x*i),y=pos1.y,z=pos1.z+(dir.z*i)}
|
|
p2={x=p1.x+math.random(-1,1),y=pos1.y,z=p1.z+math.random(-1,1)}
|
|
if not p1.x or p1.x~=p1.x or not p2.x or p2.x~=p2.x then
|
|
return
|
|
end
|
|
aliveai_threats.quaking(p2,i,i1)
|
|
aliveai_threats.quaking(p1,i,i1)
|
|
i1=i1+1
|
|
if i1>3 then i1=1 end
|
|
end
|
|
minetest.after((ii*0.1)+10, function()
|
|
aliveai_threats.n=aliveai_threats.n-1
|
|
end)
|
|
|
|
end
|
|
|
|
aliveai_threats.close=function(re,i1,lo)
|
|
for i, p in pairs(re) do
|
|
if aliveai.def(p.p,"buildable_to") then
|
|
minetest.set_node(p.p,{name=p.n})
|
|
end
|
|
end
|
|
|
|
if lo>7 and re[#re] and (i1==1 or lo<25) then
|
|
for _, ob in ipairs(minetest.get_objects_inside_radius(re[#re].p, 3)) do
|
|
ob:punch(ob,20,{full_punch_interval=1,damage_groups={fleshy=9000}})
|
|
end
|
|
end
|
|
end
|
|
|
|
aliveai_threats.quaking=function(pos,i2,i1)
|
|
local pos2
|
|
local s
|
|
local re={}
|
|
for i=0,-30,-1 do
|
|
pos2={x=pos.x,y=pos.y+i,z=pos.z}
|
|
if aliveai.def(pos2,"is_ground_content") and
|
|
minetest.get_item_group(minetest.get_node(pos2).name, "cracky")~=0 or
|
|
minetest.get_item_group(minetest.get_node(pos2).name, "soil")~=0 and
|
|
minetest.is_protected(pos2,"")==false then
|
|
|
|
table.insert(re,{n=minetest.get_node(pos2).name,p=pos2})
|
|
|
|
if s then
|
|
s=s+1
|
|
minetest.set_node(pos2,{name="air"})
|
|
else
|
|
s=0
|
|
minetest.after(i2*0.1, function(pos2)
|
|
minetest.set_node(pos2,{name="air"})
|
|
end, pos2)
|
|
end
|
|
elseif s then
|
|
minetest.after((i2*0.1)+10, function(re)
|
|
aliveai_threats.close(re,i1,s)
|
|
end, re)
|
|
return
|
|
end
|
|
end
|
|
if s then
|
|
minetest.after((i2*0.1)+10, function(re)
|
|
aliveai_threats.close(re,i1,s)
|
|
end, re)
|
|
end
|
|
end
|
|
|
|
aliveai.create_bot({
|
|
description="Creates deep cracks in the ground, everything that falls down will be destroyed",
|
|
attack_players=1,
|
|
name="quake",
|
|
team="quak",
|
|
texture="default_dirt.png",
|
|
stealing=1,
|
|
steal_chanse=2,
|
|
attacking=1,
|
|
talking=0,
|
|
light=0,
|
|
building=0,
|
|
escape=0,
|
|
start_with_items={["default:dirt"]=5,["default:stone"]=5,["aliveai_threats:quake_core"]=1},
|
|
type="monster",
|
|
dmg=1,
|
|
hp=40,
|
|
name_color="",
|
|
spawn_on={"group:sand","group:soail","default:stone"},
|
|
tool_near=1,
|
|
tool_chance=2
|
|
})
|
|
|
|
|
|
|
|
aliveai.create_bot({
|
|
description="Everyone's nightmare, worse than the pull monster, pulls down everything in its way, and spreads pull monsters around its enemies",
|
|
attack_players=1,
|
|
name="pull_master_monster",
|
|
team="pull",
|
|
texture="aliveai_threats_pull.png^[colorize:#00000044",
|
|
attacking=1,
|
|
talking=0,
|
|
light=-1,
|
|
lowest_light=9,
|
|
building=0,
|
|
smartfight=0,
|
|
escape=0,
|
|
type="monster",
|
|
dmg=5,
|
|
hp=200,
|
|
arm=5,
|
|
name_color="",
|
|
spawn_on={"group:sand","group:spreading_dirt_type","group:stone","default:snow"},
|
|
attack_chance=3,
|
|
spawn_y=1,
|
|
visual_size={x=2,y=1.5},
|
|
collisionbox={-0.7,-1.5,-0.7,0.7,1.2,0.7},
|
|
start_with_items={["default:mese_crystal"]=1,["aliveai:relive"]=2},
|
|
on_punching=function(self,target)
|
|
local pos=aliveai.roundpos(target:get_pos())
|
|
local n
|
|
for i=-2,-6,-1 do
|
|
n=minetest.registered_nodes[minetest.get_node({x=pos.x,y=pos.y+i,z=pos.z}).name]
|
|
if n and n.walkable==false then
|
|
return
|
|
end
|
|
end
|
|
pos.y=pos.y-4
|
|
target:set_pos(pos)
|
|
if minetest.is_protected(pos,"")==false then
|
|
minetest.set_node(pos,{name="aliveai_threats:slime"})
|
|
end
|
|
end,
|
|
on_step=function(self,dtime)
|
|
if self.fight and math.random(1,20)==1 then
|
|
local c=0
|
|
for _, ob in ipairs(aliveai.active) do
|
|
local en=ob:get_luaentity()
|
|
if en and en.name=="aliveai_threats:pull_monster" then
|
|
if en.lifetimer and en.lifetimer<aliveai.lifetimer/2 then
|
|
aliveai.kill(en)
|
|
else
|
|
c=c+1
|
|
if c>20 then return end
|
|
end
|
|
end
|
|
end
|
|
|
|
for i=0,math.random(2,10),1 do
|
|
local p=aliveai.random_pos(self,5,10)
|
|
if p then
|
|
local n
|
|
local p1=1
|
|
for i=-2,-5,-1 do
|
|
n=minetest.registered_nodes[minetest.get_node({x=p.x,y=p.y+i,z=p.z}).name]
|
|
if n and n.walkable==false then
|
|
p1=nil
|
|
end
|
|
end
|
|
if p1 then
|
|
p.y=p.y-3
|
|
local en=minetest.add_entity(p, "aliveai_threats:pull_monster"):get_luaentity()
|
|
en.temper=2
|
|
en.fight=self.fight
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end,
|
|
on_punched=function(self,puncher)
|
|
self.object:set_properties({
|
|
mesh = aliveai.character_model,
|
|
textures = {"aliveai_threats_pull.png"},
|
|
})
|
|
local pos=self.object:get_pos()
|
|
minetest.add_particlespawner({
|
|
amount = 5,
|
|
time =0.05,
|
|
minpos = pos,
|
|
maxpos = pos,
|
|
minvel = {x=-2, y=-2, z=-2},
|
|
maxvel = {x=1, y=0.5, z=1},
|
|
minacc = {x=0, y=-8, z=0},
|
|
maxacc = {x=0, y=-10, z=0},
|
|
minexptime = 2,
|
|
maxexptime = 1,
|
|
minsize = 0.1,
|
|
maxsize = 2,
|
|
texture = self.tex or "default_dirt.png",
|
|
collisiondetection = true,
|
|
})
|
|
self.tex=nil
|
|
if self.sleep or self.hide then self.abortsleep=true end
|
|
if self.hide or not self.fight then return end
|
|
if not self.ohp then self.ohp=self.object:get_hp()*0.8 return end
|
|
if self.ohp>self.object:get_hp() then
|
|
local pos=self.object:get_pos()
|
|
local n=minetest.get_node(pos)
|
|
if minetest.registered_nodes[n.name] and minetest.registered_nodes[n.name].walkable then return end
|
|
self.hide=true
|
|
self.ohp=nil
|
|
self.time=0.2
|
|
self.pull_down=nil
|
|
return self
|
|
end
|
|
end,
|
|
death=function(self,puncher,pos)
|
|
if not self.ex then
|
|
self.ex=1
|
|
aliveai_nitroglycerine.explode(pos)
|
|
minetest.after(1, function(self)
|
|
if self and self.ex then self.ex=nil end
|
|
end,self)
|
|
end
|
|
return self
|
|
end,
|
|
})
|
|
|
|
|
|
aliveai.create_bot({
|
|
description="A very narrow monster",
|
|
attack_players=1,
|
|
name="stick_man",
|
|
team="bug",
|
|
texture="aliveai_threats_ninja.png",
|
|
attacking=1,
|
|
talking=0,
|
|
light=0,
|
|
building=0,
|
|
hp=15,
|
|
name_color="",
|
|
visual_size={x=0.2,y=1},
|
|
type="monster",
|
|
on_punched=function(self,puncher)
|
|
local pos=self.object:get_pos()
|
|
if self.finvist then
|
|
self.finvist=nil
|
|
self.object:set_properties({
|
|
is_visible=true,
|
|
makes_footstep_sound=true,
|
|
textures={"aliveai_threats_ninja.png","aliveai_threats_i.png","aliveai_threats_i.png"},
|
|
})
|
|
end
|
|
minetest.add_particlespawner({
|
|
amount = 5,
|
|
time =0.05,
|
|
minpos = pos,
|
|
maxpos = pos,
|
|
minvel = {x=-2, y=-2, z=-2},
|
|
maxvel = {x=1, y=0.5, z=1},
|
|
minacc = {x=0, y=-8, z=0},
|
|
maxacc = {x=0, y=-10, z=0},
|
|
minexptime = 2,
|
|
maxexptime = 1,
|
|
minsize = 0.1,
|
|
maxsize = 2,
|
|
texture = "default_dirt.png^[colorize:#000000cc",
|
|
collisiondetection = true,
|
|
})
|
|
end
|
|
})
|
|
|
|
aliveai.create_bot({
|
|
description="Flying terminator grabs its enemies and drags them up to the sky and drops them",
|
|
attack_players=1,
|
|
name="bronze_terminator",
|
|
team="nuke",
|
|
texture="aliveai_threats_terminator_bronze.png",
|
|
attacking=1,
|
|
talking=0,
|
|
light=0,
|
|
building=0,
|
|
escape=0,
|
|
start_with_items={["default:bronze_ingot"]=4,["default:bronzeblock"]=1},
|
|
type="monster",
|
|
dmg=5,
|
|
hp=200,
|
|
arm=2,
|
|
name_color="",
|
|
spawn_on={"group:sand","group:spreading_dirt_type","default:gravel","group:stone"},
|
|
attack_chance=5,
|
|
floating=1,
|
|
mindamage=5,
|
|
on_punching=function(self,target)
|
|
if not self.att and self.object:get_velocity().y==0 then
|
|
self.att=target
|
|
self.att:set_attach(self.object, "", {x=0,y=0,z=0}, {x=0,y=2,z=0})
|
|
self.att_pos=self.object:get_pos()
|
|
self.controlled=1
|
|
self.att_a=self.att:get_acceleration()
|
|
end
|
|
end,
|
|
on_step=function(self,dtime)
|
|
if self.att then
|
|
self.object:set_velocity({x=math.random(-3,3), y=10, z=math.random(-3,3)})
|
|
aliveai.punch(self,self.att)
|
|
if self.object:get_pos().y-self.att_pos.y>40 then
|
|
self.att:set_detach()
|
|
minetest.after(0.5, function(self)
|
|
if self.att then
|
|
self.att:set_acceleration(self.att_a)
|
|
self.att=nil
|
|
end
|
|
self.object:set_pos(self.att_pos)
|
|
self.controlled=nil
|
|
end,self)
|
|
end
|
|
|
|
end
|
|
end,
|
|
on_punched=function(self,puncher)
|
|
local pos=self.object:get_pos()
|
|
minetest.add_particlespawner({
|
|
amount = 5,
|
|
time =0.05,
|
|
minpos = pos,
|
|
maxpos = pos,
|
|
minvel = {x=-2, y=-2, z=-2},
|
|
maxvel = {x=1, y=0.5, z=1},
|
|
minacc = {x=0, y=-8, z=0},
|
|
maxacc = {x=0, y=-10, z=0},
|
|
minexptime = 2,
|
|
maxexptime = 1,
|
|
minsize = 0.1,
|
|
maxsize = 2,
|
|
texture = "default_bronze_block.png",
|
|
collisiondetection = true,
|
|
spawn_chance=100,
|
|
})
|
|
end,
|
|
death=function(self,puncher,pos)
|
|
aliveai.floating(self)
|
|
if self.att then
|
|
self.att:set_detach()
|
|
end
|
|
end
|
|
|
|
|
|
})
|
|
|
|
aliveai.create_bot({
|
|
description="camouflage monsters are hidden among nodes, but constantly jumping",
|
|
attack_players=1,
|
|
name="jumper",
|
|
team="natural",
|
|
texture="default_dirt.png^aliveai_threats_eyes.png",
|
|
talking=0,
|
|
light=0,
|
|
building=0,
|
|
type="monster",
|
|
hp=10,
|
|
dmg=2,
|
|
name_color="",
|
|
collisionbox={-0.5,-0.5,-0.5,0.5,0.5,0.5},
|
|
visual="cube",
|
|
basey=-0.5,
|
|
drop_dead_body=0,
|
|
escape=0,
|
|
spawn_on={"group:sand","group:soil","default:snow","default:snowblock","default:ice","group:leaves","group:tree","group:stone","group:cracky","group:level","group:crumbly","group:choppy"},
|
|
attack_chance=2,
|
|
spawn_y=0,
|
|
smartfight=0,
|
|
spawn=function(self)
|
|
local pos=self.object:get_pos()
|
|
pos.y=pos.y-1.5
|
|
if minetest.get_node(pos).name=="aliveai:spawner" then pos.y=pos.y-1 end
|
|
local drop=minetest.get_node_drops(minetest.get_node(pos).name)[1]
|
|
local n=minetest.registered_nodes[minetest.get_node(pos).name]
|
|
if not (n and n.walkable) or drop=="" or type(drop)~="string" then self.object:remove() return self end
|
|
local t=n.tiles
|
|
if not t[1] then self.object:remove() return self end
|
|
local tx={}
|
|
self.t1=t[1]
|
|
self.t2=t[1]
|
|
self.t3=t[1]
|
|
self.natural_monster=1
|
|
self.consists=drop
|
|
self.team=self.consists
|
|
if t[2] then self.t2=t[2] self.t3=t[2] end
|
|
if t[3] and t[3].name then self.t3=t[3].name
|
|
elseif t[3] then self.t3=t[3]
|
|
end
|
|
if type(self.t3)=="table" then return end
|
|
|
|
tx[1]=self.t1
|
|
tx[2]=self.t2
|
|
tx[3]=self.t3
|
|
tx[4]=self.t3
|
|
tx[5]=self.t3 .."^aliveai_threats_eyes.png"
|
|
tx[6]=self.t3
|
|
|
|
self.object:set_properties({textures=tx})
|
|
self.textxs=tx
|
|
self.jtimer=0
|
|
end,
|
|
on_load=function(self)
|
|
if self.natural_monster then
|
|
local tx={}
|
|
tx[1]=self.t1
|
|
tx[2]=self.t2
|
|
tx[3]=self.t3
|
|
tx[4]=self.t3
|
|
tx[5]=self.t3 .."^aliveai_threats_eyes.png"
|
|
tx[6]=self.t3
|
|
self.object:set_properties({textures=tx})
|
|
self.team=self.consists
|
|
self.textxs=tx
|
|
else
|
|
self.object:remove()
|
|
end
|
|
self.jtimer=0
|
|
end,
|
|
on_step=function(self,dtime)
|
|
local v=self.object:get_velocity()
|
|
if self.jtimer>1 and v.y==0 then
|
|
aliveai.jump(self)
|
|
self.jtimer=0
|
|
else
|
|
self.jtimer=self.jtimer+1
|
|
end
|
|
if self.fight and not self.fight_before then
|
|
local t=self.textxs
|
|
t[5]=self.t3 .."^aliveai_threats_eyes_mad.png"
|
|
self.object:set_properties({textures=t})
|
|
self.fight_before=1
|
|
elseif not self.fight and self.fight_before then
|
|
local t=self.textxs
|
|
t[5]=self.t3 .."^aliveai_threats_eyes.png"
|
|
self.object:set_properties({textures=t})
|
|
self.fight_before=nil
|
|
end
|
|
end,
|
|
death=function(self,puncher,pos)
|
|
aliveai.invadd(self,self.consists,math.random(1, 4),false)
|
|
end,
|
|
on_punched=function(self,puncher)
|
|
local pos=self.object:get_pos()
|
|
aliveai.lookat(self,pos)
|
|
minetest.add_particlespawner({
|
|
amount = 5,
|
|
time =0.05,
|
|
minpos = pos,
|
|
maxpos = pos,
|
|
minvel = {x=-2, y=-2, z=-2},
|
|
maxvel = {x=1, y=0.5, z=1},
|
|
minacc = {x=0, y=-8, z=0},
|
|
maxacc = {x=0, y=-10, z=0},
|
|
minexptime = 2,
|
|
maxexptime = 1,
|
|
minsize = 0.2,
|
|
maxsize = 4,
|
|
texture = self.t1,
|
|
collisiondetection = true,
|
|
})
|
|
end
|
|
})
|
|
|
|
aliveai_threats.acid=function(ob)
|
|
if aliveai.gethp(ob,1)<1 then return end
|
|
|
|
if ob:is_player() and aliveai_threats.stopacidplayer[ob:get_player_name()] then
|
|
return
|
|
end
|
|
|
|
local pos=ob:get_pos()
|
|
minetest.add_particlespawner({
|
|
amount = 3,
|
|
time =0.1,
|
|
minpos = pos,
|
|
maxpos = pos,
|
|
minvel = {x=-1, y=-1, z=-1},
|
|
maxvel = {x=1, y=-1, z=1},
|
|
minacc = {x=0, y=-9, z=0},
|
|
maxacc = {x=0, y=-10, z=0},
|
|
minexptime = 2,
|
|
maxexptime = 1,
|
|
minsize = 0.1,
|
|
maxsize = 2,
|
|
texture = "default_dirt.png^[colorize:#00aa00ff",
|
|
collisiondetection = true,
|
|
})
|
|
aliveai.punchdmg(ob)
|
|
if aliveai.gethp(ob,1)<1 then
|
|
if ob:is_player() then
|
|
aliveai_threats.stopacidplayer[ob:get_player_name()]=1
|
|
minetest.after(10, function(ob)
|
|
aliveai_threats.stopacidplayer[ob:get_player_name()]=nil
|
|
end,ob)
|
|
end
|
|
return
|
|
end
|
|
|
|
minetest.after(math.random(1,4), function()
|
|
aliveai_threats.acid(ob)
|
|
end)
|
|
end
|
|
|
|
|
|
minetest.register_tool("aliveai_threats:acid", {
|
|
description = "Acid",
|
|
inventory_image = "aliveai_relive.png^[colorize:#00aa00aa",
|
|
on_use = function(itemstack, user, pointed_thing)
|
|
if pointed_thing.type~="object" or aliveai.team(pointed_thing.ref)=="nuke" then return end
|
|
aliveai_threats.acid(pointed_thing.ref)
|
|
itemstack:add_wear(6000)
|
|
return itemstack
|
|
end
|
|
})
|
|
|
|
|
|
aliveai.create_bot({
|
|
description="The gassman loves play with acid, everyone else becomes its toys",
|
|
attack_players=1,
|
|
name="acidman",
|
|
team="nuke",
|
|
texture="aliveai_threats_acidman.png",
|
|
attacking=1,
|
|
talking=0,
|
|
light=0,
|
|
building=0,
|
|
escape=0,
|
|
type="monster",
|
|
hp=50,
|
|
name_color="",
|
|
arm=2,
|
|
coming=0,
|
|
smartfight=0,
|
|
spawn_on={"group:sand","group:spreading_dirt_type","default:gravel","group:stone"},
|
|
attack_chance=5,
|
|
start_with_items={["aliveai_threats:acid"]=1},
|
|
tool_near=1,
|
|
tool_chance=1,
|
|
on_blow=function(self)
|
|
aliveai.kill(self)
|
|
self.death(self,self.object,self.object:get_pos())
|
|
end,
|
|
death=function(self,puncher,pos)
|
|
if not self.ex then
|
|
self.ex=true
|
|
aliveai_nitroglycerine.explode(pos,{
|
|
radius=1,
|
|
set="air",
|
|
blow_nodes=0,
|
|
hurt=0
|
|
})
|
|
for _, ob in ipairs(minetest.get_objects_inside_radius(pos, 4)) do
|
|
if aliveai.visiable(pos,ob:get_pos()) then aliveai_threats.tox(ob) end
|
|
end
|
|
end
|
|
return self
|
|
end,
|
|
on_punched=function(self,puncher)
|
|
local pos=self.object:get_pos()
|
|
aliveai_threats.acid(puncher)
|
|
minetest.add_particlespawner({
|
|
amount = 5,
|
|
time=0.2,
|
|
minpos = pos,
|
|
maxpos = pos,
|
|
minvel = {x=-0.1, y=-0.1, z=-0.1},
|
|
maxvel = {x=0.1, y=0.1, z=0.1},
|
|
minacc = {x=0, y=0, z=0},
|
|
maxacc = {x=0, y=0, z=0},
|
|
minexptime = 0.5,
|
|
maxexptime = 1,
|
|
minsize = 0.5,
|
|
maxsize = 2,
|
|
texture = "default_grass.png^[colorize:#00ff00aa",
|
|
})
|
|
end
|
|
})
|
|
|
|
|
|
aliveai.create_bot({
|
|
description="The massive dirt is living and eats everything",
|
|
attack_players=1,
|
|
name="fangs",
|
|
team="fangs",
|
|
texture="default_dirt.png^aliveai_threats_fangs.png",
|
|
talking=0,
|
|
light=0,
|
|
building=0,
|
|
type="monster",
|
|
hp=100,
|
|
arm=2,
|
|
name_color="",
|
|
collisionbox={-1,-1,-1,1,1,1},
|
|
visual="cube",
|
|
drop_dead_body=0,
|
|
escape=0,
|
|
spawn_on={"group:sand","group:soil","default:snow"},
|
|
attack_chance=1,
|
|
spawn_y=2,
|
|
smartfight=0,
|
|
spawn=function(self,t,t2)
|
|
local tx=""
|
|
if not t then
|
|
tx="aliveai_threats:fangs"
|
|
elseif t==1 then
|
|
tx="aliveai_threats:fangs_fight"
|
|
elseif t2 and t2:is_player() then
|
|
t2:set_eye_offset({x=0, y=0, z=0}, {x=0, y=0, z=0})
|
|
else
|
|
tx="aliveai_threats:fangs_attack"
|
|
end
|
|
self.fangs=t
|
|
self.object:set_properties({visual="wielditem",visual_size={x=1.2,y=1.2},textures={tx}})
|
|
end,
|
|
on_load=function(self)
|
|
self.spawn(self)
|
|
end,
|
|
on_step=function(self,dtime)
|
|
if self.eating then
|
|
if not self.eating:get_attach() then
|
|
self.spawn(self,3,self.eating)
|
|
self.eating=nil
|
|
return
|
|
end
|
|
local hp=aliveai.gethp(self.eating)
|
|
if self.eating:get_luaentity() then
|
|
if self.eating:get_luaentity().health then
|
|
self.eating:get_luaentity().health=hp-2
|
|
elseif self.eating:get_luaentity().hp then
|
|
self.eating:get_luaentity().hp=hp-2
|
|
end
|
|
elseif self.eating:is_player() then
|
|
self.eating:set_hp(hp-2)
|
|
end
|
|
if self.fangs then
|
|
self.spawn(self)
|
|
end
|
|
aliveai.punchdmg(self.eating,2)
|
|
if hp<=0 then
|
|
self.eating:set_detach()
|
|
if self.eating:get_luaentity() then
|
|
self.eating:remove()
|
|
else
|
|
local pos=aliveai.roundpos(self.eating:get_pos())
|
|
local n
|
|
for i=-2,-6,-1 do
|
|
if not aliveai.def({x=pos.x,y=pos.y+i,z=pos.z},"walkable") then
|
|
return
|
|
end
|
|
end
|
|
pos.y=pos.y-4
|
|
self.eating:set_pos(pos)
|
|
end
|
|
self.spawn(self,3,self.eating)
|
|
self.eating=nil
|
|
self.object:set_hp(100)
|
|
aliveai.showhp(self,true)
|
|
return
|
|
end
|
|
end
|
|
if not self.eating and self.fight then
|
|
if self.fight:get_attach() then
|
|
self.fight=nil
|
|
return
|
|
end
|
|
if aliveai.distance(self,self.fight:get_pos())<2.5 then
|
|
self.eating=self.fight
|
|
self.eating:set_attach(self.object, "",{x=0, y=-3 , z=0}, {x=0, y=0, z=0})
|
|
if self.eating:is_player() then
|
|
self.eating:set_eye_offset({x=0, y=-15, z=0}, {x=0, y=0, z=0})
|
|
end
|
|
self.spawn(self,2)
|
|
return self
|
|
else
|
|
self.spawn(self,1)
|
|
end
|
|
elseif self.fangs and not self.fight then
|
|
self.spawn(self)
|
|
elseif not self.fight and math.random(1,3)==1 then
|
|
for _, ob in ipairs(minetest.get_objects_inside_radius(self.object:get_pos(), self.distance)) do
|
|
local pos=ob:get_pos()
|
|
if aliveai.is_bot(ob) and aliveai.team(ob)~=self.team and aliveai.viewfield(self,pos) then
|
|
local en=ob:get_luaentity()
|
|
if en.dying or en.dead then
|
|
self.fight=ob
|
|
self.temper=self.temper+1
|
|
return self
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end,
|
|
death=function(self,puncher,pos)
|
|
if self.eating and self.eating:get_attach() then
|
|
self.eating:set_detach()
|
|
self.spawn(self,3,self.eating)
|
|
end
|
|
aliveai.invadd(self,"default:dirt",math.random(1, 4),false)
|
|
minetest.add_particlespawner({
|
|
amount = 30,
|
|
time =0.05,
|
|
minpos = pos,
|
|
maxpos = pos,
|
|
minvel = {x=-5, y=0, z=-5},
|
|
maxvel = {x=5, y=5, z=5},
|
|
minacc = {x=0, y=-8, z=0},
|
|
maxacc = {x=0, y=-10, z=0},
|
|
minexptime = 2,
|
|
maxexptime = 1,
|
|
minsize = 2,
|
|
maxsize = 8,
|
|
texture = "default_dirt.png",
|
|
collisiondetection = true,
|
|
})
|
|
|
|
end,
|
|
on_punched=function(self,puncher)
|
|
local pos=self.object:get_pos()
|
|
aliveai.lookat(self,pos)
|
|
minetest.add_particlespawner({
|
|
amount = 5,
|
|
time =0.05,
|
|
minpos = pos,
|
|
maxpos = pos,
|
|
minvel = {x=-5, y=0, z=-5},
|
|
maxvel = {x=5, y=5, z=5},
|
|
minacc = {x=0, y=-8, z=0},
|
|
maxacc = {x=0, y=-10, z=0},
|
|
minexptime = 2,
|
|
maxexptime = 1,
|
|
minsize = 0.2,
|
|
maxsize = 8,
|
|
texture = "default_dirt.png",
|
|
collisiondetection = true,
|
|
})
|
|
end
|
|
})
|
|
local fangsbox = {
|
|
type = "fixed",
|
|
fixed = {
|
|
{0.2, -0.5, -0.5, 0.5, 0.5, 0.5},
|
|
{-0.5, 0.2, -0.5, 0.5, 0.5, 0.5},
|
|
{-0.5, -0.5, 0.2, 0.5, 0.5, 0.5},
|
|
{-0.5, -0.5, -0.5, -0.2, 0.5, 0.5},
|
|
{-0.5, -0.5, -0.5, 0.5, -0.2, 0.5},
|
|
{-0.5, -0.5, -0.5, 0.5, 0.5, -0.2},
|
|
}
|
|
}
|
|
minetest.register_node("aliveai_threats:fangs", {
|
|
tiles = {"default_dirt.png","default_dirt.png","default_dirt.png","default_dirt.png","default_dirt.png","default_dirt.png"},
|
|
groups = {cracky = 2,not_in_creative_inventory=1},
|
|
drawtype="nodebox",
|
|
node_box = fangsbox
|
|
})
|
|
minetest.register_node("aliveai_threats:fangs_fight", {
|
|
tiles = {"default_dirt.png","default_dirt.png","default_dirt.png","default_dirt.png","default_dirt.png^aliveai_threats_fangs.png","default_dirt.png"},
|
|
groups = {cracky = 2,not_in_creative_inventory=1},
|
|
drawtype="nodebox",
|
|
node_box = fangsbox
|
|
})
|
|
minetest.register_node("aliveai_threats:fangs_attack", {
|
|
tiles = {"default_dirt.png","default_dirt.png","default_dirt.png","default_dirt.png","default_dirt.png^aliveai_threats_fangs2.png","default_dirt.png"},
|
|
groups = {cracky = 2,not_in_creative_inventory=1},
|
|
drawtype="nodebox",
|
|
node_box = fangsbox
|
|
})
|
|
|
|
aliveai.create_bot({
|
|
description="The stonelike stalker, wakes to life in the darkness and slowly sneaking to its victims while noone are looking at it",
|
|
name="statue",
|
|
type="node",
|
|
team="statue",
|
|
hp=1,
|
|
mindamage=2,
|
|
texture="default_stone.png",
|
|
talking=0,
|
|
light=0,
|
|
building=0,
|
|
name_color="",
|
|
collisionbox={-0.5,-0.5,-0.5,0.5,0.5,0.5},
|
|
drop_dead_body=0,
|
|
spawn_on={"group:soil","group:stone"},
|
|
spawn_y=0,
|
|
spawn=function(self)
|
|
local pos=self.object:get_pos()
|
|
local opos=pos
|
|
for i=0,10,1 do
|
|
if aliveai.def({x=pos.x,y=pos.y-i,z=pos.z,},"walkable") and not minetest.is_protected(opos,"") then
|
|
minetest.set_node(opos,{name="aliveai_threats:statue"})
|
|
aliveai.kill(self)
|
|
return
|
|
end
|
|
opos={x=pos.x,y=pos.y-i,z=pos.z,}
|
|
end
|
|
aliveai.kill(self)
|
|
end,
|
|
})
|
|
|
|
minetest.register_node("aliveai_threats:statue", {
|
|
description = "Statue",
|
|
tiles = {"aliveai_air.png"},
|
|
inventory_image = "default_stone.png",
|
|
wield_image = "default_stone.png",
|
|
groups = {cracky = 1,level=3,stone=1,aliveai=1,not_in_creative_inventory=1},
|
|
sounds = default.node_sound_stone_defaults(),
|
|
paramtype = "light",
|
|
sunlight_propagates = true,
|
|
drawtype="glasslike",
|
|
visual_scale = 0.12,
|
|
post_effect_color = {a=255, r=0, g=0, b=0},
|
|
selection_box ={
|
|
type = "fixed",
|
|
fixed = {
|
|
{-0.4, -0.5, -0.4, 0.4, 1.2, 0.4},
|
|
}
|
|
},
|
|
on_construct = function(pos)
|
|
minetest.add_entity({x=pos.x,y=pos.y+0.5,z=pos.z}, "aliveai_threats:statue_standing")
|
|
minetest.get_node_timer(pos):start(5)
|
|
end,
|
|
on_destruct = function(pos)
|
|
for _, ob in ipairs(minetest.get_objects_inside_radius(pos, 1)) do
|
|
local en=ob:get_luaentity()
|
|
if en and en.name=="aliveai_threats:statue_standing" then
|
|
ob:remove()
|
|
end
|
|
end
|
|
end,
|
|
on_timer = function (pos, elapsed)
|
|
if math.random(1,100)==1 and not minetest.is_protected(pos,"") then
|
|
minetest.remove_node(pos)
|
|
return
|
|
end
|
|
|
|
local l=minetest.get_node_light(pos)
|
|
if l and l>5 then return true end
|
|
local o
|
|
local cfo
|
|
local c=0
|
|
for _, ob in ipairs(minetest.get_objects_inside_radius(pos, 1)) do
|
|
local en=ob:get_luaentity()
|
|
if en and en.name=="aliveai_threats:statue_standing" then
|
|
cfo=ob
|
|
break
|
|
end
|
|
|
|
end
|
|
if not cfo then
|
|
minetest.add_entity({x=pos.x,y=pos.y+0.5,z=pos.z}, "aliveai_threats:statue_standing")
|
|
return true
|
|
end
|
|
for _, ob in ipairs(minetest.get_objects_inside_radius(pos, 15)) do
|
|
local en=ob:get_luaentity()
|
|
if not (en and (en.type==nil or en.name=="aliveai_threats:statue_standing")) and aliveai.visiable(pos,ob:get_pos()) then
|
|
c=c+1
|
|
if c>1 then return true end
|
|
o=ob
|
|
|
|
end
|
|
end
|
|
if not o then
|
|
return true
|
|
end
|
|
local d
|
|
local opos=o:get_pos()
|
|
if o:get_luaentity() then
|
|
d=aliveai.pointat(o:get_luaentity(),1)
|
|
elseif o:is_player(o) then
|
|
d=o:get_look_dir()
|
|
d={x=d.x*1.1,y=d.y*1.1,z=d.z*1.1}
|
|
d={x=opos.x+d.x,y=opos.y+d.y,z=opos.z+d.z}
|
|
else
|
|
return true
|
|
end
|
|
local self=cfo:get_luaentity()
|
|
local p=aliveai.pointat(self,1)
|
|
if aliveai.distance(pos,d)>aliveai.distance(pos,opos) then
|
|
if minetest.get_node(p).name=="aliveai_threats:statue_standing" then
|
|
return true
|
|
end
|
|
if not aliveai.def(p,"buildable_to")
|
|
and aliveai.def({x=p.x,y=p.y+1,z=p.z},"buildable_to") then
|
|
if not aliveai.def({x=p.x,y=p.y+2,z=p.z},"buildable_to") then
|
|
return true
|
|
end
|
|
p={x=p.x,y=p.y+1,z=p.z}
|
|
elseif aliveai.def(p,"buildable_to")
|
|
and aliveai.def({x=p.x,y=p.y-1,z=p.z},"buildable_to") then
|
|
if aliveai.def({x=p.x,y=p.y-2,z=p.z},"buildable_to") then
|
|
return true
|
|
end
|
|
p={x=p.x,y=p.y-1,z=p.z}
|
|
end
|
|
if not aliveai.def(p,"buildable_to") or minetest.is_protected(p,"") then
|
|
return true
|
|
end
|
|
minetest.set_node(p,{name="aliveai_threats:statue_standing"})
|
|
minetest.remove_node(pos)
|
|
if aliveai.distance(p,opos)<1 then
|
|
aliveai.punchdmg(o,50)
|
|
end
|
|
for _, ob in ipairs(minetest.get_objects_inside_radius(p, 1)) do
|
|
local en=ob:get_luaentity()
|
|
if en and en.name=="aliveai_threats:statue_standing" then
|
|
aliveai.lookat(en,opos)
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
return true
|
|
end,
|
|
})
|
|
minetest.register_entity("aliveai_threats:statue_standing",{
|
|
hp_max = 10,
|
|
physical =false,
|
|
pointable=false,
|
|
visual = "mesh",
|
|
mesh=aliveai.character_model,
|
|
collisionbox={0,0,0,0,0,0},
|
|
textures ={"default_stone.png"},
|
|
on_activate=function(self, staticdata)
|
|
if minetest.get_node(aliveai.newpos(self):yy(-0.5)).name~="aliveai_threats:statue" then
|
|
self.object:remove()
|
|
end
|
|
end,
|
|
})
|
|
|
|
minetest.register_node("aliveai_threats:hat", {
|
|
tiles = {"default_coal_block.png^[colorize:#000000aa"},
|
|
groups = {dig_immediate = 3,not_in_creative_inventory=1},
|
|
on_construct = function(pos)
|
|
minetest.get_node_timer(pos):start(math.random(1,10))
|
|
end,
|
|
on_timer = function (pos, elapsed)
|
|
if minetest.get_node({x=pos.x, y=pos.y-1 , z=pos.z}).name=="default:snowblock" then
|
|
minetest.add_entity({x=pos.x, y=pos.y-1 , z=pos.z}, "aliveai_threats:snowman")
|
|
minetest.remove_node({x=pos.x, y=pos.y-1 , z=pos.z})
|
|
minetest.remove_node(pos)
|
|
end
|
|
return false
|
|
end,
|
|
drawtype="nodebox",
|
|
node_box ={
|
|
type = "fixed",
|
|
fixed = {
|
|
{-0.375, -0.5, -0.375, 0.375, -0.4375, 0.375},
|
|
{-0.22, -0.4375, -0.22, 0.22, 0.0625, 0.22}
|
|
}
|
|
}
|
|
})
|
|
|
|
minetest.register_entity("aliveai_threats:hat",{
|
|
hp_max = 20,
|
|
physical =true,
|
|
pointable=false,
|
|
visual = "wielditem",
|
|
textures ={"aliveai_threats:hat"},
|
|
visual_size={x=2,y=2},
|
|
on_step=function(self, dtime)
|
|
self.t=self.t+dtime
|
|
if self.t<1 then return end
|
|
self.t=0
|
|
if not self.object:get_attach() then
|
|
self.object:remove()
|
|
end
|
|
end,
|
|
t=0,
|
|
})
|
|
|
|
|
|
|
|
minetest.register_node("aliveai_threats:snowman", {
|
|
tiles = {"default_snow.png"},
|
|
groups = {cracky = 2,not_in_creative_inventory=1},
|
|
drawtype="nodebox",
|
|
node_box ={
|
|
type = "fixed",
|
|
fixed = {
|
|
{-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
|
|
{-0.375, 0.5, -0.375, 0.375, 1.2, 0.375},
|
|
{-0.25, 1.2, -0.25, 0.25, 1.6, 0.25}
|
|
}
|
|
}
|
|
})
|
|
|
|
|
|
aliveai.create_bot({
|
|
description="Snowballs warrior, keeping away everything from its empire",
|
|
attack_players=1,
|
|
name="snowman",
|
|
team="snow",
|
|
texture="default_snow.png",
|
|
talking=0,
|
|
light=0,
|
|
building=0,
|
|
type="monster",
|
|
hp=10,
|
|
arm=2,
|
|
name_color="",
|
|
collisionbox={-0.5,-0.45,-0.5,0.5,2.0,0.5},
|
|
visual="cube",
|
|
drop_dead_body=0,
|
|
escape=0,
|
|
start_with_items={["default:snow"]=1,["default:snowblock"]=3,["aliveai_threats:hat"]=1},
|
|
spawn_on={"default:snow","default:snowblock"},
|
|
attack_chance=1,
|
|
basey=-1,
|
|
smartfight=0,
|
|
spawn_chance=100,
|
|
spawn=function(self,t,t2)
|
|
self.object:set_properties({visual="wielditem",visual_size={x=0.6,y=0.6},textures={"aliveai_threats:snowman"}})
|
|
local e=minetest.add_entity(self.object:get_pos(), "aliveai_threats:hat")
|
|
e:set_attach(self.object, "",{x=0, y=62 , z=0}, {x=0, y=0, z=0})
|
|
self.hat=e
|
|
self.cctime=0
|
|
end,
|
|
on_load=function(self)
|
|
self.spawn(self)
|
|
end,
|
|
on_step=function(self,dtime)
|
|
if self.fight and (self.cctime<1 or self.time==self.otime) then
|
|
self.cctime=5
|
|
local d=aliveai.distance(self,self.fight:get_pos())
|
|
if not (aliveai.viewfield(self,self.fight) and aliveai.visiable(self,self.fight:get_pos())) then return end
|
|
local pos=self.object:get_pos()
|
|
local ta=self.fight:get_pos()
|
|
if not (ta and pos) then return end
|
|
ta.y=ta.y+1.5
|
|
aliveai.stand(self)
|
|
aliveai.lookat(self,ta)
|
|
local e=minetest.add_item(aliveai.pointat(self,2),"default:snow")
|
|
local dir=aliveai.get_dir(self,ta)
|
|
e:set_velocity({x =aliveai.nan(dir.x*30), y = aliveai.nan(dir.y*30), z = aliveai.nan(dir.z*30)})
|
|
e:get_luaentity().age=(tonumber(minetest.settings:get("item_entity_ttl")) or 900)-2
|
|
table.insert(aliveai_threats.debris,{ob=e,n=self.botname})
|
|
return self
|
|
elseif self.fight and self.cctime>1 then
|
|
self.cctime=self.cctime-1
|
|
end
|
|
|
|
end,
|
|
death=function(self,puncher,pos)
|
|
if self.hat and self.hat:get_attach() then
|
|
self.hat:set_detach()
|
|
self.hat:remove()
|
|
end
|
|
minetest.add_particlespawner({
|
|
amount = 30,
|
|
time =0.05,
|
|
minpos = pos,
|
|
maxpos = pos,
|
|
minvel = {x=-5, y=0, z=-5},
|
|
maxvel = {x=5, y=5, z=5},
|
|
minacc = {x=0, y=-8, z=0},
|
|
maxacc = {x=0, y=-10, z=0},
|
|
minexptime = 2,
|
|
maxexptime = 1,
|
|
minsize = 2,
|
|
maxsize = 4,
|
|
texture = "default_snow.png",
|
|
collisiondetection = true,
|
|
})
|
|
minetest.sound_play("default_snow_footstep", {pos=pos, gain = 1.0, max_hear_distance = 5,})
|
|
end,
|
|
on_punched=function(self,puncher)
|
|
local pos=self.object:get_pos()
|
|
if self.hp<6 and self.hp>0 and not minetest.is_protected(pos,"") and aliveai.def(pos,"buildable_to") and math.random(1,5)==1 then
|
|
minetest.set_node(pos,{name="default:snowblock"})
|
|
local psa={x=pos.x,y=pos.y+1,z=pos.z}
|
|
if not minetest.is_protected(psa,"") and aliveai.def(psa,"buildable_to") then
|
|
self.inv["aliveai_threats:hat"]=nil
|
|
minetest.set_node(psa,{name="aliveai_threats:hat"})
|
|
end
|
|
aliveai.punchdmg(self.object,100)
|
|
end
|
|
aliveai.lookat(self,pos)
|
|
minetest.add_particlespawner({
|
|
amount = 5,
|
|
time =0.05,
|
|
minpos = pos,
|
|
maxpos = pos,
|
|
minvel = {x=-5, y=0, z=-5},
|
|
maxvel = {x=5, y=5, z=5},
|
|
minacc = {x=0, y=-8, z=0},
|
|
maxacc = {x=0, y=-10, z=0},
|
|
minexptime = 2,
|
|
maxexptime = 1,
|
|
minsize = 0.2,
|
|
maxsize = 2,
|
|
texture = "default_snow.png",
|
|
collisiondetection = true,
|
|
})
|
|
end
|
|
})
|
|
|
|
minetest.register_tool("aliveai_threats:stoneman_spawn", {
|
|
description = "Stoneman",
|
|
inventory_image = "aliveai_threats_stoneman.png",
|
|
on_use=function(itemstack, user, pointed_thing)
|
|
if user:get_luaentity() then user=user:get_luaentity() end
|
|
local type=pointed_thing.type
|
|
local pos
|
|
if type=="node" then
|
|
pos=pointed_thing.above
|
|
pos.y=pos.y+1
|
|
elseif type=="object" then
|
|
pos=pointed_thing.ref:get_pos()
|
|
else
|
|
pos=user:get_pos()
|
|
pos.y=pos.y+1
|
|
end
|
|
local e=minetest.add_entity(pos, "aliveai_threats:stoneman")
|
|
e:get_luaentity().team=aliveai.team(user)
|
|
local self=user:get_luaentity()
|
|
if self then
|
|
minetest.after(0.1, function(self)
|
|
if self and self.object then
|
|
aliveai.invadd(self,"aliveai_threats:stoneman_spawn",-1)
|
|
self.tools=""
|
|
self.savetool=1
|
|
self.tool_near=0
|
|
end
|
|
end,self)
|
|
end
|
|
itemstack:add_wear(65536)
|
|
return itemstack
|
|
end,
|
|
on_place=function(itemstack, user, pointed_thing)
|
|
if user:get_luaentity() then user=user:get_luaentity() end
|
|
local type=pointed_thing.type
|
|
local pos
|
|
if type=="node" then
|
|
pos=pointed_thing.above
|
|
pos.y=pos.y+1
|
|
elseif type=="object" then
|
|
pos=pointed_thing.ref:get_pos()
|
|
else
|
|
pos=user:get_pos()
|
|
pos.y=pos.y+1
|
|
end
|
|
local e=minetest.add_entity(pos, "aliveai_threats:stoneman")
|
|
e:get_luaentity().team=aliveai.team(user)
|
|
itemstack:add_wear(65536)
|
|
return itemstack
|
|
end
|
|
})
|
|
|
|
minetest.register_craft({
|
|
output = "aliveai_threats:stoneman_spawn",
|
|
recipe = {
|
|
{"default:stone","default:stone","default:stone"},
|
|
{"","default:cobble",""},
|
|
{"default:stone","","default:stone"},
|
|
}
|
|
})
|
|
|
|
aliveai.create_bot({
|
|
description="Stonewarrior, keeping away everything from its empire",
|
|
attack_players=1,
|
|
name="stoneman",
|
|
team="stone",
|
|
texture="default_stone.png",
|
|
talking=0,
|
|
light=0,
|
|
building=0,
|
|
type="monster",
|
|
hp=30,
|
|
arm=2,
|
|
dmg=3,
|
|
hugwalk=1,
|
|
name_color="",
|
|
escape=0,
|
|
start_with_items={["default:stone"]=1},
|
|
spawn_on={"default:stone"},
|
|
annoyed_by_staring=0,
|
|
attack_chance=1,
|
|
smartfight=0,
|
|
spawn_chance=100,
|
|
mindamage=2,
|
|
spawn=function(self)
|
|
self.animation.stand.speed=0
|
|
aliveai.stand(self)
|
|
minetest.after(0, function(self)
|
|
if self.team~="stone" then
|
|
self.name_color="aaaaaa"
|
|
self.object:set_properties({nametag=self.botname,nametag_color="#" .. self.name_color})
|
|
end
|
|
end,self)
|
|
end,
|
|
on_load=function(self)
|
|
self.animation.stand.speed=0
|
|
aliveai.stand(self)
|
|
if self.team~="stone" then
|
|
self.name_color="aaaaaa"
|
|
self.object:set_properties({nametag=self.botname,nametag_color="#" .. self.name_color})
|
|
|
|
end
|
|
end,
|
|
death=function(self,puncher,pos)
|
|
minetest.add_particlespawner({
|
|
amount = 30,
|
|
time =0.05,
|
|
minpos = pos,
|
|
maxpos = pos,
|
|
minvel = {x=-5, y=0, z=-5},
|
|
maxvel = {x=5, y=5, z=5},
|
|
minacc = {x=0, y=-8, z=0},
|
|
maxacc = {x=0, y=-10, z=0},
|
|
minexptime = 2,
|
|
maxexptime = 1,
|
|
minsize = 0.2,
|
|
maxsize = 2,
|
|
texture = "default_stone.png",
|
|
collisiondetection = true,
|
|
})
|
|
end,
|
|
})
|
|
|
|
if minetest.get_modpath("aliveai_folk") then
|
|
aliveai.create_bot({
|
|
description="The toxic npc is toxic people, turns everyone until their own members, can easily eliminate civilizations",
|
|
attack_players=1,
|
|
name="toxic_npc",
|
|
team="toxic_npc",
|
|
texture="aliveai_folk23a.png",
|
|
talking=0,
|
|
light=0,
|
|
building=0,
|
|
type="monster",
|
|
hp=40,
|
|
arm=2,
|
|
dmg=3,
|
|
hugwalk=1,
|
|
name_color="",
|
|
escape=0,
|
|
--start_with_items={["default:stone"]=1},
|
|
spawn_on={"default:stone","bones:bones","default:silver_sandstone_brick","default:sandstone_brick"},
|
|
annoyed_by_staring=0,
|
|
attack_chance=1,
|
|
smartfight=0,
|
|
spawn_chance=100,
|
|
mindamage=2,
|
|
spawn=function(self)
|
|
local t={}
|
|
for _, v in pairs(aliveai.registered_bots) do
|
|
if v.mod_name=="aliveai_folk" and string.find(v.name,"folk") then
|
|
table.insert(t,v.textures[1])
|
|
end
|
|
end
|
|
self.save__1=t[math.random(1,#t)] or "aliveai_threats_stubborn_monster.png"
|
|
self.object:set_properties({textures={self.save__1}})
|
|
end,
|
|
on_load=function(self)
|
|
self.object:set_properties({textures={self.save__1 or "aliveai_threats_stubborn_monster.png"}})
|
|
if self.save__3 and self.save__4 then
|
|
self.object:set_properties({visual_size=self.save__3,collisionbox=self.save__4})
|
|
end
|
|
end,
|
|
on_detect_enemy=function(self,target)
|
|
if self.save__2~="by_another" then
|
|
for i=1,math.random(1,5),1 do
|
|
local pos=aliveai.random_pos(self,10,20)
|
|
if not pos then
|
|
pos=aliveai.random_pos(self,10,20)
|
|
if not pos then return self end
|
|
end
|
|
local en=minetest.add_entity(pos, "aliveai_threats:toxic_npc"):get_luaentity()
|
|
en.temper=3
|
|
en.fight=target
|
|
en.save__2="by_another"
|
|
end
|
|
self.save__2="by_another"
|
|
end
|
|
end,
|
|
on_punch_hit=function(self,fight)
|
|
if aliveai.is_bot(fight) and fight:get_properties().visual=="mesh" and fight:get_properties().mesh==aliveai.character_model then
|
|
local pos=fight:get_pos()
|
|
local t=fight:get_properties().textures[1]
|
|
local e=minetest.add_entity(pos, "aliveai_threats:toxic_npc")
|
|
local en=e:get_luaentity()
|
|
e:set_yaw(self.object:get_yaw())
|
|
en.inv=fight:get_luaentity().inv
|
|
en.namecolor="ff0000"
|
|
en.save__1=t
|
|
en.save__2="by_another"
|
|
en.dmg=fight:get_luaentity().dmg
|
|
en.floating=fight:get_luaentity().floating
|
|
en.save__3=fight:get_properties().visual_size
|
|
en.save__4=fight:get_properties().collisionbox
|
|
e:set_properties({
|
|
textures={t},
|
|
visual_size=en.save__3,
|
|
collisionbox=en.save__4,
|
|
})
|
|
fight:remove()
|
|
self.fight=nil
|
|
|
|
elseif aliveai.is_bot(fight) then
|
|
local en=fight:get_luaentity()
|
|
en.fight=nil
|
|
en.save__2="by_another"
|
|
en.team=self.team
|
|
en.namecolor="ff0000"
|
|
aliveai.showhp(en)
|
|
en.on_punch_hit=self.on_punch_hit
|
|
self.fight=nil
|
|
end
|
|
end,
|
|
})
|
|
end
|
|
|