aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.World/Creeper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Minecraft.World/Creeper.cpp')
-rw-r--r--Minecraft.World/Creeper.cpp119
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);
}