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