forked from MineClone5/MineClone5
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,
|
||||
tamed = false,
|
||||
pause_timer = 0,
|
||||
horny = false,
|
||||
hornytimer = 0,
|
||||
gotten = false,
|
||||
health = 0,
|
||||
reach = def.reach or 3,
|
||||
|
@ -298,7 +296,6 @@ function mobs:register_mob(name, def)
|
|||
owner_loyal = def.owner_loyal,
|
||||
facing_fence = false,
|
||||
|
||||
|
||||
_cmi_is_mob = true,
|
||||
|
||||
pushable = def.pushable or true,
|
||||
|
@ -331,6 +328,12 @@ function mobs:register_mob(name, def)
|
|||
skittish = def.skittish,
|
||||
lifetimer_reset = 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
|
||||
|
||||
-- MCL2 extensions
|
||||
|
|
|
@ -6,6 +6,7 @@ local math_round = math.round
|
|||
local vector_multiply = vector.multiply
|
||||
local vector_add = vector.add
|
||||
local vector_new = vector.new
|
||||
local vector_distance = vector.distance
|
||||
|
||||
local minetest_yaw_to_dir = minetest.yaw_to_dir
|
||||
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)
|
||||
|
||||
--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
|
||||
|
||||
--only run away
|
||||
|
@ -76,18 +78,27 @@ local land_state_switch = function(self, dtime)
|
|||
if self.run_timer > 0 then
|
||||
return
|
||||
end
|
||||
|
||||
--continue
|
||||
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
|
||||
if self.hostile and self.attacking then
|
||||
self.state = "attack"
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
|
||||
--if finally reached here then do random wander
|
||||
if self.state_timer <= 0 then
|
||||
self.state_timer = math.random(4,10) + math.random()
|
||||
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
|
||||
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 collisionbox = self.object:get_properties().collisionbox
|
||||
--get the center of the mob
|
||||
|
@ -145,6 +166,24 @@ local land_state_execution = function(self,dtime)
|
|||
|
||||
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
|
||||
|
||||
self.walk_timer = self.walk_timer - dtime
|
||||
|
@ -697,7 +736,7 @@ mobs.mob_step = function(self, dtime)
|
|||
end
|
||||
|
||||
--despawn mechanism
|
||||
--don't despawned tamed mobs
|
||||
--don't despawned tamed or bred mobs
|
||||
if not self.tamed and not self.bred then
|
||||
self.lifetimer = self.lifetimer - dtime
|
||||
if self.lifetimer <= 0 then
|
||||
|
|
|
@ -213,4 +213,26 @@ mobs.handle_explosion_animation = function(self)
|
|||
visual_size_modified.y = visual_size_modified.y * explosion_timer_adjust
|
||||
|
||||
self.object:set_properties({visual_size = visual_size_modified})
|
||||
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)
|
||||
|
||||
--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 mobs.check_for_player_within_area(self, 64) then
|
||||
--print("removing SERIALIZED!")
|
||||
|
|
|
@ -50,13 +50,13 @@ local cow_def = {
|
|||
},
|
||||
follow = mobs_mc.follow.cow,
|
||||
on_rightclick = function(self, clicker)
|
||||
if mobs:feed_tame(self, clicker, 1, true, true) then
|
||||
return
|
||||
end
|
||||
--if mobs:feed_tame(self, clicker, 1, true, true) then
|
||||
--return
|
||||
--end
|
||||
|
||||
if self.child then
|
||||
return
|
||||
end
|
||||
--if self.child then
|
||||
-- return
|
||||
--end
|
||||
|
||||
local item = clicker:get_wielded_item()
|
||||
if item:get_name() == mobs_mc.items.bucket and clicker:get_inventory() then
|
||||
|
@ -74,6 +74,8 @@ local cow_def = {
|
|||
return
|
||||
end
|
||||
end,
|
||||
breedable = true,
|
||||
follow_distance = 2,
|
||||
follow = mobs_mc.items.wheat,
|
||||
view_range = 10,
|
||||
fear_height = 4,
|
||||
|
|
Loading…
Reference in New Issue