the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 392 lines 9.2 kB view raw
1#include "stdafx.h" 2#include "net.minecraft.world.level.h" 3#include "net.minecraft.world.level.tile.h" 4#include "net.minecraft.world.entity.player.h" 5#include "net.minecraft.world.phys.h" 6#include "net.minecraft.world.item.h" 7#include "net.minecraft.world.damagesource.h" 8#include "com.mojang.nbt.h" 9#include "Fireball.h" 10#include "net.minecraft.world.level.dimension.h" 11#include "SharedConstants.h" 12 13 14// 4J - added common ctor code. 15void Fireball::_init() 16{ 17 xTile = -1; 18 yTile = -1; 19 zTile = -1; 20 lastTile = 0; 21 inGround = false; 22 flightTime = 0; 23 24 life = 0; 25 owner = nullptr; 26 xPower = 0.0; 27 yPower = 0.0; 28 zPower = 0.0; 29} 30 31Fireball::Fireball(Level *level) : Entity( level ) 32{ 33 // 4J Stu - This function call had to be moved here from the Entity ctor to ensure that 34 // the derived version of the function is called 35 this->defineSynchedData(); 36 37 _init(); 38 39 setSize(16 / 16.0f, 16 / 16.0f); 40 41} 42 43void Fireball::defineSynchedData() 44{ 45 46} 47 48bool Fireball::shouldRenderAtSqrDistance(double distance) 49{ 50 double size = bb->getSize() * 4; 51 size *= 64.0f; 52 return distance < size * size; 53} 54 55 56Fireball::Fireball(Level *level, double x, double y, double z, double xa, double ya, double za) : Entity( level ) 57{ 58 // 4J Stu - This function call had to be moved here from the Entity ctor to ensure that 59 // the derived version of the function is called 60 this->defineSynchedData(); 61 62 _init(); 63 64 setSize(16 / 16.0f, 16 / 16.0f); 65 66 moveTo(x, y, z, yRot, xRot); 67 setPos(x, y, z); 68 69 double dd = sqrt(xa * xa + ya * ya + za * za); 70 71 // Fix for #69150 - [CRASH] TU8: Code: Gameplay: Nether portal mechanics can become permanently broken, causing a hard lock upon usage. 72 // IF xa, ya and za are 0 then dd is 0 and the xa/dd etc return NAN 73 if(dd == 0.0) 74 { 75 xPower = 0.0; 76 yPower = 0.0; 77 zPower = 0.0; 78 } 79 else 80 { 81 xPower = xa / dd * 0.10; 82 yPower = ya / dd * 0.10; 83 zPower = za / dd * 0.10; 84 } 85} 86 87Fireball::Fireball(Level *level, shared_ptr<LivingEntity> mob, double xa, double ya, double za) : Entity ( level ) 88{ 89 // 4J Stu - This function call had to be moved here from the Entity ctor to ensure that 90 // the derived version of the function is called 91 this->defineSynchedData(); 92 93 _init(); 94 95 owner = mob; 96 97 setSize(16 / 16.0f, 16 / 16.0f); 98 99 moveTo(mob->x, mob->y, mob->z, mob->yRot, mob->xRot); 100 setPos(x, y, z); 101 heightOffset = 0; 102 103 104 xd = yd = zd = 0.0; 105 106 xa += random->nextGaussian() * 0.4; 107 ya += random->nextGaussian() * 0.4; 108 za += random->nextGaussian() * 0.4; 109 double dd = sqrt(xa * xa + ya * ya + za * za); 110 111 // Fix for #69150 - [CRASH] TU8: Code: Gameplay: Nether portal mechanics can become permanently broken, causing a hard lock upon usage. 112 // IF xa, ya and za are 0 then dd is 0 and the xa/dd etc return NAN 113 if(dd == 0.0) 114 { 115 xPower = 0.0; 116 yPower = 0.0; 117 zPower = 0.0; 118 } 119 else 120 { 121 xPower = xa / dd * 0.10; 122 yPower = ya / dd * 0.10; 123 zPower = za / dd * 0.10; 124 } 125} 126 127void Fireball::tick() 128{ 129 // 4J-PB - Moved forward from 1.2.3 130 //if (!level->isClientSide && (owner == NULL || owner->removed)) 131 if (!level->isClientSide) 132 { 133 if((owner != NULL && owner->removed) || !level->hasChunkAt((int) x, (int) y, (int) z)) 134 { 135 app.DebugPrintf("Fireball removed - owner is null or removed is true for owner\n"); 136 remove(); 137 return; 138 } 139 else 140 { 141 // 4J-PB - TU9 bug fix - fireballs can hit the edge of the world, and stay there 142 int minXZ = - (level->dimension->getXZSize() * 16 ) / 2; 143 int maxXZ = (level->dimension->getXZSize() * 16 ) / 2 - 1; 144 145 if ((x<=minXZ) || (x>=maxXZ) || (z<=minXZ) || (z>=maxXZ)) 146 { 147 remove(); 148 app.DebugPrintf("Fireball removed - end of world\n"); 149 return; 150 } 151 } 152 } 153 154 Entity::tick(); 155 156 //app.DebugPrintf("Fireball x %d, y %d, z%d\n",(int)x,(int)y,(int)z); 157 158 if(shouldBurn()) setOnFire(1); 159 160 if (inGround) 161 { 162 int tile = level->getTile(xTile, yTile, zTile); 163 if (tile == lastTile) 164 { 165 life++; 166 if (life == SharedConstants::TICKS_PER_SECOND * 30) 167 { 168 remove(); 169 app.DebugPrintf("Fireball removed - life is 20*60\n"); 170 } 171 return; 172 } 173 else 174 { 175 inGround = false; 176 177 xd *= random->nextFloat() * 0.2f; 178 yd *= random->nextFloat() * 0.2f; 179 zd *= random->nextFloat() * 0.2f; 180 life = 0; 181 flightTime = 0; 182 } 183 } 184 else 185 { 186 flightTime++; 187 } 188 189 MemSect(41); 190 Vec3 *from = Vec3::newTemp(x, y, z); 191 Vec3 *to = Vec3::newTemp(x + xd, y + yd, z + zd); 192 HitResult *res = level->clip(from, to); 193 194 from = Vec3::newTemp(x, y, z); 195 to = Vec3::newTemp(x + xd, y + yd, z + zd); 196 if (res != NULL) 197 { 198 to = Vec3::newTemp(res->pos->x, res->pos->y, res->pos->z); 199 } 200 shared_ptr<Entity> hitEntity = nullptr; 201 vector<shared_ptr<Entity> > *objects = level->getEntities(shared_from_this(), bb->expand(xd, yd, zd)->grow(1, 1, 1)); 202 double nearest = 0; 203 AUTO_VAR(itEnd, objects->end()); 204 for (AUTO_VAR(it, objects->begin()); it != itEnd; it++) 205 { 206 shared_ptr<Entity> e = *it; //objects->at(i); 207 if (!e->isPickable() || (e->is(owner) )) continue; //4J Stu - Never collide with the owner (Enderdragon) // && flightTime < 25)) continue; 208 209 float rr = 0.3f; 210 AABB *bb = e->bb->grow(rr, rr, rr); 211 HitResult *p = bb->clip(from, to); 212 if (p != NULL) 213 { 214 double dd = from->distanceTo(p->pos); 215 if (dd < nearest || nearest == 0) 216 { 217 hitEntity = e; 218 nearest = dd; 219 } 220 delete p; 221 } 222 223 } 224 225 if (hitEntity != NULL) 226 { 227 delete res; 228 res = new HitResult(hitEntity); 229 } 230 MemSect(0); 231 232 if (res != NULL) 233 { 234 onHit(res); 235 } 236 delete res; 237 x += xd; 238 y += yd; 239 z += zd; 240 241 double sd = sqrt(xd * xd + zd * zd); 242 yRot = (float) (atan2(zd, xd) * 180 / PI) + 90; 243 xRot = (float) (atan2(sd, yd) * 180 / PI) - 90; 244 245 while (xRot - xRotO < -180) 246 xRotO -= 360; 247 while (xRot - xRotO >= 180) 248 xRotO += 360; 249 250 while (yRot - yRotO < -180) 251 yRotO -= 360; 252 while (yRot - yRotO >= 180) 253 yRotO += 360; 254 255 xRot = xRotO + (xRot - xRotO) * 0.2f; 256 yRot = yRotO + (yRot - yRotO) * 0.2f; 257 258 259 float inertia = getInertia(); 260 if (isInWater()) 261 { 262 for (int i = 0; i < 4; i++) 263 { 264 float s = 1 / 4.0f; 265 level->addParticle(eParticleType_bubble, x - xd * s, y - yd * s, z - zd * s, xd, yd, zd); 266 } 267 inertia = 0.80f; 268 } 269 270 xd += xPower; 271 yd += yPower; 272 zd += zPower; 273 xd *= inertia; 274 yd *= inertia; 275 zd *= inertia; 276 277 // 4J-PB - bug fix for the fireballs in a saved game - they are saved with no/very small velocity, so end up hanging around in the air 278 if (!level->isClientSide) 279 { 280 if((abs(xd)<0.002) && (abs(yd)<0.002) && (abs(zd)<0.002)) 281 { 282 xd=0.0; 283 zd=0.0; 284 yd=0.0; 285 app.DebugPrintf("Removing a fireball with zero velocity\n"); 286 remove(); 287 } 288 } 289 290 level->addParticle(getTrailParticleType(), x, y + 0.5f, z, 0, 0.01, 0); 291 292 setPos(x, y, z); 293} 294 295float Fireball::getInertia() 296{ 297 return 0.95f; 298} 299 300void Fireball::addAdditonalSaveData(CompoundTag *tag) 301{ 302 tag->putShort(L"xTile", (short) xTile); 303 tag->putShort(L"yTile", (short) yTile); 304 tag->putShort(L"zTile", (short) zTile); 305 tag->putByte(L"inTile", (byte) lastTile); 306 tag->putByte(L"inGround", (byte) (inGround ? 1 : 0)); 307 tag->put(L"direction", newDoubleList(3, xd, yd, zd)); 308} 309 310void Fireball::readAdditionalSaveData(CompoundTag *tag) 311{ 312 xTile = tag->getShort(L"xTile"); 313 yTile = tag->getShort(L"yTile"); 314 zTile = tag->getShort(L"zTile"); 315 lastTile = tag->getByte(L"inTile") & 0xff; 316 inGround = tag->getByte(L"inGround") == 1; 317 318 // Load the stored direction and apply it to the fireball 319 // if it has no stored direction, remove it. 320 if (tag->contains(L"direction")) 321 { 322 ListTag<DoubleTag> *listTag = (ListTag<DoubleTag> *)tag->getList(L"direction"); 323 xd = ((DoubleTag *) listTag->get(0))->data; 324 yd = ((DoubleTag *) listTag->get(1))->data; 325 zd = ((DoubleTag *) listTag->get(2))->data; 326 } 327 else 328 { 329 remove(); 330 } 331} 332 333bool Fireball::isPickable() 334{ 335 return true; 336} 337 338float Fireball::getPickRadius() 339{ 340 return 1; 341} 342 343bool Fireball::hurt(DamageSource *source, float damage) 344{ 345 if (isInvulnerable()) return false; 346 markHurt(); 347 348 if (source->getEntity() != NULL) 349 { 350 Vec3 *lookAngle = source->getEntity()->getLookAngle(); 351 if (lookAngle != NULL) 352 { 353 xd = lookAngle->x; 354 yd = lookAngle->y; 355 zd = lookAngle->z; 356 xPower = xd * 0.1; 357 yPower = yd * 0.1; 358 zPower = zd * 0.1; 359 } 360 if ( source->getEntity()->instanceof(eTYPE_LIVINGENTITY) ) 361 { 362 owner = dynamic_pointer_cast<LivingEntity>( source->getEntity() ); 363 } 364 return true; 365 } 366 return false; 367} 368 369float Fireball::getShadowHeightOffs() 370{ 371 return 0; 372} 373 374float Fireball::getBrightness(float a) 375{ 376 return 1.0f; 377} 378 379int Fireball::getLightColor(float a) 380{ 381 return 15 << 20 | 15 << 4; 382} 383 384ePARTICLE_TYPE Fireball::getTrailParticleType() 385{ 386 return eParticleType_smoke; 387} 388 389bool Fireball::shouldBurn() 390{ 391 return true; 392}