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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
#include "stdafx.h"
#include "net.minecraft.world.entity.ai.control.h"
#include "net.minecraft.world.entity.ai.navigation.h"
#include "net.minecraft.world.entity.ai.goal.h"
#include "net.minecraft.world.entity.animal.h"
#include "net.minecraft.world.level.h"
#include "net.minecraft.world.level.tile.h"
#include "net.minecraft.world.level.tile.entity.h"
#include "BasicTypeContainers.h"
#include "Arrays.h"
#include "OcelotSitOnTileGoal.h"
const int OcelotSitOnTileGoal::GIVE_UP_TICKS = 3 * SharedConstants::TICKS_PER_SECOND;
const int OcelotSitOnTileGoal::SIT_TICKS = 60 * SharedConstants::TICKS_PER_SECOND;
const int OcelotSitOnTileGoal::SEARCH_RANGE = 8;
const double OcelotSitOnTileGoal::SIT_CHANCE = 0.0065f;
OcelotSitOnTileGoal::OcelotSitOnTileGoal(Ozelot *ocelot, float speed)
{
_tick = 0;
tryTicks = 0;
maxTicks = 0;
tileX = 0;
tileY = 0;
tileZ = 0;
this->ocelot = ocelot;
this->speed = speed;
setRequiredControlFlags(Control::MoveControlFlag | Control::JumpControlFlag);
}
bool OcelotSitOnTileGoal::canUse()
{
return ocelot->isTame() && !ocelot->isSitting() && ocelot->getRandom()->nextDouble() <= SIT_CHANCE && findNearestTile();
}
bool OcelotSitOnTileGoal::canContinueToUse()
{
return _tick <= maxTicks && tryTicks <= GIVE_UP_TICKS && isValidTarget(ocelot->level, tileX, tileY, tileZ);
}
void OcelotSitOnTileGoal::start()
{
ocelot->getNavigation()->moveTo((float) tileX + 0.5, tileY + 1, (float) tileZ + 0.5, speed);
_tick = 0;
tryTicks = 0;
maxTicks = ocelot->getRandom()->nextInt(ocelot->getRandom()->nextInt(SIT_TICKS) + SIT_TICKS) + SIT_TICKS;
ocelot->getSitGoal()->wantToSit(false);
}
void OcelotSitOnTileGoal::stop()
{
ocelot->setSitting(false);
}
void OcelotSitOnTileGoal::tick()
{
_tick++;
ocelot->getSitGoal()->wantToSit(false);
if (ocelot->distanceToSqr(tileX, tileY + 1, tileZ) > 1)
{
ocelot->setSitting(false);
ocelot->getNavigation()->moveTo((float) tileX + 0.5, tileY + 1, (float) tileZ + 0.5, speed);
tryTicks++;
}
else if (!ocelot->isSitting())
{
ocelot->setSitting(true);
}
else
{
tryTicks--;
}
}
bool OcelotSitOnTileGoal::findNearestTile()
{
int y = (int) ocelot->y;
double distSqr = Integer::MAX_VALUE;
for (int x = (int) ocelot->x - SEARCH_RANGE; x < ocelot->x + SEARCH_RANGE; x++)
{
for (int z = (int) ocelot->z - SEARCH_RANGE; z < ocelot->z + SEARCH_RANGE; z++)
{
if (isValidTarget(ocelot->level, x, y, z) && ocelot->level->isEmptyTile(x, y + 1, z))
{
double dist = ocelot->distanceToSqr(x, y, z);
if (dist < distSqr)
{
this->tileX = x;
this->tileY = y;
this->tileZ = z;
distSqr = dist;
}
}
}
}
return distSqr < Integer::MAX_VALUE;
}
bool OcelotSitOnTileGoal::isValidTarget(Level *level, int x, int y, int z)
{
int tile = level->getTile(x, y, z);
int data = level->getData(x, y, z);
if (tile == Tile::chest_Id)
{
std::shared_ptr<ChestTileEntity> chest = dynamic_pointer_cast<ChestTileEntity>(level->getTileEntity(x, y, z));
if (chest->openCount < 1)
{
return true;
}
}
else if (tile == Tile::furnace_lit_Id)
{
return true;
}
else if (tile == Tile::bed_Id && !BedTile::isHeadPiece(data))
{
return true;
}
return false;
}
|