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.h"
3#include "net.minecraft.world.phys.h"
4#include "net.minecraft.world.level.h"
5#include "net.minecraft.world.level.storage.h"
6#include "net.minecraft.world.level.chunk.h"
7#include "net.minecraft.world.entity.h"
8#include "net.minecraft.world.item.h"
9#include "net.minecraft.world.entity.ai.attributes.h"
10#include "net.minecraft.world.entity.item.h"
11#include "net.minecraft.world.entity.player.h"
12#include "net.minecraft.world.entity.monster.h"
13#include "net.minecraft.world.damagesource.h"
14#include "com.mojang.nbt.h"
15#include "Slime.h"
16#include "..\Minecraft.Client\Textures.h"
17#include "SoundTypes.h"
18
19
20
21void Slime::_init()
22{
23 jumpDelay = 0;
24
25 targetSquish = 0;
26 squish = 0;
27 oSquish = 0;
28}
29
30Slime::Slime(Level *level) : Mob( 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 _init();
39
40 int size = 1 << (random->nextInt(3));
41 heightOffset = 0;
42 jumpDelay = random->nextInt(20) + 10;
43 setSize(size);
44}
45
46void Slime::defineSynchedData()
47{
48 Mob::defineSynchedData();
49
50 entityData->define(ID_SIZE, (byte) 1);
51}
52
53void Slime::setSize(int size)
54{
55 entityData->set(ID_SIZE, (byte) size);
56 setSize(0.6f * size, 0.6f * size);
57 setPos(x, y, z);
58 getAttribute(SharedMonsterAttributes::MAX_HEALTH)->setBaseValue(size * size);
59 setHealth(getMaxHealth());
60 xpReward = size;
61}
62
63int Slime::getSize()
64{
65 return entityData->getByte(ID_SIZE);
66}
67
68void Slime::addAdditonalSaveData(CompoundTag *tag)
69{
70 Mob::addAdditonalSaveData(tag);
71 tag->putInt(L"Size", getSize() - 1);
72}
73
74void Slime::readAdditionalSaveData(CompoundTag *tag)
75{
76 Mob::readAdditionalSaveData(tag);
77 setSize(tag->getInt(L"Size") + 1);
78}
79
80ePARTICLE_TYPE Slime::getParticleName()
81{
82 return eParticleType_slime;
83}
84
85int Slime::getSquishSound()
86{
87 return getSize() > 1 ? eSoundType_MOB_SLIME_BIG : eSoundType_MOB_SLIME;
88}
89
90void Slime::tick()
91{
92 if (!level->isClientSide && level->difficulty == Difficulty::PEACEFUL && getSize() > 0)
93 {
94 removed = true;
95 }
96
97 squish = squish + (targetSquish - squish) * .5f;
98
99 oSquish = squish;
100 bool wasOnGround = onGround;
101 Mob::tick();
102 if (onGround && !wasOnGround)
103 {
104 int size = getSize();
105 for (int i = 0; i < size * 8; i++)
106 {
107 float dir = random->nextFloat() * PI * 2;
108 float d = random->nextFloat() * 0.5f + 0.5f;
109 float xd = Mth::sin(dir) * size * 0.5f * d;
110 float zd = Mth::cos(dir) * size * 0.5f * d;
111 level->addParticle(getParticleName(), x + xd, bb->y0, z + zd, 0, 0, 0);
112 }
113
114 if (doPlayLandSound())
115 {
116 playSound(getSquishSound(), getSoundVolume(), ((random->nextFloat() - random->nextFloat()) * 0.2f + 1.0f) / 0.8f);
117 }
118 targetSquish = -0.5f;
119 }
120 // 4J Stu - Brought forward from 1.3 in TU7 to fix lava slime render
121 else if (!onGround && wasOnGround)
122 {
123 targetSquish = 1;
124 }
125 decreaseSquish();
126
127 if (level->isClientSide)
128 {
129 int size = getSize();
130 setSize(0.6f * size, 0.6f * size);
131 }
132}
133
134void Slime::serverAiStep()
135{
136 checkDespawn();
137 shared_ptr<Player> player = level->getNearestAttackablePlayer(shared_from_this(), 16);
138 if (player != NULL)
139 {
140 lookAt(player, 10, 20);
141 }
142 if (onGround && jumpDelay-- <= 0)
143 {
144 jumpDelay = getJumpDelay();
145 if (player != NULL)
146 {
147 jumpDelay /= 3;
148 }
149 jumping = true;
150 if (doPlayJumpSound())
151 {
152 playSound(getSquishSound(), getSoundVolume(), ((random->nextFloat() - random->nextFloat()) * 0.2f + 1.0f) * 0.8f);
153 }
154
155 // 4J Removed TU7 to bring forward change to fix lava slime render in MP
156 //targetSquish = 1;
157 xxa = 1 - random->nextFloat() * 2;
158 yya = (float) 1 * getSize();
159 }
160 else
161 {
162 jumping = false;
163 if (onGround)
164 {
165 xxa = yya = 0;
166 }
167 }
168}
169
170void Slime::decreaseSquish()
171{
172 targetSquish = targetSquish * 0.6f;
173}
174
175int Slime::getJumpDelay()
176{
177 return random->nextInt(20) + 10;
178}
179
180shared_ptr<Slime> Slime::createChild()
181{
182 return shared_ptr<Slime>( new Slime(level) );
183}
184
185void Slime::remove()
186{
187 int size = getSize();
188 if (!level->isClientSide && size > 1 && getHealth() <= 0)
189 {
190 int count = 2 + random->nextInt(3);
191 for (int i = 0; i < count; i++)
192 {
193 // The mob spawner can currently make a maximum of 25 slimes (limited to 50% of the total amount of monsters which is 50)
194 // and so limit to slightly more than this so we have some head room to make a few spawned children. Also always create at least one
195 // new slime since we are getting rid of this one anyway.
196 if( i == 0 || level->countInstanceOf( eTYPE_SLIME, true) < 35 )
197 {
198 float xd = (i % 2 - 0.5f) * size / 4.0f;
199 float zd = (i / 2 - 0.5f) * size / 4.0f;
200 shared_ptr<Slime> slime = createChild();
201 slime->setSize(size / 2);
202 slime->moveTo(x + xd, y + 0.5, z + zd, random->nextFloat() * 360, 0);
203 level->addEntity(slime);
204 }
205 }
206 }
207 Mob::remove();
208}
209
210void Slime::playerTouch(shared_ptr<Player> player)
211{
212 if (isDealsDamage())
213 {
214 int size = getSize();
215 if (canSee(player) && distanceToSqr(player) < (0.6 * size) * (0.6 * size))
216 {
217 DamageSource *damageSource = DamageSource::mobAttack( dynamic_pointer_cast<Mob>( shared_from_this() ) );
218 if (player->hurt(damageSource, getAttackDamage()))
219 {
220 playSound(eSoundType_MOB_SLIME_ATTACK, 1, (random->nextFloat() - random->nextFloat()) * 0.2f + 1.0f);
221 }
222 delete damageSource;
223 }
224 }
225}
226
227bool Slime::isDealsDamage()
228{
229 return getSize() > 1;
230}
231
232int Slime::getAttackDamage()
233{
234 return getSize();
235}
236
237int Slime::getHurtSound()
238{
239 return getSize() > 1 ? eSoundType_MOB_SLIME_BIG : eSoundType_MOB_SLIME;
240}
241
242int Slime::getDeathSound()
243{
244 return getSize() > 1 ? eSoundType_MOB_SLIME_BIG : eSoundType_MOB_SLIME;
245}
246
247int Slime::getDeathLoot()
248{
249 if (getSize() == 1) return Item::slimeBall->id;
250 return 0;
251}
252
253bool Slime::canSpawn()
254{
255 LevelChunk *lc = level->getChunkAt( Mth::floor(x), Mth::floor(z));
256 if (level->getLevelData()->getGenerator() == LevelType::lvl_flat && random->nextInt(4) != 1)
257 {
258 return false;
259 }
260 Random *lcr = lc->getRandom(987234911l); // 4J - separated out so we can delete
261 if ((getSize() == 1 || level->difficulty > Difficulty::PEACEFUL))
262 {
263 // spawn slime in swamplands at night
264 Biome *biome = level->getBiome(Mth::floor(x), Mth::floor(z));
265
266 if (biome == Biome::swampland && y > 50 && y < 70 && random->nextFloat() < 0.5f)
267 {
268 if (random->nextFloat() < level->getMoonBrightness() && level->getRawBrightness(Mth::floor(x), Mth::floor(y), Mth::floor(z)) <= random->nextInt(8))
269 {
270 return Mob::canSpawn();
271 }
272 }
273 if (random->nextInt(10) == 0 && lcr->nextInt(10) == 0 && y < 40)
274 {
275 return Mob::canSpawn();
276 }
277 }
278
279 delete lcr;
280 return false;
281}
282
283float Slime::getSoundVolume()
284{
285 return 0.4f * getSize();
286}
287
288int Slime::getMaxHeadXRot()
289{
290 return 0;
291}
292
293bool Slime::doPlayJumpSound()
294{
295 return getSize() > 0;
296}
297
298bool Slime::doPlayLandSound()
299{
300 return getSize() > 2;
301}