forked from Kolyah35/minecraft-pe-0.6.1
253 lines
6.4 KiB
C++
Executable File
253 lines
6.4 KiB
C++
Executable File
#include "Sheep.h"
|
|
#include "../../item/DyePowderItem.h"
|
|
#include "../../level/tile/LevelEvent.h"
|
|
|
|
const float Sheep::COLOR[][3] = {
|
|
{ 1.0f, 1.0f, 1.0f }, // white
|
|
{ 0.95f, 0.7f, 0.2f }, // orange
|
|
{ 0.9f, 0.5f, 0.85f }, // magenta
|
|
{ 0.6f, 0.7f, 0.95f }, // light blue
|
|
{ 0.9f, 0.9f, 0.2f }, // yellow
|
|
{ 0.5f, 0.8f, 0.1f }, // light green
|
|
{ 0.95f, 0.7f, 0.8f }, // pink
|
|
{ 0.3f, 0.3f, 0.3f }, // gray
|
|
{ 0.6f, 0.6f, 0.6f }, // silver
|
|
{ 0.3f, 0.6f, 0.7f }, // cyan
|
|
{ 0.7f, 0.4f, 0.9f }, // purple
|
|
{ 0.2f, 0.4f, 0.8f }, // blue
|
|
{ 0.5f, 0.4f, 0.3f }, // brown
|
|
{ 0.4f, 0.5f, 0.2f }, // green
|
|
{ 0.8f, 0.3f, 0.3f }, // red
|
|
{ 0.1f, 0.1f, 0.1f }, // black
|
|
};
|
|
const int Sheep::NumColors = sizeof(Sheep::COLOR) / sizeof(Sheep*);
|
|
|
|
|
|
Sheep::Sheep( Level* level )
|
|
: super(level),
|
|
eatAnimationTick(0)
|
|
{
|
|
entityRendererId = ER_SHEEP_RENDERER;
|
|
|
|
this->textureName = "mob/sheep.png";
|
|
this->setSize(0.9f, 1.3f);
|
|
|
|
// sheared and color share a char
|
|
entityData.define(DATA_WOOL_ID, (SynchedEntityData::TypeChar) 0);
|
|
}
|
|
|
|
int Sheep::getMaxHealth()
|
|
{
|
|
return 8;
|
|
}
|
|
|
|
void Sheep::aiStep()
|
|
{
|
|
super::aiStep();
|
|
|
|
if (eatAnimationTick > 0) {
|
|
eatAnimationTick--;
|
|
}
|
|
}
|
|
|
|
void Sheep::handleEntityEvent( char id )
|
|
{
|
|
if (id == EntityEvent::EAT_GRASS) {
|
|
eatAnimationTick = EAT_ANIMATION_TICKS;
|
|
} else {
|
|
super::handleEntityEvent(id);
|
|
}
|
|
}
|
|
|
|
float Sheep::getHeadEatPositionScale( float a )
|
|
{
|
|
if (eatAnimationTick <= 0) {
|
|
return 0;
|
|
}
|
|
if (eatAnimationTick >= 4 && eatAnimationTick <= (EAT_ANIMATION_TICKS - 4)) {
|
|
return 1;
|
|
}
|
|
if (eatAnimationTick < 4) {
|
|
return ((float) eatAnimationTick - a) / 4.f;
|
|
}
|
|
return -((float) (eatAnimationTick - EAT_ANIMATION_TICKS) - a) / 4.f;
|
|
}
|
|
|
|
float Sheep::getHeadEatAngleScale( float a )
|
|
{
|
|
if (eatAnimationTick > 4 && eatAnimationTick <= (EAT_ANIMATION_TICKS - 4)) {
|
|
float scale = ((float) (eatAnimationTick - 4) - a) / (float) (EAT_ANIMATION_TICKS - 8);
|
|
return Mth::PI * .20f + Mth::PI * .07f * Mth::sin(scale * 28.7f);
|
|
}
|
|
if (eatAnimationTick > 0) {
|
|
return Mth::PI * .20f;
|
|
}
|
|
return ((xRot / (float) (180 / Mth::PI)));
|
|
}
|
|
|
|
bool Sheep::interact( Player* player )
|
|
{
|
|
ItemInstance* item = player->inventory->getSelected();
|
|
if (item && item->id == ((Item*)Item::shears)->id && !isSheared() && !isBaby()) {
|
|
if (!level->isClientSide) {
|
|
setSheared(true);
|
|
int count = 1 + random.nextInt(3);
|
|
for (int i = 0; i < count; i++) {
|
|
ItemEntity* ie = spawnAtLocation(new ItemInstance(Tile::cloth->id, 1, getColor()), 1);
|
|
ie->yd += random.nextFloat() * 0.05f;
|
|
ie->xd += (random.nextFloat() - random.nextFloat()) * 0.1f;
|
|
ie->zd += (random.nextFloat() - random.nextFloat()) * 0.1f;
|
|
}
|
|
}
|
|
item->hurt(1);
|
|
}
|
|
|
|
return super::interact(player);
|
|
}
|
|
|
|
void Sheep::addAdditonalSaveData( CompoundTag* tag )
|
|
{
|
|
super::addAdditonalSaveData(tag);
|
|
tag->putBoolean("Sheared", isSheared());
|
|
tag->putByte("Color", (char) getColor());
|
|
}
|
|
|
|
void Sheep::readAdditionalSaveData( CompoundTag* tag )
|
|
{
|
|
super::readAdditionalSaveData(tag);
|
|
setSheared(tag->getBoolean("Sheared"));
|
|
setColor((int) tag->getByte("Color"));
|
|
}
|
|
|
|
int Sheep::getColor() const
|
|
{
|
|
return (int) (entityData.getByte(DATA_WOOL_ID) & 0x0f);
|
|
}
|
|
|
|
void Sheep::setColor( int color )
|
|
{
|
|
char current = entityData.getByte(DATA_WOOL_ID);
|
|
entityData.set(DATA_WOOL_ID, (SynchedEntityData::TypeChar) ((current & 0xf0) | (color & 0x0f)));
|
|
}
|
|
|
|
bool Sheep::isSheared() const
|
|
{
|
|
return (entityData.getByte(DATA_WOOL_ID) & 0x10) != 0;
|
|
}
|
|
|
|
void Sheep::setSheared( bool value )
|
|
{
|
|
char current = entityData.getByte(DATA_WOOL_ID);
|
|
if (value) {
|
|
entityData.set(DATA_WOOL_ID, (SynchedEntityData::TypeChar) (current | 0x10));
|
|
} else {
|
|
entityData.set(DATA_WOOL_ID, (SynchedEntityData::TypeChar) (current & ~0x10));
|
|
}
|
|
}
|
|
|
|
int Sheep::getSheepColor( Random* random )
|
|
{
|
|
int nextInt = random->nextInt(100);
|
|
if (nextInt < 5)
|
|
return 15 - DyePowderItem::BLACK;
|
|
if (nextInt < 10)
|
|
return 15 - DyePowderItem::GRAY;
|
|
if (nextInt < 15)
|
|
return 15 - DyePowderItem::SILVER;
|
|
if (nextInt < 18)
|
|
return 15 - DyePowderItem::BROWN;
|
|
|
|
if (random->nextInt(500) == 0)
|
|
return 15 - DyePowderItem::PINK;
|
|
|
|
return 0; // white
|
|
}
|
|
|
|
int Sheep::getEntityTypeId() const
|
|
{
|
|
return MobTypes::Sheep;
|
|
}
|
|
|
|
void Sheep::dropDeathLoot(/* bool wasKilledByPlayer, int playerBonusLevel*/ )
|
|
{
|
|
if (!isSheared()) {
|
|
// killing a non-sheared sheep will drop a single block of cloth
|
|
spawnAtLocation(new ItemInstance(Tile::cloth->id, 1, getColor()), 0);
|
|
}
|
|
}
|
|
|
|
int Sheep::getDeathLoot()
|
|
{
|
|
return Tile::cloth->id;
|
|
}
|
|
|
|
void Sheep::jumpFromGround()
|
|
{
|
|
if (eatAnimationTick <= 0) {
|
|
super::jumpFromGround();
|
|
}
|
|
}
|
|
|
|
void Sheep::updateAi()
|
|
{
|
|
super::updateAi();
|
|
|
|
if (!isPathFinding() && eatAnimationTick <= 0 && ((isBaby() && random.nextInt(50) == 0) || random.nextInt(1000) == 0)) {
|
|
|
|
int xx = Mth::floor(x);
|
|
int yy = Mth::floor(y);
|
|
int zz = Mth::floor(z);
|
|
|
|
if (/*(level->getTile(xx, yy, zz) == Tile::tallgrass->id && level->getData(xx, yy, zz) == TallGrass::TALL_GRASS) || */ level->getTile(xx, yy - 1, zz) == ((Tile*)Tile::grass)->id) {
|
|
eatAnimationTick = EAT_ANIMATION_TICKS;
|
|
level->broadcastEntityEvent(this, EntityEvent::EAT_GRASS);
|
|
}
|
|
} else if (eatAnimationTick == 4) {
|
|
int xx = Mth::floor(x);
|
|
int yy = Mth::floor(y);
|
|
int zz = Mth::floor(z);
|
|
|
|
bool ate = false;
|
|
/* if (level->getTile(xx, yy, zz) == Tile::tallgrass->id) {
|
|
level->levelEvent(LevelEvent::PARTICLES_DESTROY_BLOCK, xx, yy, zz, Tile::tallgrass->id + TallGrass::TALL_GRASS * 256);
|
|
level->setTile(xx, yy, zz, 0);
|
|
ate = true;
|
|
} else */if (level->getTile(xx, yy - 1, zz) == ((Tile*)Tile::grass)->id) {
|
|
level->levelEvent(NULL, LevelEvent::PARTICLES_DESTROY_BLOCK, xx, yy - 1, zz, ((Tile*)Tile::grass)->id);
|
|
level->setTile(xx, yy - 1, zz, Tile::dirt->id);
|
|
ate = true;
|
|
}
|
|
if (ate) {
|
|
setSheared(false);
|
|
if (isBaby()) {
|
|
// remove a minute from aging
|
|
int age = getAge() + SharedConstants::TicksPerSecond * 60;
|
|
if (age > 0) {
|
|
age = 0;
|
|
}
|
|
setAge(age);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool Sheep::shouldHoldGround()
|
|
{
|
|
return eatAnimationTick > 0;
|
|
}
|
|
|
|
const char* Sheep::getAmbientSound()
|
|
{
|
|
return "mob.sheep";
|
|
}
|
|
|
|
std::string Sheep::getHurtSound()
|
|
{
|
|
return "mob.sheep";
|
|
}
|
|
|
|
std::string Sheep::getDeathSound()
|
|
{
|
|
return "mob.sheep";
|
|
}
|