|
|
|
@ -68,105 +68,107 @@ function goblins.attack(self, target, type)
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local pos = vector.round(self.object:getpos())
|
|
|
|
|
local s = self.object:get_pos()
|
|
|
|
|
local objs = minetest.get_objects_inside_radius(s, self.view_range)
|
|
|
|
|
local aggro_wielded = {}
|
|
|
|
|
if goblins_aggro_on_wield then
|
|
|
|
|
aggro_wielded = self.aggro_wielded
|
|
|
|
|
end
|
|
|
|
|
local defend_groups = goblins_defend_groups
|
|
|
|
|
--print_s(S(dump(aggro_wielded)))
|
|
|
|
|
-- remove entities we aren't interested in
|
|
|
|
|
for n = 1, #objs do
|
|
|
|
|
local ent = objs[n]:get_luaentity()
|
|
|
|
|
-- are we a player?
|
|
|
|
|
if objs[n]:is_player() then
|
|
|
|
|
local pname = objs[n]:get_player_name()
|
|
|
|
|
local relations_self = {}
|
|
|
|
|
local relations = {}
|
|
|
|
|
local relations_adj = 0
|
|
|
|
|
--do we know this player?
|
|
|
|
|
local relations_self = goblins.relations(self, pname)
|
|
|
|
|
if not relations_self.trade then goblins.relations(self, pname,{trade = 0}) end
|
|
|
|
|
if not relations_self.aggro then goblins.relations(self, pname,{aggro = 0}) end
|
|
|
|
|
local pos = vector.round(self.object:get_pos())
|
|
|
|
|
if pos then
|
|
|
|
|
local s = self.object:get_pos()
|
|
|
|
|
local objs = minetest.get_objects_inside_radius(s, self.view_range)
|
|
|
|
|
local aggro_wielded = {}
|
|
|
|
|
if goblins_aggro_on_wield then
|
|
|
|
|
aggro_wielded = self.aggro_wielded
|
|
|
|
|
end
|
|
|
|
|
local defend_groups = goblins_defend_groups
|
|
|
|
|
--print_s(S(dump(aggro_wielded)))
|
|
|
|
|
-- remove entities we aren't interested in
|
|
|
|
|
for n = 1, #objs do
|
|
|
|
|
local ent = objs[n]:get_luaentity()
|
|
|
|
|
-- are we a player?
|
|
|
|
|
if objs[n]:is_player() then
|
|
|
|
|
local pname = objs[n]:get_player_name()
|
|
|
|
|
local relations_self = {}
|
|
|
|
|
local relations = {}
|
|
|
|
|
local relations_adj = 0
|
|
|
|
|
--do we know this player?
|
|
|
|
|
local relations_self = goblins.relations(self, pname)
|
|
|
|
|
if not relations_self.trade then goblins.relations(self, pname,{trade = 0}) end
|
|
|
|
|
if not relations_self.aggro then goblins.relations(self, pname,{aggro = 0}) end
|
|
|
|
|
|
|
|
|
|
--tally the territorial scores
|
|
|
|
|
relations.aggro = goblins.relations_territory(self, pname, "aggro")
|
|
|
|
|
relations.trade = goblins.relations_territory(self, pname, "trade")
|
|
|
|
|
if debug_goblins_attack then
|
|
|
|
|
print_s(S("@1 of @2: ", self.secret_name, self.secret_territory.name))
|
|
|
|
|
print_s(S("mob relations = @1",dump(goblins.relations(self, pname))))
|
|
|
|
|
print_s(S("comparing territory trade @1 and aggro @2",dump(relations.trade),dump(relations.aggro)))
|
|
|
|
|
end
|
|
|
|
|
--tally the territorial scores
|
|
|
|
|
relations.aggro = goblins.relations_territory(self, pname, "aggro")
|
|
|
|
|
relations.trade = goblins.relations_territory(self, pname, "trade")
|
|
|
|
|
if debug_goblins_attack then
|
|
|
|
|
print_s(S("@1 of @2: ", self.secret_name, self.secret_territory.name))
|
|
|
|
|
print_s(S("mob relations = @1",dump(goblins.relations(self, pname))))
|
|
|
|
|
print_s(S("comparing territory trade @1 and aggro @2",dump(relations.trade),dump(relations.aggro)))
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
if relations.trade >= relations.aggro then
|
|
|
|
|
relations_adj = relations.trade - relations.aggro
|
|
|
|
|
end
|
|
|
|
|
if debug_goblins_attack then print_s(S("relations = @1",dump(relations))) end
|
|
|
|
|
if mobs.invis[pname]
|
|
|
|
|
or self.owner == pname then
|
|
|
|
|
local name = ""
|
|
|
|
|
else
|
|
|
|
|
local player = objs[n]
|
|
|
|
|
local name = "player"
|
|
|
|
|
end
|
|
|
|
|
-- if player invisible or mob not setup to attack then remove from list
|
|
|
|
|
local wielded = objs[n]:get_wielded_item():to_string()
|
|
|
|
|
--print(self.secret_name.." is loyal to " ..self.owner)
|
|
|
|
|
if debug_goblins_attack then print_s( S("player has @1 in hand",dump(objs[n]:get_wielded_item():to_string())))end
|
|
|
|
|
if self.attack_players == false
|
|
|
|
|
or relations_adj >= 100
|
|
|
|
|
or not self.owner == pname
|
|
|
|
|
--or not self.tamed
|
|
|
|
|
or mobs.invis[pname]
|
|
|
|
|
or self.specific_attack == "player" then
|
|
|
|
|
if debug_goblins_attack then print_s(S("found exempt player with score of @1 holding @2",relations_adj,dump(objs[n]:get_wielded_item():to_string()))) end
|
|
|
|
|
objs[n] = nil
|
|
|
|
|
--print("- pla", n)
|
|
|
|
|
else
|
|
|
|
|
if debug_goblins_attack then print_s(S("attackable player, @1 holding @2",pname,wielded)) end
|
|
|
|
|
--lets check if our friends in a fight with the player!
|
|
|
|
|
for n = 1, #objs do
|
|
|
|
|
local ent_other = objs[n]:get_luaentity()
|
|
|
|
|
if defend_groups and ent_other and ent_other.groups and self.groups_defend then
|
|
|
|
|
for k,v in pairs(self.groups_defend) do
|
|
|
|
|
if match_only_list(v, ent_other.groups) and
|
|
|
|
|
ent_other.state == "attack" and
|
|
|
|
|
ent_other.attack:is_player() and
|
|
|
|
|
ent_other.attack:get_player_name() == pname then
|
|
|
|
|
local xname = ent_other.attack:get_player_name()
|
|
|
|
|
if debug_goblins_attack then print_s( S(" ****Defending @1 from @2!",v,xname)) end
|
|
|
|
|
minetest.sound_play("goblins_goblin_war_cry", {
|
|
|
|
|
pos = pos,
|
|
|
|
|
gain = 1.0,
|
|
|
|
|
max_hear_distance = self.sounds.distance or 10
|
|
|
|
|
})
|
|
|
|
|
self:set_animation("run")
|
|
|
|
|
self:set_velocity(self.run_velocity)
|
|
|
|
|
self.state = "attack"
|
|
|
|
|
self.attack = ent_other.attack
|
|
|
|
|
if relations.trade >= relations.aggro then
|
|
|
|
|
relations_adj = relations.trade - relations.aggro
|
|
|
|
|
end
|
|
|
|
|
if debug_goblins_attack then print_s(S("relations = @1",dump(relations))) end
|
|
|
|
|
if mobs.invis[pname]
|
|
|
|
|
or self.owner == pname then
|
|
|
|
|
local name = ""
|
|
|
|
|
else
|
|
|
|
|
local player = objs[n]
|
|
|
|
|
local name = "player"
|
|
|
|
|
end
|
|
|
|
|
-- if player invisible or mob not setup to attack then remove from list
|
|
|
|
|
local wielded = objs[n]:get_wielded_item():to_string()
|
|
|
|
|
--print(self.secret_name.." is loyal to " ..self.owner)
|
|
|
|
|
if debug_goblins_attack then print_s( S("player has @1 in hand",dump(objs[n]:get_wielded_item():to_string())))end
|
|
|
|
|
if self.attack_players == false
|
|
|
|
|
or relations_adj >= 100
|
|
|
|
|
or not self.owner == pname
|
|
|
|
|
--or not self.tamed
|
|
|
|
|
or mobs.invis[pname]
|
|
|
|
|
or self.specific_attack == "player" then
|
|
|
|
|
if debug_goblins_attack then print_s(S("found exempt player with score of @1 holding @2",relations_adj,dump(objs[n]:get_wielded_item():to_string()))) end
|
|
|
|
|
objs[n] = nil
|
|
|
|
|
--print("- pla", n)
|
|
|
|
|
else
|
|
|
|
|
if debug_goblins_attack then print_s(S("attackable player, @1 holding @2",pname,wielded)) end
|
|
|
|
|
--lets check if our friends in a fight with the player!
|
|
|
|
|
for n = 1, #objs do
|
|
|
|
|
local ent_other = objs[n]:get_luaentity()
|
|
|
|
|
if defend_groups and ent_other and ent_other.groups and self.groups_defend then
|
|
|
|
|
for k,v in pairs(self.groups_defend) do
|
|
|
|
|
if match_only_list(v, ent_other.groups) and
|
|
|
|
|
ent_other.state == "attack" and
|
|
|
|
|
ent_other.attack:is_player() and
|
|
|
|
|
ent_other.attack:get_player_name() == pname then
|
|
|
|
|
local xname = ent_other.attack:get_player_name()
|
|
|
|
|
if debug_goblins_attack then print_s( S(" ****Defending @1 from @2!",v,xname)) end
|
|
|
|
|
minetest.sound_play("goblins_goblin_war_cry", {
|
|
|
|
|
pos = pos,
|
|
|
|
|
gain = 1.0,
|
|
|
|
|
max_hear_distance = self.sounds.distance or 10
|
|
|
|
|
})
|
|
|
|
|
self:set_animation("run")
|
|
|
|
|
self:set_velocity(self.run_velocity)
|
|
|
|
|
self.state = "attack"
|
|
|
|
|
self.attack = ent_other.attack
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
if aggro_wielded and match_item_list(wielded, aggro_wielded)
|
|
|
|
|
then
|
|
|
|
|
if debug_goblins_attack then print_s(S("*** aggro triggered by @1 at @2 !! ***",wielded,minetest.pos_to_string(pos))) end
|
|
|
|
|
minetest.sound_play("goblins_goblin_war_cry", {
|
|
|
|
|
pos = pos,
|
|
|
|
|
gain = 1.0,
|
|
|
|
|
max_hear_distance = self.sounds.distance or 10
|
|
|
|
|
})
|
|
|
|
|
self:set_animation("run")
|
|
|
|
|
self:set_velocity(self.run_velocity)
|
|
|
|
|
self.state = "attack"
|
|
|
|
|
self.attack = (objs[n])
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
if aggro_wielded and match_item_list(wielded, aggro_wielded)
|
|
|
|
|
then
|
|
|
|
|
if debug_goblins_attack then print_s(S("*** aggro triggered by @1 at @2 !! ***",wielded,minetest.pos_to_string(pos))) end
|
|
|
|
|
minetest.sound_play("goblins_goblin_war_cry", {
|
|
|
|
|
pos = pos,
|
|
|
|
|
gain = 1.0,
|
|
|
|
|
max_hear_distance = self.sounds.distance or 10
|
|
|
|
|
})
|
|
|
|
|
self:set_animation("run")
|
|
|
|
|
self:set_velocity(self.run_velocity)
|
|
|
|
|
self.state = "attack"
|
|
|
|
|
self.attack = (objs[n])
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end --end of player eval
|
|
|
|
|
--what else do we care about?
|
|
|
|
|
--group_attack mobs nearby
|
|
|
|
|
end --end of player eval
|
|
|
|
|
--what else do we care about?
|
|
|
|
|
--group_attack mobs nearby
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
@ -185,32 +187,34 @@ function goblins.special_gifts(self, pname, drop_chance, max_drops)
|
|
|
|
|
end
|
|
|
|
|
if #rares > 0 then
|
|
|
|
|
--print_s("rares = "..dump(rares))
|
|
|
|
|
local pos = self.object:getpos()
|
|
|
|
|
pos.y = pos.y + 0.5
|
|
|
|
|
goblins.mixitup(pos)
|
|
|
|
|
if #rares > max_drops then
|
|
|
|
|
rares = rares[math.random(max_drops, #rares)]
|
|
|
|
|
if type(rares) ~= table then rares = {rares} end --
|
|
|
|
|
end
|
|
|
|
|
for k,v in pairs(rares) do
|
|
|
|
|
minetest.sound_play("goblins_goblin_cackle", {
|
|
|
|
|
pos = pos,
|
|
|
|
|
gain = 1.0,
|
|
|
|
|
max_hear_distance = self.sounds.distance or 10
|
|
|
|
|
})
|
|
|
|
|
local item_wear = math.random(5000,10000)
|
|
|
|
|
local stack = ItemStack({name = v, wear = item_wear })
|
|
|
|
|
local org_desc = minetest.registered_items[v].description
|
|
|
|
|
local meta = stack:get_meta()
|
|
|
|
|
local tool_adj = goblins.generate_name(goblins.words_desc, {"tool_adj"})
|
|
|
|
|
-- special thanks here to rubenwardy for showing me how translation works!
|
|
|
|
|
meta:set_string(
|
|
|
|
|
"description", S("@1's @2 @3", self.secret_name, tool_adj, org_desc)
|
|
|
|
|
)
|
|
|
|
|
local obj = minetest.add_item(pos, stack)
|
|
|
|
|
minetest.chat_send_player(
|
|
|
|
|
pname,S("@1 drops @2",self.secret_name, meta:get_string("description"))
|
|
|
|
|
)
|
|
|
|
|
local pos = self.object:get_pos()
|
|
|
|
|
if pos then
|
|
|
|
|
pos.y = pos.y + 0.5
|
|
|
|
|
goblins.mixitup(pos)
|
|
|
|
|
if #rares > max_drops then
|
|
|
|
|
rares = rares[math.random(max_drops, #rares)]
|
|
|
|
|
if type(rares) ~= table then rares = {rares} end --
|
|
|
|
|
end
|
|
|
|
|
for k,v in pairs(rares) do
|
|
|
|
|
minetest.sound_play("goblins_goblin_cackle", {
|
|
|
|
|
pos = pos,
|
|
|
|
|
gain = 1.0,
|
|
|
|
|
max_hear_distance = self.sounds.distance or 10
|
|
|
|
|
})
|
|
|
|
|
local item_wear = math.random(5000,10000)
|
|
|
|
|
local stack = ItemStack({name = v, wear = item_wear })
|
|
|
|
|
local org_desc = minetest.registered_items[v].description
|
|
|
|
|
local meta = stack:get_meta()
|
|
|
|
|
local tool_adj = goblins.generate_name(goblins.words_desc, {"tool_adj"})
|
|
|
|
|
-- special thanks here to rubenwardy for showing me how translation works!
|
|
|
|
|
meta:set_string(
|
|
|
|
|
"description", S("@1's @2 @3", self.secret_name, tool_adj, org_desc)
|
|
|
|
|
)
|
|
|
|
|
local obj = minetest.add_item(pos, stack)
|
|
|
|
|
minetest.chat_send_player(
|
|
|
|
|
pname,S("@1 drops @2",self.secret_name, meta:get_string("description"))
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
@ -284,10 +288,10 @@ end
|
|
|
|
|
function goblins.give_gift(self,clicker)
|
|
|
|
|
--if mobs:feed_tame(self, clicker, 14, false, false) then
|
|
|
|
|
local item = clicker:get_wielded_item()
|
|
|
|
|
local name = clicker:get_player_name()
|
|
|
|
|
local pname = clicker:get_player_name()
|
|
|
|
|
local gift_accepted = nil
|
|
|
|
|
local gift_declined = nil
|
|
|
|
|
local pname = clicker:get_player_name()
|
|
|
|
|
|
|
|
|
|
local name_told = goblins.secret_name(self, pname)
|
|
|
|
|
local territory_told = goblins.secret_territory(self, pname)
|
|
|
|
|
local trade_shrewdness = goblins_trade_shrewdness
|
|
|
|
@ -332,7 +336,7 @@ function goblins.give_gift(self,clicker)
|
|
|
|
|
self.path.way = nil
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
--print_s(dump(self.object:get_luaentity()).. " at " ..dump(self.object:getpos()).. " takes: " ..dump(item:get_name()))
|
|
|
|
|
--print_s(dump(self.object:get_luaentity()).. " at " ..dump(self.object:get_pos()).. " takes: " ..dump(item:get_name()))
|
|
|
|
|
if self.drops then
|
|
|
|
|
if debug_goblins_trade then
|
|
|
|
|
print_s("you may get some of "..dump(#self.drops).. " things such as: ")
|
|
|
|
@ -342,30 +346,32 @@ function goblins.give_gift(self,clicker)
|
|
|
|
|
end
|
|
|
|
|
-- we can make some mobs extra stingy despite trade relations
|
|
|
|
|
if not self.shrewdness then self.shrewdness = 1 end
|
|
|
|
|
local pos = self.object:getpos()
|
|
|
|
|
pos.y = pos.y + 0.5
|
|
|
|
|
for _,v in pairs(self.drops) do
|
|
|
|
|
--@d_chance takes all the factors of trade into account for each item in drop list
|
|
|
|
|
local d_chance = 0
|
|
|
|
|
d_chance = ((gift_value + v.chance) * (self.shrewdness + trade_shrewdness)) / (gr_trade + 1)
|
|
|
|
|
--print(v.name.." d_chance = " ..d_chance)
|
|
|
|
|
--more likely to get something really rare , less likely to get something common
|
|
|
|
|
if gift == self.follow[1] then d_chance = self.shrewdness + trade_shrewdness end
|
|
|
|
|
d_chance = math.ceil(d_chance)
|
|
|
|
|
if math.random(d_chance) == 1 then
|
|
|
|
|
if debug_goblins_trade == true then
|
|
|
|
|
print_s(S("\n @1 dropped by @2 at an adjusted chance of 1 in @3", dump(v.name),dump(self.name),dump(d_chance)))
|
|
|
|
|
local pos = self.object:get_pos()
|
|
|
|
|
if pos then
|
|
|
|
|
pos.y = pos.y + 0.5
|
|
|
|
|
for _,v in pairs(self.drops) do
|
|
|
|
|
--@d_chance takes all the factors of trade into account for each item in drop list
|
|
|
|
|
local d_chance = 0
|
|
|
|
|
d_chance = ((gift_value + v.chance) * (self.shrewdness + trade_shrewdness)) / (gr_trade + 1)
|
|
|
|
|
--print(v.name.." d_chance = " ..d_chance)
|
|
|
|
|
--more likely to get something really rare , less likely to get something common
|
|
|
|
|
if gift == self.follow[1] then d_chance = self.shrewdness + trade_shrewdness end
|
|
|
|
|
d_chance = math.ceil(d_chance)
|
|
|
|
|
if math.random(d_chance) == 1 then
|
|
|
|
|
if debug_goblins_trade == true then
|
|
|
|
|
print_s(S("\n @1 dropped by @2 at an adjusted chance of 1 in @3", dump(v.name),dump(self.name),dump(d_chance)))
|
|
|
|
|
end
|
|
|
|
|
minetest.sound_play("goblins_goblin_cackle", {
|
|
|
|
|
pos = pos,
|
|
|
|
|
gain = 0.2,
|
|
|
|
|
max_hear_distance = self.sounds.distance or 10
|
|
|
|
|
})
|
|
|
|
|
--let it go already!
|
|
|
|
|
goblins.mixitup(pos)
|
|
|
|
|
minetest.add_item(pos, {
|
|
|
|
|
name = v.name
|
|
|
|
|
})
|
|
|
|
|
end
|
|
|
|
|
minetest.sound_play("goblins_goblin_cackle", {
|
|
|
|
|
pos = pos,
|
|
|
|
|
gain = 0.2,
|
|
|
|
|
max_hear_distance = self.sounds.distance or 10
|
|
|
|
|
})
|
|
|
|
|
--let it go already!
|
|
|
|
|
goblins.mixitup(pos)
|
|
|
|
|
minetest.add_item(pos, {
|
|
|
|
|
name = v.name
|
|
|
|
|
})
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
@ -382,12 +388,14 @@ function goblins.give_gift(self,clicker)
|
|
|
|
|
if debug_goblins_trade == true then print_s("You did not offer " .. dump(string.split(v,":")[2]) ) end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
local pos = self.object:getpos()
|
|
|
|
|
minetest.sound_play("goblins_goblin_damage", {
|
|
|
|
|
pos = pos,
|
|
|
|
|
gain = 0.2,
|
|
|
|
|
max_hear_distance = self.sounds.distance or 10
|
|
|
|
|
})
|
|
|
|
|
local pos = self.object:get_pos()
|
|
|
|
|
if pos then
|
|
|
|
|
minetest.sound_play("goblins_goblin_damage", {
|
|
|
|
|
pos = pos,
|
|
|
|
|
gain = 0.2,
|
|
|
|
|
max_hear_distance = self.sounds.distance or 10
|
|
|
|
|
})
|
|
|
|
|
end
|
|
|
|
|
if name_told and territory_told then
|
|
|
|
|
minetest.chat_send_player(
|
|
|
|
|
pname,S("@1 of @2 does not want your @3",
|
|
|
|
@ -417,28 +425,28 @@ function goblins.search_replace(
|
|
|
|
|
decorate, --this is for placing attached nodes like goblin mushrooms and torches
|
|
|
|
|
debug_me,
|
|
|
|
|
tools) -- {primary, secondary} based on index# of self.goblin_tools
|
|
|
|
|
local pos = self.object:getpos()
|
|
|
|
|
if mobs_griefing and not minetest.is_protected(pos, "") and math.random(1, search_rate) == 1 then
|
|
|
|
|
local pos = self.object:get_pos()
|
|
|
|
|
if pos and mobs_griefing and not minetest.is_protected(pos, "") and math.random(1, search_rate) == 1 then
|
|
|
|
|
-- look for nodes
|
|
|
|
|
local pos = self.object:getpos()
|
|
|
|
|
local pos1 = self.object:getpos()
|
|
|
|
|
local pos2 = self.object:getpos()
|
|
|
|
|
local pos = self.object:get_pos()
|
|
|
|
|
local pos1 = self.object:get_pos()
|
|
|
|
|
local pos2 = self.object:get_pos()
|
|
|
|
|
|
|
|
|
|
--local pos = vector.round(self.object:getpos()) --will have to investigate these further
|
|
|
|
|
--local pos1 = vector.round(self.object:getpos())
|
|
|
|
|
--local pos2 = vector.round(self.object:getpos())
|
|
|
|
|
--local pos = vector.round(self.object:get_pos()) --will have to investigate these further
|
|
|
|
|
--local pos1 = vector.round(self.object:get_pos())
|
|
|
|
|
--local pos2 = vector.round(self.object:get_pos())
|
|
|
|
|
local tool_set = {}
|
|
|
|
|
if tools then
|
|
|
|
|
tool_set = tools
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- if we are looking, will we look below and by how much?
|
|
|
|
|
if math.random(1, search_rate_below) == 1 then
|
|
|
|
|
if pos1 and math.random(1, search_rate_below) == 1 then
|
|
|
|
|
pos1.y = pos1.y - search_offset_below
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- if we are looking, will we look above and by how much?
|
|
|
|
|
if math.random(1, search_rate_above) == 1 then
|
|
|
|
|
if pos2 and math.random(1, search_rate_above) == 1 then
|
|
|
|
|
pos2.y = pos2.y + search_offset_above
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
@ -547,8 +555,8 @@ function goblins.tunneling(self, type)
|
|
|
|
|
type = "digger"
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local pos = self.object:getpos()
|
|
|
|
|
if mobs_griefing and not minetest.is_protected(pos, "") then
|
|
|
|
|
local pos = self.object:get_pos()
|
|
|
|
|
if pos and mobs_griefing and not minetest.is_protected(pos, "") then
|
|
|
|
|
if self.state == "tunnel" then
|
|
|
|
|
self:set_animation("walk")
|
|
|
|
|
self:set_velocity(self.walk_velocity)
|
|
|
|
@ -655,152 +663,156 @@ function goblins.tunneling(self, type)
|
|
|
|
|
if debug_goblins_tunneling then print_s("goblineer is now making a room") end
|
|
|
|
|
elseif self.state == "tunnel" and math.random() < 0.1 then
|
|
|
|
|
self.state = "stand"
|
|
|
|
|
if debug_goblins_tunneling then print_s(dump(vector.round(self.object:getpos())).. "goblineer is thinking...") end
|
|
|
|
|
if debug_goblins_tunneling then print_s(dump(vector.round(self.object:get_pos())).. "goblineer is thinking...") end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function goblins.danger_dig(self,freq,depth)
|
|
|
|
|
local pos = vector.round(self.object:getpos())
|
|
|
|
|
local lol = minetest.get_node_light(pos) or 0
|
|
|
|
|
local freq = freq or 0.1
|
|
|
|
|
local depth = depth or 1
|
|
|
|
|
local target = table.copy(pos)
|
|
|
|
|
target.y = target.y - depth
|
|
|
|
|
local pos = vector.round(self.object:get_pos())
|
|
|
|
|
if pos then
|
|
|
|
|
local lol = minetest.get_node_light(pos) or 0
|
|
|
|
|
local freq = freq or 0.1
|
|
|
|
|
local depth = depth or 1
|
|
|
|
|
local target = table.copy(pos)
|
|
|
|
|
target.y = target.y - depth
|
|
|
|
|
|
|
|
|
|
if self.light_damage_min and
|
|
|
|
|
lol >= self.light_damage_min and
|
|
|
|
|
mobs_griefing and
|
|
|
|
|
not minetest.is_protected(target, "") and
|
|
|
|
|
math.random() <= freq and
|
|
|
|
|
minetest.get_node(target).name ~="air" then
|
|
|
|
|
local target_node = minetest.get_node(target)
|
|
|
|
|
|
|
|
|
|
if self.state ~= "stand" then self.state = "stand" end
|
|
|
|
|
if self.light_damage_min and
|
|
|
|
|
lol >= self.light_damage_min and
|
|
|
|
|
mobs_griefing and
|
|
|
|
|
not minetest.is_protected(target, "") and
|
|
|
|
|
math.random() <= freq and
|
|
|
|
|
minetest.get_node(target).name ~="air" then
|
|
|
|
|
local target_node = minetest.get_node(target)
|
|
|
|
|
|
|
|
|
|
if self.state ~= "stand" then self.state = "stand" end
|
|
|
|
|
|
|
|
|
|
--find a pick among goblin tools if we can
|
|
|
|
|
if self.goblin_tools and type(self.goblin_tools) == "table" then
|
|
|
|
|
local tool = match_item_list("pick",self.goblin_tools)
|
|
|
|
|
if tool then
|
|
|
|
|
goblins.tool_attach(self,self.goblin_tools[tool])
|
|
|
|
|
--print("changing tool: "..self.goblin_tools[replace])
|
|
|
|
|
--find a pick among goblin tools if we can
|
|
|
|
|
if self.goblin_tools and type(self.goblin_tools) == "table" then
|
|
|
|
|
local tool = match_item_list("pick",self.goblin_tools)
|
|
|
|
|
if tool then
|
|
|
|
|
goblins.tool_attach(self,self.goblin_tools[tool])
|
|
|
|
|
--print("changing tool: "..self.goblin_tools[replace])
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
self:set_velocity(0)
|
|
|
|
|
self:set_animation("punch")
|
|
|
|
|
minetest.remove_node(target)
|
|
|
|
|
local node_above = vector.round(self.object:getpos())
|
|
|
|
|
node_above.y = node_above.y + 2
|
|
|
|
|
local nb_node1 = vector.round(self.object:getpos())
|
|
|
|
|
local nb_node2 = vector.round(self.object:getpos())
|
|
|
|
|
nb_node1.y = node_above.y
|
|
|
|
|
nb_node2.y = node_above.y
|
|
|
|
|
nb_node1.x = nb_node1.x - 1
|
|
|
|
|
nb_node1.z = nb_node1.z - 1
|
|
|
|
|
nb_node2.x = nb_node1.x + 1
|
|
|
|
|
nb_node2.z = nb_node1.z + 1
|
|
|
|
|
local air_nodes = minetest.find_nodes_in_area(nb_node1,nb_node2, "air")
|
|
|
|
|
--print(#nodes)
|
|
|
|
|
if #air_nodes == 1 then
|
|
|
|
|
minetest.set_node(node_above, {name = target_node.name})
|
|
|
|
|
end
|
|
|
|
|
self:set_velocity(0)
|
|
|
|
|
self:set_animation("punch")
|
|
|
|
|
minetest.remove_node(target)
|
|
|
|
|
local node_above = vector.round(self.object:get_pos())
|
|
|
|
|
node_above.y = node_above.y + 2
|
|
|
|
|
local nb_node1 = vector.round(self.object:get_pos())
|
|
|
|
|
local nb_node2 = vector.round(self.object:get_pos())
|
|
|
|
|
nb_node1.y = node_above.y
|
|
|
|
|
nb_node2.y = node_above.y
|
|
|
|
|
nb_node1.x = nb_node1.x - 1
|
|
|
|
|
nb_node1.z = nb_node1.z - 1
|
|
|
|
|
nb_node2.x = nb_node1.x + 1
|
|
|
|
|
nb_node2.z = nb_node1.z + 1
|
|
|
|
|
local air_nodes = minetest.find_nodes_in_area(nb_node1,nb_node2, "air")
|
|
|
|
|
--print(#nodes)
|
|
|
|
|
if #air_nodes == 1 then
|
|
|
|
|
minetest.set_node(node_above, {name = target_node.name})
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function goblins.goblin_dog_behaviors(self)
|
|
|
|
|
local pos = self.object:getpos()
|
|
|
|
|
if math.random() < 0.1 then
|
|
|
|
|
goblins.attack(self)
|
|
|
|
|
--print("looking for a reason to fight")
|
|
|
|
|
end
|
|
|
|
|
if mobs_griefing and not minetest.is_protected(pos, "") then
|
|
|
|
|
if math.random() < 0.5 then
|
|
|
|
|
--consume meaty bones"
|
|
|
|
|
goblins.search_replace(
|
|
|
|
|
self,
|
|
|
|
|
100, --search_rate
|
|
|
|
|
100000, --search_rate_above
|
|
|
|
|
100000, --search_rate_below
|
|
|
|
|
1, --search_offset
|
|
|
|
|
1, --search_offset_above
|
|
|
|
|
1, --search_offset_below
|
|
|
|
|
5, --replace_rate
|
|
|
|
|
{"group:meat","group:food_meat","group:food_meat_raw"}, --replace_what
|
|
|
|
|
"goblins:goblins_goblin_bone", --replace_with
|
|
|
|
|
10, --replace_rate_secondary
|
|
|
|
|
"air", --replace_with_secondary --very hungry
|
|
|
|
|
nil, --decorate
|
|
|
|
|
false --debug_me if debugging also enabled in behaviors.lua
|
|
|
|
|
)
|
|
|
|
|
elseif math.random() < 0.5 then
|
|
|
|
|
--consume dry bones"
|
|
|
|
|
goblins.search_replace(
|
|
|
|
|
self,
|
|
|
|
|
100, --search_rate
|
|
|
|
|
100000, --search_rate_above
|
|
|
|
|
100000, --search_rate_below
|
|
|
|
|
1, --search_offset
|
|
|
|
|
1, --search_offset_above
|
|
|
|
|
1, --search_offset_below
|
|
|
|
|
5, --replace_rate
|
|
|
|
|
"goblins:goblins_goblin_bone", --replace_what
|
|
|
|
|
"air", --replace_with
|
|
|
|
|
nil, --replace_rate_secondary
|
|
|
|
|
nil, --replace_with_secondary
|
|
|
|
|
nil, --decorate
|
|
|
|
|
false--debug_me if debugging also enabled in behaviors.lua
|
|
|
|
|
)
|
|
|
|
|
elseif math.random() < 0.8 then
|
|
|
|
|
--dig and maybe bury bones if theres suitable terrain around
|
|
|
|
|
goblins.search_replace(
|
|
|
|
|
self,
|
|
|
|
|
100, --search_rate
|
|
|
|
|
100000, --search_rate_above
|
|
|
|
|
100, --search_rate_below
|
|
|
|
|
1, --search_offset
|
|
|
|
|
1, --search_offset_above
|
|
|
|
|
2, --search_offset_below
|
|
|
|
|
10, --replace_rate
|
|
|
|
|
{"group:soil",
|
|
|
|
|
"group:sand",
|
|
|
|
|
"default:gravel"}, --replace_what
|
|
|
|
|
"goblins:dirt_with_bone",
|
|
|
|
|
2, --replace_rate_secondary
|
|
|
|
|
"default:dirt", --replace_with_secondary
|
|
|
|
|
nil, --decorate
|
|
|
|
|
false --debug_me if debugging also enabled in behaviors.lua
|
|
|
|
|
)
|
|
|
|
|
else
|
|
|
|
|
--or maybe bury something more useful
|
|
|
|
|
goblins.search_replace(
|
|
|
|
|
self,
|
|
|
|
|
100, --search_rate
|
|
|
|
|
100000, --search_rate_above
|
|
|
|
|
100, --search_rate_below
|
|
|
|
|
1, --search_offset
|
|
|
|
|
1, --search_offset_above
|
|
|
|
|
2, --search_offset_below
|
|
|
|
|
10, --replace_rate
|
|
|
|
|
{"group:soil",
|
|
|
|
|
"group:sand",
|
|
|
|
|
"default:gravel"}, --replace_what
|
|
|
|
|
"goblins:dirt_with_stuff",
|
|
|
|
|
2, --replace_rate_secondary
|
|
|
|
|
"default:dirt", --replace_with_secondary
|
|
|
|
|
nil, --decorate
|
|
|
|
|
false --debug_me if debugging also enabled in behaviors.lua
|
|
|
|
|
)
|
|
|
|
|
local pos = self.object:get_pos()
|
|
|
|
|
if pos then
|
|
|
|
|
if math.random() < 0.1 then
|
|
|
|
|
goblins.attack(self)
|
|
|
|
|
--print("looking for a reason to fight")
|
|
|
|
|
end
|
|
|
|
|
if mobs_griefing and not minetest.is_protected(pos, "") then
|
|
|
|
|
if math.random() < 0.5 then
|
|
|
|
|
--consume meaty bones"
|
|
|
|
|
goblins.search_replace(
|
|
|
|
|
self,
|
|
|
|
|
100, --search_rate
|
|
|
|
|
100000, --search_rate_above
|
|
|
|
|
100000, --search_rate_below
|
|
|
|
|
1, --search_offset
|
|
|
|
|
1, --search_offset_above
|
|
|
|
|
1, --search_offset_below
|
|
|
|
|
5, --replace_rate
|
|
|
|
|
{"group:meat","group:food_meat","group:food_meat_raw"}, --replace_what
|
|
|
|
|
"goblins:goblins_goblin_bone", --replace_with
|
|
|
|
|
10, --replace_rate_secondary
|
|
|
|
|
"air", --replace_with_secondary --very hungry
|
|
|
|
|
nil, --decorate
|
|
|
|
|
false --debug_me if debugging also enabled in behaviors.lua
|
|
|
|
|
)
|
|
|
|
|
elseif math.random() < 0.5 then
|
|
|
|
|
--consume dry bones"
|
|
|
|
|
goblins.search_replace(
|
|
|
|
|
self,
|
|
|
|
|
100, --search_rate
|
|
|
|
|
100000, --search_rate_above
|
|
|
|
|
100000, --search_rate_below
|
|
|
|
|
1, --search_offset
|
|
|
|
|
1, --search_offset_above
|
|
|
|
|
1, --search_offset_below
|
|
|
|
|
5, --replace_rate
|
|
|
|
|
"goblins:goblins_goblin_bone", --replace_what
|
|
|
|
|
"air", --replace_with
|
|
|
|
|
nil, --replace_rate_secondary
|
|
|
|
|
nil, --replace_with_secondary
|
|
|
|
|
nil, --decorate
|
|
|
|
|
false--debug_me if debugging also enabled in behaviors.lua
|
|
|
|
|
)
|
|
|
|
|
elseif math.random() < 0.8 then
|
|
|
|
|
--dig and maybe bury bones if theres suitable terrain around
|
|
|
|
|
goblins.search_replace(
|
|
|
|
|
self,
|
|
|
|
|
100, --search_rate
|
|
|
|
|
100000, --search_rate_above
|
|
|
|
|
100, --search_rate_below
|
|
|
|
|
1, --search_offset
|
|
|
|
|
1, --search_offset_above
|
|
|
|
|
2, --search_offset_below
|
|
|
|
|
10, --replace_rate
|
|
|
|
|
{"group:soil",
|
|
|
|
|
"group:sand",
|
|
|
|
|
"default:gravel"}, --replace_what
|
|
|
|
|
"goblins:dirt_with_bone",
|
|
|
|
|
2, --replace_rate_secondary
|
|
|
|
|
"default:dirt", --replace_with_secondary
|
|
|
|
|
nil, --decorate
|
|
|
|
|
false --debug_me if debugging also enabled in behaviors.lua
|
|
|
|
|
)
|
|
|
|
|
else
|
|
|
|
|
--or maybe bury something more useful
|
|
|
|
|
goblins.search_replace(
|
|
|
|
|
self,
|
|
|
|
|
100, --search_rate
|
|
|
|
|
100000, --search_rate_above
|
|
|
|
|
100, --search_rate_below
|
|
|
|
|
1, --search_offset
|
|
|
|
|
1, --search_offset_above
|
|
|
|
|
2, --search_offset_below
|
|
|
|
|
10, --replace_rate
|
|
|
|
|
{"group:soil",
|
|
|
|
|
"group:sand",
|
|
|
|
|
"default:gravel"}, --replace_what
|
|
|
|
|
"goblins:dirt_with_stuff",
|
|
|
|
|
2, --replace_rate_secondary
|
|
|
|
|
"default:dirt", --replace_with_secondary
|
|
|
|
|
nil, --decorate
|
|
|
|
|
false --debug_me if debugging also enabled in behaviors.lua
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
--[[not quite ready yet...
|
|
|
|
|
if math.random() < 0.01 then
|
|
|
|
|
goblins.do_taunt_at(self)
|
|
|
|
|
print_s("are " ..dump(self.name).. " barking?" )
|
|
|
|
|
end
|
|
|
|
|
--]]
|
|
|
|
|
end
|
|
|
|
|
--[[not quite ready yet...
|
|
|
|
|
if math.random() < 0.01 then
|
|
|
|
|
goblins.do_taunt_at(self)
|
|
|
|
|
print_s("are " ..dump(self.name).. " barking?" )
|
|
|
|
|
end
|
|
|
|
|
--]]
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|