forked from Kolyah35/minecraft-pe-0.6.1
the whole game
This commit is contained in:
963
src/world/entity/Entity.cpp
Executable file
963
src/world/entity/Entity.cpp
Executable file
@@ -0,0 +1,963 @@
|
||||
#include "Entity.h"
|
||||
#include "EntityPos.h"
|
||||
#include "../level/Level.h"
|
||||
#include "../level/tile/LiquidTile.h"
|
||||
#include "item/ItemEntity.h"
|
||||
#include "../item/ItemInstance.h"
|
||||
#include "../../nbt/CompoundTag.h"
|
||||
#include "../../util/PerfTimer.h"
|
||||
|
||||
int
|
||||
Entity::entityCounter = 0;
|
||||
Random
|
||||
Entity::sharedRandom(getEpochTimeS());
|
||||
|
||||
Entity::Entity( Level* level )
|
||||
: level(level),
|
||||
viewScale(1.0f),
|
||||
blocksBuilding(false),
|
||||
onGround(false),
|
||||
wasInWater(false),
|
||||
collision(false),
|
||||
hurtMarked(false),
|
||||
slide(true),
|
||||
isStuckInWeb(false),
|
||||
removed(false),
|
||||
reallyRemoveIfPlayer(false),
|
||||
canRemove(true), //@todo: remove
|
||||
noPhysics(false),
|
||||
firstTick(true),
|
||||
|
||||
bbWidth(0.6f),
|
||||
bbHeight(1.8f),
|
||||
heightOffset(0 / 16.0f),
|
||||
bb(0,0,0,0,0,0),
|
||||
|
||||
ySlideOffset(0),
|
||||
fallDistance(0),
|
||||
footSize(0),
|
||||
invulnerableTime(0),
|
||||
pushthrough(0),
|
||||
airCapacity(TOTAL_AIR_SUPPLY),
|
||||
airSupply(TOTAL_AIR_SUPPLY),
|
||||
|
||||
xOld(0),yOld(0),zOld(0),
|
||||
horizontalCollision(false), verticalCollision(false),
|
||||
|
||||
x(0), y(0), z(0),
|
||||
xo(0),yo(0),zo(0),xd(0),yd(0),zd(0),
|
||||
xRot(0), yRot(0),
|
||||
xRotO(0), yRotO(0),
|
||||
|
||||
xChunk(0), yChunk(0), zChunk(0),
|
||||
inChunk(false),
|
||||
|
||||
fireImmune(false),
|
||||
onFire(0),
|
||||
flameTime(1),
|
||||
walkDist(0), walkDistO(0),
|
||||
tickCount(0),
|
||||
entityRendererId(ER_DEFAULT_RENDERER),
|
||||
nextStep(1),
|
||||
makeStepSound(true),
|
||||
invisible(false)
|
||||
{
|
||||
_init();
|
||||
|
||||
entityId = ++entityCounter;
|
||||
|
||||
//ref = Ref<Entity>::create(this);
|
||||
|
||||
setPos(0, 0, 0);
|
||||
}
|
||||
|
||||
Entity::~Entity() {
|
||||
//if (ref->isUnique())
|
||||
// delete ref;
|
||||
}
|
||||
|
||||
SynchedEntityData* Entity::getEntityData() {
|
||||
return NULL;
|
||||
}
|
||||
const SynchedEntityData* Entity::getEntityData() const {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool Entity::isInWall() {
|
||||
int xt = Mth::floor(x);
|
||||
int yt = Mth::floor(y + getHeadHeight());
|
||||
int zt = Mth::floor(z);
|
||||
return level->isSolidBlockingTile(xt, yt, zt);
|
||||
}
|
||||
|
||||
void Entity::resetPos(bool clearMore) {
|
||||
if (level == NULL) return;
|
||||
while (y > 0) {
|
||||
setPos(x, y, z);
|
||||
if (level->getCubes(this, bb).size() == 0) break;
|
||||
y += 1;
|
||||
}
|
||||
|
||||
xd = yd = zd = 0;
|
||||
xRot = 0;
|
||||
}
|
||||
|
||||
bool Entity::isInWater() {
|
||||
return level->checkAndHandleWater(bb.grow(0, -0.4f, 0), Material::water, this);
|
||||
}
|
||||
|
||||
bool Entity::isInLava() {
|
||||
return level->containsMaterial(bb.grow(-0.1f, -0.4f, -0.1f), Material::lava);
|
||||
}
|
||||
|
||||
bool Entity::isFree(float xa, float ya, float za, float grow) {
|
||||
AABB box = bb.grow(grow, grow, grow).cloneMove(xa, ya, za);
|
||||
const std::vector<AABB>& aABBs = level->getCubes(this, box);
|
||||
if (aABBs.size() > 0) return false;
|
||||
if (level->containsAnyLiquid(box)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Entity::isFree(float xa, float ya, float za) {
|
||||
AABB box = bb.cloneMove(xa, ya, za);
|
||||
const std::vector<AABB>& aABBs = level->getCubes(this, box);
|
||||
if (aABBs.size() > 0) return false;
|
||||
if (level->containsAnyLiquid(box)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
//static void __attribute__((noinline)) setPositionFromBbox(Entity* e) { // @RPI
|
||||
// const AABB& bb = e->bb;
|
||||
// e->x = (e->bb.x0 + e->bb.x1) / 2.0f;
|
||||
// e->y = bb.y0 + e->heightOffset - e->ySlideOffset;
|
||||
// e->z = (bb.z0 + bb.z1) / 2.0f;
|
||||
//}
|
||||
|
||||
/*public*/
|
||||
void Entity::move(float xa, float ya, float za) {
|
||||
//if (std::abs(xa) + std::abs(ya) + std::abs(za) < 0.00001f) //@RPI
|
||||
// return;
|
||||
|
||||
if (noPhysics) {
|
||||
bb.move(xa, ya, za);
|
||||
x = (bb.x0 + bb.x1) / 2.0f;
|
||||
y = bb.y0 + heightOffset - ySlideOffset;
|
||||
z = (bb.z0 + bb.z1) / 2.0f;
|
||||
return;
|
||||
}
|
||||
|
||||
TIMER_PUSH("move");
|
||||
|
||||
float xo = x;
|
||||
float zo = z;
|
||||
|
||||
if (isStuckInWeb) {
|
||||
isStuckInWeb = false;
|
||||
|
||||
xa *= .25f;
|
||||
ya *= .05f;
|
||||
za *= .25f;
|
||||
xd = .0f;
|
||||
yd = .0f;
|
||||
zd = .0f;
|
||||
}
|
||||
|
||||
float xaOrg = xa;
|
||||
float yaOrg = ya;
|
||||
float zaOrg = za;
|
||||
|
||||
AABB bbOrg = bb;
|
||||
|
||||
bool sneaking = onGround && isSneaking();
|
||||
|
||||
if (sneaking) {
|
||||
float d = 0.05f;
|
||||
while (xa != 0 && level->getCubes(this, bb.cloneMove(xa, -1.0, 0)).empty()) {
|
||||
if (xa < d && xa >= -d) xa = 0;
|
||||
else if (xa > 0) xa -= d;
|
||||
else xa += d;
|
||||
xaOrg = xa;
|
||||
}
|
||||
while (za != 0 && level->getCubes(this, bb.cloneMove(0, -1.0, za)).empty()) {
|
||||
if (za < d && za >= -d) za = 0;
|
||||
else if (za > 0) za -= d;
|
||||
else za += d;
|
||||
zaOrg = za;
|
||||
}
|
||||
|
||||
while (xa != 0 && za != 0 && level->getCubes(this, bb.cloneMove(xa, -1.0, za)).empty()) {
|
||||
if (xa < d && xa >= -d) xa = 0;
|
||||
else if (xa > 0) xa -= d;
|
||||
else xa += d;
|
||||
if (za < d && za >= -d) za = 0;
|
||||
else if (za > 0) za -= d;
|
||||
else za += d;
|
||||
xaOrg = xa;
|
||||
zaOrg = za;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::vector<AABB>& aABBs = level->getCubes(this, bb.expand(xa, ya, za));
|
||||
|
||||
// LAND FIRST, then x and z
|
||||
for (unsigned int i = 0; i < aABBs.size(); i++)
|
||||
ya = aABBs[i].clipYCollide(bb, ya);
|
||||
bb.move(0, ya, 0);
|
||||
|
||||
if (!slide && yaOrg != ya) {
|
||||
xa = ya = za = 0;
|
||||
}
|
||||
|
||||
bool og = onGround || (yaOrg != ya && yaOrg < 0);
|
||||
|
||||
for (unsigned int i = 0; i < aABBs.size(); i++)
|
||||
xa = aABBs[i].clipXCollide(bb, xa);
|
||||
|
||||
bb.move(xa, 0, 0);
|
||||
|
||||
if (!slide && xaOrg != xa) {
|
||||
xa = ya = za = 0;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < aABBs.size(); i++)
|
||||
za = aABBs[i].clipZCollide(bb, za);
|
||||
bb.move(0, 0, za);
|
||||
|
||||
if (!slide && zaOrg != za) {
|
||||
xa = ya = za = 0;
|
||||
}
|
||||
|
||||
if (footSize > 0 && og && (ySlideOffset < 0.05f) && ((xaOrg != xa) || (zaOrg != za))) {
|
||||
|
||||
float xaN = xa;
|
||||
float yaN = ya;
|
||||
float zaN = za;
|
||||
|
||||
xa = xaOrg;
|
||||
ya = footSize;
|
||||
za = zaOrg;
|
||||
|
||||
AABB normal = bb;
|
||||
bb.set(bbOrg);
|
||||
aABBs = level->getCubes(this, bb.expand(xa, ya, za));
|
||||
|
||||
// LAND FIRST, then x and z
|
||||
for (unsigned int i = 0; i < aABBs.size(); i++)
|
||||
ya = aABBs[i].clipYCollide(bb, ya);
|
||||
bb.move(0, ya, 0);
|
||||
|
||||
if (!slide && yaOrg != ya) {
|
||||
xa = ya = za = 0;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < aABBs.size(); i++)
|
||||
xa = aABBs[i].clipXCollide(bb, xa);
|
||||
bb.move(xa, 0, 0);
|
||||
|
||||
if (!slide && xaOrg != xa) {
|
||||
xa = ya = za = 0;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < aABBs.size(); i++)
|
||||
za = aABBs[i].clipZCollide(bb, za);
|
||||
bb.move(0, 0, za);
|
||||
|
||||
if (!slide && zaOrg != za) {
|
||||
xa = ya = za = 0;
|
||||
}
|
||||
|
||||
if (xaN * xaN + zaN * zaN >= xa * xa + za * za) {
|
||||
xa = xaN;
|
||||
ya = yaN;
|
||||
za = zaN;
|
||||
bb.set(normal);
|
||||
} else {
|
||||
ySlideOffset += 0.5f;
|
||||
}
|
||||
}
|
||||
|
||||
TIMER_POP_PUSH("rest");
|
||||
|
||||
x = (bb.x0 + bb.x1) / 2.0f;
|
||||
y = bb.y0 + heightOffset - ySlideOffset;
|
||||
z = (bb.z0 + bb.z1) / 2.0f;
|
||||
|
||||
horizontalCollision = (xaOrg != xa) || (zaOrg != za);
|
||||
verticalCollision = (yaOrg != ya);
|
||||
onGround = yaOrg != ya && yaOrg < 0;
|
||||
collision = horizontalCollision || verticalCollision;
|
||||
checkFallDamage(ya, onGround);
|
||||
|
||||
if (xaOrg != xa) xd = 0;
|
||||
if (yaOrg != ya) yd = 0;
|
||||
if (zaOrg != za) zd = 0;
|
||||
|
||||
float xm = x - xo;
|
||||
float zm = z - zo;
|
||||
|
||||
if (makeStepSound && !sneaking) {
|
||||
walkDist += Mth::sqrt(xm * xm + zm * zm) * 0.6f;
|
||||
int xt = Mth::floor(x);
|
||||
int yt = Mth::floor(y - 0.2f - this->heightOffset);
|
||||
int zt = Mth::floor(z);
|
||||
|
||||
int t = level->getTile(xt, yt, zt);
|
||||
if (t == 0) {
|
||||
int under = level->getTile(xt, yt-1, zt);
|
||||
if (Tile::fence->id == under || Tile::fenceGate->id == under) {
|
||||
t = under;
|
||||
}
|
||||
}
|
||||
|
||||
if (walkDist > nextStep && t > 0) {
|
||||
nextStep = ((int) walkDist) + 1;
|
||||
playStepSound(xt, yt, zt, t);
|
||||
//Tile::tiles[t]->stepOn(level, xt, yt, zt, this); //@todo: step
|
||||
}
|
||||
}
|
||||
|
||||
int x0 = Mth::floor(bb.x0);
|
||||
int y0 = Mth::floor(bb.y0);
|
||||
int z0 = Mth::floor(bb.z0);
|
||||
int x1 = Mth::floor(bb.x1);
|
||||
int y1 = Mth::floor(bb.y1);
|
||||
int z1 = Mth::floor(bb.z1);
|
||||
|
||||
if (level->hasChunksAt(x0, y0, z0, x1, y1, z1)) {
|
||||
for (int x = x0; x <= x1; x++)
|
||||
for (int y = y0; y <= y1; y++)
|
||||
for (int z = z0; z <= z1; z++) {
|
||||
int t = level->getTile(x, y, z);
|
||||
if (t > 0) {
|
||||
Tile::tiles[t]->entityInside(level, x, y, z, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ySlideOffset *= 0.4f;
|
||||
|
||||
bool water = this->isInWater();
|
||||
if (level->containsFireTile(bb)) {
|
||||
burn(1);
|
||||
if (!water) {
|
||||
onFire++;
|
||||
if (onFire == 0) onFire = 20 * 15;
|
||||
}
|
||||
} else {
|
||||
if (onFire <= 0) {
|
||||
onFire = -flameTime;
|
||||
}
|
||||
}
|
||||
|
||||
if (water && onFire > 0) {
|
||||
//level.playSound(this-> "random.fizz", 0.7f, 1.6f + (random.nextFloat() - random.nextFloat()) * 0.4f);
|
||||
onFire = -flameTime;
|
||||
}
|
||||
|
||||
TIMER_POP();
|
||||
}
|
||||
|
||||
void Entity::makeStuckInWeb() {
|
||||
isStuckInWeb = true;
|
||||
fallDistance = 0;
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
bool Entity::isUnderLiquid(const Material* material) {
|
||||
float yp = y + getHeadHeight();
|
||||
int xt = Mth::floor(x);
|
||||
int yt = Mth::floor((float)Mth::floor(yp));
|
||||
int zt = Mth::floor(z);
|
||||
int t = level->getTile(xt, yt, zt);
|
||||
if (t != 0 && Tile::tiles[t]->material == material) {
|
||||
float hh = LiquidTile::getHeight(level->getData(xt, yt, zt)) - 1 / 9.0f;
|
||||
float h = yt + 1 - hh;
|
||||
return yp < h;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*protected virtual*/
|
||||
void Entity::setPos(EntityPos* pos)
|
||||
{
|
||||
if (pos->move) setPos(pos->x, pos->y, pos->z);
|
||||
else setPos(x, y, z);
|
||||
|
||||
if (pos->rot) setRot(pos->yRot, pos->xRot);
|
||||
else setRot(yRot, xRot);
|
||||
}
|
||||
|
||||
void Entity::setPos( float x, float y, float z )
|
||||
{
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
this->z = z;
|
||||
float w = bbWidth / 2;
|
||||
float h = bbHeight;
|
||||
bb.set(x - w, y - heightOffset + ySlideOffset, z - w, x + w, y - heightOffset + ySlideOffset + h, z + w);
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
float Entity::getBrightness(float a) {
|
||||
int xTile = Mth::floor(x);
|
||||
|
||||
float hh = (bb.y1 - bb.y0) * 0.66f;
|
||||
int yTile = Mth::floor(y - this->heightOffset + hh);
|
||||
int zTile = Mth::floor(z);
|
||||
if (level->hasChunksAt(Mth::floor(bb.x0), Mth::floor(bb.y0), Mth::floor(bb.z0), Mth::floor(bb.x1), Mth::floor(bb.y1), Mth::floor(bb.z1))) {
|
||||
return level->getBrightness(xTile, yTile, zTile);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Entity::operator==( Entity& rhs )
|
||||
{
|
||||
return entityId == rhs.entityId;
|
||||
}
|
||||
|
||||
int Entity::hashCode()
|
||||
{
|
||||
return entityId;
|
||||
}
|
||||
|
||||
void Entity::remove()
|
||||
{
|
||||
removed = true;
|
||||
}
|
||||
|
||||
void Entity::setSize( float w, float h )
|
||||
{
|
||||
bbWidth = w;
|
||||
bbHeight = h;
|
||||
}
|
||||
|
||||
void Entity::setRot( float yRot, float xRot )
|
||||
{
|
||||
this->yRot = yRotO = yRot;
|
||||
this->xRot = xRotO = xRot;
|
||||
}
|
||||
|
||||
void Entity::turn( float xo, float yo )
|
||||
{
|
||||
float xRotOld = xRot;
|
||||
float yRotOld = yRot;
|
||||
|
||||
yRot += xo * 0.15f;
|
||||
xRot -= yo * 0.15f;
|
||||
if (xRot < -90) xRot = -90;
|
||||
if (xRot > 90) xRot = 90;
|
||||
|
||||
xRotO += xRot - xRotOld;
|
||||
yRotO += yRot - yRotOld;
|
||||
}
|
||||
|
||||
void Entity::interpolateTurn( float xo, float yo )
|
||||
{
|
||||
yRot += xo * 0.15f;
|
||||
xRot -= yo * 0.15f;
|
||||
if (xRot < -90) xRot = -90;
|
||||
if (xRot > 90) xRot = 90;
|
||||
}
|
||||
|
||||
void Entity::tick()
|
||||
{
|
||||
baseTick();
|
||||
}
|
||||
|
||||
void Entity::baseTick()
|
||||
{
|
||||
TIMER_PUSH("entityBaseTick");
|
||||
|
||||
tickCount++;
|
||||
walkDistO = walkDist;
|
||||
xo = x;
|
||||
yo = y;
|
||||
zo = z;
|
||||
xRotO = xRot;
|
||||
yRotO = yRot;
|
||||
|
||||
if (isInWater()) {
|
||||
if (!wasInWater && !firstTick) {
|
||||
float speed = sqrt(xd * xd * 0.2f + yd * yd + zd * zd * 0.2f) * 0.2f;
|
||||
if (speed > 1) speed = 1;
|
||||
level->playSound(this, "random.splash", speed, 1 + (sharedRandom.nextFloat() - sharedRandom.nextFloat()) * 0.4f);
|
||||
float yt = floorf(bb.y0);
|
||||
for (int i = 0; i < 1 + bbWidth * 20; i++) {
|
||||
float xo = (sharedRandom.nextFloat() * 2 - 1) * bbWidth;
|
||||
float zo = (sharedRandom.nextFloat() * 2 - 1) * bbWidth;
|
||||
level->addParticle(PARTICLETYPE(bubble), x + xo, yt + 1, z + zo, xd, yd - sharedRandom.nextFloat() * 0.2f, zd);
|
||||
}
|
||||
//for (int i = 0; i < 1 + bbWidth * 20; i++) {
|
||||
// float xo = (sharedRandom.nextFloat() * 2 - 1) * bbWidth;
|
||||
// float zo = (sharedRandom.nextFloat() * 2 - 1) * bbWidth;
|
||||
// level->addParticle(PARTICLETYPE(splash), x + xo, yt + 1, z + zo, xd, yd, zd);
|
||||
//}
|
||||
}
|
||||
fallDistance = 0;
|
||||
wasInWater = true;
|
||||
onFire = 0;
|
||||
} else {
|
||||
wasInWater = false;
|
||||
}
|
||||
|
||||
if (level->isClientSide) {
|
||||
onFire = 0;
|
||||
} else {
|
||||
if (onFire > 0) {
|
||||
if (fireImmune) {
|
||||
onFire -= 4;
|
||||
if (onFire < 0) onFire = 0;
|
||||
} else {
|
||||
if (onFire % 20 == 0) {
|
||||
hurt(NULL, 1);
|
||||
}
|
||||
onFire--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isInLava()) {
|
||||
lavaHurt();
|
||||
}
|
||||
|
||||
if (y < -64) {
|
||||
outOfWorld();
|
||||
}
|
||||
|
||||
//if (!level->isOnline) {
|
||||
// setSharedFlag(FLAG_ONFIRE, onFire > 0);
|
||||
//}
|
||||
|
||||
firstTick = false;
|
||||
TIMER_POP();
|
||||
}
|
||||
|
||||
void Entity::outOfWorld()
|
||||
{
|
||||
remove();
|
||||
}
|
||||
|
||||
void Entity::checkFallDamage( float ya, bool onGround )
|
||||
{
|
||||
if (onGround) {
|
||||
if (fallDistance > 0) {
|
||||
if(isMob()) {
|
||||
int xt = Mth::floor(x);
|
||||
int yt = Mth::floor(y - 0.2f - heightOffset);
|
||||
int zt = Mth::floor(z);
|
||||
int t = level->getTile(xt, yt, zt);
|
||||
if (t == 0 && level->getTile(xt, yt - 1, zt) == Tile::fence->id) {
|
||||
t = level->getTile(xt, yt - 1, zt);
|
||||
}
|
||||
|
||||
if (t > 0) {
|
||||
Tile::tiles[t]->fallOn(level, xt, yt, zt, this, fallDistance);
|
||||
}
|
||||
}
|
||||
causeFallDamage(fallDistance);
|
||||
fallDistance = 0;
|
||||
}
|
||||
} else {
|
||||
if (ya < 0) fallDistance -= ya;
|
||||
}
|
||||
}
|
||||
|
||||
void Entity::causeFallDamage( float fallDamage2 )
|
||||
{
|
||||
}
|
||||
|
||||
float Entity::getHeadHeight()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Entity::moveRelative( float xa, float za, float speed )
|
||||
{
|
||||
float dist = sqrt(xa * xa + za * za);
|
||||
if (dist < 0.01f) return;
|
||||
|
||||
if (dist < 1) dist = 1;
|
||||
dist = speed / dist;
|
||||
xa *= dist;
|
||||
za *= dist;
|
||||
|
||||
float sin_ = (float) sin(yRot * Mth::PI / 180);
|
||||
float cos_ = (float) cos(yRot * Mth::PI / 180);
|
||||
|
||||
xd += xa * cos_ - za * sin_;
|
||||
zd += za * cos_ + xa * sin_;
|
||||
}
|
||||
|
||||
void Entity::setLevel( Level* level )
|
||||
{
|
||||
this->level = level;
|
||||
}
|
||||
|
||||
void Entity::moveTo( float x, float y, float z, float yRot, float xRot )
|
||||
{
|
||||
this->xOld = this->xo = this->x = x;
|
||||
this->yOld = this->yo = this->y = y + heightOffset;
|
||||
this->zOld = this->zo = this->z = z;
|
||||
this->yRot = this->yRotO = yRot;
|
||||
this->xRot = this->xRotO = xRot;
|
||||
this->setPos(this->x, this->y, this->z);
|
||||
}
|
||||
|
||||
float Entity::distanceTo( Entity* e )
|
||||
{
|
||||
float xd = (float) (x - e->x);
|
||||
float yd = (float) (y - e->y);
|
||||
float zd = (float) (z - e->z);
|
||||
return sqrt(xd * xd + yd * yd + zd * zd);
|
||||
}
|
||||
|
||||
float Entity::distanceTo( float x2, float y2, float z2 )
|
||||
{
|
||||
float xd = (x - x2);
|
||||
float yd = (y - y2);
|
||||
float zd = (z - z2);
|
||||
return sqrt(xd * xd + yd * yd + zd * zd);
|
||||
}
|
||||
|
||||
float Entity::distanceToSqr( float x2, float y2, float z2 )
|
||||
{
|
||||
float xd = (x - x2);
|
||||
float yd = (y - y2);
|
||||
float zd = (z - z2);
|
||||
return xd * xd + yd * yd + zd * zd;
|
||||
}
|
||||
|
||||
float Entity::distanceToSqr( Entity* e )
|
||||
{
|
||||
float xd = x - e->x;
|
||||
float yd = y - e->y;
|
||||
float zd = z - e->z;
|
||||
return xd * xd + yd * yd + zd * zd;
|
||||
}
|
||||
|
||||
void Entity::playerTouch( Player* player )
|
||||
{
|
||||
}
|
||||
|
||||
void Entity::push( Entity* e )
|
||||
{
|
||||
float xa = e->x - x;
|
||||
float za = e->z - z;
|
||||
|
||||
float dd = Mth::absMax(xa, za);
|
||||
|
||||
if (dd >= 0.01f) {
|
||||
dd = sqrt(dd);
|
||||
xa /= dd;
|
||||
za /= dd;
|
||||
|
||||
float pow = 1 / dd;
|
||||
if (pow > 1) pow = 1;
|
||||
xa *= pow;
|
||||
za *= pow;
|
||||
|
||||
xa *= 0.05f;
|
||||
za *= 0.05f;
|
||||
|
||||
xa *= 1 - pushthrough;
|
||||
za *= 1 - pushthrough;
|
||||
|
||||
this->push(-xa, 0, -za);
|
||||
e->push(xa, 0, za);
|
||||
}
|
||||
}
|
||||
|
||||
void Entity::push( float xa, float ya, float za )
|
||||
{
|
||||
xd += xa;
|
||||
yd += ya;
|
||||
zd += za;
|
||||
}
|
||||
|
||||
void Entity::markHurt()
|
||||
{
|
||||
this->hurtMarked = true;
|
||||
}
|
||||
|
||||
bool Entity::hurt( Entity* source, int damage )
|
||||
{
|
||||
markHurt();
|
||||
return false;
|
||||
}
|
||||
|
||||
void Entity::reset() {
|
||||
this->_init();
|
||||
}
|
||||
void Entity::_init() {
|
||||
xo = xOld = x;
|
||||
yo = yOld = y;
|
||||
zo = zOld = z;
|
||||
xRotO = xRot;
|
||||
yRotO = yRot;
|
||||
onFire = 0;
|
||||
removed = false;
|
||||
fallDistance = 0;
|
||||
}
|
||||
|
||||
bool Entity::intersects( float x0, float y0, float z0, float x1, float y1, float z1 )
|
||||
{
|
||||
return bb.intersects(x0, y0, z0, x1, y1, z1);
|
||||
}
|
||||
|
||||
bool Entity::isPickable()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Entity::isPushable()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Entity::isShootable()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void Entity::awardKillScore( Entity* victim, int score )
|
||||
{
|
||||
}
|
||||
|
||||
bool Entity::shouldRender( Vec3& c )
|
||||
{
|
||||
if (invisible) return false;
|
||||
float xd = x - c.x;
|
||||
float yd = y - c.y;
|
||||
float zd = z - c.z;
|
||||
float distance = xd * xd + yd * yd + zd * zd;
|
||||
return shouldRenderAtSqrDistance(distance);
|
||||
}
|
||||
|
||||
bool Entity::shouldRenderAtSqrDistance( float distance )
|
||||
{
|
||||
float size = bb.getSize();
|
||||
size *= 64.0f * viewScale;
|
||||
return distance < size * size;
|
||||
}
|
||||
|
||||
bool Entity::isCreativeModeAllowed()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
float Entity::getShadowHeightOffs()
|
||||
{
|
||||
return bbHeight / 2;
|
||||
}
|
||||
|
||||
bool Entity::isAlive()
|
||||
{
|
||||
return !removed;
|
||||
}
|
||||
|
||||
bool Entity::interact( Player* player )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void Entity::lerpTo( float x, float y, float z, float yRot, float xRot, int steps )
|
||||
{
|
||||
setPos(x, y, z);
|
||||
setRot(yRot, xRot);
|
||||
}
|
||||
|
||||
float Entity::getPickRadius()
|
||||
{
|
||||
return 0.1f;
|
||||
}
|
||||
|
||||
void Entity::lerpMotion( float xd, float yd, float zd )
|
||||
{
|
||||
this->xd = xd;
|
||||
this->yd = yd;
|
||||
this->zd = zd;
|
||||
}
|
||||
|
||||
void Entity::animateHurt()
|
||||
{
|
||||
}
|
||||
|
||||
void Entity::setEquippedSlot( int slot, int item, int auxValue )
|
||||
{
|
||||
}
|
||||
|
||||
bool Entity::isSneaking()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Entity::isPlayer()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void Entity::lavaHurt() {
|
||||
if (fireImmune) {
|
||||
} else {
|
||||
hurt(NULL, 4);
|
||||
onFire = 30 * SharedConstants::TicksPerSecond;
|
||||
}
|
||||
}
|
||||
|
||||
// AABB getCollideBox() {
|
||||
// return NULL;
|
||||
// }
|
||||
|
||||
void Entity::burn(int dmg) {
|
||||
if (!fireImmune) {
|
||||
hurt(NULL, dmg);
|
||||
}
|
||||
}
|
||||
|
||||
// std::string getTexture() {
|
||||
// return NULL;
|
||||
// }
|
||||
|
||||
bool Entity::save(CompoundTag* entityTag) {
|
||||
int id = getEntityTypeId();
|
||||
|
||||
if (removed || id == 0) {
|
||||
return false;
|
||||
}
|
||||
entityTag->putInt("id", id);
|
||||
saveWithoutId(entityTag);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Entity::saveWithoutId(CompoundTag* entityTag) {
|
||||
entityTag->put("Pos", ListTagFloatAdder (x) (y) (z).tag);
|
||||
entityTag->put("Motion", ListTagFloatAdder (xd) (yd) (zd).tag);
|
||||
entityTag->put("Rotation", ListTagFloatAdder (yRot) (xRot).tag);
|
||||
|
||||
entityTag->putFloat("FallDistance", fallDistance);
|
||||
entityTag->putShort("Fire", (short) onFire);
|
||||
entityTag->putShort("Air", (short) airSupply);
|
||||
entityTag->putBoolean("OnGround", onGround);
|
||||
|
||||
addAdditonalSaveData(entityTag);
|
||||
}
|
||||
|
||||
bool Entity::load( CompoundTag* tag )
|
||||
{
|
||||
ListTag* pos = tag->getList("Pos");
|
||||
ListTag* motion = tag->getList("Motion");
|
||||
ListTag* rotation = tag->getList("Rotation");
|
||||
setPos(0, 0, 0);
|
||||
|
||||
xd = motion->getFloat(0);
|
||||
yd = motion->getFloat(1);
|
||||
zd = motion->getFloat(2);
|
||||
|
||||
if (Mth::abs(xd) > 10.0) {
|
||||
xd = 0;
|
||||
}
|
||||
if (Mth::abs(yd) > 10.0) {
|
||||
yd = 0;
|
||||
}
|
||||
if (Mth::abs(zd) > 10.0) {
|
||||
zd = 0;
|
||||
}
|
||||
|
||||
float xx = pos->getFloat(0);
|
||||
float yy = pos->getFloat(1);
|
||||
float zz = pos->getFloat(2);
|
||||
|
||||
// Add a small padding if standing next to the world edges
|
||||
const float padding = bbWidth * 0.5f + 0.001f;
|
||||
xx = Mth::clamp(xx, padding, (float)LEVEL_WIDTH - padding);
|
||||
zz = Mth::clamp(zz, padding, (float)LEVEL_DEPTH - padding);
|
||||
|
||||
xo = xOld = x = xx;
|
||||
yo = yOld = y = yy;
|
||||
zo = zOld = z = zz;
|
||||
|
||||
yRotO = yRot = fmod( rotation->getFloat(0), 360.0f);
|
||||
xRotO = xRot = fmod( rotation->getFloat(1), 360.0f);
|
||||
|
||||
fallDistance= tag->getFloat("FallDistance");
|
||||
onFire = tag->getShort("Fire");
|
||||
airSupply = tag->getShort("Air");
|
||||
onGround = tag->getBoolean("OnGround");
|
||||
|
||||
setPos(x, y, z);
|
||||
|
||||
readAdditionalSaveData(tag);
|
||||
return (tag->errorState == 0);
|
||||
}
|
||||
|
||||
// /*protected*/ const String getEncodeId() {
|
||||
// return EntityIO.getEncodeId(this->;
|
||||
// }
|
||||
|
||||
ItemEntity* Entity::spawnAtLocation(int resource, int count) {
|
||||
return spawnAtLocation(resource, count, 0);
|
||||
}
|
||||
|
||||
ItemEntity* Entity::spawnAtLocation(int resource, int count, float yOffs) {
|
||||
return spawnAtLocation(new ItemInstance(resource, count, 0), yOffs);
|
||||
}
|
||||
|
||||
ItemEntity* Entity::spawnAtLocation(ItemInstance* itemInstance, float yOffs) {
|
||||
ItemEntity* ie = new ItemEntity(level, x, y + yOffs, z, *itemInstance);
|
||||
|
||||
{ //@todo:itementity
|
||||
delete itemInstance;
|
||||
itemInstance = NULL;
|
||||
}
|
||||
|
||||
ie->throwTime = 10;
|
||||
level->addEntity(ie);
|
||||
return ie;
|
||||
}
|
||||
|
||||
bool Entity::isOnFire() {
|
||||
return onFire > 0;// || getSharedFlag(FLAG_ONFIRE);
|
||||
}
|
||||
|
||||
bool Entity::interactPreventDefault() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// AABB getCollideAgainstBox(Entity entity) {
|
||||
// return NULL;
|
||||
// }
|
||||
|
||||
// Vec3 getLookAngle() {
|
||||
// return NULL;
|
||||
// }
|
||||
|
||||
// void prepareCustomTextures() {
|
||||
// }
|
||||
|
||||
// ItemInstance[] getEquipmentSlots() {
|
||||
// return NULL;
|
||||
// }
|
||||
|
||||
bool Entity::isItemEntity() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Entity::isHangingEntity() {
|
||||
return false;
|
||||
}
|
||||
|
||||
int Entity::getAuxData() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Entity::playStepSound( int xt, int yt, int zt, int t ) {
|
||||
const Tile::SoundType* soundType = Tile::tiles[t]->soundType;
|
||||
if (level->getTile(xt, yt + 1, zt) == Tile::topSnow->id) {
|
||||
soundType = Tile::topSnow->soundType;
|
||||
level->playSound(this, soundType->getStepSound(), soundType->getVolume() * 0.25f, soundType->getPitch()); // was * 0.15f
|
||||
} else if (!Tile::tiles[t]->material->isLiquid()) {
|
||||
level->playSound(this, soundType->getStepSound(), soundType->getVolume() * 0.25f, soundType->getPitch());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user