Files
minecraft-pe-0.6.1/src/world/entity/monster/Zombie.cpp
2026-03-02 22:04:18 +03:00

130 lines
3.3 KiB
C++
Executable File

#include "Zombie.h"
#include "../../item/Item.h"
#include "../../level/Level.h"
#include "../../../util/Mth.h"
//#include "../MobType.h"
#include "../ai/goal/GoalSelector.h"
#include "../ai/control/JumpControl.h"
#include "../ai/goal/RandomStrollGoal.h"
#include "../ai/goal/MeleeAttackGoal.h"
#include "../ai/goal/target/NearestAttackableTargetGoal.h"
#include "../ai/goal/target/HurtByTargetGoal.h"
#include "../ai/goal/BreakDoorGoal.h"
Zombie::Zombie( Level* level )
: super(level),
fireCheckTick(0),
_useNewAi(false)
{
entityRendererId = ER_ZOMBIE_RENDERER;
this->textureName = "mob/zombie.png";
//pathfinderMask |= CAN_OPEN_DOORS;
//navigation->canOpenDoors = true;
runSpeed = 0.5f;
attackDamage = 4;
targetSelector = new GoalSelector();
targetSelector->addGoal(1, new HurtByTargetGoal(this, false));
targetSelector->addGoal(2, new NearestAttackableTargetGoal(this, 1, 16, 0, true));
goalSelector = new GoalSelector();
//goalSelector->addGoal(1, new BreakDoorGoal(this));
goalSelector->addGoal(2, new MeleeAttackGoal(this, runSpeed, false, 0));
goalSelector->addGoal(7, new RandomStrollGoal(this, runSpeed) );
moveControl = new MoveControl(this);
jumpControl = new JumpControl(this);
}
Zombie::~Zombie() {
delete goalSelector;
delete targetSelector;
delete moveControl;
delete jumpControl;
}
int Zombie::getMaxHealth() {
return 12; // 16
}
void Zombie::aiStep() {
if ((++fireCheckTick & 1) && level->isDay() && !level->isClientSide) {
float br = getBrightness(1);
if (br > 0.5f) {
if (level->canSeeSky(Mth::floor(x), Mth::floor(y), Mth::floor(z)) && random.nextFloat() * 3.5f < (br - 0.4f)) {
hurt(NULL, 1);
for (int i = 0; i < 5; ++i) {
float xa = (2.0f * random.nextFloat() - 1.0f) * (2.0f * random.nextFloat() - 1.0f) * 0.02f;
float ya = (2.0f * random.nextFloat() - 1.0f) * (2.0f * random.nextFloat() - 1.0f) * 0.02f;
float za = (2.0f * random.nextFloat() - 1.0f) * (2.0f * random.nextFloat() - 1.0f) * 0.02f;
level->addParticle(PARTICLETYPE(explode), x + random.nextFloat() * bbWidth * 2 - bbWidth, y + random.nextFloat() * bbHeight, z + random.nextFloat() * bbWidth * 2 - bbWidth, xa, ya, za);
}
//setOnFire(8); //@todo
}
}
}
super::aiStep();
}
int Zombie::getEntityTypeId() const {
return MobTypes::Zombie;
}
void Zombie::setUseNewAi( bool use ) {
_useNewAi = use;
}
int Zombie::getArmorValue() {
int armor = super::getArmorValue() + 2;
if (armor > 20) armor = 20;
return armor;
}
const char* Zombie::getAmbientSound() {
return "mob.zombie";
}
std::string Zombie::getHurtSound() {
return "mob.zombiehurt";
}
std::string Zombie::getDeathSound() {
return "mob.zombiedeath";
}
int Zombie::getDeathLoot() {
return 0; //@todo
//return Item::rotten_flesh->id;
}
bool Zombie::useNewAi() {
return _useNewAi;
}
void Zombie::die( Entity* source ) {
super::die(source);
if(!level->isClientSide) {
if(random.nextInt(4) == 0) {
spawnAtLocation(Item::feather->id, random.nextInt(1) + 1);
}
}
}
int Zombie::getAttackDamage( Entity* target ) {
ItemInstance* weapon = getCarriedItem();
int damage = attackDamage;
if(weapon != NULL) damage += weapon->getAttackDamage(this);
return damage;
}
/*@Override*/ //@todo?
//MobType getMobType() {
// return MobType::UNDEAD;
//}