From b691c43c44ff180d10e7d4a9afc83b98551ff586 Mon Sep 17 00:00:00 2001 From: daoge_cmd <3523206925@qq.com> Date: Sun, 1 Mar 2026 12:16:08 +0800 Subject: Initial commit --- Minecraft.World/Creeper.cpp | 169 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 Minecraft.World/Creeper.cpp (limited to 'Minecraft.World/Creeper.cpp') diff --git a/Minecraft.World/Creeper.cpp b/Minecraft.World/Creeper.cpp new file mode 100644 index 00000000..3f6c66a7 --- /dev/null +++ b/Minecraft.World/Creeper.cpp @@ -0,0 +1,169 @@ +#include "stdafx.h" +#include "net.minecraft.world.level.h" +#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.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.damagesource.h" +#include "GeneralStat.h" +#include "Skeleton.h" +#include "Creeper.h" +#include "Arrow.h" +#include "..\Minecraft.Client\Textures.h" +#include "SoundTypes.h" + + + +void Creeper::_init() +{ + swell = 0; + oldSwell = 0; +} + +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(); + + _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(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(2, new HurtByTargetGoal(this, false)); +} + +bool Creeper::useNewAi() +{ + return true; +} + +int Creeper::getMaxHealth() +{ + return 20; +} + +void Creeper::defineSynchedData() +{ + Monster::defineSynchedData(); + + 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); +} + +void Creeper::readAdditionalSaveData(CompoundTag *tag) +{ + Monster::readAdditionalSaveData(tag); + entityData->set(DATA_IS_POWERED, (byte) (tag->getBoolean(L"powered") ? 1 : 0)); +} + +void Creeper::tick() +{ + oldSwell = swell; + if (isAlive()) + { + 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) + { + swell = MAX_SWELL; + 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); + remove(); + } + } + } + Monster::tick(); +} + +int Creeper::getHurtSound() +{ + return eSoundType_MOB_CREEPER_HURT; +} + +int Creeper::getDeathSound() +{ + return eSoundType_MOB_CREEPER_DEATH; +} + +void Creeper::die(DamageSource *source) +{ + Monster::die(source); + + if ( dynamic_pointer_cast(source->getEntity()) != NULL ) + { + spawnAtLocation(Item::record_01_Id + random->nextInt(12), 1); + } + + shared_ptr player = dynamic_pointer_cast(source->getEntity()); + if ( (dynamic_pointer_cast(source->getDirectEntity()) != NULL) && (player != NULL) ) + { + player->awardStat(GenericStats::archer(), GenericStats::param_archer()); + } +} + +bool Creeper::doHurtTarget(shared_ptr target) +{ + return true; +} + +bool Creeper::isPowered() +{ + return entityData->getByte(DATA_IS_POWERED) == 1; +} + +float Creeper::getSwelling(float a) +{ + return (oldSwell + (swell - oldSwell) * a) / (MAX_SWELL - 2); +} + +int Creeper::getDeathLoot() +{ + return Item::sulphur->id; +} + +int Creeper::getSwellDir() +{ + return (int) (char) entityData->getByte(DATA_SWELL_DIR); +} + +void Creeper::setSwellDir(int dir) +{ + entityData->set(DATA_SWELL_DIR, (byte) dir); +} + +void Creeper::thunderHit(const LightningBolt *lightningBolt) +{ + Monster::thunderHit(lightningBolt); + entityData->set(DATA_IS_POWERED, (byte) 1); +} -- cgit v1.2.3