aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.World/PathfinderMob.cpp
diff options
context:
space:
mode:
authordaoge <3523206925@qq.com>2026-03-03 03:04:10 +0800
committerGitHub <noreply@github.com>2026-03-03 03:04:10 +0800
commitb3feddfef372618c8a9d7a0abcaf18cfad866c18 (patch)
tree267761c3bb39241ba5c347bfbe2254d06686e287 /Minecraft.World/PathfinderMob.cpp
parent84c31a2331f7a0ec85b9d438992e244f60e5020f (diff)
feat: TU19 (Dec 2014) Features & Content (#155)
* try to resolve merge conflict * feat: TU19 (Dec 2014) Features & Content (#32) * December 2014 files * Working release build * Fix compilation issues * Add sound to Windows64Media * Add DLC content and force Tutorial DLC * Revert "Add DLC content and force Tutorial DLC" This reverts commit 97a43994725008e35fceb984d5549df9c8cea470. * Disable broken light packing * Disable breakpoint during DLC texture map load Allows DLC loading but the DLC textures are still broken * Fix post build not working * ... * fix vs2022 build * fix cmake build --------- Co-authored-by: Loki <lokirautio@gmail.com>
Diffstat (limited to 'Minecraft.World/PathfinderMob.cpp')
-rw-r--r--Minecraft.World/PathfinderMob.cpp133
1 files changed, 124 insertions, 9 deletions
diff --git a/Minecraft.World/PathfinderMob.cpp b/Minecraft.World/PathfinderMob.cpp
index b72e064f..c01790e7 100644
--- a/Minecraft.World/PathfinderMob.cpp
+++ b/Minecraft.World/PathfinderMob.cpp
@@ -1,12 +1,17 @@
#include "stdafx.h"
#include "net.minecraft.world.entity.h"
+#include "net.minecraft.world.entity.animal.h"
+#include "net.minecraft.world.entity.ai.attributes.h"
+#include "net.minecraft.world.entity.ai.goal.h"
+#include "net.minecraft.world.entity.ai.navigation.h"
+#include "net.minecraft.world.entity.monster.h"
#include "net.minecraft.world.level.h"
#include "net.minecraft.world.level.pathfinder.h"
#include "net.minecraft.world.phys.h"
#include "SharedConstants.h"
#include "PathfinderMob.h"
-
+AttributeModifier *PathfinderMob::SPEED_MODIFIER_FLEEING = (new AttributeModifier(eModifierId_MOB_FLEEING, 2.0f, AttributeModifier::OPERATION_MULTIPLY_TOTAL))->setSerialize(false);
PathfinderMob::PathfinderMob(Level *level) : Mob( level )
{
@@ -14,6 +19,11 @@ PathfinderMob::PathfinderMob(Level *level) : Mob( level )
attackTarget = nullptr;
holdGround = false;
fleeTime = 0;
+
+ restrictRadius = -1;
+ restrictCenter = new Pos(0, 0, 0);
+ addedLeashRestrictionGoal = false;
+ leashRestrictionGoal = new MoveTowardsRestrictionGoal(this, 1.0f);
}
bool PathfinderMob::shouldHoldGround()
@@ -24,11 +34,20 @@ bool PathfinderMob::shouldHoldGround()
PathfinderMob::~PathfinderMob()
{
delete path;
+ delete restrictCenter;
+ delete leashRestrictionGoal;
}
void PathfinderMob::serverAiStep()
{
- if (fleeTime > 0) fleeTime--;
+ if (fleeTime > 0)
+ {
+ if (--fleeTime == 0)
+ {
+ AttributeInstance *speed = getAttribute(SharedMonsterAttributes::MOVEMENT_SPEED);
+ speed->removeModifier(SPEED_MODIFIER_FLEEING);
+ }
+ }
holdGround = shouldHoldGround();
float maxDist = 16;
@@ -124,7 +143,7 @@ void PathfinderMob::serverAiStep()
double yd = target->y - yFloor;
float yRotD = (float) (atan2(zd, xd) * 180 / PI) - 90;
float rotDiff = Mth::wrapDegrees(yRotD - yRot);
- yya = runSpeed;
+ yya = (float) getAttribute(SharedMonsterAttributes::MOVEMENT_SPEED)->getValue();
if (rotDiff > MAX_TURN)
{
rotDiff = MAX_TURN;
@@ -161,7 +180,7 @@ void PathfinderMob::serverAiStep()
lookAt(attackTarget, 30, 30);
}
- if (this->horizontalCollision && !isPathFinding()) jumping = true;
+ if (horizontalCollision && !isPathFinding()) jumping = true;
if (random->nextFloat() < 0.8f && (inWater || inLava)) jumping = true;
}
@@ -250,12 +269,108 @@ void PathfinderMob::setAttackTarget(shared_ptr<Entity> attacker)
attackTarget = attacker;
}
-float PathfinderMob::getWalkingSpeedModifier()
+// might move to navigation, might make area
+bool PathfinderMob::isWithinRestriction()
+{
+ return isWithinRestriction(Mth::floor(x), Mth::floor(y), Mth::floor(z));
+}
+
+bool PathfinderMob::isWithinRestriction(int x, int y, int z)
+{
+ if (restrictRadius == -1) return true;
+ return restrictCenter->distSqr(x, y, z) < restrictRadius * restrictRadius;
+}
+
+void PathfinderMob::restrictTo(int x, int y, int z, int radius)
+{
+ restrictCenter->set(x, y, z);
+ restrictRadius = radius;
+}
+
+Pos *PathfinderMob::getRestrictCenter()
+{
+ return restrictCenter;
+}
+
+float PathfinderMob::getRestrictRadius()
+{
+ return restrictRadius;
+}
+
+void PathfinderMob::clearRestriction()
+{
+ restrictRadius = -1;
+}
+
+bool PathfinderMob::hasRestriction()
+{
+ return restrictRadius != -1;
+}
+
+void PathfinderMob::tickLeash()
+{
+ Mob::tickLeash();
+
+ if (isLeashed() && getLeashHolder() != NULL && getLeashHolder()->level == this->level)
+ {
+ // soft restriction
+ shared_ptr<Entity> leashHolder = getLeashHolder();
+ restrictTo((int) leashHolder->x, (int) leashHolder->y, (int) leashHolder->z, 5);
+
+ float _distanceTo = distanceTo(leashHolder);
+
+ shared_ptr<TamableAnimal> tamabaleAnimal = shared_from_this()->instanceof(eTYPE_TAMABLE_ANIMAL) ? dynamic_pointer_cast<TamableAnimal>(shared_from_this()) : nullptr;
+ if ( (tamabaleAnimal != NULL) && tamabaleAnimal->isSitting() )
+ {
+ if (_distanceTo > 10)
+ {
+ dropLeash(true, true);
+ }
+ return;
+ }
+
+ if (!addedLeashRestrictionGoal)
+ {
+ goalSelector.addGoal(2, leashRestrictionGoal, false);
+ getNavigation()->setAvoidWater(false);
+ addedLeashRestrictionGoal = true;
+ }
+
+ onLeashDistance(_distanceTo);
+
+ if (_distanceTo > 4)
+ {
+ // harder restriction
+ getNavigation()->moveTo(leashHolder, 1.0);
+ }
+ if (_distanceTo > 6)
+ {
+ // hardest restriction
+ double dx = (leashHolder->x - x) / _distanceTo;
+ double dy = (leashHolder->y - y) / _distanceTo;
+ double dz = (leashHolder->z - z) / _distanceTo;
+
+ xd += dx * abs(dx) * .4;
+ yd += dy * abs(dy) * .4;
+ zd += dz * abs(dz) * .4;
+ }
+ if (_distanceTo > 10)
+ {
+ dropLeash(true, true);
+ }
+
+ }
+ else if (!isLeashed() && addedLeashRestrictionGoal)
+ {
+ addedLeashRestrictionGoal = false;
+ goalSelector.removeGoal(leashRestrictionGoal);
+ getNavigation()->setAvoidWater(true);
+ clearRestriction();
+ }
+}
+
+void PathfinderMob::onLeashDistance(float distanceToLeashHolder)
{
- if (useNewAi()) return 1.0f;
- float speed = Mob::getWalkingSpeedModifier();
- if (fleeTime > 0) speed *= 2;
- return speed;
}
bool PathfinderMob::couldWander()