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

89 lines
2.5 KiB
C++

#include "stdafx.h"
#include "net.minecraft.world.entity.h"
#include "net.minecraft.world.entity.animal.h"
#include "net.minecraft.world.entity.monster.h"
#include "net.minecraft.world.phys.h"
#include "TameAnimalDefendGoal.h"
#include "Level.h"
TameAnimalDefendGoal::TameAnimalDefendGoal(TamableAnimal* tameAnimal, bool mustSee)
: TargetGoal(tameAnimal, mustSee)
{
this->tameAnimal = tameAnimal;
setRequiredControlFlags(TargetGoal::TargetFlag);
}
bool TameAnimalDefendGoal::canUse()
{
// Òîëüêî ïðèðó÷åííûé è íå ñèäÿùèé ïèòîìåö èùåò óãðîçû ñàì
if (!tameAnimal->isTame()) return false;
if (tameAnimal->isSitting()) return false;
// Åñëè óæå åñòü öåëü — íå ïåðåáèâàåì (ïðèîðèòåò ó ðåàêòèâíûõ öåëåé)
if (mob->getTarget() != nullptr && mob->getTarget()->isAlive()) return false;
shared_ptr<LivingEntity> owner =
dynamic_pointer_cast<LivingEntity>(tameAnimal->getOwner());
// owner ìîæåò áûòü nullptr (îôôëàéí-èãðîê) — äîïóñêàåì, íî wantsToAttack
// íèæå îáðàáîòàåò ýòî êîððåêòíî
double range = getFollowDistance();
// Èùåì âñå Monster-ñóùíîñòè â ðàäèóñå
vector<shared_ptr<Entity>>* candidates = mob->level->getEntitiesOfClass(
typeid(Monster),
mob->bb->grow(range, 4.0, range),
nullptr // áåç äîïîëíèòåëüíîãî ôèëüòðà — canAttack ñäåëàåò çà íàñ
);
if (candidates == nullptr || candidates->empty())
{
delete candidates;
return false;
}
shared_ptr<LivingEntity> best = nullptr;
double bestSq = DBL_MAX;
for (auto& e : *candidates)
{
shared_ptr<LivingEntity> le = dynamic_pointer_cast<LivingEntity>(e);
if (!le) continue;
// Ñòàíäàðòíàÿ ïðîâåðêà äèñòàíöèè, âèäèìîñòè, îãðàíè÷åíèé
if (!canAttack(le, false)) continue;
// Ñïåöèôè÷íàÿ äëÿ ïèòîìöà ôèëüòðàöèÿ
// (íå àòàêîâàòü êðèïåðà, ñâîèõ ïèòîìöåâ âëàäåëüöà è ò.ä.)
if (owner != nullptr && !tameAnimal->wantsToAttack(le, owner)) continue;
double distSq = mob->distanceToSqr(le);
if (distSq < bestSq)
{
bestSq = distSq;
best = le;
}
}
delete candidates;
if (!best) return false;
nearestHostile = weak_ptr<LivingEntity>(best);
return true;
}
void TameAnimalDefendGoal::start()
{
shared_ptr<LivingEntity> target = nearestHostile.lock();
mob->setTarget(target);
tameAnimal->onTameAggroStarted(target);
TargetGoal::start();
}
void TameAnimalDefendGoal::stop()
{
tameAnimal->onTameAggroStopped();
TargetGoal::stop();
}