the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 301 lines 6.9 kB view raw
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}