the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 261 lines 6.0 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.entity.h" 6#include "net.minecraft.world.entity.ai.attributes.h" 7#include "net.minecraft.world.entity.projectile.h" 8#include "net.minecraft.world.entity.player.h" 9#include "net.minecraft.world.entity.monster.h" 10#include "net.minecraft.world.item.h" 11#include "net.minecraft.world.damagesource.h" 12#include "net.minecraft.stats.h" 13#include "Ghast.h" 14#include "..\Minecraft.Client\Textures.h" 15#include "LevelEvent.h" 16#include "SoundTypes.h" 17 18 19 20void Ghast::_init() 21{ 22 explosionPower = 1; 23 floatDuration = 0; 24 target = nullptr; 25 retargetTime = 0; 26 oCharge = 0; 27 charge = 0; 28 29 xTarget = 0.0f; 30 yTarget = 0.0f; 31 zTarget = 0.0f; 32} 33 34Ghast::Ghast(Level *level) : FlyingMob( level ) 35{ 36 // 4J Stu - This function call had to be moved here from the Entity ctor to ensure that 37 // the derived version of the function is called 38 this->defineSynchedData(); 39 registerAttributes(); 40 setHealth(getMaxHealth()); 41 42 _init(); 43 44 setSize(4, 4); 45 fireImmune = true; 46 xpReward = Enemy::XP_REWARD_MEDIUM; 47} 48 49bool Ghast::isCharging() 50{ 51 return entityData->getByte(DATA_IS_CHARGING) != 0; 52} 53 54bool Ghast::hurt(DamageSource *source, float dmg) 55{ 56 if (isInvulnerable()) return false; 57 if (source->getMsgId() == ChatPacket::e_ChatDeathFireball) 58 { 59 if ( (source->getEntity() != NULL) && source->getEntity()->instanceof(eTYPE_PLAYER) ) 60 { 61 // reflected fireball, kill the ghast 62 FlyingMob::hurt(source, 1000); 63 dynamic_pointer_cast<Player>(source->getEntity())->awardStat(GenericStats::ghast(), GenericStats::param_ghast()); 64 return true; 65 } 66 } 67 68 return FlyingMob::hurt(source, dmg); 69} 70 71void Ghast::defineSynchedData() 72{ 73 FlyingMob::defineSynchedData(); 74 75 entityData->define(DATA_IS_CHARGING, (byte) 0); 76} 77 78void Ghast::registerAttributes() 79{ 80 FlyingMob::registerAttributes(); 81 82 getAttribute(SharedMonsterAttributes::MAX_HEALTH)->setBaseValue(10); 83} 84 85void Ghast::serverAiStep() 86{ 87 if (!level->isClientSide && level->difficulty == Difficulty::PEACEFUL) remove(); 88 checkDespawn(); 89 90 oCharge = charge; 91 double xd = xTarget - x; 92 double yd = yTarget - y; 93 double zd = zTarget - z; 94 95 double dd = xd * xd + yd * yd + zd * zd; 96 97 if (dd < 1 * 1 || dd > 60 * 60) 98 { 99 xTarget = x + (random->nextFloat() * 2 - 1) * 16; 100 yTarget = y + (random->nextFloat() * 2 - 1) * 16; 101 zTarget = z + (random->nextFloat() * 2 - 1) * 16; 102 } 103 104 if (floatDuration-- <= 0) 105 { 106 floatDuration += random->nextInt(5) + 2; 107 108 dd = sqrt(dd); 109 110 if (canReach(xTarget, yTarget, zTarget, dd)) 111 { 112 this->xd += xd / dd * 0.1; 113 this->yd += yd / dd * 0.1; 114 this->zd += zd / dd * 0.1; 115 } 116 else 117 { 118 xTarget = x; 119 yTarget = y; 120 zTarget = z; 121 } 122 } 123 124 if (target != NULL && target->removed) target = nullptr; 125 if (target == NULL || retargetTime-- <= 0) 126 { 127 target = level->getNearestAttackablePlayer(shared_from_this(), 100); 128 if (target != NULL) 129 { 130 retargetTime = 20; 131 } 132 } 133 134 double maxDist = 64.0f; 135 if (target != NULL && target->distanceToSqr(shared_from_this()) < maxDist * maxDist) 136 { 137 double xdd = target->x - x; 138 double ydd = (target->bb->y0 + target->bbHeight / 2) - (y + bbHeight / 2); 139 double zdd = target->z - z; 140 yBodyRot = yRot = -(float) atan2(xdd, zdd) * 180 / PI; 141 142 if (canSee(target)) 143 { 144 if (charge == 10) 145 { 146 // 4J - change brought forward from 1.2.3 147 level->levelEvent(nullptr, LevelEvent::SOUND_GHAST_WARNING, (int) x, (int) y, (int) z, 0); 148 } 149 charge++; 150 if (charge == 20) 151 { 152 // 4J - change brought forward from 1.2.3 153 level->levelEvent(nullptr, LevelEvent::SOUND_GHAST_FIREBALL, (int) x, (int) y, (int) z, 0); 154 shared_ptr<LargeFireball> ie = shared_ptr<LargeFireball>( new LargeFireball(level, dynamic_pointer_cast<Mob>( shared_from_this() ), xdd, ydd, zdd) ); 155 ie->explosionPower = explosionPower; 156 double d = 4; 157 Vec3 *v = getViewVector(1); 158 ie->x = x + v->x * d; 159 ie->y = y + bbHeight / 2 + 0.5f; 160 ie->z = z + v->z * d; 161 level->addEntity(ie); 162 charge = -40; 163 } 164 } 165 else 166 { 167 if (charge > 0) charge--; 168 } 169 } 170 else 171 { 172 yBodyRot = yRot = -(float) atan2(this->xd, this->zd) * 180 / PI; 173 if (charge > 0) charge--; 174 } 175 176 if (!level->isClientSide) 177 { 178 byte old = entityData->getByte(DATA_IS_CHARGING); 179 byte current = (byte) (charge > 10 ? 1 : 0); 180 if (old != current) 181 { 182 entityData->set(DATA_IS_CHARGING, current); 183 } 184 } 185} 186 187bool Ghast::canReach(double xt, double yt, double zt, double dist) 188{ 189 double xd = (xTarget - x) / dist; 190 double yd = (yTarget - y) / dist; 191 double zd = (zTarget - z) / dist; 192 193 AABB *bb = this->bb->copy(); 194 for (int d = 1; d < dist; d++) 195 { 196 bb->move(xd, yd, zd); 197 if (!level->getCubes( shared_from_this(), bb)->empty()) return false; 198 } 199 200 return true; 201} 202 203int Ghast::getAmbientSound() 204{ 205 return eSoundType_MOB_GHAST_MOAN; 206} 207 208int Ghast::getHurtSound() 209{ 210 return eSoundType_MOB_GHAST_SCREAM; 211} 212 213int Ghast::getDeathSound() 214{ 215 return eSoundType_MOB_GHAST_DEATH; 216} 217 218int Ghast::getDeathLoot() 219{ 220 return Item::gunpowder_Id; 221} 222 223void Ghast::dropDeathLoot(bool wasKilledByPlayer, int playerBonusLevel) 224{ 225 int count = random->nextInt(2) + random->nextInt(1 + playerBonusLevel); 226 for (int i = 0; i < count; i++) 227 { 228 spawnAtLocation(Item::ghastTear_Id, 1); 229 } 230 count = random->nextInt(3) + random->nextInt(1 + playerBonusLevel); 231 for (int i = 0; i < count; i++) 232 { 233 spawnAtLocation(Item::gunpowder_Id, 1); 234 } 235} 236 237float Ghast::getSoundVolume() 238{ 239 return 0.4f;//10; 4J-PB - changing due to customer demands 240} 241 242bool Ghast::canSpawn() 243{ 244 return (random->nextInt(20) == 0 && FlyingMob::canSpawn() && level->difficulty > Difficulty::PEACEFUL); 245} 246 247int Ghast::getMaxSpawnClusterSize() 248{ 249 return 1; 250} 251void Ghast::addAdditonalSaveData(CompoundTag *tag) 252{ 253 FlyingMob::addAdditonalSaveData(tag); 254 tag->putInt(L"ExplosionPower", explosionPower); 255} 256 257void Ghast::readAdditionalSaveData(CompoundTag *tag) 258{ 259 FlyingMob::readAdditionalSaveData(tag); 260 if (tag->contains(L"ExplosionPower")) explosionPower = tag->getInt(L"ExplosionPower"); 261}