aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.World/MakeLoveGoal.cpp
blob: c308e33cc828e13abfed407682ba13ff00b383ca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#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<Village>();
	partner = weak_ptr<Villager>();
	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() == nullptr) return false;
	if (!villageNeedsMoreVillagers()) return false;

	shared_ptr<Entity> mate = level->getClosestEntityOfClass(typeid(Villager), villager->bb->grow(8, 3, 8), villager->shared_from_this());
	if (mate == nullptr) return false;

	partner = weak_ptr<Villager>(dynamic_pointer_cast<Villager>(mate));
	if (partner.lock()->getAge() != 0) return false;

	return true;
}

void MakeLoveGoal::start()
{
	loveMakingTime = 300;
	villager->setInLove(true);
}

void MakeLoveGoal::stop()
{
	village = weak_ptr<Village>();
	partner = weak_ptr<Villager>();
	villager->setInLove(false);
}

bool MakeLoveGoal::canContinueToUse()
{
	return partner.lock() != nullptr && 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 = village.lock();
	if( _village == nullptr ) return false;

	if (!_village->isBreedTimerOk())
	{
		return false;
	}

	int idealSize = static_cast<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<Villager> child = dynamic_pointer_cast<Villager>( villager->getBreedOffspring(partner.lock()) );
		child->setAge(-20 * 60 * 20);
		child->moveTo(villager->x, villager->y, villager->z, 0, 0);
		level->addEntity(child);
		level->broadcastEntityEvent(child, EntityEvent::LOVE_HEARTS);
	}
}