Something went wrong. Try again.
the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
Something went wrong. Try again.
11 kB · 527 lines
C++
at master
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528#include "stdafx.h"#include "com.mojang.nbt.h"#include "net.minecraft.world.entity.h"#include "net.minecraft.world.entity.player.h"#include "net.minecraft.world.item.h"#include "net.minecraft.world.level.h"#include "net.minecraft.world.level.material.h"#include "net.minecraft.world.level.tile.h"#include "net.minecraft.world.phys.h"#include "net.minecraft.world.damagesource.h"#include "Boat.h"
const double Boat::MAX_SPEED = 0.35;const double Boat::MAX_COLLISION_SPEED = MAX_SPEED * 0.75;const double Boat::MIN_ACCELERATION = 0.07;const double Boat::MAX_ACCELERATION = 0.35;
// 4J - added for common ctor codevoid Boat::_init(){ doLerp = true; acceleration = MIN_ACCELERATION;
lSteps = 0; lx = ly = lz = lyr = lxr = 0.0; lxd = lyd = lzd = 0.0;
blocksBuilding = true; setSize(1.5f, 0.6f); heightOffset = bbHeight / 2.0f;
// 4J Stu - This function call had to be moved here from the Entity ctor to ensure that // the derived version of the function is called this->defineSynchedData();}
Boat::Boat(Level *level) : Entity( level ){
_init();}
bool Boat::makeStepSound(){ return false;}
void Boat::defineSynchedData(){ entityData->define(DATA_ID_HURT, 0); entityData->define(DATA_ID_HURTDIR, 1); entityData->define(DATA_ID_DAMAGE, 0.0f);}
AABB *Boat::getCollideAgainstBox(shared_ptr<Entity> entity){ return entity->bb;}
AABB *Boat::getCollideBox(){ return bb;}
bool Boat::isPushable(){ return true;}
Boat::Boat(Level *level, double x, double y, double z) : Entity( level ){ _init(); setPos(x, y + heightOffset, z);
xd = 0; yd = 0; zd = 0;
xo = x; yo = y; zo = z;}
double Boat::getRideHeight(){ return bbHeight * 0.0f - 0.3f;}
bool Boat::hurt(DamageSource *source, float hurtDamage){ if (isInvulnerable()) return false; if (level->isClientSide || removed) return true;
// 4J-JEV: Fix for #88212, // Untrusted players shouldn't be able to damage minecarts or boats. if (dynamic_cast<EntityDamageSource *>(source) != NULL) { shared_ptr<Entity> attacker = source->getDirectEntity();
if ( attacker->instanceof(eTYPE_PLAYER) && !dynamic_pointer_cast<Player>(attacker)->isAllowedToHurtEntity( shared_from_this() )) { return false; } }
setHurtDir(-getHurtDir()); setHurtTime(10);
// 4J Stu - If someone is riding in this, then it can tick multiple times which causes the damage to // decrease too quickly. So just make the damage a bit higher to start with for similar behaviour // to an unridden one. Only do this change if the riding player is attacking it. if( rider.lock() != NULL && rider.lock() == source->getEntity() ) hurtDamage += 1;
setDamage(getDamage() + hurtDamage * 10); markHurt();
// 4J Stu - Brought froward from 12w36 to fix #46611 - TU5: Gameplay: Minecarts and boat requires more hits than one to be destroyed in creative mode // 4J-PB - Fix for XB1 #175735 - [CRASH] [Multi-Plat]: Code: Gameplay: Placing a boat on harmful surfaces causes the game to crash bool creativePlayer = (source->getEntity() != NULL) && source->getEntity()->instanceof(eTYPE_PLAYER) && dynamic_pointer_cast<Player>(source->getEntity())->abilities.instabuild;
if (creativePlayer || getDamage() > 20 * 2) { if (rider.lock() != NULL) rider.lock()->ride( shared_from_this() ); if (!creativePlayer) spawnAtLocation(Item::boat_Id, 1, 0); remove(); } return true;}
void Boat::animateHurt(){ setHurtDir(-getHurtDir()); setHurtTime(10); setDamage(getDamage() * 11);}
bool Boat::isPickable(){ return !removed;}
void Boat::lerpTo(double x, double y, double z, float yRot, float xRot, int steps){ if (doLerp) { lSteps = steps + 5; } else { double xdiff = x - this->x; double ydiff = y - this->y; double zdiff = z - this->z; double diff = xdiff * xdiff + ydiff * ydiff + zdiff * zdiff;
if (diff > 1) { lSteps = 3; } else { return; } }
lx = x; ly = y; lz = z; lyr = yRot; lxr = xRot;
xd = lxd; yd = lyd; zd = lzd;}
void Boat::lerpMotion(double xd, double yd, double zd){ lxd = this->xd = xd; lyd = this->yd = yd; lzd = this->zd = zd;}
void Boat::tick(){ Entity::tick(); if (getHurtTime() > 0) setHurtTime(getHurtTime() - 1); if (getDamage() > 0) setDamage(getDamage() - 1); xo = x; yo = y; zo = z;
int steps = 5; double waterPercentage = 0; for (int i = 0; i < steps; i++) { double y0 = bb->y0 + (bb->y1 - bb->y0) * (i + 0) / steps - 2 / 16.0f; double y1 = bb->y0 + (bb->y1 - bb->y0) * (i + 1) / steps - 2 / 16.0f; AABB *bb2 = AABB::newTemp(bb->x0, y0, bb->z0, bb->x1, y1, bb->z1); if (level->containsLiquid(bb2, Material::water)) { waterPercentage += 1.0 / steps; } }
double lastSpeed = sqrt(xd * xd + zd * zd); if (lastSpeed > MAX_COLLISION_SPEED) { double xa = cos(yRot * PI / 180); double za = sin(yRot * PI / 180);
for (int i = 0; i < 1 + lastSpeed * 60; i++) {
double side = (random->nextFloat() * 2 - 1);
double side2 = (random->nextInt(2) * 2 - 1) * 0.7; if (random->nextBoolean()) { double xx = x - xa * side * 0.8 + za * side2; double zz = z - za * side * 0.8 - xa * side2; level->addParticle(eParticleType_splash, xx, y - 2 / 16.0f, zz, +xd, yd, +zd); } else { double xx = x + xa + za * side * 0.7; double zz = z + za - xa * side * 0.7; level->addParticle(eParticleType_splash, xx, y - 2 / 16.0f, zz, +xd, yd, +zd); } } }
if (level->isClientSide && doLerp) { if (lSteps > 0) { double xt = x + (lx - x) / lSteps; double yt = y + (ly - y) / lSteps; double zt = z + (lz - z) / lSteps;
double yrd = Mth::wrapDegrees(lyr - yRot);
yRot += (float) ( (yrd) / lSteps ); xRot += (float) ( (lxr - xRot) / lSteps );
lSteps--; setPos(xt, yt, zt); setRot(yRot, xRot); } else {#if 1 // Original //double xt = x + xd; //double yt = y + yd; //double zt = z + zd; //this->setPos(xt, yt, zt);
// 4J Stu - Fix for various boat bugs, ensure that we check collision on client-side movement move(xd,yd,zd);
if (onGround) { xd *= 0.5f; yd *= 0.5f; zd *= 0.5f; } xd *= 0.99f; yd *= 0.95f; zd *= 0.99f;#else // 4J Stu - Fix for #8280 - Gameplay : Boats behave erratically when exited next to land. // The client shouldn't change the position of the boat double xt = x;// + xd; double yt = y + yd; double zt = z;// + zd; this->setPos(xt, yt, zt);
// 4J Stu - Fix for #9579 - GAMEPLAY: Boats with a player in them slowly sink under the water over time, and with no player in them they float into the sky. // Just make the boats bob up and down rather than any other client-side movement when not receiving packets from server if (waterPercentage < 1) { double bob = waterPercentage * 2 - 1; yd += 0.04f * bob; } else { if (yd < 0) yd /= 2; yd += 0.007f; } //if (onGround) //{ xd *= 0.5f; yd *= 0.5f; zd *= 0.5f; //} //xd *= 0.99f; //yd *= 0.95f; //zd *= 0.99f;#endif } return; }
if (waterPercentage < 1) { double bob = waterPercentage * 2 - 1; yd += 0.04f * bob; } else { if (yd < 0) yd /= 2; yd += 0.007f; }
if ( rider.lock() != NULL && rider.lock()->instanceof(eTYPE_LIVINGENTITY) ) { shared_ptr<LivingEntity> livingRider = dynamic_pointer_cast<LivingEntity>(rider.lock()); double forward = livingRider->yya;
if (forward > 0) { double riderXd = -sin(livingRider->yRot * PI / 180); double riderZd = cos(livingRider->yRot * PI / 180); xd += riderXd * acceleration * 0.05f; zd += riderZd * acceleration * 0.05f; } }
double curSpeed = sqrt(xd * xd + zd * zd);
if (curSpeed > MAX_SPEED) { double ratio = MAX_SPEED / curSpeed;
xd *= ratio; zd *= ratio; curSpeed = MAX_SPEED; }
if (curSpeed > lastSpeed && acceleration < MAX_ACCELERATION) { acceleration += (MAX_ACCELERATION - acceleration) / 35; if (acceleration > MAX_ACCELERATION) acceleration = MAX_ACCELERATION; } else { acceleration -= (acceleration - MIN_ACCELERATION) / 35; if (acceleration < MIN_ACCELERATION) acceleration = MIN_ACCELERATION; }
if (onGround) { xd *= 0.5f; yd *= 0.5f; zd *= 0.5f; } move(xd, yd, zd);
if ((horizontalCollision && lastSpeed > 0.20)) { if (!level->isClientSide && !removed) { remove(); for (int i = 0; i < 3; i++) { spawnAtLocation(Tile::wood_Id, 1, 0); } for (int i = 0; i < 2; i++) { spawnAtLocation(Item::stick->id, 1, 0); } } } else { xd *= 0.99f; yd *= 0.95f; zd *= 0.99f; }
xRot = 0; double yRotT = yRot; double xDiff = xo - x; double zDiff = zo - z; if (xDiff * xDiff + zDiff * zDiff > 0.001) { yRotT = (float) (atan2(zDiff, xDiff) * 180 / PI); }
double rotDiff = Mth::wrapDegrees(yRotT - yRot);
if (rotDiff > 20) rotDiff = 20; if (rotDiff < -20) rotDiff = -20;
yRot += (float) rotDiff; setRot(yRot, xRot);
if(level->isClientSide) return;
vector<shared_ptr<Entity> > *entities = level->getEntities(shared_from_this(), bb->grow(0.2f, 0, 0.2f)); if (entities != NULL && !entities->empty()) { AUTO_VAR(itEnd, entities->end()); for (AUTO_VAR(it, entities->begin()); it != itEnd; it++) { shared_ptr<Entity> e = (*it); // entities->at(i); if (e != rider.lock() && e->isPushable() && e->GetType() == eTYPE_BOAT) { e->push(shared_from_this()); } } }
for (int i = 0; i < 4; i++) { int xx = Mth::floor(x + ((i % 2) - 0.5) * 0.8); int zz = Mth::floor(z + ((i / 2) - 0.5) * 0.8);
for (int j = 0; j < 2; j++) { int yy = Mth::floor(y) + j; int tile = level->getTile(xx, yy, zz);
if (tile == Tile::topSnow_Id) { level->removeTile(xx, yy, zz); } else if (tile == Tile::waterLily_Id) { level->destroyTile(xx, yy, zz, true); } }
}
if (rider.lock() != NULL) { if (rider.lock()->removed) rider = weak_ptr<Entity>(); }}
void Boat::positionRider(){ if (rider.lock() == NULL) return;
double xa = cos(yRot * PI / 180) * 0.4; double za = sin(yRot * PI / 180) * 0.4; rider.lock()->setPos(x + xa, y + getRideHeight() + rider.lock()->getRidingHeight(), z + za);}
void Boat::addAdditonalSaveData(CompoundTag *base){}
void Boat::readAdditionalSaveData(CompoundTag *base){}
float Boat::getShadowHeightOffs(){ return 0;}
wstring Boat::getName(){ return L"Boat";}
bool Boat::interact(shared_ptr<Player> player){ if ( (rider.lock() != NULL) && rider.lock()->instanceof(eTYPE_PLAYER) && (rider.lock() != player) ) return true; if (!level->isClientSide) { // 4J HEG - Fixed issue with player not being able to dismount boat (issue #4446) player->ride( rider.lock() == player ? nullptr : shared_from_this() ); } return true;}
void Boat::setDamage(float damage){ entityData->set(DATA_ID_DAMAGE, damage);}
float Boat::getDamage(){ return entityData->getFloat(DATA_ID_DAMAGE);}
void Boat::setHurtTime(int hurtTime){ entityData->set(DATA_ID_HURT, hurtTime);}
int Boat::getHurtTime(){ return entityData->getInteger(DATA_ID_HURT);}
void Boat::setHurtDir(int hurtDir){ entityData->set(DATA_ID_HURTDIR, hurtDir);}
int Boat::getHurtDir(){ return entityData->getInteger(DATA_ID_HURTDIR);}
bool Boat::getDoLerp(){ return doLerp;}
void Boat::setDoLerp(bool doLerp){ this->doLerp = doLerp;}