pregnancy

This commit is contained in:
berengma 2020-12-05 18:10:57 +01:00
parent 57504fee10
commit 0d7a33034f
5 changed files with 356 additions and 30 deletions

View File

@ -5,6 +5,24 @@ local min=math.min
local max=math.max
local function find_matching_partners(self)
local pos = mobkit.get_stand_pos(self)
local name = "wildcow:auroch_female"
local otable = minetest.get_objects_inside_radius(pos,self.view_range)
local horny = water_life.horny(self)
for i = #otable,1,-1 do
local entity = otable[i]:get_luaentity()
if entity and entity.name == name then
if abs(water_life.horny(entity) - horny) > 50 or water_life.pregnant(entity) > 0 then
table.remove(otable,i)
end
else
table.remove(otable,i)
end
end
return otable
end
local function sortout(self,ftable)
@ -40,7 +58,7 @@ function wildcow.hq_overrun(self,prty,target)
end
if mobkit.is_queue_empty_low(self) and self.isonground then
local pos = mobkit.get_stand_pos(self)
if vector.distance(pos,tpos) > 1 then
if vector.distance(pos,tpos) >= 1.1 then
wildcow.goto_next_waypoint(self,tpos,2)
else
return true
@ -52,9 +70,80 @@ function wildcow.hq_overrun(self,prty,target)
end
function wildcow.hq_meetmygirl(self,prty)
local name ="wildcow:auroch_female"
local pos = self.object:get_pos()
local found = water_life.count_objects(pos,48,name)
local init = true
local passangan = {}
local tpos = {}
local func = function(self)
if init then
if not found[name] then return true end
local otable = minetest.get_objects_inside_radius(pos, 48)
for _,obj in ipairs(otable) do
local luaent = obj:get_luaentity()
if luaent and luaent.name == name and water_life.is_boss(luaent) then
passangan = obj
break
end
end
init = false
if passangan == {} then return true end
tpos = passangan:get_pos()
--water_life.temp_show(tpos,5,5)
if not water_life.gopath(self,tpos) then
--minetest.chat_send_all("No way to there")
return true
end
end
if mobkit.is_queue_empty_low(self) and self.isonground then
pos = mobkit.get_stand_pos(self)
tpos = passangan:get_pos()
if vector.distance(pos,tpos) >= 5 then
wildcow.goto_next_waypoint(self,tpos,1)
else
local mate = find_matching_partners(self)
local hunger = math.floor(water_life.hunger(self)/20) -1
minetest.chat_send_all(dump(#mate).." matches found, energy for "..hunger.." of them")
if not mate or #mate < 1 then return true end
if hunger > #mate then hunger = #mate end
for i = 1,hunger,1 do
water_life.hunger(self,-20)
local choice = mate[i]:get_luaentity()
water_life.pregnant(choice,os.clock())
water_life.horny(choice,100)
end
water_life.horny(self,100)
return true
end
end
end
mobkit.queue_high(self,func,prty)
end
function wildcow.hq_stare(self,prty,target)
local init = true
local gethim = 10
local func = function(self)
if not mobkit.is_alive(target) then return true end
@ -67,10 +156,12 @@ function wildcow.hq_stare(self,prty,target)
local yaw = self.object:get_yaw()
local tpos = target:get_pos()
local apos = mobkit.pos_translate2d(pos,tyaw,10)
gethim = gethim - self.dtime
if water_life.dist2tgt(self,target) > 15 then return true end
if water_life.dist2tgt(self,target) < 8 then
if water_life.dist2tgt(self,target) < 8 or gethim < 0 then
--mobkit.lq_dumbwalk(self,apos,2)
water_life.hunger(self,-5)
wildcow.hq_overrun(self,prty+1,target)
end
@ -87,7 +178,7 @@ function wildcow.hq_goto(self,prty,tpos)
local func = function(self)
if mobkit.is_queue_empty_low(self) and self.isonground then
local pos = mobkit.get_stand_pos(self)
if vector.distance(pos,tpos) > 1.5 then
if vector.distance(pos,tpos) >= 1.2 then
wildcow.goto_next_waypoint(self,tpos,0.5)
else
return true

193
calf.lua Normal file
View File

@ -0,0 +1,193 @@
local random = water_life.random
local function calf_brain(self)
if self.tamed == nil then self.tamed = false end
if mobkit.timer(self,1) then wildcow.node_dps_dmg(self) end
mobkit.vitals(self)
if self.hp <= 0 then
mobkit.clear_queue_high(self)
water_life.handle_drops(self)
mobkit.hq_die(self)
return
end
if mobkit.timer(self,120) then water_life.hunger(self,-5) end
if mobkit.timer(self,10) then
if water_life.hunger(self) < 10 then mobkit.hurt(self,5) end
end
if mobkit.timer(self,2) then
local prty = mobkit.get_queue_priority(self)
if prty < 15 then
local members = water_life.get_herd_members(self,water_life.abr * 16)
local score = 0
local entity = {}
-- this loop is searching for the herd boss with the highest score. All others will be deleted.
if #members > 1 then
for i = #members,1,-1 do
entity = members[i]:get_luaentity()
if entity then
--minetest.chat_send_all(dump(entity.head).." : "..dump(score))
if water_life.head(entity) <= score then
table.remove(members,i)
water_life.is_boss(entity,0)
else
score = water_life.head(entity)
end
else
table.remove(members,i)
end
end
local hpos = members[1]:get_pos()
local obj = members[1]:get_luaentity()
water_life.is_boss(obj,1)
local showpos = mobkit.pos_shift(hpos,{y=2})
--water_life.temp_show(showpos,2,5)
--minetest.chat_send_all(dump("Boss-POS :"..minetest.pos_to_string(hpos)).." score= "..dump(score))
if water_life.head(self) ~= score then water_life.headpos(self,hpos) end -- if active mob (self) is not boss then remember boss position
end
end
end
if mobkit.timer(self,1) then
local prty = mobkit.get_queue_priority(self)
local obj = self.object
local pos = self.object:get_pos()
local bosspos = water_life.headpos(self)
obj:set_nametag_attributes({
color = '#ff7373',
text = ">>> "..tostring(water_life.hunger(self)).."% <<<",
})
if prty < 20 and self.isinliquid then
mobkit.hq_liquid_recovery(self,20)
water_life.hunger(self,-5)
return
end
if prty < 15 then
local pred = mobkit.get_closest_entity(self,'water_life:croc')
if not pred then pred = mobkit.get_closest_entity(self,'water_life:snake') end
if pred then
mobkit.hq_runfrom(self,15,pred)
water_life.hunger(self,-1)
return
end
end
if prty < 13 then
local plyr = mobkit.get_nearby_player(self)
if plyr and vector.distance(pos,plyr:get_pos()) < 8 and not self.tamed then
mobkit.hq_runfrom(self,13,plyr)
water_life.hunger(self,-1)
return
end
end
if prty < 9 then
if random(100) > water_life.hunger(self) then
local radius = 5 + math.floor((100 - water_life.hunger(self))/20) * 5
if water_life.is_boss(self) > 0 then radius = radius * 2 end -- boss sees everything
wildcow.hq_find_food(self,9,radius)
return
end
end
if prty < 5 and bosspos then
local boss = math.floor(vector.distance(pos,bosspos))
--minetest.chat_send_all(dump(boss))
if boss > 10 then
water_life.hq_findpath(self,5,bosspos, 7,0.5)
end
end
if mobkit.is_queue_empty_high(self) then
mobkit.hq_roam(self,0)
water_life.hunger(self,-1)
end
end
end
minetest.register_entity("wildcow:auroch_calf",{
-- common props
physical = true,
stepheight = 0.1, --EVIL!
collide_with_objects = false,
collisionbox = {-0.45, 0, -0.45, 0.45, 0.95, 0.45},
visual = "mesh",
mesh = "wildcow_auroch_calf.b3d",
textures = {"wildcow_auroch_calf_male.png"},
visual_size = {x = 1, y = 1},
static_save = true,
makes_footstep_sound = true,
on_step = mobkit.stepfunc, -- required
on_activate = mobkit.actfunc, -- required
get_staticdata = mobkit.statfunc,
-- api props
springiness=0,
buoyancy = 0.9,
max_speed = 4,
jump_height = 1.26,
view_range = 12,
lung_capacity = 10, -- seconds
max_hp = 25,
timeout = 0,
attack={range=0.5,damage_groups={fleshy=10}},
sounds = {
--scared='deer_scared',
--hurt = 'deer_hurt',
},
animation = {
walk={range={x=216,y=231},speed=10,loop=true},
trot={range={x=85,y=114},speed=20,loop=true},
run={range={x=120,y=140},speed=30,loop=true},
stand={range={x=31,y=74},speed=15,loop=true},
eat={range={x=0,y=30},speed=15,loop=true},
attack={range={x=145,y=160},speed=20,loop=true},
},
drops = {
{name = "default:diamond", chance = 20, min = 1, max = 3,},
{name = "water_life:meat_raw", chance = 2, min = 1, max = 3,},
},
brainfunc = calf_brain,
on_punch=function(self, puncher, time_from_last_punch, tool_capabilities, dir)
local hvel = vector.multiply(vector.normalize({x=dir.x,y=0,z=dir.z}),4)
self.object:set_velocity({x=hvel.x,y=2,z=hvel.z})
mobkit.make_sound(self,'hurt')
mobkit.hurt(self,tool_capabilities.damage_groups.fleshy or 1)
end,
on_rightclick = function(self, clicker)
if not clicker or not clicker:is_player() then return end
local inv = clicker:get_inventory()
local item = clicker:get_wielded_item()
--minetest.chat_send_all(dump(item:get_name()))
if not item or item:get_name() ~= water_life.catchBA then return end
if not inv:room_for_item("main", "wildcow:auroch_female_item") then return end
local pos = mobkit.get_stand_pos(self)
local name = clicker:get_player_name()
local hasowner = minetest.is_protected(pos)
if hasowner and self.tamed then return end
inv:add_item("main", "wildcow:auroch_female_item")
self.object:remove()
end,
})

View File

@ -14,7 +14,12 @@ local function female_brain(self)
end
if mobkit.timer(self,120) then water_life.hunger(self,-10) end
if mobkit.timer(self,120) then
if water_life.pregnant(self) < 0 then
water_life.horny(self,-1)
end
water_life.hunger(self,-5)
end
if mobkit.timer(self,10) then
@ -63,17 +68,37 @@ local function female_brain(self)
local obj = self.object
local pos = self.object:get_pos()
local bosspos = water_life.headpos(self)
local calf = water_life.pregnant(self)
--[[
obj:set_nametag_attributes({
color = '#ff7373',
text = ">>> "..tostring(water_life.is_boss(self)).."% <<<",
})
]]
if calf > 0 then
calf = os.clock() - calf
if calf > wildcow.ptime then
-- add little calf here
water_life.pregnant(self,-1)
end
end
if wildcow.debug then
local kepala = ""
local hamil = "not_pregnant"
if water_life.is_boss(self) == 1 then kepala="BOSS" end
if water_life.pregnant(self) >= 0 then
local timer = wildcow.ptime - math.floor( os.clock() - water_life.pregnant(self))
hamil=tostring(timer).." secs left"
end
obj:set_nametag_attributes({
color = '#ff7373',
text = kepala.."\n"..hamil.."\n"..tostring(water_life.hunger(self)).."% hunger\n"..tostring(water_life.horny(self)).."% horny",
})
end
if prty < 20 and self.isinliquid then
mobkit.hq_liquid_recovery(self,20)
water_life.hunger(self,-10)
water_life.hunger(self,-5)
return
end
@ -85,7 +110,7 @@ local function female_brain(self)
if pred then
mobkit.hq_runfrom(self,15,pred)
water_life.hunger(self,-5)
water_life.hunger(self,-1)
return
end
end
@ -93,7 +118,7 @@ local function female_brain(self)
local plyr = mobkit.get_nearby_player(self)
if plyr and vector.distance(pos,plyr:get_pos()) < 8 and not self.tamed then
mobkit.hq_runfrom(self,13,plyr)
water_life.hunger(self,-5)
water_life.hunger(self,-1)
return
end
end
@ -118,7 +143,7 @@ local function female_brain(self)
if mobkit.is_queue_empty_high(self) then
mobkit.hq_roam(self,0)
water_life.hunger(self,-5)
water_life.hunger(self,-1)
end
end
end

View File

@ -7,7 +7,9 @@ local max=math.max
wildcow = {}
wildcow.spawn_rate = 0.5 -- less is more
wildcow.spawnfreq = 10 -- spawn frequency
wildcow.herdsize = 5
wildcow.herdsize = 5 -- max member in a herd
wildcow.ptime = 720 -- time in secs until baby is born
wildcow.debug = true
wildcow.spawn_rate = 1 - max(min(minetest.settings:get('wildcow_spawn_chance') or 0.2,1),0)
wildcow.spawn_reduction = minetest.settings:get('wildcow_spawn_reduction') or 0.5
@ -16,7 +18,7 @@ local hdrops = minetest.get_modpath("water_life")
water_life.register_shark_food("wildcow:auroch_male")
water_life.register_shark_food("wildcow:auroch_female")
water_life.register_shark_food("wildcow:auroch_calf")
local path = minetest.get_modpath(minetest.get_current_modname())
@ -24,6 +26,7 @@ local path = minetest.get_modpath(minetest.get_current_modname())
dofile(path.."/behaviors.lua")
dofile(path.."/male.lua")
dofile(path.."/female.lua")
dofile(path.."/calf.lua")
dofile(path.."/spawn.lua")

View File

@ -14,11 +14,23 @@ local function male_brain(self)
end
if mobkit.timer(self,120) then water_life.hunger(self,-10) end
if mobkit.timer(self,120) then
water_life.hunger(self,-5)
water_life.horny(self,-5)
end
if mobkit.timer(self,10) then
if water_life.hunger(self) < 10 then mobkit.hurt(self,5) end
local prty = mobkit.get_queue_priority(self)
local horny = water_life.horny(self)
local hunger = water_life.hunger(self)
if prty < 30 and water_life.is_boss(self) == 1 and horny < 70 and hunger > horny then
mobkit.clear_queue_high(self)
wildcow.hq_meetmygirl(self,30)
end
end
if mobkit.timer(self,2) then
@ -64,20 +76,23 @@ local function male_brain(self)
local pos = self.object:get_pos()
local bosspos = water_life.headpos(self)
--[[
obj:set_nametag_attributes({
color = '#ff7373',
text = ">>> "..tostring(water_life.is_boss(self)).."% <<<",
})
]]
if wildcow.debug then
local kepala = ""
if water_life.is_boss(self) == 1 then kepala="BOSS" end
obj:set_nametag_attributes({
color = '#ff7373',
text = kepala.."\n"..tostring(water_life.hunger(self)).."% hunger\n"..tostring(water_life.horny(self)).."% horny",
})
end
if prty < 20 and self.isinliquid then
mobkit.hq_liquid_recovery(self,20)
water_life.hunger(self,-10)
water_life.hunger(self,-5)
end
if prty < 15 then
local pred = mobkit.get_closest_entity(self,'water_life:croc')
if not pred then pred = mobkit.get_closest_entity(self,'water_life:snake') end
@ -85,7 +100,7 @@ local function male_brain(self)
if pred then
mobkit.clear_queue_high(self)
mobkit.hq_runfrom(self,15,pred)
water_life.hunger(self,-5)
water_life.hunger(self,-1)
end
end
if prty < 13 then
@ -93,7 +108,6 @@ local function male_brain(self)
if plyr and vector.distance(pos,plyr:get_pos()) < 16 and not self.tamed then
mobkit.clear_queue_high(self)
wildcow.hq_stare(self,13,plyr)
water_life.hunger(self,-5)
end
end
@ -116,7 +130,7 @@ local function male_brain(self)
if mobkit.is_queue_empty_high(self) then
mobkit.hq_roam(self,0)
water_life.hunger(self,-5)
water_life.hunger(self,-1)
end
end
end