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 "com.mojang.nbt.h"
3#include "net.minecraft.world.level.tile.h"
4#include "net.minecraft.world.phys.h"
5#include "net.minecraft.world.level.h"
6#include "net.minecraft.world.item.h"
7#include "net.minecraft.world.item.crafting.h"
8#include "net.minecraft.world.inventory.h"
9#include "net.minecraft.world.entity.ai.attributes.h"
10#include "net.minecraft.world.entity.ai.goal.h"
11#include "net.minecraft.world.entity.ai.navigation.h"
12#include "net.minecraft.world.entity.h"
13#include "net.minecraft.world.entity.item.h"
14#include "net.minecraft.world.entity.player.h"
15#include "net.minecraft.world.entity.global.h"
16#include "net.minecraft.world.entity.player.h"
17#include "net.minecraft.world.entity.monster.h"
18#include "Sheep.h"
19#include "..\Minecraft.Client\Textures.h"
20#include "MobCategory.h"
21#include "GenericStats.h"
22
23const float Sheep::COLOR[Sheep::COLOR_LENGTH][3] =
24{
25 { 1.0f, 1.0f, 1.0f }, // white
26 { 0.85f, 0.5f, 0.2f }, // orange
27 { 0.7f, 0.3f, 0.85f }, // magenta
28 { 0.4f, 0.6f, 0.85f }, // light blue
29 { 0.9f, 0.9f, 0.2f }, // yellow
30 { 0.5f, 0.8f, 0.1f }, // light green
31 { 0.95f, 0.5f, 0.65f }, // pink
32 { 0.3f, 0.3f, 0.3f }, // gray
33 { 0.6f, 0.6f, 0.6f }, // silver
34 { 0.3f, 0.5f, 0.65f }, // cyan
35 { 0.5f, 0.25f, 0.7f }, // purple
36 { 0.2f, 0.3f, 0.7f }, // blue
37 { 0.4f, 0.3f, 0.2f }, // brown
38 { 0.4f, 0.5f, 0.2f }, // green
39 { 0.6f, 0.2f, 0.2f }, // red
40 { 0.1f, 0.1f, 0.1f }, // black
41};
42
43Sheep::Sheep(Level *level) : Animal( level )
44{
45 // 4J Stu - This function call had to be moved here from the Entity ctor to ensure that
46 // the derived version of the function is called
47 this->defineSynchedData();
48 registerAttributes();
49 setHealth(getMaxHealth());
50
51 setSize(0.9f, 1.3f);
52
53 eatAnimationTick = 0;
54
55 eatTileGoal = new EatTileGoal(this);
56
57 getNavigation()->setAvoidWater(true);
58 goalSelector.addGoal(0, new FloatGoal(this));
59 goalSelector.addGoal(1, new PanicGoal(this, 1.25));
60 goalSelector.addGoal(2, new BreedGoal(this, 1.0));
61 goalSelector.addGoal(3, new TemptGoal(this, 1.1, Item::wheat_Id, false));
62 goalSelector.addGoal(4, new FollowParentGoal(this, 1.1));
63 goalSelector.addGoal(5, eatTileGoal, false);
64 goalSelector.addGoal(6, new RandomStrollGoal(this, 1.0));
65 goalSelector.addGoal(7, new LookAtPlayerGoal(this, typeid(Player), 6));
66 goalSelector.addGoal(8, new RandomLookAroundGoal(this));
67
68 container = shared_ptr<CraftingContainer>(new CraftingContainer(new SheepContainer(), 2, 1));
69 container->setItem(0, shared_ptr<ItemInstance>( new ItemInstance(Item::dye_powder, 1, 0)));
70 container->setItem(1, shared_ptr<ItemInstance>( new ItemInstance(Item::dye_powder, 1, 0)));
71}
72
73bool Sheep::useNewAi()
74{
75 return true;
76}
77
78void Sheep::newServerAiStep()
79{
80 eatAnimationTick = eatTileGoal->getEatAnimationTick();
81 Animal::newServerAiStep();
82}
83
84void Sheep::aiStep()
85{
86 if (level->isClientSide) eatAnimationTick = max(0, eatAnimationTick - 1);
87 Animal::aiStep();
88}
89
90void Sheep::registerAttributes()
91{
92 Animal::registerAttributes();
93
94 getAttribute(SharedMonsterAttributes::MAX_HEALTH)->setBaseValue(8);
95 getAttribute(SharedMonsterAttributes::MOVEMENT_SPEED)->setBaseValue(0.23f);
96}
97
98void Sheep::defineSynchedData()
99{
100 Animal::defineSynchedData();
101
102 // sheared and color share a byte
103 entityData->define(DATA_WOOL_ID, ((byte) 0)); //was new Byte((byte), 0)
104}
105
106void Sheep::dropDeathLoot(bool wasKilledByPlayer, int playerBonusLevel)
107{
108 if(!isSheared())
109 {
110 // killing a non-sheared sheep will drop a single block of cloth
111 spawnAtLocation(shared_ptr<ItemInstance>( new ItemInstance(Tile::wool_Id, 1, getColor()) ), 0.0f);
112 }
113}
114
115int Sheep::getDeathLoot()
116{
117 return Tile::wool_Id;
118}
119
120void Sheep::handleEntityEvent(byte id)
121{
122 if (id == EntityEvent::EAT_GRASS)
123 {
124 eatAnimationTick = EAT_ANIMATION_TICKS;
125 }
126 else
127 {
128 Animal::handleEntityEvent(id);
129 }
130}
131
132float Sheep::getHeadEatPositionScale(float a)
133{
134 if (eatAnimationTick <= 0)
135 {
136 return 0;
137 }
138 if (eatAnimationTick >= 4 && eatAnimationTick <= (EAT_ANIMATION_TICKS - 4))
139 {
140 return 1;
141 }
142 if (eatAnimationTick < 4)
143 {
144 return ((float) eatAnimationTick - a) / 4.0f;
145 }
146 return -((float) (eatAnimationTick - EAT_ANIMATION_TICKS) - a) / 4.0f;
147}
148
149float Sheep::getHeadEatAngleScale(float a)
150{
151 if (eatAnimationTick > 4 && eatAnimationTick <= (EAT_ANIMATION_TICKS - 4))
152 {
153 float scale = ((float) (eatAnimationTick - 4) - a) / (float) (EAT_ANIMATION_TICKS - 8);
154 return PI * .20f + PI * .07f * Mth::sin(scale * 28.7f);
155 }
156 if (eatAnimationTick > 0)
157 {
158 return PI * .20f;
159 }
160 return ((xRot / (180.0f / PI)));
161}
162
163bool Sheep::mobInteract(shared_ptr<Player> player)
164{
165 shared_ptr<ItemInstance> item = player->inventory->getSelected();
166
167 // 4J-JEV: Fix for #88212,
168 // Untrusted players shouldn't be able to sheer sheep.
169 if (!player->isAllowedToInteract( shared_from_this() ))
170 return false; //Animal::interact(player);
171
172 if (item != NULL && item->id == Item::shears->id && !isSheared() && !isBaby())
173 {
174 if (!level->isClientSide)
175 {
176 setSheared(true);
177 int count = 1 + random->nextInt(3);
178 for (int i = 0; i < count; i++)
179 {
180 shared_ptr<ItemEntity> ie = spawnAtLocation(shared_ptr<ItemInstance>( new ItemInstance(Tile::wool_Id, 1, getColor()) ), 1.0f);
181 ie->yd += random->nextFloat() * 0.05f;
182 ie->xd += (random->nextFloat() - random->nextFloat()) * 0.1f;
183 ie->zd += (random->nextFloat() - random->nextFloat()) * 0.1f;
184 }
185
186 player->awardStat( GenericStats::shearedEntity(eTYPE_SHEEP), GenericStats::param_shearedEntity(eTYPE_SHEEP) );
187 }
188 item->hurtAndBreak(1, player);
189 playSound(eSoundType_MOB_SHEEP_SHEAR, 1, 1);
190 }
191
192 return Animal::mobInteract(player);
193}
194
195void Sheep::addAdditonalSaveData(CompoundTag *tag)
196{
197 Animal::addAdditonalSaveData(tag);
198 tag->putBoolean(L"Sheared", isSheared());
199 tag->putByte(L"Color", (byte) getColor());
200}
201
202void Sheep::readAdditionalSaveData(CompoundTag *tag)
203{
204 Animal::readAdditionalSaveData(tag);
205 setSheared(tag->getBoolean(L"Sheared"));
206 setColor((int) tag->getByte(L"Color"));
207}
208
209int Sheep::getAmbientSound()
210{
211 return eSoundType_MOB_SHEEP_AMBIENT;
212}
213
214int Sheep::getHurtSound()
215{
216 return eSoundType_MOB_SHEEP_AMBIENT;
217}
218
219int Sheep::getDeathSound()
220{
221 return eSoundType_MOB_SHEEP_AMBIENT;
222}
223
224void Sheep::playStepSound(int xt, int yt, int zt, int t)
225{
226 playSound(eSoundType_MOB_SHEEP_STEP, 0.15f, 1);
227}
228
229int Sheep::getColor()
230{
231 return (entityData->getByte(DATA_WOOL_ID) & 0x0f);
232}
233
234void Sheep::setColor(int color)
235{
236 byte current = entityData->getByte(DATA_WOOL_ID);
237 entityData->set(DATA_WOOL_ID, (byte) ((current & 0xf0) | (color & 0x0f)));
238}
239
240bool Sheep::isSheared()
241{
242 return (entityData->getByte(DATA_WOOL_ID) & 0x10) != 0;
243}
244
245void Sheep::setSheared(bool value)
246{
247 byte current = entityData->getByte(DATA_WOOL_ID);
248 if (value)
249 {
250 entityData->set(DATA_WOOL_ID, (byte) (current | 0x10));
251 }
252 else
253 {
254 entityData->set(DATA_WOOL_ID, (byte) (current & ~0x10));
255 }
256}
257
258int Sheep::getSheepColor(Random *random)
259{
260 int nextInt = random->nextInt(100);
261 if (nextInt < 5)
262 {
263 return 15 - DyePowderItem::BLACK;
264 }
265 if (nextInt < 10)
266 {
267 return 15 - DyePowderItem::GRAY;
268 }
269 if (nextInt < 15)
270 {
271 return 15 - DyePowderItem::SILVER;
272 }
273 if (nextInt < 18)
274 {
275 return 15 - DyePowderItem::BROWN;
276 }
277 if (random->nextInt(500) == 0) return 15 - DyePowderItem::PINK;
278 return 0; // white
279}
280
281shared_ptr<AgableMob> Sheep::getBreedOffspring(shared_ptr<AgableMob> target)
282{
283 // 4J - added limit to number of animals that can be bred
284 if( level->canCreateMore( GetType(), Level::eSpawnType_Breed) )
285 {
286 shared_ptr<Sheep> otherSheep = dynamic_pointer_cast<Sheep>( target );
287 shared_ptr<Sheep> sheep = shared_ptr<Sheep>( new Sheep(level) );
288 int color = getOffspringColor(dynamic_pointer_cast<Animal>(shared_from_this()), otherSheep);
289 sheep->setColor(15 - color);
290 return sheep;
291 }
292 else
293 {
294 return nullptr;
295 }
296}
297
298void Sheep::ate()
299{
300 setSheared(false);
301 if (isBaby())
302 {
303 // remove a minute from aging
304 ageUp(60);
305 }
306}
307
308MobGroupData *Sheep::finalizeMobSpawn(MobGroupData *groupData, int extraData /*= 0*/) // 4J Added extraData param
309{
310 groupData = Animal::finalizeMobSpawn(groupData);
311
312 setColor(getSheepColor(level->random));
313 return groupData;
314}
315
316int Sheep::getOffspringColor(shared_ptr<Animal> animal, shared_ptr<Animal> partner)
317{
318 int parent1DyeColor = getDyeColor(animal);
319 int parent2DyeColor = getDyeColor(partner);
320
321 container->getItem(0)->setAuxValue(parent1DyeColor);
322 container->getItem(1)->setAuxValue(parent2DyeColor);
323
324 shared_ptr<ItemInstance> instance = Recipes::getInstance()->getItemFor(container, animal->level);
325
326 int color = 0;
327 if (instance != NULL && instance->getItem()->id == Item::dye_powder_Id)
328 {
329 color = instance->getAuxValue();
330 }
331 else
332 {
333 color = level->random->nextBoolean() ? parent1DyeColor : parent2DyeColor;
334 }
335 return color;
336}
337
338int Sheep::getDyeColor(shared_ptr<Animal> animal)
339{
340 return 15 - dynamic_pointer_cast<Sheep>(animal)->getColor();
341}