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/ArrowAttackGoal.cpp | 91 +++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 Minecraft.World/ArrowAttackGoal.cpp (limited to 'Minecraft.World/ArrowAttackGoal.cpp') diff --git a/Minecraft.World/ArrowAttackGoal.cpp b/Minecraft.World/ArrowAttackGoal.cpp new file mode 100644 index 00000000..23a2d2ac --- /dev/null +++ b/Minecraft.World/ArrowAttackGoal.cpp @@ -0,0 +1,91 @@ +#include "stdafx.h" +#include "net.minecraft.world.entity.ai.control.h" +#include "net.minecraft.world.entity.ai.navigation.h" +#include "net.minecraft.world.entity.ai.sensing.h" +#include "net.minecraft.world.entity.projectile.h" +#include "net.minecraft.world.entity.h" +#include "net.minecraft.world.level.h" +#include "net.minecraft.world.phys.h" +#include "SoundTypes.h" +#include "ArrowAttackGoal.h" + +ArrowAttackGoal::ArrowAttackGoal(Mob *mob, float speed, int projectileType, int attackInterval) +{ + // 4J Init + target = weak_ptr(); + attackTime = 0; + seeTime = 0; + + this->mob = mob; + this->level = mob->level; + this->speed = speed; + this->projectileType = projectileType; + this->attackInterval = attackInterval; + setRequiredControlFlags(Control::MoveControlFlag | Control::LookControlFlag); +} + +bool ArrowAttackGoal::canUse() +{ + shared_ptr bestTarget = mob->getTarget(); + if (bestTarget == NULL) return false; + target = weak_ptr(bestTarget); + return true; +} + +bool ArrowAttackGoal::canContinueToUse() +{ + return target.lock() != NULL && (canUse() || !mob->getNavigation()->isDone()); +} + +void ArrowAttackGoal::stop() +{ + target = weak_ptr(); +} + +void ArrowAttackGoal::tick() +{ + double attackRadiusSqr = 10 * 10; + shared_ptr tar = target.lock(); + double targetDistSqr = mob->distanceToSqr(tar->x, tar->bb->y0, tar->z); + bool canSee = mob->getSensing()->canSee(tar); + + if (canSee) + { + ++seeTime; + } + else seeTime = 0; + + if (targetDistSqr > attackRadiusSqr || seeTime < 20) mob->getNavigation()->moveTo(tar, speed); + else mob->getNavigation()->stop(); + + mob->getLookControl()->setLookAt(tar, 30, 30); + + attackTime = max(attackTime - 1, 0); + if (attackTime > 0) return; + if (targetDistSqr > attackRadiusSqr || !canSee) return; + fireAtTarget(); + attackTime = attackInterval; +} + +void ArrowAttackGoal::fireAtTarget() +{ + shared_ptr tar = target.lock(); + if (projectileType == ArrowType) + { + shared_ptr arrow = shared_ptr( new Arrow(level, dynamic_pointer_cast(mob->shared_from_this()), tar, 1.60f, 12) ); + level->playSound(mob->shared_from_this(), eSoundType_RANDOM_BOW, 1.0f, 1 / (mob->getRandom()->nextFloat() * 0.4f + 0.8f)); + level->addEntity(arrow); + } + else if (projectileType == SnowballType) + { + shared_ptr snowball = shared_ptr( new Snowball(level, dynamic_pointer_cast(mob->shared_from_this())) ); + double xd = tar->x - mob->x; + double yd = (tar->y + tar->getHeadHeight() - 1.1f) - snowball->y; + double zd = tar->z - mob->z; + float yo = sqrt(xd * xd + zd * zd) * 0.2f; + snowball->shoot(xd, yd + yo, zd, 1.60f, 12); + + level->playSound(mob->shared_from_this(), eSoundType_RANDOM_BOW, 1.0f, 1 / (mob->getRandom()->nextFloat() * 0.4f + 0.8f)); + level->addEntity(snowball); + } +} \ No newline at end of file -- cgit v1.2.3