forked from VoxeLibre/VoxeLibre
Add in mob following for cows
This commit is contained in:
parent
fcfd6b9d19
commit
ed9d629b99
|
@ -265,8 +265,6 @@ function mobs:register_mob(name, def)
|
||||||
env_damage_timer = 0,
|
env_damage_timer = 0,
|
||||||
tamed = false,
|
tamed = false,
|
||||||
pause_timer = 0,
|
pause_timer = 0,
|
||||||
horny = false,
|
|
||||||
hornytimer = 0,
|
|
||||||
gotten = false,
|
gotten = false,
|
||||||
health = 0,
|
health = 0,
|
||||||
reach = def.reach or 3,
|
reach = def.reach or 3,
|
||||||
|
@ -298,7 +296,6 @@ function mobs:register_mob(name, def)
|
||||||
owner_loyal = def.owner_loyal,
|
owner_loyal = def.owner_loyal,
|
||||||
facing_fence = false,
|
facing_fence = false,
|
||||||
|
|
||||||
|
|
||||||
_cmi_is_mob = true,
|
_cmi_is_mob = true,
|
||||||
|
|
||||||
pushable = def.pushable or true,
|
pushable = def.pushable or true,
|
||||||
|
@ -331,6 +328,12 @@ function mobs:register_mob(name, def)
|
||||||
skittish = def.skittish,
|
skittish = def.skittish,
|
||||||
lifetimer_reset = 30, --30 seconds
|
lifetimer_reset = 30, --30 seconds
|
||||||
lifetimer = 30, --30 seconds
|
lifetimer = 30, --30 seconds
|
||||||
|
|
||||||
|
breedable = def.breedable,
|
||||||
|
breed_timer = 0,
|
||||||
|
breed_cooloff_timer = 5*60, -- 5 minutes
|
||||||
|
bred = false,
|
||||||
|
follow_distance = def.follow_distance or 2,
|
||||||
--end j4i stuff
|
--end j4i stuff
|
||||||
|
|
||||||
-- MCL2 extensions
|
-- MCL2 extensions
|
||||||
|
|
|
@ -6,6 +6,7 @@ local math_round = math.round
|
||||||
local vector_multiply = vector.multiply
|
local vector_multiply = vector.multiply
|
||||||
local vector_add = vector.add
|
local vector_add = vector.add
|
||||||
local vector_new = vector.new
|
local vector_new = vector.new
|
||||||
|
local vector_distance = vector.distance
|
||||||
|
|
||||||
local minetest_yaw_to_dir = minetest.yaw_to_dir
|
local minetest_yaw_to_dir = minetest.yaw_to_dir
|
||||||
local minetest_get_item_group = minetest.get_item_group
|
local minetest_get_item_group = minetest.get_item_group
|
||||||
|
@ -67,7 +68,8 @@ local land_state_list_wandering = {"stand", "walk"}
|
||||||
|
|
||||||
local land_state_switch = function(self, dtime)
|
local land_state_switch = function(self, dtime)
|
||||||
|
|
||||||
--do math after sure not attacking or running away
|
--do math before sure not attacking, following, or running away so continue
|
||||||
|
--doing random walking for mobs if all states are not met
|
||||||
self.state_timer = self.state_timer - dtime
|
self.state_timer = self.state_timer - dtime
|
||||||
|
|
||||||
--only run away
|
--only run away
|
||||||
|
@ -76,18 +78,27 @@ local land_state_switch = function(self, dtime)
|
||||||
if self.run_timer > 0 then
|
if self.run_timer > 0 then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
--continue
|
--continue
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--ignore everything else if following
|
||||||
|
if mobs.check_following(self) then
|
||||||
|
self.state = "follow"
|
||||||
|
return
|
||||||
|
--reset the state timer to get the mob out of
|
||||||
|
--the follow state - not the cleanest option
|
||||||
|
--but the easiest
|
||||||
|
elseif self.state == "follow" then
|
||||||
|
self.state_timer = 0
|
||||||
|
end
|
||||||
|
|
||||||
--only attack
|
--only attack
|
||||||
if self.hostile and self.attacking then
|
if self.hostile and self.attacking then
|
||||||
self.state = "attack"
|
self.state = "attack"
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--if finally reached here then do random wander
|
||||||
|
|
||||||
if self.state_timer <= 0 then
|
if self.state_timer <= 0 then
|
||||||
self.state_timer = math.random(4,10) + math.random()
|
self.state_timer = math.random(4,10) + math.random()
|
||||||
self.state = land_state_list_wandering[math.random(1,#land_state_list_wandering)]
|
self.state = land_state_list_wandering[math.random(1,#land_state_list_wandering)]
|
||||||
|
@ -103,6 +114,16 @@ local land_state_execution = function(self,dtime)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--cool off after breeding
|
||||||
|
if self.breed_timer and self.breed_timer > 0 then
|
||||||
|
self.breed_timer = self.breed_timer - dtime
|
||||||
|
--do this to skip the first check, using as switch
|
||||||
|
if self.breed_timer <= 0 then
|
||||||
|
self.breed_timer = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
local pos = self.object:get_pos()
|
local pos = self.object:get_pos()
|
||||||
local collisionbox = self.object:get_properties().collisionbox
|
local collisionbox = self.object:get_properties().collisionbox
|
||||||
--get the center of the mob
|
--get the center of the mob
|
||||||
|
@ -145,6 +166,24 @@ local land_state_execution = function(self,dtime)
|
||||||
|
|
||||||
mobs.lock_yaw(self)
|
mobs.lock_yaw(self)
|
||||||
|
|
||||||
|
elseif self.state == "follow" then
|
||||||
|
|
||||||
|
mobs.set_yaw_while_following(self)
|
||||||
|
|
||||||
|
local distance_from_follow_person = vector_distance(self.object:get_pos(), self.following_person:get_pos())
|
||||||
|
|
||||||
|
if self.follow_distance < distance_from_follow_person then
|
||||||
|
mobs.set_mob_animation(self, "run")
|
||||||
|
mobs.set_velocity(self,self.run_velocity)
|
||||||
|
|
||||||
|
if mobs.jump_check(self) == 1 then
|
||||||
|
mobs.jump(self)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
mobs.set_mob_animation(self, "stand")
|
||||||
|
mobs.set_velocity(self,0)
|
||||||
|
end
|
||||||
|
|
||||||
elseif self.state == "walk" then
|
elseif self.state == "walk" then
|
||||||
|
|
||||||
self.walk_timer = self.walk_timer - dtime
|
self.walk_timer = self.walk_timer - dtime
|
||||||
|
@ -697,7 +736,7 @@ mobs.mob_step = function(self, dtime)
|
||||||
end
|
end
|
||||||
|
|
||||||
--despawn mechanism
|
--despawn mechanism
|
||||||
--don't despawned tamed mobs
|
--don't despawned tamed or bred mobs
|
||||||
if not self.tamed and not self.bred then
|
if not self.tamed and not self.bred then
|
||||||
self.lifetimer = self.lifetimer - dtime
|
self.lifetimer = self.lifetimer - dtime
|
||||||
if self.lifetimer <= 0 then
|
if self.lifetimer <= 0 then
|
||||||
|
|
|
@ -214,3 +214,25 @@ mobs.handle_explosion_animation = function(self)
|
||||||
|
|
||||||
self.object:set_properties({visual_size = visual_size_modified})
|
self.object:set_properties({visual_size = visual_size_modified})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--this is used when a mob is following player
|
||||||
|
mobs.set_yaw_while_following = function(self)
|
||||||
|
|
||||||
|
if self.object:get_properties().automatic_face_movement_dir then
|
||||||
|
self.object:set_properties{automatic_face_movement_dir = false}
|
||||||
|
end
|
||||||
|
|
||||||
|
--turn positions into pseudo 2d vectors
|
||||||
|
local pos1 = self.object:get_pos()
|
||||||
|
pos1.y = 0
|
||||||
|
|
||||||
|
local pos2 = self.following_person:get_pos()
|
||||||
|
pos2.y = 0
|
||||||
|
|
||||||
|
local new_direction = vector_direction(pos1,pos2)
|
||||||
|
local new_yaw = minetest_dir_to_yaw(new_direction)
|
||||||
|
|
||||||
|
self.object:set_yaw(new_yaw)
|
||||||
|
self.yaw = new_yaw
|
||||||
|
end
|
|
@ -0,0 +1,33 @@
|
||||||
|
--check to see if someone nearby has some tasty food
|
||||||
|
mobs.check_following = function(self) -- returns true or false
|
||||||
|
|
||||||
|
--ignore
|
||||||
|
if not self.follow then
|
||||||
|
self.following_person = nil
|
||||||
|
return(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
--hey look, this thing works for passive mobs too!
|
||||||
|
local follower = mobs.detect_closest_player_within_radius(self,true,self.view_range,self.eye_height)
|
||||||
|
|
||||||
|
--check if the follower is a player incase they log out
|
||||||
|
if follower and follower:is_player() then
|
||||||
|
local stack = follower:get_wielded_item()
|
||||||
|
--safety check
|
||||||
|
if not stack then
|
||||||
|
self.following_person = nil
|
||||||
|
return(false)
|
||||||
|
end
|
||||||
|
local item_name = stack:get_name()
|
||||||
|
|
||||||
|
--all checks have passed, that guy has some good looking food
|
||||||
|
if item_name == self.follow then
|
||||||
|
self.following_person = follower
|
||||||
|
return(true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--everything failed
|
||||||
|
self.following_person = nil
|
||||||
|
return(false)
|
||||||
|
end
|
|
@ -6,7 +6,7 @@ local minetest_settings = minetest.settings
|
||||||
mobs.mob_staticdata = function(self)
|
mobs.mob_staticdata = function(self)
|
||||||
|
|
||||||
--despawn mechanism
|
--despawn mechanism
|
||||||
--don't despawned tamed mobs
|
--don't despawned tamed or bred mobs
|
||||||
if not self.tamed and not self.bred then
|
if not self.tamed and not self.bred then
|
||||||
if not mobs.check_for_player_within_area(self, 64) then
|
if not mobs.check_for_player_within_area(self, 64) then
|
||||||
--print("removing SERIALIZED!")
|
--print("removing SERIALIZED!")
|
||||||
|
|
|
@ -50,13 +50,13 @@ local cow_def = {
|
||||||
},
|
},
|
||||||
follow = mobs_mc.follow.cow,
|
follow = mobs_mc.follow.cow,
|
||||||
on_rightclick = function(self, clicker)
|
on_rightclick = function(self, clicker)
|
||||||
if mobs:feed_tame(self, clicker, 1, true, true) then
|
--if mobs:feed_tame(self, clicker, 1, true, true) then
|
||||||
return
|
--return
|
||||||
end
|
--end
|
||||||
|
|
||||||
if self.child then
|
--if self.child then
|
||||||
return
|
-- return
|
||||||
end
|
--end
|
||||||
|
|
||||||
local item = clicker:get_wielded_item()
|
local item = clicker:get_wielded_item()
|
||||||
if item:get_name() == mobs_mc.items.bucket and clicker:get_inventory() then
|
if item:get_name() == mobs_mc.items.bucket and clicker:get_inventory() then
|
||||||
|
@ -74,6 +74,8 @@ local cow_def = {
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
breedable = true,
|
||||||
|
follow_distance = 2,
|
||||||
follow = mobs_mc.items.wheat,
|
follow = mobs_mc.items.wheat,
|
||||||
view_range = 10,
|
view_range = 10,
|
||||||
fear_height = 4,
|
fear_height = 4,
|
||||||
|
|
Loading…
Reference in New Issue