forked from Kolyah35/minecraft-pe-0.6.1
212 lines
4.7 KiB
C++
Executable File
212 lines
4.7 KiB
C++
Executable File
#include "ItemEntity.h"
|
|
#include "../../entity/player/Player.h"
|
|
#include "../../item/ItemInstance.h"
|
|
#include "../../level/Level.h"
|
|
#include "../../level/material/Material.h"
|
|
#include "../../level/tile/Tile.h"
|
|
#include "../../../util/Mth.h"
|
|
#include "../../../nbt/CompoundTag.h"
|
|
|
|
const int ItemEntity::LIFETIME = 5 * 60 * SharedConstants::TicksPerSecond; // Five minutes, changed in 0.3.3!
|
|
|
|
ItemEntity::ItemEntity( Level* level, float x, float y, float z, const ItemInstance& item )
|
|
: super(level),
|
|
item(item),
|
|
health(5),
|
|
age(0),
|
|
tickCount(0),
|
|
throwTime(0),
|
|
lifeTime(LIFETIME),
|
|
bobOffs((float) (Mth::random() * Mth::PI * 2))
|
|
{
|
|
entityRendererId = ER_ITEM_RENDERER;
|
|
|
|
setSize(0.25f, 0.25f);
|
|
heightOffset = bbHeight / 2.0f;
|
|
setPos(x, y, z);
|
|
|
|
yRot = (float) (Mth::random() * 360);
|
|
|
|
xd = (float) (Mth::random() * 0.2f - 0.1f);
|
|
yd = +0.2f;
|
|
zd = (float) (Mth::random() * 0.2f - 0.1f);
|
|
makeStepSound = false;
|
|
}
|
|
|
|
ItemEntity::ItemEntity( Level* level )
|
|
: super(level),
|
|
health(5),
|
|
age(0),
|
|
tickCount(0),
|
|
throwTime(0),
|
|
lifeTime(LIFETIME),
|
|
bobOffs((float) (Mth::random() * Mth::PI * 2))
|
|
{
|
|
entityRendererId = ER_ITEM_RENDERER;
|
|
|
|
setSize(0.25f, 0.25f);
|
|
heightOffset = bbHeight / 2.0f;
|
|
}
|
|
|
|
ItemEntity::~ItemEntity()
|
|
{
|
|
}
|
|
|
|
|
|
void ItemEntity::tick()
|
|
{
|
|
super::tick();
|
|
if (throwTime > 0) throwTime--;
|
|
xo = x;
|
|
yo = y;
|
|
zo = z;
|
|
|
|
yd -= 0.04f;
|
|
if (level->getMaterial(Mth::floor(x), Mth::floor(y), Mth::floor(z)) == Material::lava) {
|
|
yd = 0.2f;
|
|
xd = (sharedRandom.nextFloat() - sharedRandom.nextFloat()) * 0.2f;
|
|
zd = (sharedRandom.nextFloat() - sharedRandom.nextFloat()) * 0.2f;
|
|
level->playSound(this, "random.fizz", 0.4f, 2.0f + sharedRandom.nextFloat() * 0.4f);
|
|
}
|
|
checkInTile(x, y, z);
|
|
move(xd, yd, zd);
|
|
|
|
float friction = 0.98f;
|
|
if (onGround) {
|
|
friction = 0.6f * 0.98f;
|
|
int t = level->getTile(Mth::floor(x), Mth::floor(bb.y0) - 1, Mth::floor(z));
|
|
if (t > 0) {
|
|
friction = Tile::tiles[t]->friction * 0.98f;
|
|
}
|
|
}
|
|
|
|
xd *= friction;
|
|
yd *= 0.98f;
|
|
zd *= friction;
|
|
|
|
if (onGround) {
|
|
yd *= -0.5f;
|
|
}
|
|
|
|
tickCount++;
|
|
age++;
|
|
if (age >= lifeTime) {
|
|
remove();
|
|
}
|
|
}
|
|
|
|
bool ItemEntity::isInWater()
|
|
{
|
|
return level->checkAndHandleWater(bb, Material::water, this);
|
|
}
|
|
|
|
bool ItemEntity::hurt( Entity* source, int damage )
|
|
{
|
|
markHurt();
|
|
health -= damage;
|
|
if (health <= 0) {
|
|
remove();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void ItemEntity::playerTouch( Player* player )
|
|
{
|
|
if (level->isClientSide) return;
|
|
|
|
int orgCount = item.count;
|
|
if (throwTime == 0 && player->isAlive() && player->inventory->add(&item)) {
|
|
level->playSound(this, "random.pop", 0.3f, ((sharedRandom.nextFloat() - sharedRandom.nextFloat()) * 0.7f + 1.0f) * 2.f);
|
|
player->take(this, orgCount);
|
|
//if (item.count <= 0) remove(); //@todo
|
|
remove();
|
|
}
|
|
}
|
|
|
|
void ItemEntity::burn( int dmg )
|
|
{
|
|
hurt(NULL, dmg);
|
|
}
|
|
|
|
bool ItemEntity::checkInTile( float x, float y, float z )
|
|
{
|
|
int xTile = Mth::floor(x);
|
|
int yTile = Mth::floor(y);
|
|
int zTile = Mth::floor(z);
|
|
|
|
float xd = x - xTile;
|
|
float yd = y - yTile;
|
|
float zd = z - zTile;
|
|
|
|
if (Tile::solid[level->getTile(xTile, yTile, zTile)]) {
|
|
bool west = !Tile::solid[level->getTile(xTile - 1, yTile, zTile)];
|
|
bool east = !Tile::solid[level->getTile(xTile + 1, yTile, zTile)];
|
|
bool up = !Tile::solid[level->getTile(xTile, yTile - 1, zTile)];
|
|
bool down = !Tile::solid[level->getTile(xTile, yTile + 1, zTile)];
|
|
bool north = !Tile::solid[level->getTile(xTile, yTile, zTile - 1)];
|
|
bool south = !Tile::solid[level->getTile(xTile, yTile, zTile + 1)];
|
|
|
|
int dir = -1;
|
|
float closest = 9999;
|
|
if (west && xd < closest) {
|
|
closest = xd;
|
|
dir = 0;
|
|
}
|
|
if (east && 1 - xd < closest) {
|
|
closest = 1 - xd;
|
|
dir = 1;
|
|
}
|
|
if (up && yd < closest) {
|
|
closest = yd;
|
|
dir = 2;
|
|
}
|
|
if (down && 1 - yd < closest) {
|
|
closest = 1 - yd;
|
|
dir = 3;
|
|
}
|
|
if (north && zd < closest) {
|
|
closest = zd;
|
|
dir = 4;
|
|
}
|
|
if (south && 1 - zd < closest) {
|
|
// closest = 1 - zd; //@note: not read
|
|
dir = 5;
|
|
}
|
|
|
|
float speed = sharedRandom.nextFloat() * 0.2f + 0.1f;
|
|
if (dir == 0) this->xd = -speed;
|
|
if (dir == 1) this->xd = +speed;
|
|
if (dir == 2) this->yd = -speed;
|
|
if (dir == 3) this->yd = +speed;
|
|
if (dir == 4) this->zd = -speed;
|
|
if (dir == 5) this->zd = +speed;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void ItemEntity::addAdditonalSaveData(CompoundTag* entityTag) {
|
|
entityTag->putShort("Health", (char) health);
|
|
entityTag->putShort("Age", (short) age);
|
|
entityTag->putCompound("Item", item.save(new CompoundTag()));
|
|
}
|
|
|
|
void ItemEntity::readAdditionalSaveData(CompoundTag* tag) {
|
|
health = tag->getShort("Health") & 0xff;
|
|
age = tag->getShort("Age");
|
|
CompoundTag* itemTag = tag->getCompound("Item");
|
|
item.load(itemTag);
|
|
}
|
|
|
|
bool ItemEntity::isItemEntity() {
|
|
return true;
|
|
}
|
|
|
|
int ItemEntity::getEntityTypeId() const {
|
|
return EntityTypes::IdItemEntity;
|
|
}
|
|
|
|
int ItemEntity::getLifeTime() const {
|
|
return lifeTime;
|
|
}
|