diff --git a/mods/ENTITIES/mcl_mobs/api/api.lua b/mods/ENTITIES/mcl_mobs/api/api.lua index 235453918c..0d1a347c58 100644 --- a/mods/ENTITIES/mcl_mobs/api/api.lua +++ b/mods/ENTITIES/mcl_mobs/api/api.lua @@ -164,6 +164,7 @@ dofile(api_path .. "sound_handling.lua") dofile(api_path .. "death_logic.lua") dofile(api_path .. "mob_effects.lua") dofile(api_path .. "projectile_handling.lua") +dofile(api_path .. "breeding.lua") mobs.spawning_mobs = {} @@ -244,7 +245,6 @@ function mobs:register_mob(name, def) shoot_interval = def.shoot_interval, sounds = def.sounds or {}, animation = def.animation, - follow = def.follow, jump = def.jump ~= false, walk_chance = def.walk_chance or 50, attacks_monsters = def.attacks_monsters or false, @@ -264,8 +264,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, @@ -297,7 +295,6 @@ function mobs:register_mob(name, def) owner_loyal = def.owner_loyal, facing_fence = false, - _cmi_is_mob = true, pushable = def.pushable or true, @@ -330,6 +327,25 @@ function mobs:register_mob(name, def) skittish = def.skittish, lifetimer_reset = 30, --30 seconds lifetimer = 30, --30 seconds + + --breeding stuff + breed_timer = 0, + breed_lookout_timer = 0, + breed_distance = def.breed_distance or 1.5, --how far away mobs have to be to begin actual breeding + breed_lookout_timer_goal = 30, --30 seconds (this timer is for how long the mob looks for a mate) + breed_timer_cooloff = 5*60, -- 5 minutes (this timer is for how long the mob has to wait before being bred again) + bred = false, + follow = def.follow, --this item is also used for the breeding mechanism + follow_distance = def.follow_distance or 2, + baby_size = def.baby_size or 0.5, + baby = false, + grow_up_timer = 0, + grow_up_goal = 20*60, --in 20 minutes the mob grows up + special_breed_timer = 0, --this is used for the AHEM AHEM part of breeding + + backup_visual_size = def.visual_size, + backup_collisionbox = collisionbox, + backup_selectionbox = def.selectionbox or def.collisionbox, --end j4i stuff -- MCL2 extensions diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/ai.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/ai.lua index 5295060640..b5af5f5330 100644 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/ai.lua +++ b/mods/ENTITIES/mcl_mobs/api/mob_functions/ai.lua @@ -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,39 @@ local land_state_switch = function(self, dtime) if self.run_timer > 0 then return end - --continue end + --ignore everything else if breeding + if self.breed_lookout_timer and self.breed_lookout_timer > 0 then + self.state = "breed" + return + --reset the state timer to get the mob out of + --the breed state + elseif self.state == "breed" then + self.state_timer = 0 + end + + --ignore everything else if following + if mobs.check_following(self) and + (not self.breed_lookout_timer or (self.breed_lookout_timer and self.breed_lookout_timer == 0)) and + (not self.breed_timer or (self.breed_timer and self.breed_timer == 0)) 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)] @@ -98,10 +121,40 @@ end -- states are executed here local land_state_execution = function(self,dtime) + --[[ -- this is a debug which shows the timer and makes mobs breed 100 times faster + print(self.breed_timer) + if self.breed_timer > 0 then + self.breed_timer = self.breed_timer - (dtime * 100) + if self.breed_timer <= 0 then + self.breed_timer = 0 + end + end + ]]-- + --no collisionbox exception if not self.object:get_properties() then return end + + + --timer to time out looking for mate + if self.breed_lookout_timer and self.breed_lookout_timer > 0 then + self.breed_lookout_timer = self.breed_lookout_timer - dtime + --looking for mate failed + if self.breed_lookout_timer <= 0 then + self.breed_lookout_timer = 0 + 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 = 0 + end + end + local pos = self.object:get_pos() local collisionbox = self.object:get_properties().collisionbox @@ -144,6 +197,26 @@ local land_state_execution = function(self,dtime) end mobs.lock_yaw(self) + elseif self.state == "follow" then + + --always look at players + mobs.set_yaw_while_following(self) + + --check distance + local distance_from_follow_person = vector_distance(self.object:get_pos(), self.following_person:get_pos()) + + --don't push the player if too close + 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 @@ -246,6 +319,48 @@ local land_state_execution = function(self,dtime) mobs.projectile_attack_walk(self,dtime) end + elseif self.state == "breed" then + + mobs.breeding_effect(self) + + local mate = mobs.look_for_mate(self) + + --found a mate + if mate then + mobs.set_yaw_while_breeding(self,mate) + mobs.set_velocity(self, self.walk_velocity) + + --smoosh together basically + if vector_distance(self.object:get_pos(), mate:get_pos()) <= self.breed_distance then + mobs.set_mob_animation(self, "stand") + if self.special_breed_timer == 0 then + self.special_breed_timer = 2 --breeding takes 2 seconds + end + + self.special_breed_timer = self.special_breed_timer - dtime + if self.special_breed_timer <= 0 then + + --pop a baby out, it's a miracle! + local baby_pos = vector.divide(vector.add(self.object:get_pos(), mate:get_pos()), 2) + local baby_mob = minetest.add_entity(pos, self.name, minetest.serialize({baby = true, grow_up_timer = self.grow_up_goal, bred = true})) + + self.special_breed_timer = 0 + self.breed_lookout_timer = 0 + self.breed_timer = self.breed_timer_cooloff + + mate:get_luaentity().special_breed_timer = 0 + mate:get_luaentity().breed_lookout_timer = 0 + mate:get_luaentity().breed_timer = self.breed_timer_cooloff -- can reuse because it's the same mob + end + else + mobs.set_mob_animation(self, "walk") + end + --couldn't find a mate, just stand there until the player pushes it towards one + --or the timer runs out + else + mobs.set_mob_animation(self, "stand") + mobs.set_velocity(self,0) + end end @@ -697,8 +812,8 @@ mobs.mob_step = function(self, dtime) end --despawn mechanism - --don't despawned tamed mobs - if not self.tamed then + --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 self.lifetimer = self.lifetimer_reset @@ -735,6 +850,24 @@ mobs.mob_step = function(self, dtime) return end + --baby grows up + if self.baby then + --print(self.grow_up_timer) + --catch missing timer + if not self.grow_up_timer then + self.grow_up_timer = self.grow_up_goal + end + + self.grow_up_timer = self.grow_up_timer - dtime + + --baby grows up! + if self.grow_up_timer <= 0 then + self.grow_up_timer = 0 + mobs.baby_grow_up(self) + end + end + + --do custom mob instructions if self.do_custom then diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/animation.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/animation.lua index fbf140034c..c26d330897 100644 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/animation.lua +++ b/mods/ENTITIES/mcl_mobs/api/mob_functions/animation.lua @@ -213,4 +213,47 @@ 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 + +--this is used for when mobs breed +mobs.set_yaw_while_breeding = function(self, mate) + + 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 = mate: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 \ No newline at end of file diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/breeding.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/breeding.lua new file mode 100644 index 0000000000..f71018aba5 --- /dev/null +++ b/mods/ENTITIES/mcl_mobs/api/mob_functions/breeding.lua @@ -0,0 +1,177 @@ +local minetest_get_objects_inside_radius = minetest.get_objects_inside_radius + +local vector_distance = vector.distance + +--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 + +--a function which attempts to make mobs enter +--the breeding state +mobs.enter_breed_state = function(self,clicker) + + --do not breed if baby + if self.baby then + return(false) + end + + --do not do anything if looking for mate or + --if cooling off from breeding + if self.breed_lookout_timer > 0 or self.breed_timer > 0 then + return(false) + end + + --if this is caught, that means something has gone + --seriously wrong + if not clicker or not clicker:is_player() then + return(false) + end + + local stack = clicker:get_wielded_item() + --safety check + if not stack then + 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 + if not minetest.is_creative_enabled(clicker:get_player_name()) then + stack:take_item() + clicker:set_wielded_item(stack) + end + self.breed_lookout_timer = self.breed_lookout_timer_goal + self.bred = true + return(true) + end + + --everything failed + return(false) +end + + +--find the closest mate in the area +mobs.look_for_mate = function(self) + + local pos1 = self.object:get_pos() + pos1.y = pos1.y + self.eye_height + + local mates_in_area = {} + local winner_mate = nil + local mates_detected = 0 + local radius = self.view_range + + --get mates in radius + for _,mate in pairs(minetest_get_objects_inside_radius(pos1, radius)) do + + --look for a breeding mate + if mate and mate:get_luaentity() + and mate:get_luaentity()._cmi_is_mob + and mate:get_luaentity().name == self.name + and mate:get_luaentity().breed_lookout_timer > 0 + and mate:get_luaentity() ~= self then + + local pos2 = mate:get_pos() + + local distance = vector_distance(pos1,pos2) + + if distance <= radius then + if line_of_sight then + --must add eye height or stuff breaks randomly because of + --seethrough nodes being a blocker (like grass) + if minetest_line_of_sight( + vector_new(pos1.x, pos1.y, pos1.z), + vector_new(pos2.x, pos2.y + mate:get_properties().eye_height, pos2.z) + ) then + mates_detected = mates_detected + 1 + mates_in_area[mate] = distance + end + else + mates_detected = mates_detected + 1 + mates_in_area[mate] = distance + end + end + end + end + + + --return if there's no one near by + if mates_detected <= 0 then --handle negative numbers for some crazy error that could possibly happen + return nil + end + + --do a default radius max + local shortest_distance = radius + 1 + + --sort through mates and find the closest mate + for mate,distance in pairs(mates_in_area) do + if distance < shortest_distance then + shortest_distance = distance + winner_mate = mate + end + end + + return(winner_mate) + +end + +--make the baby grow up +mobs.baby_grow_up = function(self) + self.baby = nil + self.visual_size = self.backup_visual_size + self.collisionbox = self.backup_collisionbox + self.selectionbox = self.backup_selectionbox + self.object:set_properties(self) +end + +--makes the baby grow up faster with diminishing returns +mobs.make_baby_grow_faster = function(self,clicker) + if clicker and clicker:is_player() then + local stack = clicker:get_wielded_item() + --safety check + if not stack then + return + 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.grow_up_timer = self.grow_up_timer - (self.grow_up_timer * 0.10) --take 10 percent off - diminishing returns + + if not minetest.is_creative_enabled(clicker:get_player_name()) then + stack:take_item() + clicker:set_wielded_item(stack) + end + end + end +end \ No newline at end of file diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/environment.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/environment.lua index fe77305b0d..5b5dc5d47a 100644 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/environment.lua +++ b/mods/ENTITIES/mcl_mobs/api/mob_functions/environment.lua @@ -9,6 +9,7 @@ local minetest_registered_nodes = minetest.registered_nodes local minetest_get_connected_players = minetest.get_connected_players local vector_new = vector.new +local vector_add = vector.add local vector_multiply = vector.multiply local vector_distance = vector.distance @@ -39,7 +40,7 @@ mobs.detect_closest_player_within_radius = function(self, line_of_sight, radius, local pos2 = player:get_pos() - local distance = vector.distance(pos1,pos2) + local distance = vector_distance(pos1,pos2) if distance <= radius then if line_of_sight then @@ -67,12 +68,12 @@ mobs.detect_closest_player_within_radius = function(self, line_of_sight, radius, end --do a default radius max - local shortest_disance = radius + 1 + local shortest_distance = radius + 1 --sort through players and find the closest player for player,distance in pairs(players_in_area) do - if distance < shortest_disance then - shortest_disance = distance + if distance < shortest_distance then + shortest_distance = distance winner_player = player end end @@ -94,7 +95,7 @@ mobs.jump_check = function(self,dtime) vector_multiply(dir, radius) --only jump if there's a node and a non-solid node above it - local test_dir = vector.add(pos,dir) + local test_dir = vector_add(pos,dir) local green_flag_1 = minetest_get_item_group(minetest_get_node(test_dir).name, "solid") ~= 0 diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/mob_effects.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/mob_effects.lua index b01920f18b..847315ff18 100644 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/mob_effects.lua +++ b/mods/ENTITIES/mcl_mobs/api/mob_functions/mob_effects.lua @@ -119,4 +119,34 @@ mobs.tamed_effect = function(self) vertical = false, texture = "heart.png", }) +end + +--hearts when breeding +mobs.breeding_effect = function(self) + local pos = self.object:get_pos() + local yaw = self.object:get_yaw() + local collisionbox = self.object:get_properties().collisionbox + + local min, max + + if collisionbox then + min = {x=collisionbox[1], y=collisionbox[2], z=collisionbox[3]} + max = {x=collisionbox[4], y=collisionbox[5], z=collisionbox[6]} + end + + minetest_add_particlespawner({ + amount = 2, + time = 0.0001, + minpos = vector.add(pos, min), + maxpos = vector.add(pos, max), + minvel = vector.new(-1,1,-1), + maxvel = vector.new(1,3,1), + minexptime = 0.7, + maxexptime = 1, + minsize = 1, + maxsize = 2, + collisiondetection = false, + vertical = false, + texture = "heart.png", + }) end \ No newline at end of file diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/set_up.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/set_up.lua index 5f55d344a8..41f3932f75 100644 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/set_up.lua +++ b/mods/ENTITIES/mcl_mobs/api/mob_functions/set_up.lua @@ -6,8 +6,8 @@ local minetest_settings = minetest.settings mobs.mob_staticdata = function(self) --despawn mechanism - --don't despawned tamed mobs - if not self.tamed then + --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!") self.object:remove() @@ -107,12 +107,12 @@ mobs.mob_activate = function(self, staticdata, def, dtime) mesh = def.gotten_mesh end - -- set child objects to half size - if self.child == true then + -- set baby mobs to half size + if self.baby == true then vis_size = { - x = self.base_size.x * .5, - y = self.base_size.y * .5, + x = self.base_size.x * self.baby_size, + y = self.base_size.y * self.baby_size, } if def.child_texture then @@ -120,20 +120,20 @@ mobs.mob_activate = function(self, staticdata, def, dtime) end colbox = { - self.base_colbox[1] * .5, - self.base_colbox[2] * .5, - self.base_colbox[3] * .5, - self.base_colbox[4] * .5, - self.base_colbox[5] * .5, - self.base_colbox[6] * .5 + self.base_colbox[1] * self.baby_size, + self.base_colbox[2] * self.baby_size, + self.base_colbox[3] * self.baby_size, + self.base_colbox[4] * self.baby_size, + self.base_colbox[5] * self.baby_size, + self.base_colbox[6] * self.baby_size } selbox = { - self.base_selbox[1] * .5, - self.base_selbox[2] * .5, - self.base_selbox[3] * .5, - self.base_selbox[4] * .5, - self.base_selbox[5] * .5, - self.base_selbox[6] * .5 + self.base_selbox[1] * self.baby_size, + self.base_selbox[2] * self.baby_size, + self.base_selbox[3] * self.baby_size, + self.base_selbox[4] * self.baby_size, + self.base_selbox[5] * self.baby_size, + self.base_selbox[6] * self.baby_size } end diff --git a/mods/ENTITIES/mobs_mc/chicken.lua b/mods/ENTITIES/mobs_mc/chicken.lua index 5f619c0510..538baa33a6 100644 --- a/mods/ENTITIES/mobs_mc/chicken.lua +++ b/mods/ENTITIES/mobs_mc/chicken.lua @@ -65,12 +65,25 @@ mobs:register_mob("mobs_mc:chicken", { run_start = 0, run_end = 40, }, - follow = mobs_mc.follow.chicken, + follow = "mcl_farming:wheat_seeds", + breed_distance = 1.5, + baby_size = 0.5, + follow_distance = 2, view_range = 16, fear_height = 4, + --why do chickend breed if they lay eggs?? on_rightclick = function(self, clicker) - if mobs:feed_tame(self, clicker, 1, true, true) then return end + --attempt to enter breed state + if mobs.enter_breed_state(self,clicker) then + return + end + + --make baby grow faster + if self.baby then + mobs.make_baby_grow_faster(self,clicker) + return + end end, do_custom = function(self, dtime) diff --git a/mods/ENTITIES/mobs_mc/cow+mooshroom.lua b/mods/ENTITIES/mobs_mc/cow+mooshroom.lua index 9cc4e5d158..d3791ab3d7 100644 --- a/mods/ENTITIES/mobs_mc/cow+mooshroom.lua +++ b/mods/ENTITIES/mobs_mc/cow+mooshroom.lua @@ -48,11 +48,17 @@ local cow_def = { walk_end = 40, run_start = 0, run_end = 40, }, - follow = mobs_mc.follow.cow, + --follow = mobs_mc.follow.cow, on_rightclick = function(self, clicker) - if mobs:feed_tame(self, clicker, 1, true, true) then return end - if self.child then + --attempt to enter breed state + if mobs.enter_breed_state(self,clicker) then + return + end + + --make baby grow faster + if self.baby then + mobs.make_baby_grow_faster(self,clicker) return end @@ -72,6 +78,9 @@ local cow_def = { return end end, + breed_distance = 1.5, + baby_size = 0.5, + follow_distance = 2, follow = mobs_mc.items.wheat, view_range = 10, fear_height = 4, @@ -85,11 +94,17 @@ local mooshroom_def = table.copy(cow_def) mooshroom_def.mesh = "mobs_mc_cow.b3d" mooshroom_def.textures = { {"mobs_mc_mooshroom.png", "mobs_mc_mushroom_red.png"}, {"mobs_mc_mooshroom_brown.png", "mobs_mc_mushroom_brown.png" } } mooshroom_def.on_rightclick = function(self, clicker) - if mobs:feed_tame(self, clicker, 1, true, true) then return end - - if self.child then + --attempt to enter breed state + if mobs.enter_breed_state(self,clicker) then return end + + --make baby grow faster + if self.baby then + mobs.make_baby_grow_faster(self,clicker) + return + end + local item = clicker:get_wielded_item() -- Use shears to get mushrooms and turn mooshroom into cow if item:get_name() == mobs_mc.items.shears then diff --git a/mods/ENTITIES/mobs_mc/horse.lua b/mods/ENTITIES/mobs_mc/horse.lua index 404efc2921..3099f0f09b 100644 --- a/mods/ENTITIES/mobs_mc/horse.lua +++ b/mods/ENTITIES/mobs_mc/horse.lua @@ -117,7 +117,8 @@ local horse = { fly = false, walk_chance = 60, view_range = 16, - follow = mobs_mc.follow.horse, + follow = "mcl_farming:wheat_item", + follow_distance = 3, passive = true, hp_min = 15, hp_max = 30, @@ -217,6 +218,22 @@ local horse = { local iname = item:get_name() local heal = 0 + --sneak click to breed the horse/feed it + if self.owner and self.owner == clicker:get_player_name() and clicker:get_player_control().sneak then + --attempt to enter breed state + if mobs.enter_breed_state(self,clicker) then + return + end + + --make baby grow faster + if self.baby then + mobs.make_baby_grow_faster(self,clicker) + return + end + + return + end + -- Taming self.temper = self.temper or (math.random(1,100)) diff --git a/mods/ENTITIES/mobs_mc/llama.lua b/mods/ENTITIES/mobs_mc/llama.lua index 81120dfdd8..c396635280 100644 --- a/mods/ENTITIES/mobs_mc/llama.lua +++ b/mods/ENTITIES/mobs_mc/llama.lua @@ -58,6 +58,9 @@ mobs:register_mob("mobs_mc:llama", { walk_velocity = 1, run_velocity = 4.4, follow_velocity = 4.4, + breed_distance = 1.5, + baby_size = 0.5, + follow_distance = 2, floats = 1, reach = 6, drops = { @@ -92,7 +95,7 @@ mobs:register_mob("mobs_mc:llama", { look_start = 78, look_end = 108, }, - follow = mobs_mc.follow.llama, + follow = mobs_mc.items.hay_bale, view_range = 16, do_custom = function(self, dtime) @@ -135,15 +138,20 @@ mobs:register_mob("mobs_mc:llama", { return end - local item = clicker:get_wielded_item() - if item:get_name() == mobs_mc.items.hay_bale then - -- Breed with hay bale - if mobs:feed_tame(self, clicker, 1, true, false) then return end - else - -- Feed with anything else - if mobs:feed_tame(self, clicker, 1, false, true) then return end + if clicker:get_player_control().sneak then + --attempt to enter breed state + if mobs.enter_breed_state(self,clicker) then + return + end + + --make baby grow faster + if self.baby then + mobs.make_baby_grow_faster(self,clicker) + return + end end + -- Make sure tamed llama is mature and being clicked by owner only if self.tamed and not self.child and self.owner == clicker:get_player_name() then diff --git a/mods/ENTITIES/mobs_mc/pig.lua b/mods/ENTITIES/mobs_mc/pig.lua index 8ce0f1829c..5ba091c44a 100644 --- a/mods/ENTITIES/mobs_mc/pig.lua +++ b/mods/ENTITIES/mobs_mc/pig.lua @@ -24,6 +24,9 @@ mobs:register_mob("mobs_mc:pig", { walk_velocity = 1, run_velocity = 3, follow_velocity = 3.4, + breed_distance = 1.5, + baby_size = 0.5, + follow_distance = 2, drops = { {name = mobs_mc.items.porkchop_raw, chance = 1, @@ -50,7 +53,7 @@ mobs:register_mob("mobs_mc:pig", { run_start = 0, run_end = 40, }, - follow = mobs_mc.follow.pig, + follow = "mcl_farming:carrot_item", view_range = 8, do_custom = function(self, dtime) @@ -91,10 +94,17 @@ mobs:register_mob("mobs_mc:pig", { return end - local wielditem = clicker:get_wielded_item() - -- Feed pig - if wielditem:get_name() ~= mobs_mc.items.carrot_on_a_stick then - if mobs:feed_tame(self, clicker, 1, true, true) then return end + if clicker:get_player_control().sneak then + --attempt to enter breed state + if mobs.enter_breed_state(self,clicker) then + return + end + + --make baby grow faster + if self.baby then + mobs.make_baby_grow_faster(self,clicker) + return + end end if self.child then diff --git a/mods/ENTITIES/mobs_mc/sheep.lua b/mods/ENTITIES/mobs_mc/sheep.lua index dfd1c612b2..bad7e7c558 100644 --- a/mods/ENTITIES/mobs_mc/sheep.lua +++ b/mods/ENTITIES/mobs_mc/sheep.lua @@ -63,6 +63,10 @@ mobs:register_mob("mobs_mc:sheep", { xp_min = 1, xp_max = 3, skittish = true, + breed_distance = 1.5, + baby_size = 0.5, + follow_distance = 2, + follow = mobs_mc.items.wheat, collisionbox = {-0.45, -0.01, -0.45, 0.45, 1.29, 0.45}, rotate = 270, visual = "mesh", @@ -100,7 +104,6 @@ mobs:register_mob("mobs_mc:sheep", { walk_start = 0, walk_end = 40, run_start = 0, run_end = 40, }, - follow = mobs_mc.follow.sheep, view_range = 12, -- Eat grass @@ -196,7 +199,16 @@ mobs:register_mob("mobs_mc:sheep", { on_rightclick = function(self, clicker) local item = clicker:get_wielded_item() - if mobs:feed_tame(self, clicker, 1, true, true) then return end + --attempt to enter breed state + if mobs.enter_breed_state(self,clicker) then + return + end + + --make baby grow faster + if self.baby then + mobs.make_baby_grow_faster(self,clicker) + return + end if item:get_name() == mobs_mc.items.shears and not self.gotten and not self.child then self.gotten = true diff --git a/mods/ENTITIES/mobs_mc/wolf.lua b/mods/ENTITIES/mobs_mc/wolf.lua index aad4db037e..4cd76dd323 100644 --- a/mods/ENTITIES/mobs_mc/wolf.lua +++ b/mods/ENTITIES/mobs_mc/wolf.lua @@ -76,6 +76,7 @@ local wolf = { dog:set_yaw(yaw) ent = dog:get_luaentity() ent.owner = clicker:get_player_name() + ent.tamed = true -- cornfirm taming minetest.sound_play("mobs_mc_wolf_bark", {object=dog, max_hear_distance=16}, true) -- Replace wolf @@ -143,12 +144,29 @@ dog.owner_loyal = true dog.follow_velocity = 3.2 -- Automatically teleport dog to owner dog.do_custom = mobs_mc.make_owner_teleport_function(12) -dog.follow = mobs_mc.follow.dog dog.attack_animals = nil dog.specific_attack = nil +dog.breed_distance = 1.5 +dog.baby_size = 0.5 +dog.follow_distance = 2 +dog.follow = "mcl_mobitems:beef" + dog.on_rightclick = function(self, clicker) local item = clicker:get_wielded_item() + if self.owner and self.owner == clicker:get_player_name() and clicker:get_player_control().sneak then + --attempt to enter breed state + if mobs.enter_breed_state(self,clicker) then + return + end + + --make baby grow faster + if self.baby then + mobs.make_baby_grow_faster(self,clicker) + return + end + end + if is_food(item:get_name()) then -- Feed to increase health local hp = self.health