From b691c43c44ff180d10e7d4a9afc83b98551ff586 Mon Sep 17 00:00:00 2001 From: daoge_cmd <3523206925@qq.com> Date: Sun, 1 Mar 2026 12:16:08 +0800 Subject: Initial commit --- Minecraft.World/MakeLoveGoal.cpp | 103 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 Minecraft.World/MakeLoveGoal.cpp (limited to 'Minecraft.World/MakeLoveGoal.cpp') diff --git a/Minecraft.World/MakeLoveGoal.cpp b/Minecraft.World/MakeLoveGoal.cpp new file mode 100644 index 00000000..89f09f1d --- /dev/null +++ b/Minecraft.World/MakeLoveGoal.cpp @@ -0,0 +1,103 @@ +#include "stdafx.h" +#include "net.minecraft.world.entity.ai.control.h" +#include "net.minecraft.world.entity.ai.village.h" +#include "net.minecraft.world.entity.ai.navigation.h" +#include "net.minecraft.world.entity.npc.h" +#include "net.minecraft.world.entity.h" +#include "net.minecraft.world.level.h" +#include "net.minecraft.world.phys.h" +#include "MakeLoveGoal.h" + +MakeLoveGoal::MakeLoveGoal(Villager *villager) +{ + village = weak_ptr(); + partner = weak_ptr(); + loveMakingTime = 0; + + this->villager = villager; + level = villager->level; + setRequiredControlFlags(Control::MoveControlFlag | Control::LookControlFlag); +} + +bool MakeLoveGoal::canUse() +{ + + if (villager->getAge() != 0) return false; + if (villager->getRandom()->nextInt(500) != 0) return false; + + village = level->villages->getClosestVillage(Mth::floor(villager->x), Mth::floor(villager->y), Mth::floor(villager->z), 0); + if (village.lock() == NULL) return false; + if (!villageNeedsMoreVillagers()) return false; + + shared_ptr mate = level->getClosestEntityOfClass(typeid(Villager), villager->bb->grow(8, 3, 8), villager->shared_from_this()); + if (mate == NULL) return false; + + partner = weak_ptr(dynamic_pointer_cast(mate)); + if (partner.lock()->getAge() != 0) return false; + + return true; +} + +void MakeLoveGoal::start() +{ + loveMakingTime = 300; + villager->setInLove(true); +} + +void MakeLoveGoal::stop() +{ + village = weak_ptr(); + partner = weak_ptr(); + villager->setInLove(false); +} + +bool MakeLoveGoal::canContinueToUse() +{ + return partner.lock() != NULL && loveMakingTime >= 0 && villageNeedsMoreVillagers() && villager->getAge() == 0; +} + +void MakeLoveGoal::tick() +{ + --loveMakingTime; + villager->getLookControl()->setLookAt(partner.lock(), 10, 30); + + if (villager->distanceToSqr(partner.lock()) > 1.5 * 1.5) + { + villager->getNavigation()->moveTo(partner.lock(), 0.25f); + } + else + { + if (loveMakingTime == 0 && partner.lock()->isInLove()) breed(); + } + + if (villager->getRandom()->nextInt(35) == 0) level->broadcastEntityEvent(villager->shared_from_this(), EntityEvent::LOVE_HEARTS); +} + +bool MakeLoveGoal::villageNeedsMoreVillagers() +{ + shared_ptr _village = village.lock(); + if( _village == NULL ) return false; + + int idealSize = (int) ((float) _village->getDoorCount() * 0.35); + // System.out.println("idealSize: " + idealSize + " pop: " + + // village.getPopulationSize()); + return _village->getPopulationSize() < idealSize; +} + +void MakeLoveGoal::breed() +{ + // 4J Stu - This sets a timer that stops these villagers from trying to breed again + // We should do this even if breeding fails due to vilalger count to stop them continually trying to breed + partner.lock()->setAge(5 * 60 * 20); + villager->setAge(5 * 60 * 20); + // 4J - added limit to number of animals that can be bred + if(level->canCreateMore( eTYPE_VILLAGER, Level::eSpawnType_Breed) ) + { + shared_ptr child = shared_ptr( new Villager(level) ); + child->setAge(-20 * 60 * 20); + child->setProfession(villager->getRandom()->nextInt(Villager::PROFESSION_MAX)); + child->moveTo(villager->x, villager->y, villager->z, 0, 0); + level->addEntity(child); + level->broadcastEntityEvent(child, EntityEvent::LOVE_HEARTS); + } +} -- cgit v1.2.3