MinecraftConsoles/Minecraft.World/WolfRetreatGoal.cpp
2026-03-15 21:10:32 +03:00

103 lines
3.2 KiB
C++

#include "stdafx.h"
#include "net.minecraft.world.entity.h"
#include "net.minecraft.world.entity.animal.h"
#include "net.minecraft.world.entity.ai.navigation.h"
#include "WolfRetreatGoal.h"
WolfRetreatGoal::WolfRetreatGoal(TamableAnimal* tameAnimal,
float retreatHealthFraction,
float runSpeedMultiplier)
{
this->tameAnimal = tameAnimal;
this->retreatHealthFraction = retreatHealthFraction;
this->runSpeedMultiplier = runSpeedMultiplier;
this->recalcPathTicks = 0;
// Öåëü èñïîëüçóåò ôëàã äâèæåíèÿ — áëîêèðóåò FollowOwnerGoal,
// RandomStrollGoal è ò.ä. ïîêà àêòèâíà
setRequiredControlFlags(0);
}
// ---------------------------------------------------------------------------
bool WolfRetreatGoal::canUse()
{
// Òîëüêî ïðèðó÷åííûé è íå ñèäÿùèé
if (!tameAnimal->isTame()) return false;
if (tameAnimal->isSitting()) return false;
// Ïðîâåðÿåì ïîðîã çäîðîâüÿ
float hpFraction = tameAnimal->getHealth() / tameAnimal->getMaxHealth();
if (hpFraction > retreatHealthFraction) return false;
// Åñòü æèâîé õîçÿèí
shared_ptr<Entity> owner = tameAnimal->getOwner();
if (owner == nullptr) return false;
shared_ptr<LivingEntity> ownerLiving =
dynamic_pointer_cast<LivingEntity>(owner);
return ownerLiving != nullptr && ownerLiving->isAlive();
}
// ---------------------------------------------------------------------------
bool WolfRetreatGoal::canContinueToUse()
{
// Ïðåêðàòèòü åñëè ñåë ïî êîìàíäå
if (tameAnimal->isSitting()) return false;
// Ïðåêðàòèòü åñëè äîñòàòî÷íî âûëå÷èëñÿ (ñ ãèñòåðåçèñîì)
float hpFraction = tameAnimal->getHealth() / tameAnimal->getMaxHealth();
if (hpFraction >= retreatHealthFraction + HYSTERESIS) return false;
// Ïðåêðàòèòü åñëè õîçÿèí èñ÷åç èëè óìåð
shared_ptr<Entity> owner = tameAnimal->getOwner();
if (owner == nullptr) return false;
shared_ptr<LivingEntity> ownerLiving =
dynamic_pointer_cast<LivingEntity>(owner);
if (ownerLiving == nullptr || !ownerLiving->isAlive()) return false;
// Ïðåêðàòèòü åñëè óæå äîáåæàëè äî õîçÿèíà
if (tameAnimal->distanceToSqr(owner) <= SAFE_DIST_SQ) return false;
return true;
}
// ---------------------------------------------------------------------------
void WolfRetreatGoal::start()
{
recalcPathTicks = 0;
// Áðîñèòü òåêóùóþ áîåâóþ öåëü è ñáðîñèòü çëîñòü
tameAnimal->setTarget(nullptr);
tameAnimal->onTameAggroStopped(); // Wolf: setAngry(false)
// Ñðàçó äâèãàåìñÿ ê õîçÿèíó
shared_ptr<Entity> owner = tameAnimal->getOwner();
if (owner != nullptr)
{
tameAnimal->getNavigation()->moveTo(owner, runSpeedMultiplier);
}
}
// ---------------------------------------------------------------------------
void WolfRetreatGoal::stop()
{
tameAnimal->getNavigation()->stop();
}
// ---------------------------------------------------------------------------
void WolfRetreatGoal::tick()
{
// Ïåðåñ÷èòûâàåì ïóòü íå êàæäûé òèê — õîçÿèí äâèæåòñÿ,
// ïóòü óñòàðåâàåò
if (--recalcPathTicks <= 0)
{
recalcPathTicks = PATH_RECALC_INTERVAL;
shared_ptr<Entity> owner = tameAnimal->getOwner();
if (owner != nullptr)
{
tameAnimal->getNavigation()->moveTo(owner, runSpeedMultiplier);
}
}
}