the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
1#include "stdafx.h"
2#include "net.minecraft.world.entity.ai.control.h"
3#include "net.minecraft.world.entity.ai.goal.target.h"
4#include "net.minecraft.world.entity.ai.goal.h"
5#include "net.minecraft.world.entity.ai.navigation.h"
6#include "net.minecraft.world.entity.animal.h"
7#include "net.minecraft.world.entity.player.h"
8#include "net.minecraft.world.entity.h"
9#include "net.minecraft.world.damagesource.h"
10#include "net.minecraft.world.level.h"
11#include "net.minecraft.world.item.h"
12#include "net.minecraft.world.phys.h"
13#include "SynchedEntityData.h"
14#include "StringHelpers.h"
15#include "..\Minecraft.Client\Textures.h"
16#include "GenericStats.h"
17#include "Ozelot.h"
18
19const float Ozelot::SNEAK_SPEED = 0.18f;
20const float Ozelot::WALK_SPEED = 0.23f;
21const float Ozelot::FOLLOW_SPEED = 0.3f;
22const float Ozelot::SPRINT_SPEED = 0.4f;
23
24const int Ozelot::DATA_TYPE_ID = 18;
25
26const int Ozelot::TYPE_OZELOT = 0;
27const int Ozelot::TYPE_BLACK = 1;
28const int Ozelot::TYPE_RED = 2;
29const int Ozelot::TYPE_SIAMESE = 3;
30
31Ozelot::Ozelot(Level *level) : TamableAnimal(level)
32{
33 // 4J Stu - This function call had to be moved here from the Entity ctor to ensure that
34 // the derived version of the function is called
35 this->defineSynchedData();
36
37 // 4J Stu - This function call had to be moved here from the Entity ctor to ensure that the derived version of the function is called
38 health = getMaxHealth();
39
40 this->textureIdx = TN_MOB_OZELOT; // "/mob/ozelot.png";
41 this->setSize(0.6f, 0.8f);
42
43 getNavigation()->setAvoidWater(true);
44 goalSelector.addGoal(1, new FloatGoal(this));
45 goalSelector.addGoal(2, sitGoal, false);
46 goalSelector.addGoal(3, temptGoal = new TemptGoal(this, SNEAK_SPEED, Item::fish_raw_Id, true), false);
47 goalSelector.addGoal(4, new AvoidPlayerGoal(this, typeid(Player), 16, WALK_SPEED, SPRINT_SPEED));
48 goalSelector.addGoal(5, new FollowOwnerGoal(this, FOLLOW_SPEED, 10, 5));
49 goalSelector.addGoal(6, new OcelotSitOnTileGoal(this, SPRINT_SPEED));
50 goalSelector.addGoal(7, new LeapAtTargetGoal(this, 0.3f));
51 goalSelector.addGoal(8, new OzelotAttackGoal(this));
52 goalSelector.addGoal(9, new BreedGoal(this, WALK_SPEED));
53 goalSelector.addGoal(10, new RandomStrollGoal(this, WALK_SPEED));
54 goalSelector.addGoal(11, new LookAtPlayerGoal(this, typeid(Player), 10));
55
56 targetSelector.addGoal(1, new NonTameRandomTargetGoal(this, typeid(Chicken), 14, 750, false));
57}
58
59void Ozelot::defineSynchedData()
60{
61 TamableAnimal::defineSynchedData();
62
63 entityData->define(DATA_TYPE_ID, (byte) TYPE_OZELOT);
64}
65
66void Ozelot::serverAiMobStep()
67{
68 if (getMoveControl()->hasWanted())
69 {
70 float speed = getMoveControl()->getSpeed();
71 if (speed == SNEAK_SPEED)
72 {
73 setSneaking(true);
74 setSprinting(false);
75 }
76 else if (speed == SPRINT_SPEED)
77 {
78 setSneaking(false);
79 setSprinting(true);
80 }
81 else
82 {
83 setSneaking(false);
84 setSprinting(false);
85 }
86 }
87 else
88 {
89 setSneaking(false);
90 setSprinting(false);
91 }
92}
93
94bool Ozelot::removeWhenFarAway()
95{
96 return Animal::removeWhenFarAway() && !isTame();
97}
98
99int Ozelot::getTexture()
100{
101 switch (getCatType())
102 {
103 case TYPE_OZELOT:
104 return TN_MOB_OZELOT; //"/mob/ozelot.png";
105 case TYPE_BLACK:
106 return TN_MOB_CAT_BLACK; //"/mob/cat_black.png";
107 case TYPE_RED:
108 return TN_MOB_CAT_RED; //"/mob/cat_red.png";
109 case TYPE_SIAMESE:
110 return TN_MOB_CAT_SIAMESE; //"/mob/cat_siamese.png";
111 }
112 return TamableAnimal::getTexture();
113}
114
115bool Ozelot::useNewAi()
116{
117 return true;
118}
119
120int Ozelot::getMaxHealth()
121{
122 return 10;
123}
124
125void Ozelot::causeFallDamage(float distance)
126{
127 // do nothing
128}
129
130void Ozelot::addAdditonalSaveData(CompoundTag *tag)
131{
132 TamableAnimal::addAdditonalSaveData(tag);
133 tag->putInt(L"CatType", getCatType());
134}
135
136void Ozelot::readAdditionalSaveData(CompoundTag *tag)
137{
138 TamableAnimal::readAdditionalSaveData(tag);
139 if(isTame())
140 {
141 setCatType(tag->getInt(L"CatType"));
142 }
143 else
144 {
145 setCatType(TYPE_OZELOT);
146 }
147}
148
149int Ozelot::getAmbientSound()
150{
151 if (isTame())
152 {
153 if (isInLove())
154 {
155 return eSoundType_MOB_CAT_PURR;
156 }
157 if (random->nextInt(4) == 0)
158 {
159 return eSoundType_MOB_CAT_PURREOW;
160 }
161 return eSoundType_MOB_CAT_MEOW;
162 }
163
164 return -1;
165}
166
167int Ozelot::getHurtSound()
168{
169 return eSoundType_MOB_CAT_HITT;
170}
171
172int Ozelot::getDeathSound()
173{
174 return eSoundType_MOB_CAT_HITT;
175}
176
177float Ozelot::getSoundVolume()
178{
179 return 0.4f;
180}
181
182int Ozelot::getDeathLoot()
183{
184 return Item::leather_Id;
185}
186
187bool Ozelot::doHurtTarget(shared_ptr<Entity> target)
188{
189 return target->hurt(DamageSource::mobAttack(dynamic_pointer_cast<Mob>(shared_from_this())), 3);
190}
191
192bool Ozelot::hurt(DamageSource *source, int dmg)
193{
194 sitGoal->wantToSit(false);
195 return TamableAnimal::hurt(source, dmg);
196}
197
198void Ozelot::dropDeathLoot(bool wasKilledByPlayer, int playerBonusLevel)
199{
200}
201
202bool Ozelot::interact(shared_ptr<Player> player)
203{
204 shared_ptr<ItemInstance> item = player->inventory->getSelected();
205 if (isTame())
206 {
207 if (equalsIgnoreCase(player->getUUID(), getOwnerUUID()))
208 {
209 if (!level->isClientSide && !isFood(item))
210 {
211 sitGoal->wantToSit(!isSitting());
212 }
213 }
214 }
215 else
216 {
217 if (temptGoal->isRunning() && item != NULL && item->id == Item::fish_raw_Id && player->distanceToSqr(shared_from_this()) < 3 * 3)
218 {
219 // 4J-PB - don't lose the fish in creative mode
220 if (!player->abilities.instabuild) item->count--;
221 if (item->count <= 0)
222 {
223 player->inventory->setItem(player->inventory->selected, nullptr);
224 }
225
226 if (!level->isClientSide)
227 {
228 if (random->nextInt(3) == 0)
229 {
230 setTame(true);
231
232 // 4J-JEV, hook for durango event.
233 player->awardStat(GenericStats::tamedEntity(eTYPE_OZELOT),GenericStats::param_tamedEntity(eTYPE_OZELOT));
234
235 setCatType(1 + level->random->nextInt(3));
236 setOwnerUUID(player->getUUID());
237 spawnTamingParticles(true);
238 sitGoal->wantToSit(true);
239 level->broadcastEntityEvent(shared_from_this(), EntityEvent::TAMING_SUCCEEDED);
240 }
241 else
242 {
243 spawnTamingParticles(false);
244 level->broadcastEntityEvent(shared_from_this(), EntityEvent::TAMING_FAILED);
245 }
246 }
247 return true;
248 }
249 }
250 return TamableAnimal::interact(player);
251}
252
253shared_ptr<AgableMob> Ozelot::getBreedOffspring(shared_ptr<AgableMob> target)
254{
255 // 4J - added limit to number of animals that can be bred
256 if( level->canCreateMore( GetType(), Level::eSpawnType_Breed) )
257 {
258 shared_ptr<Ozelot> offspring = shared_ptr<Ozelot>( new Ozelot(level) );
259 if (isTame())
260 {
261 offspring->setOwnerUUID(getOwnerUUID());
262 offspring->setTame(true);
263 offspring->setCatType(getCatType());
264 }
265 return offspring;
266 }
267 else
268 {
269 return nullptr;
270 }
271}
272
273bool Ozelot::isFood(shared_ptr<ItemInstance> itemInstance)
274{
275 return itemInstance != NULL && itemInstance->id == Item::fish_raw_Id;
276}
277
278bool Ozelot::canMate(shared_ptr<Animal> animal)
279{
280 if (animal == shared_from_this()) return false;
281 if (!isTame()) return false;
282
283 shared_ptr<Ozelot> partner = dynamic_pointer_cast<Ozelot>(animal);
284 if (partner == NULL) return false;
285 if (!partner->isTame()) return false;
286
287 return isInLove() && partner->isInLove();
288}
289
290int Ozelot::getCatType()
291{
292 return entityData->getByte(DATA_TYPE_ID);
293}
294
295void Ozelot::setCatType(int type)
296{
297 entityData->set(DATA_TYPE_ID, (byte) type);
298}
299
300bool Ozelot::canSpawn()
301{
302 // artificially make ozelots more rare
303 if (level->random->nextInt(3) == 0)
304 {
305 return false;
306 }
307 if (level->isUnobstructed(bb) && level->getCubes(shared_from_this(), bb)->empty() && !level->containsAnyLiquid(bb))
308 {
309 int xt = Mth::floor(x);
310 int yt = Mth::floor(bb->y0);
311 int zt = Mth::floor(z);
312 if (yt < level->seaLevel)
313 {
314 return false;
315 }
316
317 int tile = level->getTile(xt, yt - 1, zt);
318 if (tile == Tile::grass_Id || tile == Tile::leaves_Id)
319 {
320 return true;
321 }
322 }
323 return false;
324}
325
326wstring Ozelot::getAName()
327{
328 if (isTame())
329 {
330 return L"entity.Cat.name";
331 }
332 return TamableAnimal::getAName();
333}