diff options
Diffstat (limited to 'Minecraft.World/Creeper.cpp')
| -rw-r--r-- | Minecraft.World/Creeper.cpp | 119 |
1 files changed, 71 insertions, 48 deletions
diff --git a/Minecraft.World/Creeper.cpp b/Minecraft.World/Creeper.cpp index 3f6c66a7..29be2c0c 100644 --- a/Minecraft.World/Creeper.cpp +++ b/Minecraft.World/Creeper.cpp @@ -3,11 +3,13 @@ #include "net.minecraft.world.level.tile.h" #include "net.minecraft.world.item.h" #include "net.minecraft.world.entity.h" +#include "net.minecraft.world.entity.ai.attributes.h" #include "net.minecraft.world.entity.ai.goal.h" #include "net.minecraft.world.entity.ai.goal.target.h" #include "net.minecraft.world.entity.ai.navigation.h" #include "net.minecraft.world.entity.animal.h" #include "net.minecraft.world.entity.player.h" +#include "net.minecraft.world.entity.monster.h" #include "net.minecraft.world.damagesource.h" #include "GeneralStat.h" #include "Skeleton.h" @@ -22,6 +24,8 @@ void Creeper::_init() { swell = 0; oldSwell = 0; + maxSwell = 30; + explosionRadius = 3; } Creeper::Creeper(Level *level) : Monster( level ) @@ -29,105 +33,124 @@ Creeper::Creeper(Level *level) : Monster( level ) // 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(); - - // 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 - health = getMaxHealth(); + registerAttributes(); + setHealth(getMaxHealth()); _init(); - - this->textureIdx = TN_MOB_CREEPER; // 4J was L"/mob/creeper.png"; goalSelector.addGoal(1, new FloatGoal(this)); goalSelector.addGoal(2, new SwellGoal(this)); - goalSelector.addGoal(3, new AvoidPlayerGoal(this, typeid(Ozelot), 6, 0.25f, 0.30f)); - goalSelector.addGoal(4, new MeleeAttackGoal(this, 0.25f, false)); - goalSelector.addGoal(5, new RandomStrollGoal(this, 0.20f)); + goalSelector.addGoal(3, new AvoidPlayerGoal(this, typeid(Ocelot), 6, 1.0, 1.2)); + goalSelector.addGoal(4, new MeleeAttackGoal(this, 1.0, false)); + goalSelector.addGoal(5, new RandomStrollGoal(this, 0.8)); goalSelector.addGoal(6, new LookAtPlayerGoal(this, typeid(Player), 8)); goalSelector.addGoal(6, new RandomLookAroundGoal(this)); - targetSelector.addGoal(1, new NearestAttackableTargetGoal(this, typeid(Player), 16, 0, true)); + targetSelector.addGoal(1, new NearestAttackableTargetGoal(this, typeid(Player), 0, true)); targetSelector.addGoal(2, new HurtByTargetGoal(this, false)); } +void Creeper::registerAttributes() +{ + Monster::registerAttributes(); + + getAttribute(SharedMonsterAttributes::MOVEMENT_SPEED)->setBaseValue(0.25f); +} + bool Creeper::useNewAi() { return true; } -int Creeper::getMaxHealth() +int Creeper::getMaxFallDistance() +{ + if (getTarget() == NULL) return 3; + // As long as they survive the fall they should try. + return 3 + (int) (getHealth() - 1); +} + +void Creeper::causeFallDamage(float distance) { - return 20; + Monster::causeFallDamage(distance); + + swell += distance * 1.5f; + if (swell > maxSwell - 5) swell = maxSwell - 5; } void Creeper::defineSynchedData() { - Monster::defineSynchedData(); + Monster::defineSynchedData(); - entityData->define(DATA_SWELL_DIR, (byte) -1); - entityData->define(DATA_IS_POWERED, (byte) 0); + entityData->define(DATA_SWELL_DIR, (byte) -1); + entityData->define(DATA_IS_POWERED, (byte) 0); } void Creeper::addAdditonalSaveData(CompoundTag *entityTag) { - Monster::addAdditonalSaveData(entityTag); - if (entityData->getByte(DATA_IS_POWERED) == 1) entityTag->putBoolean(L"powered", true); + Monster::addAdditonalSaveData(entityTag); + if (entityData->getByte(DATA_IS_POWERED) == 1) entityTag->putBoolean(L"powered", true); + entityTag->putShort(L"Fuse", (short) maxSwell); + entityTag->putByte(L"ExplosionRadius", (byte) explosionRadius); } void Creeper::readAdditionalSaveData(CompoundTag *tag) { - Monster::readAdditionalSaveData(tag); - entityData->set(DATA_IS_POWERED, (byte) (tag->getBoolean(L"powered") ? 1 : 0)); + Monster::readAdditionalSaveData(tag); + entityData->set(DATA_IS_POWERED, (byte) (tag->getBoolean(L"powered") ? 1 : 0)); + if (tag->contains(L"Fuse")) maxSwell = tag->getShort(L"Fuse"); + if (tag->contains(L"ExplosionRadius")) explosionRadius = tag->getByte(L"ExplosionRadius"); } void Creeper::tick() { - oldSwell = swell; - if (isAlive()) + oldSwell = swell; + if (isAlive()) { - int swellDir = getSwellDir(); - if (swellDir > 0 && swell == 0) + int swellDir = getSwellDir(); + if (swellDir > 0 && swell == 0) { - level->playSound(shared_from_this(), eSoundType_RANDOM_FUSE, 1, 0.5f); - } - swell += swellDir; - if (swell < 0) swell = 0; - if (swell >= MAX_SWELL) + playSound(eSoundType_RANDOM_FUSE, 1, 0.5f); + } + swell += swellDir; + if (swell < 0) swell = 0; + if (swell >= maxSwell) { - swell = MAX_SWELL; + swell = maxSwell; if (!level->isClientSide) { - bool destroyBlocks = true; //level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); - if (isPowered()) level->explode(shared_from_this(), x, y, z, 6, destroyBlocks); - else level->explode(shared_from_this(), x, y, z, 3,destroyBlocks); + bool destroyBlocks = level->getGameRules()->getBoolean(GameRules::RULE_MOBGRIEFING); + if (isPowered()) level->explode(shared_from_this(), x, y, z, explosionRadius * 2, destroyBlocks); + else level->explode(shared_from_this(), x, y, z, explosionRadius, destroyBlocks); remove(); } } - } - Monster::tick(); + } + Monster::tick(); } int Creeper::getHurtSound() { - return eSoundType_MOB_CREEPER_HURT; + return eSoundType_MOB_CREEPER_HURT; } int Creeper::getDeathSound() { - return eSoundType_MOB_CREEPER_DEATH; + return eSoundType_MOB_CREEPER_DEATH; } void Creeper::die(DamageSource *source) { - Monster::die(source); + Monster::die(source); - if ( dynamic_pointer_cast<Skeleton>(source->getEntity()) != NULL ) + if ( source->getEntity() != NULL && source->getEntity()->instanceof(eTYPE_SKELETON) ) { - spawnAtLocation(Item::record_01_Id + random->nextInt(12), 1); - } + int recordId = Item::record_01_Id + random->nextInt(Item::record_12_Id - Item::record_01_Id + 1); + spawnAtLocation(recordId, 1); + } - shared_ptr<Player> player = dynamic_pointer_cast<Player>(source->getEntity()); - if ( (dynamic_pointer_cast<Arrow>(source->getDirectEntity()) != NULL) && (player != NULL) ) + if ( source->getDirectEntity() != NULL && source->getDirectEntity()->instanceof(eTYPE_ARROW) && source->getEntity() != NULL && source->getEntity()->instanceof(eTYPE_PLAYER) ) { + shared_ptr<Player> player = dynamic_pointer_cast<Player>(source->getEntity()); player->awardStat(GenericStats::archer(), GenericStats::param_archer()); } } @@ -139,31 +162,31 @@ bool Creeper::doHurtTarget(shared_ptr<Entity> target) bool Creeper::isPowered() { - return entityData->getByte(DATA_IS_POWERED) == 1; + return entityData->getByte(DATA_IS_POWERED) == 1; } float Creeper::getSwelling(float a) { - return (oldSwell + (swell - oldSwell) * a) / (MAX_SWELL - 2); + return (oldSwell + (swell - oldSwell) * a) / (maxSwell - 2); } int Creeper::getDeathLoot() { - return Item::sulphur->id; + return Item::gunpowder_Id; } int Creeper::getSwellDir() { - return (int) (char) entityData->getByte(DATA_SWELL_DIR); + return (int) (char) entityData->getByte(DATA_SWELL_DIR); } void Creeper::setSwellDir(int dir) { - entityData->set(DATA_SWELL_DIR, (byte) dir); + entityData->set(DATA_SWELL_DIR, (byte) dir); } void Creeper::thunderHit(const LightningBolt *lightningBolt) { - Monster::thunderHit(lightningBolt); - entityData->set(DATA_IS_POWERED, (byte) 1); + Monster::thunderHit(lightningBolt); + entityData->set(DATA_IS_POWERED, (byte) 1); } |
