mirror of
https://github.com/smartcmd/MinecraftConsoles.git
synced 2026-08-20 09:57:09 +00:00
89 lines
2.5 KiB
C++
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();
|
|
}
|