forked from VoxeLibre/VoxeLibre
Compare commits
8 Commits
master
...
fix_skelet
Author | SHA1 | Date |
---|---|---|
nixnoxus | ad97d5326c | |
nixnoxus | 71750e6037 | |
nixnoxus | 6c35f672e8 | |
nixnoxus | ea6d5012e3 | |
nixnoxus | 078f5d760b | |
nixnoxus | 105a702931 | |
nixnoxus | 4dcffc0d5a | |
nixnoxus | 3870f38e87 |
|
@ -128,7 +128,7 @@ functions needed for the mob to work properly which contains the following:
|
||||||
arrow/fireball appears on mob.
|
arrow/fireball appears on mob.
|
||||||
'specific_attack' has a table of entity names that mob can also attack
|
'specific_attack' has a table of entity names that mob can also attack
|
||||||
e.g. {"player", "mobs_animal:chicken"}.
|
e.g. {"player", "mobs_animal:chicken"}.
|
||||||
'runaway_from' contains a table with mob names to run away from, add
|
'runaway_from' contains a table with mob/node names to run away from, add
|
||||||
"player" to list to runaway from player also.
|
"player" to list to runaway from player also.
|
||||||
'pathfinding' set to 1 for mobs to use pathfinder feature to locate
|
'pathfinding' set to 1 for mobs to use pathfinder feature to locate
|
||||||
player, set to 2 so they can build/break also (only
|
player, set to 2 so they can build/break also (only
|
||||||
|
@ -263,6 +263,9 @@ functions needed for the mob to work properly which contains the following:
|
||||||
'noyaw' If true this mob will not automatically change yaw
|
'noyaw' If true this mob will not automatically change yaw
|
||||||
'particlespawners' Table of particlespawners attached to the mob. This is implemented in a coord safe manner i.e. spawners are only sent to players within the player_transfer_distance (and automatically removed). This enables infinitely lived particlespawners.
|
'particlespawners' Table of particlespawners attached to the mob. This is implemented in a coord safe manner i.e. spawners are only sent to players within the player_transfer_distance (and automatically removed). This enables infinitely lived particlespawners.
|
||||||
'attack_frequency' Attack frequency in seconds. If unset, this defaults to 1. Implemented for melee only atm.
|
'attack_frequency' Attack frequency in seconds. If unset, this defaults to 1. Implemented for melee only atm.
|
||||||
|
'avoid_from' contains a table with mob/node names to avoid from, add
|
||||||
|
"player" to list to avoid from player also.
|
||||||
|
|
||||||
|
|
||||||
mobs:gopath(self,target,callback_arrived) pathfind a way to target and run callback on arrival
|
mobs:gopath(self,target,callback_arrived) pathfind a way to target and run callback on arrival
|
||||||
|
|
||||||
|
@ -449,6 +452,16 @@ Create death particles at pos with the given collisionbox.
|
||||||
|
|
||||||
mcl_mobs.spawn(pos,name/entity name)
|
mcl_mobs.spawn(pos,name/entity name)
|
||||||
|
|
||||||
|
|
||||||
|
mcl_mobs:is_object_in_view(object_list, object_range, node_range, turn_around)
|
||||||
|
|
||||||
|
Returns 'true' if an object (mob or node) is in the field of view.
|
||||||
|
|
||||||
|
'object_list' list of mob and/or node names
|
||||||
|
'object_range' maximum distance to a mob from object_list
|
||||||
|
'node_range' maximum distance to a node from object_list
|
||||||
|
'turn_around' true or false
|
||||||
|
|
||||||
Making Arrows
|
Making Arrows
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
|
|
|
@ -289,6 +289,7 @@ function mcl_mobs.register_mob(name, def)
|
||||||
noyaw = def.noyaw or false,
|
noyaw = def.noyaw or false,
|
||||||
particlespawners = def.particlespawners,
|
particlespawners = def.particlespawners,
|
||||||
spawn_check = def.spawn_check,
|
spawn_check = def.spawn_check,
|
||||||
|
avoid_from = def.avoid_from,
|
||||||
-- End of MCL2 extensions
|
-- End of MCL2 extensions
|
||||||
on_spawn = def.on_spawn,
|
on_spawn = def.on_spawn,
|
||||||
on_blast = def.on_blast or function(self,damage)
|
on_blast = def.on_blast or function(self,damage)
|
||||||
|
|
|
@ -509,6 +509,81 @@ function mob_class:do_jump()
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function in_list(list, what)
|
||||||
|
return type(list) == "table" and table.indexof(list, what) ~= -1
|
||||||
|
end
|
||||||
|
|
||||||
|
function mob_class:is_object_in_view(object_list, object_range, node_range, turn_around)
|
||||||
|
local s = self.object:get_pos()
|
||||||
|
local min_dist = object_range + 1
|
||||||
|
local objs = minetest.get_objects_inside_radius(s, object_range)
|
||||||
|
local object_pos = nil
|
||||||
|
|
||||||
|
for n = 1, #objs do
|
||||||
|
local name = ""
|
||||||
|
local object = objs[n]
|
||||||
|
|
||||||
|
if object:is_player() then
|
||||||
|
if not (mcl_mobs.invis[ object:get_player_name() ]
|
||||||
|
or self.owner == object:get_player_name()
|
||||||
|
or (not self:object_in_range(object))) then
|
||||||
|
name = "player"
|
||||||
|
if not (name ~= self.name
|
||||||
|
and in_list(object_list, name)) then
|
||||||
|
local item = object:get_wielded_item()
|
||||||
|
name = item:get_name() or ""
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local obj = object:get_luaentity()
|
||||||
|
|
||||||
|
if obj then
|
||||||
|
object = obj.object
|
||||||
|
name = obj.name or ""
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- find specific mob to avoid or runaway from
|
||||||
|
if name ~= "" and name ~= self.name
|
||||||
|
and in_list(object_list, name) then
|
||||||
|
|
||||||
|
local p = object:get_pos()
|
||||||
|
local dist = vector.distance(p, s)
|
||||||
|
|
||||||
|
-- choose closest player/mob to avoid or runaway from
|
||||||
|
if dist < min_dist
|
||||||
|
-- aim higher to make looking up hills more realistic
|
||||||
|
and self:line_of_sight(vector.offset(s, 0,1,0), vector.offset(p, 0,1,0)) == true then
|
||||||
|
min_dist = dist
|
||||||
|
object_pos = p
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not object_pos then
|
||||||
|
|
||||||
|
-- find specific node to avoid or runaway from
|
||||||
|
local p = minetest.find_node_near(s, node_range, object_list, true)
|
||||||
|
local dist = p and vector.distance(p, s)
|
||||||
|
if dist and dist < min_dist
|
||||||
|
and self:line_of_sight(s, p) == true then
|
||||||
|
min_dist = dist
|
||||||
|
object_pos = p
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if object_pos and turn_around then
|
||||||
|
|
||||||
|
local vec = vector.subtract(object_pos, s)
|
||||||
|
yaw = (atan(vec.z / vec.x) + 3 *math.pi/ 2) - self.rotate
|
||||||
|
if object_pos.x > s.x then yaw = yaw + math.pi end
|
||||||
|
|
||||||
|
yaw = self:set_yaw(yaw, 4)
|
||||||
|
end
|
||||||
|
|
||||||
|
return object_pos ~= nil
|
||||||
|
end
|
||||||
|
|
||||||
-- should mob follow what I'm holding ?
|
-- should mob follow what I'm holding ?
|
||||||
function mob_class:follow_holding(clicker)
|
function mob_class:follow_holding(clicker)
|
||||||
if self.nofollow then return false end
|
if self.nofollow then return false end
|
||||||
|
@ -526,15 +601,9 @@ function mob_class:follow_holding(clicker)
|
||||||
return true
|
return true
|
||||||
|
|
||||||
-- multiple items
|
-- multiple items
|
||||||
elseif t == "table" then
|
elseif t == "table" and in_list(self.follow, item:get_name()) then
|
||||||
|
|
||||||
for no = 1, #self.follow do
|
|
||||||
|
|
||||||
if self.follow[no] == item:get_name() then
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
@ -593,104 +662,14 @@ function mob_class:replace_node(pos)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- specific runaway
|
|
||||||
local specific_runaway = function(list, what)
|
|
||||||
if type(list) ~= "table" then
|
|
||||||
list = {}
|
|
||||||
end
|
|
||||||
|
|
||||||
-- no list so do not run
|
|
||||||
if list == nil then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
-- found entity on list to attack?
|
|
||||||
for no = 1, #list do
|
|
||||||
|
|
||||||
if list[no] == what then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
-- find someone to runaway from
|
-- find someone to runaway from
|
||||||
function mob_class:check_runaway_from()
|
function mob_class:check_runaway_from()
|
||||||
if not self.runaway_from and self.state ~= "flop" then
|
if not self.runaway_from and self.state ~= "flop" then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local s = self.object:get_pos()
|
if self:is_object_in_view(self.runaway_from, self.view_range, self.view_range / 2, true) then
|
||||||
local p, sp, dist
|
self.shaking = self.shaking or 5
|
||||||
local player, obj, min_player
|
|
||||||
local type, name = "", ""
|
|
||||||
local min_dist = self.view_range + 1
|
|
||||||
local objs = minetest.get_objects_inside_radius(s, self.view_range)
|
|
||||||
|
|
||||||
for n = 1, #objs do
|
|
||||||
|
|
||||||
if objs[n]:is_player() then
|
|
||||||
|
|
||||||
if mcl_mobs.invis[ objs[n]:get_player_name() ]
|
|
||||||
or self.owner == objs[n]:get_player_name()
|
|
||||||
or (not self:object_in_range(objs[n])) then
|
|
||||||
type = ""
|
|
||||||
else
|
|
||||||
player = objs[n]
|
|
||||||
type = "player"
|
|
||||||
name = "player"
|
|
||||||
end
|
|
||||||
else
|
|
||||||
obj = objs[n]:get_luaentity()
|
|
||||||
|
|
||||||
if obj then
|
|
||||||
player = obj.object
|
|
||||||
type = obj.type
|
|
||||||
name = obj.name or ""
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- find specific mob to runaway from
|
|
||||||
if name ~= "" and name ~= self.name
|
|
||||||
and specific_runaway(self.runaway_from, name) then
|
|
||||||
|
|
||||||
p = player:get_pos()
|
|
||||||
sp = s
|
|
||||||
|
|
||||||
-- aim higher to make looking up hills more realistic
|
|
||||||
p.y = p.y + 1
|
|
||||||
sp.y = sp.y + 1
|
|
||||||
|
|
||||||
dist = vector.distance(p, s)
|
|
||||||
|
|
||||||
|
|
||||||
-- choose closest player/mpb to runaway from
|
|
||||||
if dist < min_dist
|
|
||||||
and self:line_of_sight(sp, p, 2) == true then
|
|
||||||
min_dist = dist
|
|
||||||
min_player = player
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if min_player then
|
|
||||||
|
|
||||||
local lp = player:get_pos()
|
|
||||||
local vec = {
|
|
||||||
x = lp.x - s.x,
|
|
||||||
y = lp.y - s.y,
|
|
||||||
z = lp.z - s.z
|
|
||||||
}
|
|
||||||
|
|
||||||
local yaw = (atan(vec.z / vec.x) + 3 *math.pi/ 2) - self.rotate
|
|
||||||
|
|
||||||
if lp.x > s.x then
|
|
||||||
yaw = yaw + math.pi
|
|
||||||
end
|
|
||||||
|
|
||||||
yaw = self:set_yaw( yaw, 4)
|
|
||||||
self.state = "runaway"
|
self.state = "runaway"
|
||||||
self.runaway_timer = 3
|
self.runaway_timer = 3
|
||||||
self.following = nil
|
self.following = nil
|
||||||
|
@ -914,23 +893,20 @@ function mob_class:do_states_walk()
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- A danger is near but mob is not inside
|
|
||||||
else
|
|
||||||
|
|
||||||
-- Randomly turn
|
|
||||||
if math.random(1, 100) <= 30 then
|
|
||||||
yaw = yaw + math.random(-0.5, 0.5)
|
|
||||||
yaw = self:set_yaw( yaw, 8)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
yaw = self:set_yaw( yaw, 8)
|
if not is_in_danger then
|
||||||
|
local distance = self.avoid_distance or self.view_range / 2
|
||||||
|
-- find specific node to avoid
|
||||||
|
if self:is_object_in_view(self.avoid_from, distance, distance, true) then
|
||||||
|
self.shaking = self.shaking or 2
|
||||||
|
self:set_velocity(self.walk_velocity)
|
||||||
-- otherwise randomly turn
|
-- otherwise randomly turn
|
||||||
elseif math.random(1, 100) <= 30 then
|
elseif math.random(1, 100) <= 30 then
|
||||||
yaw = yaw + math.random(-0.5, 0.5)
|
yaw = yaw + math.random(-0.5, 0.5)
|
||||||
yaw = self:set_yaw( yaw, 8)
|
yaw = self:set_yaw(yaw, 8)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- stand for great fall or danger or fence in front
|
-- stand for great fall or danger or fence in front
|
||||||
|
@ -938,6 +914,7 @@ function mob_class:do_states_walk()
|
||||||
if is_in_danger then
|
if is_in_danger then
|
||||||
cliff_or_danger = self:is_at_cliff_or_danger()
|
cliff_or_danger = self:is_at_cliff_or_danger()
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.facing_fence == true
|
if self.facing_fence == true
|
||||||
or cliff_or_danger
|
or cliff_or_danger
|
||||||
or math.random(1, 100) <= 30 then
|
or math.random(1, 100) <= 30 then
|
||||||
|
@ -1086,6 +1063,12 @@ function mob_class:check_smooth_rotation(dtime)
|
||||||
self.delay = self.delay - 1
|
self.delay = self.delay - 1
|
||||||
if self.shaking then
|
if self.shaking then
|
||||||
yaw = yaw + (math.random() * 2 - 1) * 5 * dtime
|
yaw = yaw + (math.random() * 2 - 1) * 5 * dtime
|
||||||
|
if type(self.shaking) == "number" then
|
||||||
|
self.shaking = self.shaking - dtime
|
||||||
|
if self.shaking <= 0 then
|
||||||
|
self.shaking = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
self.object:set_yaw(yaw)
|
self.object:set_yaw(yaw)
|
||||||
--self:update_roll()
|
--self:update_roll()
|
||||||
|
|
|
@ -40,6 +40,17 @@ local hoglin = {
|
||||||
makes_footstep_sound = true,
|
makes_footstep_sound = true,
|
||||||
walk_velocity = 1,
|
walk_velocity = 1,
|
||||||
run_velocity = 2.8,
|
run_velocity = 2.8,
|
||||||
|
avoid_from = {
|
||||||
|
"mcl_crimson:warped_fungus",
|
||||||
|
"mcl_flowerpots:flower_pot_warped_fungus",
|
||||||
|
"mcl_portals:portal",
|
||||||
|
"mcl_beds:respawn_anchor",
|
||||||
|
"mcl_beds:respawn_anchor_charged_1",
|
||||||
|
"mcl_beds:respawn_anchor_charged_2",
|
||||||
|
"mcl_beds:respawn_anchor_charged_3",
|
||||||
|
"mcl_beds:respawn_anchor_charged_4",
|
||||||
|
},
|
||||||
|
follow = {"mcl_crimson:crimson_fungus"},
|
||||||
drops = {
|
drops = {
|
||||||
{name = "mobs_mcitems:leather",
|
{name = "mobs_mcitems:leather",
|
||||||
chance = 1,
|
chance = 1,
|
||||||
|
@ -87,9 +98,26 @@ local hoglin = {
|
||||||
attack_animals = true,
|
attack_animals = true,
|
||||||
}
|
}
|
||||||
|
|
||||||
mcl_mobs.register_mob("mobs_mc:hoglin", hoglin)
|
|
||||||
|
|
||||||
local zoglin = table.copy(hoglin)
|
local zoglin = table.copy(hoglin)
|
||||||
|
hoglin.on_rightclick = function(self, clicker)
|
||||||
|
-- local item = clicker:get_wielded_item()
|
||||||
|
if self:feed_tame(clicker, 1, true, false) then return end
|
||||||
|
-- if mcl_mobs:protect(self, clicker) then return end
|
||||||
|
end
|
||||||
|
hoglin.on_breed = function(parent1, parent2)
|
||||||
|
local pos = parent1.object:get_pos()
|
||||||
|
local child = mcl_mobs.spawn_child(pos, parent1.name)
|
||||||
|
if child then
|
||||||
|
local ent_c = child:get_luaentity()
|
||||||
|
-- ent_c.tamed = true
|
||||||
|
ent_c.owner = parent1.owner
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
|
mcl_mobs.register_mob("mobs_mc:hoglin", hoglin)
|
||||||
|
|
||||||
zoglin.description = S("Zoglin")
|
zoglin.description = S("Zoglin")
|
||||||
zoglin.fire_resistant = 1
|
zoglin.fire_resistant = 1
|
||||||
zoglin.textures = {"extra_mobs_zoglin.png"}
|
zoglin.textures = {"extra_mobs_zoglin.png"}
|
||||||
|
|
|
@ -42,6 +42,7 @@ local rabbit = {
|
||||||
makes_footstep_sound = false,
|
makes_footstep_sound = false,
|
||||||
walk_velocity = 1,
|
walk_velocity = 1,
|
||||||
run_velocity = 3.7,
|
run_velocity = 3.7,
|
||||||
|
avoid_from = {"mobs_mc:wolf"},
|
||||||
follow_velocity = 1.1,
|
follow_velocity = 1.1,
|
||||||
floats = 1,
|
floats = 1,
|
||||||
runaway = true,
|
runaway = true,
|
||||||
|
|
|
@ -46,6 +46,7 @@ local skeleton = {
|
||||||
},
|
},
|
||||||
walk_velocity = 1.2,
|
walk_velocity = 1.2,
|
||||||
run_velocity = 2.0,
|
run_velocity = 2.0,
|
||||||
|
runaway_from = {"mobs_mc:wolf"},
|
||||||
damage = 2,
|
damage = 2,
|
||||||
reach = 2,
|
reach = 2,
|
||||||
drops = {
|
drops = {
|
||||||
|
|
|
@ -44,6 +44,7 @@ mcl_mobs.register_mob("mobs_mc:witherskeleton", {
|
||||||
},
|
},
|
||||||
walk_velocity = 1.2,
|
walk_velocity = 1.2,
|
||||||
run_velocity = 2.0,
|
run_velocity = 2.0,
|
||||||
|
runaway_from = {"mobs_mc:wolf"},
|
||||||
damage = 7,
|
damage = 7,
|
||||||
reach = 2,
|
reach = 2,
|
||||||
drops = {
|
drops = {
|
||||||
|
|
|
@ -97,7 +97,16 @@ local wolf = {
|
||||||
jump = true,
|
jump = true,
|
||||||
attacks_monsters = true,
|
attacks_monsters = true,
|
||||||
attack_animals = true,
|
attack_animals = true,
|
||||||
specific_attack = { "player", "mobs_mc:sheep" },
|
specific_attack = {
|
||||||
|
"player",
|
||||||
|
"mobs_mc:sheep",
|
||||||
|
"mobs_mc:rabbit",
|
||||||
|
-- TODO: "mobs_mc:fox",
|
||||||
|
"mobs_mc:skeleton",
|
||||||
|
"mobs_mc:stray",
|
||||||
|
"mobs_mc:witherskeleton",
|
||||||
|
},
|
||||||
|
avoid_from = { "mobs_mc:llama" },
|
||||||
}
|
}
|
||||||
|
|
||||||
mcl_mobs.register_mob("mobs_mc:wolf", wolf)
|
mcl_mobs.register_mob("mobs_mc:wolf", wolf)
|
||||||
|
|
Loading…
Reference in New Issue