chore: format Minecraft.World

This commit is contained in:
Tropical 2026-03-13 17:06:56 -05:00
parent bd6284025d
commit 33d0737d1d
1511 changed files with 108661 additions and 115521 deletions

View file

@ -5,21 +5,18 @@
const float BodyControl::maxClampAngle = 75.0f; const float BodyControl::maxClampAngle = 75.0f;
BodyControl::BodyControl(Mob *mob) BodyControl::BodyControl(Mob* mob) {
{
this->mob = mob; this->mob = mob;
timeStill = 0; timeStill = 0;
lastHeadY = 0.0f; lastHeadY = 0.0f;
} }
void BodyControl::clientTick() void BodyControl::clientTick() {
{
double xd = mob->x - mob->xo; double xd = mob->x - mob->xo;
double zd = mob->z - mob->zo; double zd = mob->z - mob->zo;
if (xd * xd + zd * zd > MoveControl::MIN_SPEED_SQR) if (xd * xd + zd * zd > MoveControl::MIN_SPEED_SQR) {
{
// we are moving. // we are moving.
mob->yBodyRot = mob->yRot; mob->yBodyRot = mob->yRot;
mob->yHeadRot = clamp(mob->yBodyRot, mob->yHeadRot, maxClampAngle); mob->yHeadRot = clamp(mob->yBodyRot, mob->yHeadRot, maxClampAngle);
@ -30,23 +27,22 @@ void BodyControl::clientTick()
// Body will align to head after looking long enough in a direction // Body will align to head after looking long enough in a direction
float clampAngle = maxClampAngle; float clampAngle = maxClampAngle;
if (abs(mob->yHeadRot - lastHeadY) > 15) if (abs(mob->yHeadRot - lastHeadY) > 15) {
{
timeStill = 0; timeStill = 0;
lastHeadY = mob->yHeadRot; lastHeadY = mob->yHeadRot;
} } else {
else
{
++timeStill; ++timeStill;
static const int timeStillBeforeTurn = 10; static const int timeStillBeforeTurn = 10;
if (timeStill > timeStillBeforeTurn) clampAngle = std::max(1 - (timeStill - timeStillBeforeTurn) / 10.f, 0.0f) * maxClampAngle; if (timeStill > timeStillBeforeTurn)
clampAngle =
std::max(1 - (timeStill - timeStillBeforeTurn) / 10.f, 0.0f) *
maxClampAngle;
} }
mob->yBodyRot = clamp(mob->yHeadRot, mob->yBodyRot, clampAngle); mob->yBodyRot = clamp(mob->yHeadRot, mob->yBodyRot, clampAngle);
} }
float BodyControl::clamp(float clampTo, float clampFrom, float clampAngle) float BodyControl::clamp(float clampTo, float clampFrom, float clampAngle) {
{
float headDiffBody = Mth::wrapDegrees(clampTo - clampFrom); float headDiffBody = Mth::wrapDegrees(clampTo - clampFrom);
if (headDiffBody < -clampAngle) headDiffBody = -clampAngle; if (headDiffBody < -clampAngle) headDiffBody = -clampAngle;
if (headDiffBody >= clampAngle) headDiffBody = +clampAngle; if (headDiffBody >= clampAngle) headDiffBody = +clampAngle;

View file

@ -2,8 +2,7 @@
#include "Control.h" #include "Control.h"
class BodyControl : public Control class BodyControl : public Control {
{
private: private:
Mob* mob; Mob* mob;
static const float maxClampAngle; static const float maxClampAngle;

View file

@ -1,7 +1,6 @@
#pragma once #pragma once
class Control class Control {
{
public: public:
static const int MoveControlFlag = 1; static const int MoveControlFlag = 1;
static const int LookControlFlag = 2; static const int LookControlFlag = 2;

View file

@ -2,20 +2,15 @@
#include "../../Headers/net.minecraft.world.entity.h" #include "../../Headers/net.minecraft.world.entity.h"
#include "JumpControl.h" #include "JumpControl.h"
JumpControl::JumpControl(Mob *mob) JumpControl::JumpControl(Mob* mob) {
{
_jump = false; _jump = false;
this->mob = mob; this->mob = mob;
} }
void JumpControl::jump() void JumpControl::jump() { _jump = true; }
{
_jump = true;
}
void JumpControl::tick() void JumpControl::tick() {
{
mob->setJumping(_jump); mob->setJumping(_jump);
_jump = false; _jump = false;
} }

View file

@ -4,8 +4,7 @@
class Mob; class Mob;
class JumpControl : public Control class JumpControl : public Control {
{
private: private:
Mob* mob; Mob* mob;
bool _jump; bool _jump;

View file

@ -4,8 +4,7 @@
#include "../../Headers/net.minecraft.world.phys.h" #include "../../Headers/net.minecraft.world.phys.h"
#include "LookControl.h" #include "LookControl.h"
LookControl::LookControl(Mob *mob) LookControl::LookControl(Mob* mob) {
{
yMax = xMax = 0.0f; yMax = xMax = 0.0f;
hasWanted = false; hasWanted = false;
wantedX = wantedY = wantedZ = 0.0; wantedX = wantedY = wantedZ = 0.0;
@ -13,20 +12,22 @@ LookControl::LookControl(Mob *mob)
this->mob = mob; this->mob = mob;
} }
void LookControl::setLookAt(std::shared_ptr<Entity> target, float yMax, float xMax) void LookControl::setLookAt(std::shared_ptr<Entity> target, float yMax,
{ float xMax) {
this->wantedX = target->x; this->wantedX = target->x;
std::shared_ptr<Mob> targetMob = std::dynamic_pointer_cast<Mob>(target); std::shared_ptr<Mob> targetMob = std::dynamic_pointer_cast<Mob>(target);
if (targetMob != NULL) this->wantedY = target->y + targetMob->getHeadHeight(); if (targetMob != NULL)
else this->wantedY = (target->bb->y0 + target->bb->y1) / 2; this->wantedY = target->y + targetMob->getHeadHeight();
else
this->wantedY = (target->bb->y0 + target->bb->y1) / 2;
this->wantedZ = target->z; this->wantedZ = target->z;
this->yMax = yMax; this->yMax = yMax;
this->xMax = xMax; this->xMax = xMax;
hasWanted = true; hasWanted = true;
} }
void LookControl::setLookAt(double x, double y, double z, float yMax, float xMax) void LookControl::setLookAt(double x, double y, double z, float yMax,
{ float xMax) {
this->wantedX = x; this->wantedX = x;
this->wantedY = y; this->wantedY = y;
this->wantedZ = z; this->wantedZ = z;
@ -35,12 +36,10 @@ void LookControl::setLookAt(double x, double y, double z, float yMax, float xMax
hasWanted = true; hasWanted = true;
} }
void LookControl::tick() void LookControl::tick() {
{
mob->xRot = 0; mob->xRot = 0;
if (hasWanted) if (hasWanted) {
{
hasWanted = false; hasWanted = false;
double xd = wantedX - mob->x; double xd = wantedX - mob->x;
@ -52,66 +51,40 @@ void LookControl::tick()
float xRotD = (float)-(atan2(yd, sd) * 180 / PI); float xRotD = (float)-(atan2(yd, sd) * 180 / PI);
mob->xRot = rotlerp(mob->xRot, xRotD, xMax); mob->xRot = rotlerp(mob->xRot, xRotD, xMax);
mob->yHeadRot = rotlerp(mob->yHeadRot, yRotD, yMax); mob->yHeadRot = rotlerp(mob->yHeadRot, yRotD, yMax);
} } else {
else
{
mob->yHeadRot = rotlerp(mob->yHeadRot, mob->yBodyRot, 10); mob->yHeadRot = rotlerp(mob->yHeadRot, mob->yBodyRot, 10);
} }
float headDiffBody = Mth::wrapDegrees(mob->yHeadRot - mob->yBodyRot); float headDiffBody = Mth::wrapDegrees(mob->yHeadRot - mob->yBodyRot);
if (!mob->getNavigation()->isDone()) if (!mob->getNavigation()->isDone()) {
{
// head clamped to body // head clamped to body
if (headDiffBody < -75) mob->yHeadRot = mob->yBodyRot - 75; if (headDiffBody < -75) mob->yHeadRot = mob->yBodyRot - 75;
if (headDiffBody > 75) mob->yHeadRot = mob->yBodyRot + 75; if (headDiffBody > 75) mob->yHeadRot = mob->yBodyRot + 75;
} }
} }
float LookControl::rotlerp(float a, float b, float max) float LookControl::rotlerp(float a, float b, float max) {
{
float diff = b - a; float diff = b - a;
while (diff < -180) while (diff < -180) diff += 360;
diff += 360; while (diff >= 180) diff -= 360;
while (diff >= 180) if (diff > max) {
diff -= 360;
if (diff > max)
{
diff = max; diff = max;
} }
if (diff < -max) if (diff < -max) {
{
diff = -max; diff = -max;
} }
return a + diff; return a + diff;
} }
bool LookControl::isHasWanted() bool LookControl::isHasWanted() { return hasWanted; }
{
return hasWanted;
}
float LookControl::getYMax() float LookControl::getYMax() { return yMax; }
{
return yMax;
}
float LookControl::getXMax() float LookControl::getXMax() { return xMax; }
{
return xMax;
}
double LookControl::getWantedX() double LookControl::getWantedX() { return wantedX; }
{
return wantedX;
}
double LookControl::getWantedY() double LookControl::getWantedY() { return wantedY; }
{
return wantedY;
}
double LookControl::getWantedZ() double LookControl::getWantedZ() { return wantedZ; }
{
return wantedZ;
}

View file

@ -4,8 +4,7 @@
class Mob; class Mob;
class LookControl : public Control class LookControl : public Control {
{
private: private:
Mob* mob; Mob* mob;
float yMax, xMax; float yMax, xMax;

View file

@ -7,8 +7,7 @@
const float MoveControl::MIN_SPEED = 0.0005f; const float MoveControl::MIN_SPEED = 0.0005f;
const float MoveControl::MIN_SPEED_SQR = MIN_SPEED * MIN_SPEED; const float MoveControl::MIN_SPEED_SQR = MIN_SPEED * MIN_SPEED;
MoveControl::MoveControl(Mob *mob) MoveControl::MoveControl(Mob* mob) {
{
this->mob = mob; this->mob = mob;
wantedX = mob->x; wantedX = mob->x;
wantedY = mob->y; wantedY = mob->y;
@ -19,18 +18,11 @@ MoveControl::MoveControl(Mob *mob)
_hasWanted = false; _hasWanted = false;
} }
bool MoveControl::hasWanted() bool MoveControl::hasWanted() { return _hasWanted; }
{
return _hasWanted;
}
float MoveControl::getSpeed() float MoveControl::getSpeed() { return speed; }
{
return speed;
}
void MoveControl::setWantedPosition(double x, double y, double z, float speed) void MoveControl::setWantedPosition(double x, double y, double z, float speed) {
{
wantedX = x; wantedX = x;
wantedY = y; wantedY = y;
wantedZ = z; wantedZ = z;
@ -38,8 +30,7 @@ void MoveControl::setWantedPosition(double x, double y, double z, float speed)
_hasWanted = true; _hasWanted = true;
} }
void MoveControl::tick() void MoveControl::tick() {
{
mob->setYya(0); mob->setYya(0);
if (!_hasWanted) return; if (!_hasWanted) return;
_hasWanted = false; _hasWanted = false;
@ -60,15 +51,12 @@ void MoveControl::tick()
if (yd > 0 && xd * xd + zd * zd < 1) mob->getJumpControl()->jump(); if (yd > 0 && xd * xd + zd * zd < 1) mob->getJumpControl()->jump();
} }
float MoveControl::rotlerp(float a, float b, float max) float MoveControl::rotlerp(float a, float b, float max) {
{
float diff = Mth::wrapDegrees(b - a); float diff = Mth::wrapDegrees(b - a);
if (diff > max) if (diff > max) {
{
diff = max; diff = max;
} }
if (diff < -max) if (diff < -max) {
{
diff = -max; diff = -max;
} }
return a + diff; return a + diff;

View file

@ -4,8 +4,7 @@
class Mob; class Mob;
class MoveControl : public Control class MoveControl : public Control {
{
public: public:
static const float MIN_SPEED; static const float MIN_SPEED;
static const float MIN_SPEED_SQR; static const float MIN_SPEED_SQR;

View file

@ -2,34 +2,30 @@
#include "../../Headers/net.minecraft.world.entity.h" #include "../../Headers/net.minecraft.world.entity.h"
#include "Sensing.h" #include "Sensing.h"
Sensing::Sensing(Mob *mob) Sensing::Sensing(Mob* mob) { this->mob = mob; }
{
this->mob = mob;
}
void Sensing::tick() void Sensing::tick() {
{
seen.clear(); seen.clear();
unseen.clear(); unseen.clear();
} }
bool Sensing::canSee(std::shared_ptr<Entity> target) bool Sensing::canSee(std::shared_ptr<Entity> target) {
{
// if ( find(seen.begin(), seen.end(), target) != seen.end() ) return true; // if ( find(seen.begin(), seen.end(), target) != seen.end() ) return true;
//if ( find(unseen.begin(), unseen.end(), target) != unseen.end()) return false; // if ( find(unseen.begin(), unseen.end(), target) != unseen.end()) return
for(AUTO_VAR(it, seen.begin()); it != seen.end(); ++it) // false;
{ for (AUTO_VAR(it, seen.begin()); it != seen.end(); ++it) {
if (target == (*it).lock()) return true; if (target == (*it).lock()) return true;
} }
for(AUTO_VAR(it, unseen.begin()); it != unseen.end(); ++it) for (AUTO_VAR(it, unseen.begin()); it != unseen.end(); ++it) {
{
if (target == (*it).lock()) return false; if (target == (*it).lock()) return false;
} }
// util.Timer.push("canSee"); // util.Timer.push("canSee");
bool canSee = mob->canSee(target); bool canSee = mob->canSee(target);
// util.Timer.pop(); // util.Timer.pop();
if (canSee) seen.push_back(std::weak_ptr<Entity>(target)); if (canSee)
else unseen.push_back(std::weak_ptr<Entity>(target)); seen.push_back(std::weak_ptr<Entity>(target));
else
unseen.push_back(std::weak_ptr<Entity>(target));
return canSee; return canSee;
} }

View file

@ -1,7 +1,6 @@
#pragma once #pragma once
class Sensing class Sensing {
{
private: private:
Mob* mob; Mob* mob;
std::vector<std::weak_ptr<Entity> > seen; std::vector<std::weak_ptr<Entity> > seen;

View file

@ -9,8 +9,8 @@
#include "../../Util/SoundTypes.h" #include "../../Util/SoundTypes.h"
#include "ArrowAttackGoal.h" #include "ArrowAttackGoal.h"
ArrowAttackGoal::ArrowAttackGoal(Mob *mob, float speed, int projectileType, int attackInterval) ArrowAttackGoal::ArrowAttackGoal(Mob* mob, float speed, int projectileType,
{ int attackInterval) {
// 4J Init // 4J Init
target = std::weak_ptr<Mob>(); target = std::weak_ptr<Mob>();
attackTime = 0; attackTime = 0;
@ -21,42 +21,39 @@ ArrowAttackGoal::ArrowAttackGoal(Mob *mob, float speed, int projectileType, int
this->speed = speed; this->speed = speed;
this->projectileType = projectileType; this->projectileType = projectileType;
this->attackInterval = attackInterval; this->attackInterval = attackInterval;
setRequiredControlFlags(Control::MoveControlFlag | Control::LookControlFlag); setRequiredControlFlags(Control::MoveControlFlag |
Control::LookControlFlag);
} }
bool ArrowAttackGoal::canUse() bool ArrowAttackGoal::canUse() {
{
std::shared_ptr<Mob> bestTarget = mob->getTarget(); std::shared_ptr<Mob> bestTarget = mob->getTarget();
if (bestTarget == NULL) return false; if (bestTarget == NULL) return false;
target = std::weak_ptr<Mob>(bestTarget); target = std::weak_ptr<Mob>(bestTarget);
return true; return true;
} }
bool ArrowAttackGoal::canContinueToUse() bool ArrowAttackGoal::canContinueToUse() {
{ return target.lock() != NULL &&
return target.lock() != NULL && (canUse() || !mob->getNavigation()->isDone()); (canUse() || !mob->getNavigation()->isDone());
} }
void ArrowAttackGoal::stop() void ArrowAttackGoal::stop() { target = std::weak_ptr<Mob>(); }
{
target = std::weak_ptr<Mob>();
}
void ArrowAttackGoal::tick() void ArrowAttackGoal::tick() {
{
double attackRadiusSqr = 10 * 10; double attackRadiusSqr = 10 * 10;
std::shared_ptr<Mob> tar = target.lock(); std::shared_ptr<Mob> tar = target.lock();
double targetDistSqr = mob->distanceToSqr(tar->x, tar->bb->y0, tar->z); double targetDistSqr = mob->distanceToSqr(tar->x, tar->bb->y0, tar->z);
bool canSee = mob->getSensing()->canSee(tar); bool canSee = mob->getSensing()->canSee(tar);
if (canSee) if (canSee) {
{
++seeTime; ++seeTime;
} } else
else seeTime = 0; seeTime = 0;
if (targetDistSqr > attackRadiusSqr || seeTime < 20) mob->getNavigation()->moveTo(tar, speed); if (targetDistSqr > attackRadiusSqr || seeTime < 20)
else mob->getNavigation()->stop(); mob->getNavigation()->moveTo(tar, speed);
else
mob->getNavigation()->stop();
mob->getLookControl()->setLookAt(tar, 30, 30); mob->getLookControl()->setLookAt(tar, 30, 30);
@ -67,25 +64,27 @@ void ArrowAttackGoal::tick()
attackTime = attackInterval; attackTime = attackInterval;
} }
void ArrowAttackGoal::fireAtTarget() void ArrowAttackGoal::fireAtTarget() {
{
std::shared_ptr<Mob> tar = target.lock(); std::shared_ptr<Mob> tar = target.lock();
if (projectileType == ArrowType) if (projectileType == ArrowType) {
{ std::shared_ptr<Arrow> arrow = std::shared_ptr<Arrow>(new Arrow(
std::shared_ptr<Arrow> arrow = std::shared_ptr<Arrow>( new Arrow(level, std::dynamic_pointer_cast<Mob>(mob->shared_from_this()), tar, 1.60f, 12) ); level, std::dynamic_pointer_cast<Mob>(mob->shared_from_this()), tar,
level->playSound(mob->shared_from_this(), eSoundType_RANDOM_BOW, 1.0f, 1 / (mob->getRandom()->nextFloat() * 0.4f + 0.8f)); 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); level->addEntity(arrow);
} } else if (projectileType == SnowballType) {
else if (projectileType == SnowballType) std::shared_ptr<Snowball> snowball = std::shared_ptr<Snowball>(
{ new Snowball(level, std::dynamic_pointer_cast<Mob>(
std::shared_ptr<Snowball> snowball = std::shared_ptr<Snowball>( new Snowball(level, std::dynamic_pointer_cast<Mob>(mob->shared_from_this())) ); mob->shared_from_this())));
double xd = tar->x - mob->x; double xd = tar->x - mob->x;
double yd = (tar->y + tar->getHeadHeight() - 1.1f) - snowball->y; double yd = (tar->y + tar->getHeadHeight() - 1.1f) - snowball->y;
double zd = tar->z - mob->z; double zd = tar->z - mob->z;
float yo = sqrt(xd * xd + zd * zd) * 0.2f; float yo = sqrt(xd * xd + zd * zd) * 0.2f;
snowball->shoot(xd, yd + yo, zd, 1.60f, 12); 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->playSound(mob->shared_from_this(), eSoundType_RANDOM_BOW, 1.0f,
1 / (mob->getRandom()->nextFloat() * 0.4f + 0.8f));
level->addEntity(snowball); level->addEntity(snowball);
} }
} }

View file

@ -2,8 +2,7 @@
#include "Goal.h" #include "Goal.h"
class ArrowAttackGoal : public Goal class ArrowAttackGoal : public Goal {
{
public: public:
static const int ArrowType = 1; static const int ArrowType = 1;
static const int SnowballType = 2; static const int SnowballType = 2;
@ -17,7 +16,8 @@ public:
int projectileType; int projectileType;
int attackInterval; int attackInterval;
ArrowAttackGoal(Mob *mob, float speed, int projectileType, int attackInterval); ArrowAttackGoal(Mob* mob, float speed, int projectileType,
int attackInterval);
virtual bool canUse(); virtual bool canUse();
virtual bool canContinueToUse(); virtual bool canContinueToUse();
@ -28,6 +28,7 @@ private:
void fireAtTarget(); void fireAtTarget();
public: public:
// 4J Added override to update ai elements when loading entity from schematics // 4J Added override to update ai elements when loading entity from
// schematics
virtual void setLevel(Level* level) { this->level = level; } virtual void setLevel(Level* level) { this->level = level; }
}; };

View file

@ -10,8 +10,10 @@
#include "../../Headers/net.minecraft.world.phys.h" #include "../../Headers/net.minecraft.world.phys.h"
#include "AvoidPlayerGoal.h" #include "AvoidPlayerGoal.h"
AvoidPlayerGoal::AvoidPlayerGoal(PathfinderMob *mob, const std::type_info& avoidType, float maxDist, float walkSpeed, float sprintSpeed) : avoidType(avoidType) AvoidPlayerGoal::AvoidPlayerGoal(PathfinderMob* mob,
{ const std::type_info& avoidType, float maxDist,
float walkSpeed, float sprintSpeed)
: avoidType(avoidType) {
this->mob = mob; this->mob = mob;
// this->avoidType = avoidType; // this->avoidType = avoidType;
this->maxDist = maxDist; this->maxDist = maxDist;
@ -24,25 +26,23 @@ AvoidPlayerGoal::AvoidPlayerGoal(PathfinderMob *mob, const std::type_info& avoid
path = NULL; path = NULL;
} }
AvoidPlayerGoal::~AvoidPlayerGoal() AvoidPlayerGoal::~AvoidPlayerGoal() {
{
if (path != NULL) delete path; if (path != NULL) delete path;
} }
bool AvoidPlayerGoal::canUse() bool AvoidPlayerGoal::canUse() {
{ if (avoidType == typeid(Player)) {
if (avoidType == typeid(Player)) std::shared_ptr<TamableAnimal> tamableAnimal =
{ std::dynamic_pointer_cast<TamableAnimal>(mob->shared_from_this());
std::shared_ptr<TamableAnimal> tamableAnimal = std::dynamic_pointer_cast<TamableAnimal>(mob->shared_from_this());
if (tamableAnimal != NULL && tamableAnimal->isTame()) return false; if (tamableAnimal != NULL && tamableAnimal->isTame()) return false;
toAvoid = std::weak_ptr<Entity>(mob->level->getNearestPlayer(mob->shared_from_this(), maxDist)); toAvoid = std::weak_ptr<Entity>(
mob->level->getNearestPlayer(mob->shared_from_this(), maxDist));
if (toAvoid.lock() == NULL) return false; if (toAvoid.lock() == NULL) return false;
} } else {
else std::vector<std::shared_ptr<Entity> >* entities =
{ mob->level->getEntitiesOfClass(avoidType,
std::vector<std::shared_ptr<Entity> > *entities = mob->level->getEntitiesOfClass(avoidType, mob->bb->grow(maxDist, 3, maxDist)); mob->bb->grow(maxDist, 3, maxDist));
if (entities->empty()) if (entities->empty()) {
{
delete entities; delete entities;
return false; return false;
} }
@ -52,9 +52,14 @@ bool AvoidPlayerGoal::canUse()
if (!mob->getSensing()->canSee(toAvoid.lock())) return false; if (!mob->getSensing()->canSee(toAvoid.lock())) return false;
Vec3 *pos = RandomPos::getPosAvoid(std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()), 16, 7, Vec3::newTemp(toAvoid.lock()->x, toAvoid.lock()->y, toAvoid.lock()->z)); Vec3* pos = RandomPos::getPosAvoid(
std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()), 16,
7,
Vec3::newTemp(toAvoid.lock()->x, toAvoid.lock()->y, toAvoid.lock()->z));
if (pos == NULL) return false; if (pos == NULL) return false;
if (toAvoid.lock()->distanceToSqr(pos->x, pos->y, pos->z) < toAvoid.lock()->distanceToSqr(mob->shared_from_this())) return false; if (toAvoid.lock()->distanceToSqr(pos->x, pos->y, pos->z) <
toAvoid.lock()->distanceToSqr(mob->shared_from_this()))
return false;
delete path; delete path;
path = pathNav->createPath(pos->x, pos->y, pos->z); path = pathNav->createPath(pos->x, pos->y, pos->z);
if (path == NULL) return false; if (path == NULL) return false;
@ -62,24 +67,20 @@ bool AvoidPlayerGoal::canUse()
return true; return true;
} }
bool AvoidPlayerGoal::canContinueToUse() bool AvoidPlayerGoal::canContinueToUse() {
{
return toAvoid.lock() != NULL && !pathNav->isDone(); return toAvoid.lock() != NULL && !pathNav->isDone();
} }
void AvoidPlayerGoal::start() void AvoidPlayerGoal::start() {
{
pathNav->moveTo(path, walkSpeed); pathNav->moveTo(path, walkSpeed);
path = NULL; path = NULL;
} }
void AvoidPlayerGoal::stop() void AvoidPlayerGoal::stop() { toAvoid = std::weak_ptr<Entity>(); }
{
toAvoid = std::weak_ptr<Entity>();
}
void AvoidPlayerGoal::tick() void AvoidPlayerGoal::tick() {
{ if (mob->distanceToSqr(toAvoid.lock()) < 7 * 7)
if (mob->distanceToSqr(toAvoid.lock()) < 7 * 7) mob->getNavigation()->setSpeed(sprintSpeed); mob->getNavigation()->setSpeed(sprintSpeed);
else mob->getNavigation()->setSpeed(walkSpeed); else
mob->getNavigation()->setSpeed(walkSpeed);
} }

View file

@ -6,8 +6,7 @@ class PathNavigation;
class PathfinderMob; class PathfinderMob;
class Path; class Path;
class AvoidPlayerGoal : public Goal class AvoidPlayerGoal : public Goal {
{
private: private:
PathfinderMob* mob; // Owner of this goal PathfinderMob* mob; // Owner of this goal
float walkSpeed, sprintSpeed; float walkSpeed, sprintSpeed;
@ -18,7 +17,8 @@ private:
const std::type_info& avoidType; const std::type_info& avoidType;
public: public:
AvoidPlayerGoal(PathfinderMob *mob, const std::type_info& avoidType, float maxDist, float walkSpeed, float sprintSpeed); AvoidPlayerGoal(PathfinderMob* mob, const std::type_info& avoidType,
float maxDist, float walkSpeed, float sprintSpeed);
~AvoidPlayerGoal(); ~AvoidPlayerGoal();
virtual bool canUse(); virtual bool canUse();

View file

@ -6,8 +6,7 @@
#include "../../Headers/net.minecraft.world.item.h" #include "../../Headers/net.minecraft.world.item.h"
#include "BegGoal.h" #include "BegGoal.h"
BegGoal::BegGoal(Wolf *wolf, float lookDistance) BegGoal::BegGoal(Wolf* wolf, float lookDistance) {
{
player = std::weak_ptr<Player>(); player = std::weak_ptr<Player>();
lookTime = 0; lookTime = 0;
@ -17,42 +16,40 @@ BegGoal::BegGoal(Wolf *wolf, float lookDistance)
setRequiredControlFlags(Control::LookControlFlag); setRequiredControlFlags(Control::LookControlFlag);
} }
bool BegGoal::canUse() bool BegGoal::canUse() {
{ player = std::weak_ptr<Player>(
player = std::weak_ptr<Player>(level->getNearestPlayer(wolf->shared_from_this(), lookDistance)); level->getNearestPlayer(wolf->shared_from_this(), lookDistance));
if (player.lock() == NULL) return false; if (player.lock() == NULL) return false;
wolf->setDespawnProtected(); wolf->setDespawnProtected();
return playerHoldingInteresting(player.lock()); return playerHoldingInteresting(player.lock());
} }
bool BegGoal::canContinueToUse() bool BegGoal::canContinueToUse() {
{
if (player.lock() == NULL || !player.lock()->isAlive()) return false; if (player.lock() == NULL || !player.lock()->isAlive()) return false;
if (wolf->distanceToSqr(player.lock()) > lookDistance * lookDistance) return false; if (wolf->distanceToSqr(player.lock()) > lookDistance * lookDistance)
return false;
wolf->setDespawnProtected(); wolf->setDespawnProtected();
return lookTime > 0 && playerHoldingInteresting(player.lock()); return lookTime > 0 && playerHoldingInteresting(player.lock());
} }
void BegGoal::start() void BegGoal::start() {
{
wolf->setIsInterested(true); wolf->setIsInterested(true);
lookTime = 40 + wolf->getRandom()->nextInt(40); lookTime = 40 + wolf->getRandom()->nextInt(40);
} }
void BegGoal::stop() void BegGoal::stop() {
{
wolf->setIsInterested(false); wolf->setIsInterested(false);
player = std::weak_ptr<Player>(); player = std::weak_ptr<Player>();
} }
void BegGoal::tick() void BegGoal::tick() {
{ wolf->getLookControl()->setLookAt(
wolf->getLookControl()->setLookAt(player.lock()->x, player.lock()->y + player.lock()->getHeadHeight(), player.lock()->z, 10, wolf->getMaxHeadXRot()); player.lock()->x, player.lock()->y + player.lock()->getHeadHeight(),
player.lock()->z, 10, wolf->getMaxHeadXRot());
--lookTime; --lookTime;
} }
bool BegGoal::playerHoldingInteresting(std::shared_ptr<Player> player) bool BegGoal::playerHoldingInteresting(std::shared_ptr<Player> player) {
{
std::shared_ptr<ItemInstance> item = player->inventory->getSelected(); std::shared_ptr<ItemInstance> item = player->inventory->getSelected();
if (item == NULL) return false; if (item == NULL) return false;
if (!wolf->isTame() && item->id == Item::bone_Id) return true; if (!wolf->isTame() && item->id == Item::bone_Id) return true;

View file

@ -4,8 +4,7 @@
class Wolf; class Wolf;
class BegGoal : public Goal class BegGoal : public Goal {
{
private: private:
Wolf* wolf; // Owner of this goal Wolf* wolf; // Owner of this goal
std::weak_ptr<Player> player; std::weak_ptr<Player> player;
@ -26,6 +25,7 @@ private:
bool playerHoldingInteresting(std::shared_ptr<Player> player); bool playerHoldingInteresting(std::shared_ptr<Player> player);
public: public:
// 4J Added override to update ai elements when loading entity from schematics // 4J Added override to update ai elements when loading entity from
// schematics
virtual void setLevel(Level* level) { this->level = level; } virtual void setLevel(Level* level) { this->level = level; }
}; };

View file

@ -6,60 +6,55 @@
#include "../../Util/SharedConstants.h" #include "../../Util/SharedConstants.h"
#include "BreakDoorGoal.h" #include "BreakDoorGoal.h"
BreakDoorGoal::BreakDoorGoal(Mob *mob) : DoorInteractGoal(mob) BreakDoorGoal::BreakDoorGoal(Mob* mob) : DoorInteractGoal(mob) {
{
breakTime = 0; breakTime = 0;
lastBreakProgress = -1; lastBreakProgress = -1;
} }
bool BreakDoorGoal::canUse() bool BreakDoorGoal::canUse() {
{
if (!DoorInteractGoal::canUse()) return false; if (!DoorInteractGoal::canUse()) return false;
return !doorTile->isOpen(mob->level, doorX, doorY, doorZ); return !doorTile->isOpen(mob->level, doorX, doorY, doorZ);
} }
void BreakDoorGoal::start() void BreakDoorGoal::start() {
{
DoorInteractGoal::start(); DoorInteractGoal::start();
breakTime = 0; breakTime = 0;
} }
bool BreakDoorGoal::canContinueToUse() bool BreakDoorGoal::canContinueToUse() {
{
double d = mob->distanceToSqr(doorX, doorY, doorZ); double d = mob->distanceToSqr(doorX, doorY, doorZ);
return breakTime <= DOOR_BREAK_TIME && !doorTile->isOpen(mob->level, doorX, doorY, doorZ) && d < 2 * 2; return breakTime <= DOOR_BREAK_TIME &&
!doorTile->isOpen(mob->level, doorX, doorY, doorZ) && d < 2 * 2;
} }
void BreakDoorGoal::stop() void BreakDoorGoal::stop() {
{
DoorInteractGoal::stop(); DoorInteractGoal::stop();
mob->level->destroyTileProgress(mob->entityId, doorX, doorY, doorZ, -1); mob->level->destroyTileProgress(mob->entityId, doorX, doorY, doorZ, -1);
} }
void BreakDoorGoal::tick() void BreakDoorGoal::tick() {
{
DoorInteractGoal::tick(); DoorInteractGoal::tick();
if (mob->getRandom()->nextInt(20) == 0) if (mob->getRandom()->nextInt(20) == 0) {
{ mob->level->levelEvent(LevelEvent::SOUND_ZOMBIE_WOODEN_DOOR, doorX,
mob->level->levelEvent(LevelEvent::SOUND_ZOMBIE_WOODEN_DOOR, doorX, doorY, doorZ, 0); doorY, doorZ, 0);
} }
breakTime++; breakTime++;
int progress = (int)(breakTime / (float)DOOR_BREAK_TIME * 10); int progress = (int)(breakTime / (float)DOOR_BREAK_TIME * 10);
if (progress != lastBreakProgress) if (progress != lastBreakProgress) {
{ mob->level->destroyTileProgress(mob->entityId, doorX, doorY, doorZ,
mob->level->destroyTileProgress(mob->entityId, doorX, doorY, doorZ, progress); progress);
lastBreakProgress = progress; lastBreakProgress = progress;
} }
if (breakTime == DOOR_BREAK_TIME) if (breakTime == DOOR_BREAK_TIME) {
{ if (mob->level->difficulty == Difficulty::HARD) {
if (mob->level->difficulty == Difficulty::HARD)
{
mob->level->setTile(doorX, doorY, doorZ, 0); mob->level->setTile(doorX, doorY, doorZ, 0);
mob->level->levelEvent(LevelEvent::SOUND_ZOMBIE_DOOR_CRASH, doorX, doorY, doorZ, 0); mob->level->levelEvent(LevelEvent::SOUND_ZOMBIE_DOOR_CRASH, doorX,
mob->level->levelEvent(LevelEvent::PARTICLES_DESTROY_BLOCK, doorX, doorY, doorZ, doorTile->id); doorY, doorZ, 0);
mob->level->levelEvent(LevelEvent::PARTICLES_DESTROY_BLOCK, doorX,
doorY, doorZ, doorTile->id);
} }
} }
} }

View file

@ -3,8 +3,7 @@
#include "DoorInteractGoal.h" #include "DoorInteractGoal.h"
#include "../../Util/SharedConstants.h" #include "../../Util/SharedConstants.h"
class BreakDoorGoal : public DoorInteractGoal class BreakDoorGoal : public DoorInteractGoal {
{
private: private:
static const int DOOR_BREAK_TIME = SharedConstants::TICKS_PER_SECOND * 12; static const int DOOR_BREAK_TIME = SharedConstants::TICKS_PER_SECOND * 12;

View file

@ -9,52 +9,48 @@
#include "../../Stats/GenericStats.h" #include "../../Stats/GenericStats.h"
BreedGoal::BreedGoal(Animal *animal, float speed) BreedGoal::BreedGoal(Animal* animal, float speed) {
{
partner = std::weak_ptr<Animal>(); partner = std::weak_ptr<Animal>();
loveTime = 0; loveTime = 0;
this->animal = animal; this->animal = animal;
this->level = animal->level; this->level = animal->level;
this->speed = speed; this->speed = speed;
setRequiredControlFlags(Control::MoveControlFlag | Control::LookControlFlag); setRequiredControlFlags(Control::MoveControlFlag |
Control::LookControlFlag);
} }
bool BreedGoal::canUse() bool BreedGoal::canUse() {
{
if (!animal->isInLove()) return false; if (!animal->isInLove()) return false;
partner = std::weak_ptr<Animal>(getFreePartner()); partner = std::weak_ptr<Animal>(getFreePartner());
return partner.lock() != NULL; return partner.lock() != NULL;
} }
bool BreedGoal::canContinueToUse() bool BreedGoal::canContinueToUse() {
{ return partner.lock() != NULL && partner.lock()->isAlive() &&
return partner.lock() != NULL && partner.lock()->isAlive() && partner.lock()->isInLove() && loveTime < 20 * 3; partner.lock()->isInLove() && loveTime < 20 * 3;
} }
void BreedGoal::stop() void BreedGoal::stop() {
{
partner = std::weak_ptr<Animal>(); partner = std::weak_ptr<Animal>();
loveTime = 0; loveTime = 0;
} }
void BreedGoal::tick() void BreedGoal::tick() {
{ animal->getLookControl()->setLookAt(partner.lock(), 10,
animal->getLookControl()->setLookAt(partner.lock(), 10, animal->getMaxHeadXRot()); animal->getMaxHeadXRot());
animal->getNavigation()->moveTo(partner.lock(), speed); animal->getNavigation()->moveTo(partner.lock(), speed);
++loveTime; ++loveTime;
if (loveTime == 20 * 3) breed(); if (loveTime == 20 * 3) breed();
} }
std::shared_ptr<Animal> BreedGoal::getFreePartner() std::shared_ptr<Animal> BreedGoal::getFreePartner() {
{
float r = 8; float r = 8;
std::vector<std::shared_ptr<Entity> > *others = level->getEntitiesOfClass(typeid(*animal), animal->bb->grow(r, r, r)); std::vector<std::shared_ptr<Entity> >* others =
for(AUTO_VAR(it, others->begin()); it != others->end(); ++it) level->getEntitiesOfClass(typeid(*animal), animal->bb->grow(r, r, r));
{ for (AUTO_VAR(it, others->begin()); it != others->end(); ++it) {
std::shared_ptr<Animal> p = std::dynamic_pointer_cast<Animal>(*it); std::shared_ptr<Animal> p = std::dynamic_pointer_cast<Animal>(*it);
if (animal->canMate(p)) if (animal->canMate(p)) {
{
delete others; delete others;
return p; return p;
} }
@ -63,32 +59,32 @@ std::shared_ptr<Animal> BreedGoal::getFreePartner()
return nullptr; return nullptr;
} }
void BreedGoal::breed() void BreedGoal::breed() {
{ std::shared_ptr<AgableMob> offspring =
std::shared_ptr<AgableMob> offspring = animal->getBreedOffspring(partner.lock()); animal->getBreedOffspring(partner.lock());
animal->setDespawnProtected(); animal->setDespawnProtected();
partner.lock()->setDespawnProtected(); partner.lock()->setDespawnProtected();
if (offspring == NULL) if (offspring == NULL) {
{ // This will be NULL if we've hit our limits for spawning any particular
// This will be NULL if we've hit our limits for spawning any particular type of animal... reset things as normally as we can, without actually producing any offspring // type of animal... reset things as normally as we can, without
// actually producing any offspring
animal->resetLove(); animal->resetLove();
partner.lock()->resetLove(); partner.lock()->resetLove();
return; return;
} }
std::shared_ptr<Player> loveCause = animal->getLoveCause(); std::shared_ptr<Player> loveCause = animal->getLoveCause();
if (loveCause == NULL && partner.lock()->getLoveCause() != NULL) if (loveCause == NULL && partner.lock()->getLoveCause() != NULL) {
{
loveCause = partner.lock()->getLoveCause(); loveCause = partner.lock()->getLoveCause();
} }
if (loveCause != NULL) if (loveCause != NULL) {
{
// Record mob bred stat. // Record mob bred stat.
loveCause->awardStat(GenericStats::breedEntity(offspring->GetType()),GenericStats::param_breedEntity(offspring->GetType())); loveCause->awardStat(
GenericStats::breedEntity(offspring->GetType()),
GenericStats::param_breedEntity(offspring->GetType()));
if (animal->GetType() == eTYPE_COW) if (animal->GetType() == eTYPE_COW) {
{
// loveCause->awardStat(Achievements.breedCow); // loveCause->awardStat(Achievements.breedCow);
} }
} }
@ -103,14 +99,21 @@ void BreedGoal::breed()
level->addEntity(offspring); level->addEntity(offspring);
Random* random = animal->getRandom(); Random* random = animal->getRandom();
for (int i = 0; i < 7; i++) for (int i = 0; i < 7; i++) {
{
double xa = random->nextGaussian() * 0.02; double xa = random->nextGaussian() * 0.02;
double ya = random->nextGaussian() * 0.02; double ya = random->nextGaussian() * 0.02;
double za = random->nextGaussian() * 0.02; double za = random->nextGaussian() * 0.02;
level->addParticle(eParticleType_heart, animal->x + random->nextFloat() * animal->bbWidth * 2 - animal->bbWidth, animal->y + .5f + random->nextFloat() * animal->bbHeight, animal->z + random->nextFloat() level->addParticle(
* animal->bbWidth * 2 - animal->bbWidth, xa, ya, za); eParticleType_heart,
animal->x + random->nextFloat() * animal->bbWidth * 2 -
animal->bbWidth,
animal->y + .5f + random->nextFloat() * animal->bbHeight,
animal->z + random->nextFloat() * animal->bbWidth * 2 -
animal->bbWidth,
xa, ya, za);
} }
// 4J-PB - Fix for 106869- Customer Encountered: TU12: Content: Gameplay: Breeding animals does not give any Experience Orbs. // 4J-PB - Fix for 106869- Customer Encountered: TU12: Content: Gameplay:
level->addEntity( std::shared_ptr<ExperienceOrb>( new ExperienceOrb(level, animal->x, animal->y, animal->z, random->nextInt(7) + 1) ) ); // Breeding animals does not give any Experience Orbs.
level->addEntity(std::shared_ptr<ExperienceOrb>(new ExperienceOrb(
level, animal->x, animal->y, animal->z, random->nextInt(7) + 1)));
} }

View file

@ -5,8 +5,7 @@
class Animal; class Animal;
class Level; class Level;
class BreedGoal : public Goal class BreedGoal : public Goal {
{
private: private:
Animal* animal; // Owner of this goal Animal* animal; // Owner of this goal
Level* level; Level* level;
@ -27,6 +26,7 @@ private:
void breed(); void breed();
public: public:
// 4J Added override to update ai elements when loading entity from schematics // 4J Added override to update ai elements when loading entity from
// schematics
virtual void setLevel(Level* level) { this->level = level; } virtual void setLevel(Level* level) { this->level = level; }
}; };

View file

@ -8,8 +8,8 @@
#include "../../Headers/net.minecraft.world.level.pathfinder.h" #include "../../Headers/net.minecraft.world.level.pathfinder.h"
#include "ControlledByPlayerGoal.h" #include "ControlledByPlayerGoal.h"
ControlledByPlayerGoal::ControlledByPlayerGoal(Mob *mob, float maxSpeed, float walkSpeed) ControlledByPlayerGoal::ControlledByPlayerGoal(Mob* mob, float maxSpeed,
{ float walkSpeed) {
this->mob = mob; this->mob = mob;
this->maxSpeed = maxSpeed; this->maxSpeed = maxSpeed;
this->walkSpeed = walkSpeed; this->walkSpeed = walkSpeed;
@ -17,32 +17,34 @@ ControlledByPlayerGoal::ControlledByPlayerGoal(Mob *mob, float maxSpeed, float w
boosting = false; boosting = false;
boostTime = 0; boostTime = 0;
boostTimeTotal = 0; boostTimeTotal = 0;
setRequiredControlFlags(Control::MoveControlFlag | Control::JumpControlFlag | Control::LookControlFlag); setRequiredControlFlags(Control::MoveControlFlag |
Control::JumpControlFlag |
Control::LookControlFlag);
} }
void ControlledByPlayerGoal::start() void ControlledByPlayerGoal::start() {
{
speed = 0; speed = 0;
// 4J Stu - Need to initialise this otherwise the pig will never move if you jump on before another goal has made it move and set the speed // 4J Stu - Need to initialise this otherwise the pig will never move if you
// jump on before another goal has made it move and set the speed
if (mob->getSpeed() < walkSpeed) mob->setSpeed(walkSpeed); if (mob->getSpeed() < walkSpeed) mob->setSpeed(walkSpeed);
} }
void ControlledByPlayerGoal::stop() void ControlledByPlayerGoal::stop() {
{
boosting = false; boosting = false;
speed = 0; speed = 0;
} }
bool ControlledByPlayerGoal::canUse() bool ControlledByPlayerGoal::canUse() {
{ std::shared_ptr<Player> player =
std::shared_ptr<Player> player = std::dynamic_pointer_cast<Player>( mob->rider.lock() ); std::dynamic_pointer_cast<Player>(mob->rider.lock());
return mob->isAlive() && player && (boosting || mob->canBeControlledByRider()); return mob->isAlive() && player &&
(boosting || mob->canBeControlledByRider());
} }
void ControlledByPlayerGoal::tick() void ControlledByPlayerGoal::tick() {
{ std::shared_ptr<Player> player =
std::shared_ptr<Player> player = std::dynamic_pointer_cast<Player>(mob->rider.lock()); std::dynamic_pointer_cast<Player>(mob->rider.lock());
PathfinderMob* pig = (PathfinderMob*)mob; PathfinderMob* pig = (PathfinderMob*)mob;
float yrd = Mth::wrapDegrees(player->yRot - mob->yRot) * 0.5f; float yrd = Mth::wrapDegrees(player->yRot - mob->yRot) * 0.5f;
@ -57,26 +59,24 @@ void ControlledByPlayerGoal::tick()
int y = Mth::floor(mob->y); int y = Mth::floor(mob->y);
int z = Mth::floor(mob->z); int z = Mth::floor(mob->z);
float moveSpeed = speed; float moveSpeed = speed;
if (boosting) if (boosting) {
{ if (boostTime++ > boostTimeTotal) {
if (boostTime++ > boostTimeTotal)
{
boosting = false; boosting = false;
} }
moveSpeed += moveSpeed * 1.15f * Mth::sin((float) boostTime / boostTimeTotal * PI); moveSpeed += moveSpeed * 1.15f *
Mth::sin((float)boostTime / boostTimeTotal * PI);
} }
float friction = 0.91f; float friction = 0.91f;
if (mob->onGround) if (mob->onGround) {
{
friction = 0.6f * 0.91f; friction = 0.6f * 0.91f;
int t = mob->level->getTile(x, y, z); int t = mob->level->getTile(x, y, z);
if (t > 0) if (t > 0) {
{
friction = Tile::tiles[t]->friction * 0.91f; friction = Tile::tiles[t]->friction * 0.91f;
} }
} }
float friction2 = (0.6f * 0.6f * 0.91f * 0.91f * 0.6f * 0.91f) / (friction * friction * friction); float friction2 = (0.6f * 0.6f * 0.91f * 0.91f * 0.6f * 0.91f) /
(friction * friction * friction);
float sin = Mth::sin(pig->yRot * PI / 180); float sin = Mth::sin(pig->yRot * PI / 180);
float cos = Mth::cos(pig->yRot * PI / 180); float cos = Mth::cos(pig->yRot * PI / 180);
float aproxSpeed = pig->getSpeed() * friction2; float aproxSpeed = pig->getSpeed() * friction2;
@ -86,14 +86,11 @@ void ControlledByPlayerGoal::tick()
float xa = -(normMoveSpeed * sin); float xa = -(normMoveSpeed * sin);
float za = normMoveSpeed * cos; float za = normMoveSpeed * cos;
if (Mth::abs(xa) > Mth::abs(za)) if (Mth::abs(xa) > Mth::abs(za)) {
{
if (xa < 0) xa -= mob->bbWidth / 2.0f; if (xa < 0) xa -= mob->bbWidth / 2.0f;
if (xa > 0) xa += mob->bbWidth / 2.0f; if (xa > 0) xa += mob->bbWidth / 2.0f;
za = 0; za = 0;
} } else {
else
{
xa = 0; xa = 0;
if (za < 0) za -= mob->bbWidth / 2.0f; if (za < 0) za -= mob->bbWidth / 2.0f;
if (za > 0) za += mob->bbWidth / 2.0f; if (za > 0) za += mob->bbWidth / 2.0f;
@ -102,31 +99,35 @@ void ControlledByPlayerGoal::tick()
int xt = Mth::floor(mob->x + xa); int xt = Mth::floor(mob->x + xa);
int zt = Mth::floor(mob->z + za); int zt = Mth::floor(mob->z + za);
Node *size = new Node(Mth::floor(mob->bbWidth + 1), Mth::floor(mob->bbHeight + player->bbHeight + 1), Mth::floor(mob->bbWidth + 1)); Node* size = new Node(Mth::floor(mob->bbWidth + 1),
Mth::floor(mob->bbHeight + player->bbHeight + 1),
Mth::floor(mob->bbWidth + 1));
if (x != xt || z != zt) if (x != xt || z != zt) {
{ if (PathFinder::isFree(mob, xt, y, zt, size, false, false, true) ==
if (PathFinder::isFree(mob, xt, y, zt, size, false, false, true) == PathFinder::TYPE_BLOCKED PathFinder::TYPE_BLOCKED &&
&& PathFinder::isFree(mob, x, y + 1, z, size, false, false, true) == PathFinder::TYPE_OPEN PathFinder::isFree(mob, x, y + 1, z, size, false, false, true) ==
&& PathFinder::isFree(mob, xt, y + 1, zt, size, false, false, true) == PathFinder::TYPE_OPEN) PathFinder::TYPE_OPEN &&
{ PathFinder::isFree(mob, xt, y + 1, zt, size, false, false, true) ==
PathFinder::TYPE_OPEN) {
pig->getJumpControl()->jump(); pig->getJumpControl()->jump();
} }
} }
if (!player->abilities.instabuild && speed >= maxSpeed * 0.5f && mob->getRandom()->nextFloat() < 0.006f && !boosting) if (!player->abilities.instabuild && speed >= maxSpeed * 0.5f &&
{ mob->getRandom()->nextFloat() < 0.006f && !boosting) {
std::shared_ptr<ItemInstance> carriedItem = player->getCarriedItem(); std::shared_ptr<ItemInstance> carriedItem = player->getCarriedItem();
if (carriedItem != NULL && carriedItem->id == Item::carrotOnAStick_Id) if (carriedItem != NULL && carriedItem->id == Item::carrotOnAStick_Id) {
{
carriedItem->hurt(1, player); carriedItem->hurt(1, player);
if (carriedItem->count == 0) if (carriedItem->count == 0) {
{ std::shared_ptr<ItemInstance> replacement =
std::shared_ptr<ItemInstance> replacement = std::shared_ptr<ItemInstance>(new ItemInstance(Item::fishingRod)); std::shared_ptr<ItemInstance>(
new ItemInstance(Item::fishingRod));
replacement->setTag(carriedItem->tag); replacement->setTag(carriedItem->tag);
player->inventory->items[player->inventory->selected] = replacement; player->inventory->items[player->inventory->selected] =
replacement;
} }
} }
} }
@ -134,19 +135,16 @@ void ControlledByPlayerGoal::tick()
mob->travel(0, moveSpeed); mob->travel(0, moveSpeed);
} }
bool ControlledByPlayerGoal::isBoosting() bool ControlledByPlayerGoal::isBoosting() { return boosting; }
{
return boosting;
}
void ControlledByPlayerGoal::boost() void ControlledByPlayerGoal::boost() {
{
boosting = true; boosting = true;
boostTime = 0; boostTime = 0;
boostTimeTotal = mob->getRandom()->nextInt(MAX_BOOST_TIME + MIN_BOOST_TIME + 1) + MIN_BOOST_TIME; boostTimeTotal =
mob->getRandom()->nextInt(MAX_BOOST_TIME + MIN_BOOST_TIME + 1) +
MIN_BOOST_TIME;
} }
bool ControlledByPlayerGoal::canBoost() bool ControlledByPlayerGoal::canBoost() {
{
return !isBoosting() && speed > maxSpeed * 0.3f; return !isBoosting() && speed > maxSpeed * 0.3f;
} }

View file

@ -5,8 +5,7 @@
class Mob; class Mob;
class ControlledByPlayerGoal : public Goal class ControlledByPlayerGoal : public Goal {
{
private: private:
static const int MIN_BOOST_TIME = SharedConstants::TICKS_PER_SECOND * 7; static const int MIN_BOOST_TIME = SharedConstants::TICKS_PER_SECOND * 7;
static const int MAX_BOOST_TIME = SharedConstants::TICKS_PER_SECOND * 35; static const int MAX_BOOST_TIME = SharedConstants::TICKS_PER_SECOND * 35;
@ -20,7 +19,8 @@ private:
int boostTimeTotal; int boostTimeTotal;
public: public:
ControlledByPlayerGoal(Mob *mob, float maxSpeed, float walkSpeed); // 4J Added walkSpeed param ControlledByPlayerGoal(Mob* mob, float maxSpeed,
float walkSpeed); // 4J Added walkSpeed param
void start(); void start();
void stop(); void stop();

View file

@ -3,22 +3,21 @@
#include "../../Headers/net.minecraft.world.entity.animal.h" #include "../../Headers/net.minecraft.world.entity.animal.h"
#include "DefendVillageTargetGoal.h" #include "DefendVillageTargetGoal.h"
DefendVillageTargetGoal::DefendVillageTargetGoal(VillagerGolem *golem) : TargetGoal(golem, 16, false, true) DefendVillageTargetGoal::DefendVillageTargetGoal(VillagerGolem* golem)
{ : TargetGoal(golem, 16, false, true) {
this->golem = golem; this->golem = golem;
setRequiredControlFlags(TargetGoal::TargetFlag); setRequiredControlFlags(TargetGoal::TargetFlag);
} }
bool DefendVillageTargetGoal::canUse() bool DefendVillageTargetGoal::canUse() {
{
std::shared_ptr<Village> village = golem->getVillage(); std::shared_ptr<Village> village = golem->getVillage();
if (village == NULL) return false; if (village == NULL) return false;
potentialTarget = std::weak_ptr<Mob>(village->getClosestAggressor(std::dynamic_pointer_cast<Mob>(golem->shared_from_this()))); potentialTarget = std::weak_ptr<Mob>(village->getClosestAggressor(
std::dynamic_pointer_cast<Mob>(golem->shared_from_this())));
return canAttack(potentialTarget.lock(), false); return canAttack(potentialTarget.lock(), false);
} }
void DefendVillageTargetGoal::start() void DefendVillageTargetGoal::start() {
{
golem->setTarget(potentialTarget.lock()); golem->setTarget(potentialTarget.lock());
TargetGoal::start(); TargetGoal::start();
} }

View file

@ -4,8 +4,7 @@
class VillagerGolem; class VillagerGolem;
class DefendVillageTargetGoal : public TargetGoal class DefendVillageTargetGoal : public TargetGoal {
{
private: private:
VillagerGolem* golem; // Owner of this goal VillagerGolem* golem; // Owner of this goal
std::weak_ptr<Mob> potentialTarget; std::weak_ptr<Mob> potentialTarget;

View file

@ -6,8 +6,7 @@
#include "../../Headers/net.minecraft.world.level.tile.h" #include "../../Headers/net.minecraft.world.level.tile.h"
#include "DoorInteractGoal.h" #include "DoorInteractGoal.h"
DoorInteractGoal::DoorInteractGoal(Mob *mob) DoorInteractGoal::DoorInteractGoal(Mob* mob) {
{
doorX = doorY = doorZ = 0; doorX = doorY = doorZ = 0;
doorTile = NULL; doorTile = NULL;
passed = false; passed = false;
@ -16,15 +15,14 @@ DoorInteractGoal::DoorInteractGoal(Mob *mob)
this->mob = mob; this->mob = mob;
} }
bool DoorInteractGoal::canUse() bool DoorInteractGoal::canUse() {
{
if (!mob->horizontalCollision) return false; if (!mob->horizontalCollision) return false;
PathNavigation* pathNav = mob->getNavigation(); PathNavigation* pathNav = mob->getNavigation();
Path* path = pathNav->getPath(); Path* path = pathNav->getPath();
if (path == NULL || path->isDone() || !pathNav->canOpenDoors()) return false; if (path == NULL || path->isDone() || !pathNav->canOpenDoors())
return false;
for (int i = 0; i < std::min(path->getIndex() + 2, path->getSize()); ++i) for (int i = 0; i < std::min(path->getIndex() + 2, path->getSize()); ++i) {
{
Node* n = path->get(i); Node* n = path->get(i);
doorX = n->x; doorX = n->x;
doorY = n->y + 1; doorY = n->y + 1;
@ -42,31 +40,24 @@ bool DoorInteractGoal::canUse()
return doorTile != NULL; return doorTile != NULL;
} }
bool DoorInteractGoal::canContinueToUse() bool DoorInteractGoal::canContinueToUse() { return !passed; }
{
return !passed;
}
void DoorInteractGoal::start() void DoorInteractGoal::start() {
{
passed = false; passed = false;
doorOpenDirX = (float)(doorX + 0.5f - mob->x); doorOpenDirX = (float)(doorX + 0.5f - mob->x);
doorOpenDirZ = (float)(doorZ + 0.5f - mob->z); doorOpenDirZ = (float)(doorZ + 0.5f - mob->z);
} }
void DoorInteractGoal::tick() void DoorInteractGoal::tick() {
{
float newDoorDirX = (float)(doorX + 0.5f - mob->x); float newDoorDirX = (float)(doorX + 0.5f - mob->x);
float newDoorDirZ = (float)(doorZ + 0.5f - mob->z); float newDoorDirZ = (float)(doorZ + 0.5f - mob->z);
float dot = doorOpenDirX * newDoorDirX + doorOpenDirZ * newDoorDirZ; float dot = doorOpenDirX * newDoorDirX + doorOpenDirZ * newDoorDirZ;
if (dot < 0) if (dot < 0) {
{
passed = true; passed = true;
} }
} }
DoorTile *DoorInteractGoal::getDoorTile(int x, int y, int z) DoorTile* DoorInteractGoal::getDoorTile(int x, int y, int z) {
{
int tileId = mob->level->getTile(x, y, z); int tileId = mob->level->getTile(x, y, z);
if (tileId != Tile::door_wood_Id) return NULL; if (tileId != Tile::door_wood_Id) return NULL;
return (DoorTile*)Tile::tiles[tileId]; return (DoorTile*)Tile::tiles[tileId];

View file

@ -4,8 +4,7 @@
class DoorTile; class DoorTile;
class DoorInteractGoal : public Goal class DoorInteractGoal : public Goal {
{
protected: protected:
Mob* mob; // Owner of this goal Mob* mob; // Owner of this goal
int doorX, doorY, doorZ; int doorX, doorY, doorZ;

View file

@ -6,51 +6,43 @@
#include "../../Headers/net.minecraft.world.level.tile.h" #include "../../Headers/net.minecraft.world.level.tile.h"
#include "EatTileGoal.h" #include "EatTileGoal.h"
EatTileGoal::EatTileGoal(Mob *mob) EatTileGoal::EatTileGoal(Mob* mob) {
{
eatAnimationTick = 0; eatAnimationTick = 0;
this->mob = mob; this->mob = mob;
this->level = mob->level; this->level = mob->level;
setRequiredControlFlags(Control::MoveControlFlag | Control::LookControlFlag | Control::JumpControlFlag); setRequiredControlFlags(Control::MoveControlFlag |
Control::LookControlFlag |
Control::JumpControlFlag);
} }
bool EatTileGoal::canUse() bool EatTileGoal::canUse() {
{
if (mob->getRandom()->nextInt(mob->isBaby() ? 50 : 1000) != 0) return false; if (mob->getRandom()->nextInt(mob->isBaby() ? 50 : 1000) != 0) return false;
int xx = Mth::floor(mob->x); int xx = Mth::floor(mob->x);
int yy = Mth::floor(mob->y); int yy = Mth::floor(mob->y);
int zz = Mth::floor(mob->z); int zz = Mth::floor(mob->z);
if (level->getTile(xx, yy, zz) == Tile::tallgrass_Id && level->getData(xx, yy, zz) == TallGrass::TALL_GRASS) return true; if (level->getTile(xx, yy, zz) == Tile::tallgrass_Id &&
level->getData(xx, yy, zz) == TallGrass::TALL_GRASS)
return true;
if (level->getTile(xx, yy - 1, zz) == Tile::grass_Id) return true; if (level->getTile(xx, yy - 1, zz) == Tile::grass_Id) return true;
return false; return false;
} }
void EatTileGoal::start() void EatTileGoal::start() {
{
eatAnimationTick = EAT_ANIMATION_TICKS; eatAnimationTick = EAT_ANIMATION_TICKS;
level->broadcastEntityEvent(mob->shared_from_this(), EntityEvent::EAT_GRASS); level->broadcastEntityEvent(mob->shared_from_this(),
EntityEvent::EAT_GRASS);
mob->getNavigation()->stop(); mob->getNavigation()->stop();
} }
void EatTileGoal::stop() void EatTileGoal::stop() { eatAnimationTick = 0; }
{
eatAnimationTick = 0;
}
bool EatTileGoal::canContinueToUse() bool EatTileGoal::canContinueToUse() { return eatAnimationTick > 0; }
{
return eatAnimationTick > 0;
}
int EatTileGoal::getEatAnimationTick() int EatTileGoal::getEatAnimationTick() { return eatAnimationTick; }
{
return eatAnimationTick;
}
void EatTileGoal::tick() void EatTileGoal::tick() {
{
eatAnimationTick = std::max(0, eatAnimationTick - 1); eatAnimationTick = std::max(0, eatAnimationTick - 1);
if (eatAnimationTick != 4) return; if (eatAnimationTick != 4) return;
@ -58,15 +50,15 @@ void EatTileGoal::tick()
int yy = Mth::floor(mob->y); int yy = Mth::floor(mob->y);
int zz = Mth::floor(mob->z); int zz = Mth::floor(mob->z);
if (level->getTile(xx, yy, zz) == Tile::tallgrass_Id) if (level->getTile(xx, yy, zz) == Tile::tallgrass_Id) {
{ level->levelEvent(LevelEvent::PARTICLES_DESTROY_BLOCK, xx, yy, zz,
level->levelEvent(LevelEvent::PARTICLES_DESTROY_BLOCK, xx, yy, zz, Tile::tallgrass_Id + (TallGrass::TALL_GRASS << Tile::TILE_NUM_SHIFT)); Tile::tallgrass_Id +
(TallGrass::TALL_GRASS << Tile::TILE_NUM_SHIFT));
level->setTile(xx, yy, zz, 0); level->setTile(xx, yy, zz, 0);
mob->ate(); mob->ate();
} } else if (level->getTile(xx, yy - 1, zz) == Tile::grass_Id) {
else if (level->getTile(xx, yy - 1, zz) == Tile::grass_Id) level->levelEvent(LevelEvent::PARTICLES_DESTROY_BLOCK, xx, yy - 1, zz,
{ Tile::grass_Id);
level->levelEvent(LevelEvent::PARTICLES_DESTROY_BLOCK, xx, yy - 1, zz, Tile::grass_Id);
level->setTile(xx, yy - 1, zz, Tile::dirt_Id); level->setTile(xx, yy - 1, zz, Tile::dirt_Id);
mob->ate(); mob->ate();
} }

View file

@ -3,11 +3,12 @@
#include "Goal.h" #include "Goal.h"
#include "../../Util/SharedConstants.h" #include "../../Util/SharedConstants.h"
// note: Mob should implement handleEntityEvent for client state, also ate to take action upon eating // note: Mob should implement handleEntityEvent for client state, also ate to
class EatTileGoal : public Goal // take action upon eating
{ class EatTileGoal : public Goal {
private: private:
static const int EAT_ANIMATION_TICKS = SharedConstants::TICKS_PER_SECOND * 2; static const int EAT_ANIMATION_TICKS =
SharedConstants::TICKS_PER_SECOND * 2;
Mob* mob; // Owner of this goal Mob* mob; // Owner of this goal
Level* level; Level* level;
@ -23,6 +24,7 @@ public:
virtual int getEatAnimationTick(); virtual int getEatAnimationTick();
virtual void tick(); virtual void tick();
// 4J Added override to update ai elements when loading entity from schematics // 4J Added override to update ai elements when loading entity from
// schematics
virtual void setLevel(Level* level) { this->level = level; } virtual void setLevel(Level* level) { this->level = level; }
}; };

View file

@ -6,19 +6,19 @@
#include "../../Headers/net.minecraft.world.phys.h" #include "../../Headers/net.minecraft.world.phys.h"
#include "FleeSunGoal.h" #include "FleeSunGoal.h"
FleeSunGoal::FleeSunGoal(PathfinderMob *mob, float speed) FleeSunGoal::FleeSunGoal(PathfinderMob* mob, float speed) {
{
this->mob = mob; this->mob = mob;
this->speed = speed; this->speed = speed;
this->level = mob->level; this->level = mob->level;
setRequiredControlFlags(Control::MoveControlFlag); setRequiredControlFlags(Control::MoveControlFlag);
} }
bool FleeSunGoal::canUse() bool FleeSunGoal::canUse() {
{
if (!level->isDay()) return false; if (!level->isDay()) return false;
if (!mob->isOnFire()) return false; if (!mob->isOnFire()) return false;
if (!level->canSeeSky(Mth::floor(mob->x), (int) mob->bb->y0, Mth::floor(mob->z))) return false; if (!level->canSeeSky(Mth::floor(mob->x), (int)mob->bb->y0,
Mth::floor(mob->z)))
return false;
Vec3* pos = getHidePos(); Vec3* pos = getHidePos();
if (pos == NULL) return false; if (pos == NULL) return false;
@ -28,25 +28,21 @@ bool FleeSunGoal::canUse()
return true; return true;
} }
bool FleeSunGoal::canContinueToUse() bool FleeSunGoal::canContinueToUse() { return !mob->getNavigation()->isDone(); }
{
return !mob->getNavigation()->isDone();
}
void FleeSunGoal::start() void FleeSunGoal::start() {
{
mob->getNavigation()->moveTo(wantedX, wantedY, wantedZ, speed); mob->getNavigation()->moveTo(wantedX, wantedY, wantedZ, speed);
} }
Vec3 *FleeSunGoal::getHidePos() Vec3* FleeSunGoal::getHidePos() {
{
Random* random = mob->getRandom(); Random* random = mob->getRandom();
for (int i = 0; i < 10; i++) for (int i = 0; i < 10; i++) {
{
int xt = Mth::floor(mob->x + random->nextInt(20) - 10); int xt = Mth::floor(mob->x + random->nextInt(20) - 10);
int yt = Mth::floor(mob->bb->y0 + random->nextInt(6) - 3); int yt = Mth::floor(mob->bb->y0 + random->nextInt(6) - 3);
int zt = Mth::floor(mob->z + random->nextInt(20) - 10); int zt = Mth::floor(mob->z + random->nextInt(20) - 10);
if (!level->canSeeSky(xt, yt, zt) && mob->getWalkTargetValue(xt, yt, zt) < 0) return Vec3::newTemp(xt, yt, zt); if (!level->canSeeSky(xt, yt, zt) &&
mob->getWalkTargetValue(xt, yt, zt) < 0)
return Vec3::newTemp(xt, yt, zt);
} }
return NULL; return NULL;
} }

View file

@ -2,8 +2,7 @@
#include "Goal.h" #include "Goal.h"
class FleeSunGoal : public Goal class FleeSunGoal : public Goal {
{
private: private:
PathfinderMob* mob; // Owner of this goal PathfinderMob* mob; // Owner of this goal
double wantedX, wantedY, wantedZ; double wantedX, wantedY, wantedZ;
@ -21,6 +20,7 @@ private:
Vec3* getHidePos(); Vec3* getHidePos();
public: public:
// 4J Added override to update ai elements when loading entity from schematics // 4J Added override to update ai elements when loading entity from
// schematics
virtual void setLevel(Level* level) { this->level = level; } virtual void setLevel(Level* level) { this->level = level; }
}; };

View file

@ -4,19 +4,14 @@
#include "../../Headers/net.minecraft.world.entity.ai.navigation.h" #include "../../Headers/net.minecraft.world.entity.ai.navigation.h"
#include "FloatGoal.h" #include "FloatGoal.h"
FloatGoal::FloatGoal(Mob *mob) FloatGoal::FloatGoal(Mob* mob) {
{
this->mob = mob; this->mob = mob;
setRequiredControlFlags(Control::JumpControlFlag); setRequiredControlFlags(Control::JumpControlFlag);
mob->getNavigation()->setCanFloat(true); mob->getNavigation()->setCanFloat(true);
} }
bool FloatGoal::canUse() bool FloatGoal::canUse() { return (mob->isInWater() || mob->isInLava()); }
{
return (mob->isInWater() || mob->isInLava());
}
void FloatGoal::tick() void FloatGoal::tick() {
{
if (mob->getRandom()->nextFloat() < 0.8f) mob->getJumpControl()->jump(); if (mob->getRandom()->nextFloat() < 0.8f) mob->getJumpControl()->jump();
} }

View file

@ -4,8 +4,7 @@
class Mob; class Mob;
class FloatGoal : public Goal class FloatGoal : public Goal {
{
private: private:
Mob* mob; Mob* mob;

View file

@ -7,8 +7,8 @@
#include "../../Headers/net.minecraft.world.phys.h" #include "../../Headers/net.minecraft.world.phys.h"
#include "FollowOwnerGoal.h" #include "FollowOwnerGoal.h"
FollowOwnerGoal::FollowOwnerGoal(TamableAnimal *tamable, float speed, float startDistance, float stopDistance) FollowOwnerGoal::FollowOwnerGoal(TamableAnimal* tamable, float speed,
{ float startDistance, float stopDistance) {
owner = std::weak_ptr<Mob>(); owner = std::weak_ptr<Mob>();
timeToRecalcPath = 0; timeToRecalcPath = 0;
oldAvoidWater = false; oldAvoidWater = false;
@ -19,64 +19,65 @@ FollowOwnerGoal::FollowOwnerGoal(TamableAnimal *tamable, float speed, float star
this->navigation = tamable->getNavigation(); this->navigation = tamable->getNavigation();
this->startDistance = startDistance; this->startDistance = startDistance;
this->stopDistance = stopDistance; this->stopDistance = stopDistance;
setRequiredControlFlags(Control::MoveControlFlag | Control::LookControlFlag); setRequiredControlFlags(Control::MoveControlFlag |
Control::LookControlFlag);
} }
bool FollowOwnerGoal::canUse() bool FollowOwnerGoal::canUse() {
{
std::shared_ptr<Mob> owner = tamable->getOwner(); std::shared_ptr<Mob> owner = tamable->getOwner();
if (owner == NULL) return false; if (owner == NULL) return false;
if (tamable->isSitting()) return false; if (tamable->isSitting()) return false;
if (tamable->distanceToSqr(owner) < startDistance * startDistance) return false; if (tamable->distanceToSqr(owner) < startDistance * startDistance)
return false;
this->owner = std::weak_ptr<Mob>(owner); this->owner = std::weak_ptr<Mob>(owner);
return true; return true;
} }
bool FollowOwnerGoal::canContinueToUse() bool FollowOwnerGoal::canContinueToUse() {
{ return owner.lock() != NULL && !navigation->isDone() &&
return owner.lock() != NULL && !navigation->isDone() && tamable->distanceToSqr(owner.lock()) > stopDistance * stopDistance && !tamable->isSitting(); tamable->distanceToSqr(owner.lock()) > stopDistance * stopDistance &&
!tamable->isSitting();
} }
void FollowOwnerGoal::start() void FollowOwnerGoal::start() {
{
timeToRecalcPath = 0; timeToRecalcPath = 0;
oldAvoidWater = tamable->getNavigation()->getAvoidWater(); oldAvoidWater = tamable->getNavigation()->getAvoidWater();
tamable->getNavigation()->setAvoidWater(false); tamable->getNavigation()->setAvoidWater(false);
} }
void FollowOwnerGoal::stop() void FollowOwnerGoal::stop() {
{
owner = std::weak_ptr<Mob>(); owner = std::weak_ptr<Mob>();
navigation->stop(); navigation->stop();
tamable->getNavigation()->setAvoidWater(oldAvoidWater); tamable->getNavigation()->setAvoidWater(oldAvoidWater);
} }
void FollowOwnerGoal::tick() void FollowOwnerGoal::tick() {
{ tamable->getLookControl()->setLookAt(owner.lock(), 10,
tamable->getLookControl()->setLookAt(owner.lock(), 10, tamable->getMaxHeadXRot()); tamable->getMaxHeadXRot());
if (tamable->isSitting()) return; if (tamable->isSitting()) return;
if (--timeToRecalcPath > 0) return; if (--timeToRecalcPath > 0) return;
timeToRecalcPath = 10; timeToRecalcPath = 10;
if (navigation->moveTo(owner.lock(), speed)) return; if (navigation->moveTo(owner.lock(), speed)) return;
if (tamable->distanceToSqr(owner.lock()) < TeleportDistance * TeleportDistance) return; if (tamable->distanceToSqr(owner.lock()) <
TeleportDistance * TeleportDistance)
return;
// find a good spawn position nearby the owner // find a good spawn position nearby the owner
int sx = Mth::floor(owner.lock()->x) - 2; int sx = Mth::floor(owner.lock()->x) - 2;
int sz = Mth::floor(owner.lock()->z) - 2; int sz = Mth::floor(owner.lock()->z) - 2;
int y = Mth::floor(owner.lock()->bb->y0); int y = Mth::floor(owner.lock()->bb->y0);
for (int x = 0; x <= 4; x++) for (int x = 0; x <= 4; x++) {
{ for (int z = 0; z <= 4; z++) {
for (int z = 0; z <= 4; z++) if (x >= 1 && z >= 1 && x <= 3 && z <= 3) {
{
if (x >= 1 && z >= 1 && x <= 3 && z <= 3)
{
continue; continue;
} }
if (level->isTopSolidBlocking(sx + x, y - 1, sz + z) && !level->isSolidBlockingTile(sx + x, y, sz + z) && !level->isSolidBlockingTile(sx + x, y + 1, sz + z)) if (level->isTopSolidBlocking(sx + x, y - 1, sz + z) &&
{ !level->isSolidBlockingTile(sx + x, y, sz + z) &&
tamable->moveTo(sx + x + .5f, y, sz + z + .5f, tamable->yRot, tamable->xRot); !level->isSolidBlockingTile(sx + x, y + 1, sz + z)) {
tamable->moveTo(sx + x + .5f, y, sz + z + .5f, tamable->yRot,
tamable->xRot);
navigation->stop(); navigation->stop();
return; return;
} }

View file

@ -5,8 +5,7 @@
class PathNavigation; class PathNavigation;
class TamableAnimal; class TamableAnimal;
class FollowOwnerGoal : public Goal class FollowOwnerGoal : public Goal {
{
public: public:
static const int TeleportDistance = 12; static const int TeleportDistance = 12;
@ -21,7 +20,8 @@ private:
bool oldAvoidWater; bool oldAvoidWater;
public: public:
FollowOwnerGoal(TamableAnimal *tamable, float speed, float startDistance, float stopDistance); FollowOwnerGoal(TamableAnimal* tamable, float speed, float startDistance,
float stopDistance);
virtual bool canUse(); virtual bool canUse();
virtual bool canContinueToUse(); virtual bool canContinueToUse();
@ -29,6 +29,7 @@ public:
virtual void stop(); virtual void stop();
virtual void tick(); virtual void tick();
// 4J Added override to update ai elements when loading entity from schematics // 4J Added override to update ai elements when loading entity from
// schematics
virtual void setLevel(Level* level) { this->level = level; } virtual void setLevel(Level* level) { this->level = level; }
}; };

View file

@ -6,24 +6,23 @@
#include "../../Util/BasicTypeContainers.h" #include "../../Util/BasicTypeContainers.h"
#include "FollowParentGoal.h" #include "FollowParentGoal.h"
FollowParentGoal::FollowParentGoal(Animal *animal, float speed) FollowParentGoal::FollowParentGoal(Animal* animal, float speed) {
{
timeToRecalcPath = 0; timeToRecalcPath = 0;
this->animal = animal; this->animal = animal;
this->speed = speed; this->speed = speed;
} }
bool FollowParentGoal::canUse() bool FollowParentGoal::canUse() {
{
if (animal->getAge() >= 0) return false; if (animal->getAge() >= 0) return false;
std::vector<std::shared_ptr<Entity> > *parents = animal->level->getEntitiesOfClass(typeid(*animal), animal->bb->grow(8, 4, 8)); std::vector<std::shared_ptr<Entity> >* parents =
animal->level->getEntitiesOfClass(typeid(*animal),
animal->bb->grow(8, 4, 8));
std::shared_ptr<Animal> closest = nullptr; std::shared_ptr<Animal> closest = nullptr;
double closestDistSqr = Double::MAX_VALUE; double closestDistSqr = Double::MAX_VALUE;
for(AUTO_VAR(it, parents->begin()); it != parents->end(); ++it) for (AUTO_VAR(it, parents->begin()); it != parents->end(); ++it) {
{
std::shared_ptr<Animal> parent = std::dynamic_pointer_cast<Animal>(*it); std::shared_ptr<Animal> parent = std::dynamic_pointer_cast<Animal>(*it);
if (parent->getAge() < 0) continue; if (parent->getAge() < 0) continue;
double distSqr = animal->distanceToSqr(parent); double distSqr = animal->distanceToSqr(parent);
@ -39,26 +38,18 @@ bool FollowParentGoal::canUse()
return true; return true;
} }
bool FollowParentGoal::canContinueToUse() bool FollowParentGoal::canContinueToUse() {
{
if (parent.lock() == NULL || !parent.lock()->isAlive()) return false; if (parent.lock() == NULL || !parent.lock()->isAlive()) return false;
double distSqr = animal->distanceToSqr(parent.lock()); double distSqr = animal->distanceToSqr(parent.lock());
if (distSqr < 3 * 3 || distSqr > 16 * 16) return false; if (distSqr < 3 * 3 || distSqr > 16 * 16) return false;
return true; return true;
} }
void FollowParentGoal::start() void FollowParentGoal::start() { timeToRecalcPath = 0; }
{
timeToRecalcPath = 0;
}
void FollowParentGoal::stop() void FollowParentGoal::stop() { parent = std::weak_ptr<Animal>(); }
{
parent = std::weak_ptr<Animal>();
}
void FollowParentGoal::tick() void FollowParentGoal::tick() {
{
if (--timeToRecalcPath > 0) return; if (--timeToRecalcPath > 0) return;
timeToRecalcPath = 10; timeToRecalcPath = 10;
animal->getNavigation()->moveTo(parent.lock(), speed); animal->getNavigation()->moveTo(parent.lock(), speed);

View file

@ -4,8 +4,7 @@
class Animal; class Animal;
class FollowParentGoal : public Goal class FollowParentGoal : public Goal {
{
private: private:
Animal* animal; // Owner of this goal Animal* animal; // Owner of this goal
std::weak_ptr<Animal> parent; std::weak_ptr<Animal> parent;

View file

@ -1,39 +1,20 @@
#include "../../Platform/stdafx.h" #include "../../Platform/stdafx.h"
#include "Goal.h" #include "Goal.h"
Goal::Goal() Goal::Goal() { _requiredControlFlags = 0; }
{
_requiredControlFlags = 0;
}
bool Goal::canContinueToUse() bool Goal::canContinueToUse() { return canUse(); }
{
return canUse();
}
bool Goal::canInterrupt() bool Goal::canInterrupt() { return true; }
{
return true;
}
void Goal::start() void Goal::start() {}
{
}
void Goal::stop() void Goal::stop() {}
{
}
void Goal::tick() void Goal::tick() {}
{
}
void Goal::setRequiredControlFlags(int requiredControlFlags) void Goal::setRequiredControlFlags(int requiredControlFlags) {
{
_requiredControlFlags = requiredControlFlags; _requiredControlFlags = requiredControlFlags;
} }
int Goal::getRequiredControlFlags() int Goal::getRequiredControlFlags() { return _requiredControlFlags; }
{
return _requiredControlFlags;
}

View file

@ -1,12 +1,12 @@
#pragma once #pragma once
class Goal class Goal {
{
private: private:
int _requiredControlFlags; int _requiredControlFlags;
protected: protected:
Goal(); Goal();
public: public:
virtual ~Goal() {} virtual ~Goal() {}
virtual bool canUse() = 0; virtual bool canUse() = 0;
@ -18,6 +18,7 @@ public:
virtual void setRequiredControlFlags(int requiredControlFlags); virtual void setRequiredControlFlags(int requiredControlFlags);
virtual int getRequiredControlFlags(); virtual int getRequiredControlFlags();
// 4J Added override to update ai elements when loading entity from schematics // 4J Added override to update ai elements when loading entity from
// schematics
virtual void setLevel(Level* level) {}; virtual void setLevel(Level* level) {};
}; };

View file

@ -2,57 +2,50 @@
#include "Goal.h" #include "Goal.h"
#include "GoalSelector.h" #include "GoalSelector.h"
GoalSelector::InternalGoal::InternalGoal(int prio, Goal* goal,
GoalSelector::InternalGoal::InternalGoal(int prio, Goal *goal, bool canDeletePointer) bool canDeletePointer) {
{
this->prio = prio; this->prio = prio;
this->goal = goal; this->goal = goal;
this->canDeletePointer = canDeletePointer; this->canDeletePointer = canDeletePointer;
} }
GoalSelector::GoalSelector() GoalSelector::GoalSelector() {
{
tickCount = 0; tickCount = 0;
newGoalRate = 3; newGoalRate = 3;
} }
GoalSelector::~GoalSelector() GoalSelector::~GoalSelector() {
{ for (AUTO_VAR(it, goals.begin()); it != goals.end(); ++it) {
for(AUTO_VAR(it, goals.begin()); it != goals.end(); ++it)
{
if ((*it)->canDeletePointer) delete (*it)->goal; if ((*it)->canDeletePointer) delete (*it)->goal;
delete (*it); delete (*it);
} }
} }
void GoalSelector::addGoal(int prio, Goal *goal, bool canDeletePointer /*= true*/) // 4J Added canDelete param void GoalSelector::addGoal(
int prio, Goal* goal,
bool canDeletePointer /*= true*/) // 4J Added canDelete param
{ {
goals.push_back(new InternalGoal(prio, goal, canDeletePointer)); goals.push_back(new InternalGoal(prio, goal, canDeletePointer));
} }
void GoalSelector::tick() void GoalSelector::tick() {
{
std::vector<InternalGoal*> toStart; std::vector<InternalGoal*> toStart;
if(tickCount++ % newGoalRate == 0) if (tickCount++ % newGoalRate == 0) {
{
// for (InternalGoal ig : goals) // for (InternalGoal ig : goals)
for(AUTO_VAR(it, goals.begin()); it != goals.end(); ++it) for (AUTO_VAR(it, goals.begin()); it != goals.end(); ++it) {
{
InternalGoal* ig = *it; InternalGoal* ig = *it;
// bool isUsing = usingGoals.contains(ig); // bool isUsing = usingGoals.contains(ig);
AUTO_VAR(usingIt, find(usingGoals.begin(), usingGoals.end(), ig)); AUTO_VAR(usingIt, find(usingGoals.begin(), usingGoals.end(), ig));
// if (isUsing) // if (isUsing)
if(usingIt != usingGoals.end()) if (usingIt != usingGoals.end()) {
{ if (!canUseInSystem(ig) || !canContinueToUse(ig)) {
if (!canUseInSystem(ig) || !canContinueToUse(ig))
{
ig->goal->stop(); ig->goal->stop();
// usingGoals.remove(ig); // usingGoals.remove(ig);
usingGoals.erase(usingIt); usingGoals.erase(usingIt);
} } else
else continue; continue;
} }
if (!canUseInSystem(ig) || !ig->goal->canUse()) continue; if (!canUseInSystem(ig) || !ig->goal->canUse()) continue;
@ -60,87 +53,72 @@ void GoalSelector::tick()
toStart.push_back(ig); toStart.push_back(ig);
usingGoals.push_back(ig); usingGoals.push_back(ig);
} }
} } else {
else for (AUTO_VAR(it, usingGoals.begin()); it != usingGoals.end();) {
{
for(AUTO_VAR(it, usingGoals.begin() ); it != usingGoals.end(); )
{
InternalGoal* ig = *it; InternalGoal* ig = *it;
if (!ig->goal->canContinueToUse()) if (!ig->goal->canContinueToUse()) {
{
ig->goal->stop(); ig->goal->stop();
it = usingGoals.erase(it); it = usingGoals.erase(it);
} } else {
else
{
++it; ++it;
} }
} }
} }
// bool debug = false; // bool debug = false;
// if (debug && toStart.size() > 0) System.out.println("Starting: "); // if (debug && toStart.size() > 0) System.out.println("Starting: ");
// for (InternalGoal ig : toStart) // for (InternalGoal ig : toStart)
for(AUTO_VAR(it, toStart.begin()); it != toStart.end(); ++it) for (AUTO_VAR(it, toStart.begin()); it != toStart.end(); ++it) {
{
// if (debug) System.out.println(ig.goal.toString() + ", "); // if (debug) System.out.println(ig.goal.toString() + ", ");
(*it)->goal->start(); (*it)->goal->start();
} }
// if (debug && usingGoals.size() > 0) System.out.println("Running: "); // if (debug && usingGoals.size() > 0) System.out.println("Running: ");
// for (InternalGoal ig : usingGoals) // for (InternalGoal ig : usingGoals)
for(AUTO_VAR(it, usingGoals.begin()); it != usingGoals.end(); ++it) for (AUTO_VAR(it, usingGoals.begin()); it != usingGoals.end(); ++it) {
{
// if (debug) System.out.println(ig.goal.toString()); // if (debug) System.out.println(ig.goal.toString());
(*it)->goal->tick(); (*it)->goal->tick();
} }
} }
std::vector<GoalSelector::InternalGoal *> *GoalSelector::getRunningGoals() std::vector<GoalSelector::InternalGoal*>* GoalSelector::getRunningGoals() {
{
return &usingGoals; return &usingGoals;
} }
bool GoalSelector::canContinueToUse(InternalGoal *ig) bool GoalSelector::canContinueToUse(InternalGoal* ig) {
{
return ig->goal->canContinueToUse(); return ig->goal->canContinueToUse();
} }
bool GoalSelector::canUseInSystem(GoalSelector::InternalGoal *goal) bool GoalSelector::canUseInSystem(GoalSelector::InternalGoal* goal) {
{
// for (InternalGoal ig : goals) // for (InternalGoal ig : goals)
for(AUTO_VAR(it, goals.begin()); it != goals.end(); ++it) for (AUTO_VAR(it, goals.begin()); it != goals.end(); ++it) {
{
InternalGoal* ig = *it; InternalGoal* ig = *it;
if (ig == goal) continue; if (ig == goal) continue;
AUTO_VAR(usingIt, find(usingGoals.begin(), usingGoals.end(), ig)); AUTO_VAR(usingIt, find(usingGoals.begin(), usingGoals.end(), ig));
if (goal->prio >= ig->prio) if (goal->prio >= ig->prio) {
{ if (usingIt != usingGoals.end() && !canCoExist(goal, ig))
if (usingIt != usingGoals.end() && !canCoExist(goal, ig)) return false; return false;
} } else if (usingIt != usingGoals.end() && !ig->goal->canInterrupt())
else if (usingIt != usingGoals.end() && !ig->goal->canInterrupt()) return false; return false;
} }
return true; return true;
} }
bool GoalSelector::canCoExist(GoalSelector::InternalGoal *goalA, GoalSelector::InternalGoal *goalB) bool GoalSelector::canCoExist(GoalSelector::InternalGoal* goalA,
{ GoalSelector::InternalGoal* goalB) {
return (goalA->goal->getRequiredControlFlags() & goalB->goal->getRequiredControlFlags()) == 0; return (goalA->goal->getRequiredControlFlags() &
goalB->goal->getRequiredControlFlags()) == 0;
} }
void GoalSelector::setNewGoalRate(int newGoalRate) void GoalSelector::setNewGoalRate(int newGoalRate) {
{
this->newGoalRate = newGoalRate; this->newGoalRate = newGoalRate;
} }
void GoalSelector::setLevel(Level *level) void GoalSelector::setLevel(Level* level) {
{ for (AUTO_VAR(it, goals.begin()); it != goals.end(); ++it) {
for(AUTO_VAR(it, goals.begin()); it != goals.end(); ++it)
{
InternalGoal* ig = *it; InternalGoal* ig = *it;
ig->goal->setLevel(level); ig->goal->setLevel(level);
} }

View file

@ -1,13 +1,10 @@
#pragma once #pragma once
class Goal; class Goal;
class GoalSelector class GoalSelector {
{
private: private:
class InternalGoal class InternalGoal {
{
public: public:
// 4J Added canDelete param // 4J Added canDelete param
InternalGoal(int prio, Goal* goal, bool canDeletePointer); InternalGoal(int prio, Goal* goal, bool canDeletePointer);
@ -40,6 +37,7 @@ private:
public: public:
void setNewGoalRate(int newGoalRate); void setNewGoalRate(int newGoalRate);
// 4J Added override to update ai elements when loading entity from schematics // 4J Added override to update ai elements when loading entity from
// schematics
void setLevel(Level* level); void setLevel(Level* level);
}; };

View file

@ -4,27 +4,27 @@
#include "../../Headers/net.minecraft.world.level.h" #include "../../Headers/net.minecraft.world.level.h"
#include "HurtByTargetGoal.h" #include "HurtByTargetGoal.h"
HurtByTargetGoal::HurtByTargetGoal(Mob *mob, bool alertSameType) : TargetGoal(mob, 16, false) HurtByTargetGoal::HurtByTargetGoal(Mob* mob, bool alertSameType)
{ : TargetGoal(mob, 16, false) {
this->alertSameType = alertSameType; this->alertSameType = alertSameType;
setRequiredControlFlags(TargetGoal::TargetFlag); setRequiredControlFlags(TargetGoal::TargetFlag);
} }
bool HurtByTargetGoal::canUse() bool HurtByTargetGoal::canUse() {
{
return canAttack(mob->getLastHurtByMob(), false); return canAttack(mob->getLastHurtByMob(), false);
} }
void HurtByTargetGoal::start() void HurtByTargetGoal::start() {
{
mob->setTarget(mob->getLastHurtByMob()); mob->setTarget(mob->getLastHurtByMob());
oldHurtByMob = mob->getLastHurtByMob(); oldHurtByMob = mob->getLastHurtByMob();
if (alertSameType) if (alertSameType) {
{ std::vector<std::shared_ptr<Entity> >* nearby =
std::vector<std::shared_ptr<Entity> > *nearby = mob->level->getEntitiesOfClass(typeid(*mob), AABB::newTemp(mob->x, mob->y, mob->z, mob->x + 1, mob->y + 1, mob->z + 1)->grow(within, 4, within)); mob->level->getEntitiesOfClass(
for(AUTO_VAR(it, nearby->begin()); it != nearby->end(); ++it) typeid(*mob), AABB::newTemp(mob->x, mob->y, mob->z, mob->x + 1,
{ mob->y + 1, mob->z + 1)
->grow(within, 4, within));
for (AUTO_VAR(it, nearby->begin()); it != nearby->end(); ++it) {
std::shared_ptr<Mob> other = std::dynamic_pointer_cast<Mob>(*it); std::shared_ptr<Mob> other = std::dynamic_pointer_cast<Mob>(*it);
if (this->mob->shared_from_this() == other) continue; if (this->mob->shared_from_this() == other) continue;
if (other->getTarget() != NULL) continue; if (other->getTarget() != NULL) continue;
@ -36,10 +36,9 @@ void HurtByTargetGoal::start()
TargetGoal::start(); TargetGoal::start();
} }
void HurtByTargetGoal::tick() void HurtByTargetGoal::tick() {
{ if (mob->getLastHurtByMob() != NULL &&
if (mob->getLastHurtByMob() != NULL && mob->getLastHurtByMob() != oldHurtByMob) mob->getLastHurtByMob() != oldHurtByMob) {
{
this->start(); this->start();
} }
} }

View file

@ -2,8 +2,7 @@
#include "TargetGoal.h" #include "TargetGoal.h"
class HurtByTargetGoal : public TargetGoal class HurtByTargetGoal : public TargetGoal {
{
private: private:
bool alertSameType; bool alertSameType;
std::shared_ptr<Mob> oldHurtByMob; std::shared_ptr<Mob> oldHurtByMob;

View file

@ -2,12 +2,16 @@
#include "../../Headers/net.minecraft.world.entity.ai.control.h" #include "../../Headers/net.minecraft.world.entity.ai.control.h"
#include "InteractGoal.h" #include "InteractGoal.h"
InteractGoal::InteractGoal(Mob *mob, const std::type_info& lookAtType, float lookDistance) : LookAtPlayerGoal(mob, lookAtType, lookDistance) InteractGoal::InteractGoal(Mob* mob, const std::type_info& lookAtType,
{ float lookDistance)
setRequiredControlFlags(Control::LookControlFlag | Control::MoveControlFlag); : LookAtPlayerGoal(mob, lookAtType, lookDistance) {
setRequiredControlFlags(Control::LookControlFlag |
Control::MoveControlFlag);
} }
InteractGoal::InteractGoal(Mob *mob, const std::type_info& lookAtType, float lookDistance, float probability) : LookAtPlayerGoal(mob, lookAtType, lookDistance, probability) InteractGoal::InteractGoal(Mob* mob, const std::type_info& lookAtType,
{ float lookDistance, float probability)
setRequiredControlFlags(Control::LookControlFlag | Control::MoveControlFlag); : LookAtPlayerGoal(mob, lookAtType, lookDistance, probability) {
setRequiredControlFlags(Control::LookControlFlag |
Control::MoveControlFlag);
} }

View file

@ -2,9 +2,10 @@
#include "LookAtPlayerGoal.h" #include "LookAtPlayerGoal.h"
class InteractGoal : public LookAtPlayerGoal class InteractGoal : public LookAtPlayerGoal {
{
public: public:
InteractGoal(Mob *mob, const std::type_info& lookAtType, float lookDistance); InteractGoal(Mob* mob, const std::type_info& lookAtType,
InteractGoal(Mob *mob, const std::type_info& lookAtType, float lookDistance, float probability); float lookDistance);
InteractGoal(Mob* mob, const std::type_info& lookAtType, float lookDistance,
float probability);
}; };

View file

@ -3,17 +3,16 @@
#include "../../Headers/net.minecraft.world.entity.h" #include "../../Headers/net.minecraft.world.entity.h"
#include "LeapAtTargetGoal.h" #include "LeapAtTargetGoal.h"
LeapAtTargetGoal::LeapAtTargetGoal(Mob *mob, float yd) LeapAtTargetGoal::LeapAtTargetGoal(Mob* mob, float yd) {
{
target = std::weak_ptr<Mob>(); target = std::weak_ptr<Mob>();
this->mob = mob; this->mob = mob;
this->yd = yd; this->yd = yd;
setRequiredControlFlags(Control::JumpControlFlag | Control::MoveControlFlag); setRequiredControlFlags(Control::JumpControlFlag |
Control::MoveControlFlag);
} }
bool LeapAtTargetGoal::canUse() bool LeapAtTargetGoal::canUse() {
{
target = std::weak_ptr<Mob>(mob->getTarget()); target = std::weak_ptr<Mob>(mob->getTarget());
if (target.lock() == NULL) return false; if (target.lock() == NULL) return false;
double d = mob->distanceToSqr(target.lock()); double d = mob->distanceToSqr(target.lock());
@ -23,13 +22,11 @@ bool LeapAtTargetGoal::canUse()
return true; return true;
} }
bool LeapAtTargetGoal::canContinueToUse() bool LeapAtTargetGoal::canContinueToUse() {
{
return target.lock() != NULL && !mob->onGround; return target.lock() != NULL && !mob->onGround;
} }
void LeapAtTargetGoal::start() void LeapAtTargetGoal::start() {
{
// TODO: move to control? // TODO: move to control?
double xdd = target.lock()->x - mob->x; double xdd = target.lock()->x - mob->x;
double zdd = target.lock()->z - mob->z; double zdd = target.lock()->z - mob->z;

View file

@ -2,8 +2,7 @@
#include "Goal.h" #include "Goal.h"
class LeapAtTargetGoal : public Goal class LeapAtTargetGoal : public Goal {
{
private: private:
Mob* mob; // Owner of this goal Mob* mob; // Owner of this goal
std::weak_ptr<Mob> target; std::weak_ptr<Mob> target;

View file

@ -5,8 +5,9 @@
#include "../../Headers/net.minecraft.world.phys.h" #include "../../Headers/net.minecraft.world.phys.h"
#include "LookAtPlayerGoal.h" #include "LookAtPlayerGoal.h"
LookAtPlayerGoal::LookAtPlayerGoal(Mob *mob, const std::type_info& lookAtType, float lookDistance) : lookAtType(lookAtType) LookAtPlayerGoal::LookAtPlayerGoal(Mob* mob, const std::type_info& lookAtType,
{ float lookDistance)
: lookAtType(lookAtType) {
this->mob = mob; this->mob = mob;
this->lookDistance = lookDistance; this->lookDistance = lookDistance;
this->probability = 0.02f; this->probability = 0.02f;
@ -15,8 +16,9 @@ LookAtPlayerGoal::LookAtPlayerGoal(Mob *mob, const std::type_info& lookAtType, f
lookTime = 0; lookTime = 0;
} }
LookAtPlayerGoal::LookAtPlayerGoal(Mob *mob, const std::type_info& lookAtType, float lookDistance, float probability) : lookAtType(lookAtType) LookAtPlayerGoal::LookAtPlayerGoal(Mob* mob, const std::type_info& lookAtType,
{ float lookDistance, float probability)
: lookAtType(lookAtType) {
this->mob = mob; this->mob = mob;
this->lookDistance = lookDistance; this->lookDistance = lookDistance;
this->probability = probability; this->probability = probability;
@ -25,33 +27,34 @@ LookAtPlayerGoal::LookAtPlayerGoal(Mob *mob, const std::type_info& lookAtType, f
lookTime = 0; lookTime = 0;
} }
bool LookAtPlayerGoal::canUse() bool LookAtPlayerGoal::canUse() {
{
if (mob->getRandom()->nextFloat() >= probability) return false; if (mob->getRandom()->nextFloat() >= probability) return false;
if (lookAtType == typeid(Player)) lookAt = mob->level->getNearestPlayer(mob->shared_from_this(), lookDistance); if (lookAtType == typeid(Player))
else lookAt = std::weak_ptr<Entity>(mob->level->getClosestEntityOfClass(lookAtType, mob->bb->grow(lookDistance, 3, lookDistance), mob->shared_from_this())); lookAt =
mob->level->getNearestPlayer(mob->shared_from_this(), lookDistance);
else
lookAt = std::weak_ptr<Entity>(mob->level->getClosestEntityOfClass(
lookAtType, mob->bb->grow(lookDistance, 3, lookDistance),
mob->shared_from_this()));
return lookAt.lock() != NULL; return lookAt.lock() != NULL;
} }
bool LookAtPlayerGoal::canContinueToUse() bool LookAtPlayerGoal::canContinueToUse() {
{
if (lookAt.lock() == NULL || !lookAt.lock()->isAlive()) return false; if (lookAt.lock() == NULL || !lookAt.lock()->isAlive()) return false;
if (mob->distanceToSqr(lookAt.lock()) > lookDistance * lookDistance) return false; if (mob->distanceToSqr(lookAt.lock()) > lookDistance * lookDistance)
return false;
return lookTime > 0; return lookTime > 0;
} }
void LookAtPlayerGoal::start() void LookAtPlayerGoal::start() {
{
lookTime = 40 + mob->getRandom()->nextInt(40); lookTime = 40 + mob->getRandom()->nextInt(40);
} }
void LookAtPlayerGoal::stop() void LookAtPlayerGoal::stop() { lookAt = std::weak_ptr<Entity>(); }
{
lookAt = std::weak_ptr<Entity>();
}
void LookAtPlayerGoal::tick() void LookAtPlayerGoal::tick() {
{ mob->getLookControl()->setLookAt(
mob->getLookControl()->setLookAt(lookAt.lock()->x, lookAt.lock()->y + lookAt.lock()->getHeadHeight(), lookAt.lock()->z, 10, mob->getMaxHeadXRot()); lookAt.lock()->x, lookAt.lock()->y + lookAt.lock()->getHeadHeight(),
lookAt.lock()->z, 10, mob->getMaxHeadXRot());
--lookTime; --lookTime;
} }

View file

@ -5,8 +5,7 @@
class Mob; class Mob;
class Level; class Level;
class LookAtPlayerGoal : public Goal class LookAtPlayerGoal : public Goal {
{
private: private:
Mob* mob; // Owner of this goal Mob* mob; // Owner of this goal
@ -20,8 +19,10 @@ private:
const std::type_info& lookAtType; const std::type_info& lookAtType;
public: public:
LookAtPlayerGoal(Mob *mob, const std::type_info& lookAtType, float lookDistance); LookAtPlayerGoal(Mob* mob, const std::type_info& lookAtType,
LookAtPlayerGoal(Mob *mob, const std::type_info& lookAtType, float lookDistance, float probability); float lookDistance);
LookAtPlayerGoal(Mob* mob, const std::type_info& lookAtType,
float lookDistance, float probability);
virtual ~LookAtPlayerGoal() {} virtual ~LookAtPlayerGoal() {}
virtual bool canUse(); virtual bool canUse();

View file

@ -3,16 +3,15 @@
#include "../../Headers/net.minecraft.world.entity.npc.h" #include "../../Headers/net.minecraft.world.entity.npc.h"
#include "LookAtTradingPlayerGoal.h" #include "LookAtTradingPlayerGoal.h"
LookAtTradingPlayerGoal::LookAtTradingPlayerGoal(Villager *villager) : LookAtPlayerGoal((Mob *)villager, typeid(Player), 8) LookAtTradingPlayerGoal::LookAtTradingPlayerGoal(Villager* villager)
{ : LookAtPlayerGoal((Mob*)villager, typeid(Player), 8) {
this->villager = villager; this->villager = villager;
} }
bool LookAtTradingPlayerGoal::canUse() bool LookAtTradingPlayerGoal::canUse() {
{ if (villager->isTrading()) {
if (villager->isTrading()) lookAt = std::weak_ptr<Entity>(
{ std::dynamic_pointer_cast<Entity>(villager->getTradingPlayer()));
lookAt = std::weak_ptr<Entity>(std::dynamic_pointer_cast<Entity>(villager->getTradingPlayer()));
return true; return true;
} }
return false; return false;

View file

@ -4,8 +4,7 @@
class Villager; class Villager;
class LookAtTradingPlayerGoal : public LookAtPlayerGoal class LookAtTradingPlayerGoal : public LookAtPlayerGoal {
{
private: private:
Villager* villager; // This is the owner of this goal Villager* villager; // This is the owner of this goal

View file

@ -8,73 +8,71 @@
#include "../../Headers/net.minecraft.world.phys.h" #include "../../Headers/net.minecraft.world.phys.h"
#include "MakeLoveGoal.h" #include "MakeLoveGoal.h"
MakeLoveGoal::MakeLoveGoal(Villager *villager) MakeLoveGoal::MakeLoveGoal(Villager* villager) {
{
village = std::weak_ptr<Village>(); village = std::weak_ptr<Village>();
partner = std::weak_ptr<Villager>(); partner = std::weak_ptr<Villager>();
loveMakingTime = 0; loveMakingTime = 0;
this->villager = villager; this->villager = villager;
level = villager->level; level = villager->level;
setRequiredControlFlags(Control::MoveControlFlag | Control::LookControlFlag); setRequiredControlFlags(Control::MoveControlFlag |
Control::LookControlFlag);
} }
bool MakeLoveGoal::canUse() bool MakeLoveGoal::canUse() {
{
if (villager->getAge() != 0) return false; if (villager->getAge() != 0) return false;
if (villager->getRandom()->nextInt(500) != 0) return false; if (villager->getRandom()->nextInt(500) != 0) return false;
village = level->villages->getClosestVillage(Mth::floor(villager->x), Mth::floor(villager->y), Mth::floor(villager->z), 0); village = level->villages->getClosestVillage(Mth::floor(villager->x),
Mth::floor(villager->y),
Mth::floor(villager->z), 0);
if (village.lock() == NULL) return false; if (village.lock() == NULL) return false;
if (!villageNeedsMoreVillagers()) return false; if (!villageNeedsMoreVillagers()) return false;
std::shared_ptr<Entity> mate = level->getClosestEntityOfClass(typeid(Villager), villager->bb->grow(8, 3, 8), villager->shared_from_this()); std::shared_ptr<Entity> mate = level->getClosestEntityOfClass(
typeid(Villager), villager->bb->grow(8, 3, 8),
villager->shared_from_this());
if (mate == NULL) return false; if (mate == NULL) return false;
partner = std::weak_ptr<Villager>(std::dynamic_pointer_cast<Villager>(mate)); partner =
std::weak_ptr<Villager>(std::dynamic_pointer_cast<Villager>(mate));
if (partner.lock()->getAge() != 0) return false; if (partner.lock()->getAge() != 0) return false;
return true; return true;
} }
void MakeLoveGoal::start() void MakeLoveGoal::start() {
{
loveMakingTime = 300; loveMakingTime = 300;
villager->setInLove(true); villager->setInLove(true);
} }
void MakeLoveGoal::stop() void MakeLoveGoal::stop() {
{
village = std::weak_ptr<Village>(); village = std::weak_ptr<Village>();
partner = std::weak_ptr<Villager>(); partner = std::weak_ptr<Villager>();
villager->setInLove(false); villager->setInLove(false);
} }
bool MakeLoveGoal::canContinueToUse() bool MakeLoveGoal::canContinueToUse() {
{ return partner.lock() != NULL && loveMakingTime >= 0 &&
return partner.lock() != NULL && loveMakingTime >= 0 && villageNeedsMoreVillagers() && villager->getAge() == 0; villageNeedsMoreVillagers() && villager->getAge() == 0;
} }
void MakeLoveGoal::tick() void MakeLoveGoal::tick() {
{
--loveMakingTime; --loveMakingTime;
villager->getLookControl()->setLookAt(partner.lock(), 10, 30); villager->getLookControl()->setLookAt(partner.lock(), 10, 30);
if (villager->distanceToSqr(partner.lock()) > 1.5 * 1.5) if (villager->distanceToSqr(partner.lock()) > 1.5 * 1.5) {
{
villager->getNavigation()->moveTo(partner.lock(), 0.25f); villager->getNavigation()->moveTo(partner.lock(), 0.25f);
} } else {
else
{
if (loveMakingTime == 0 && partner.lock()->isInLove()) breed(); if (loveMakingTime == 0 && partner.lock()->isInLove()) breed();
} }
if (villager->getRandom()->nextInt(35) == 0) level->broadcastEntityEvent(villager->shared_from_this(), EntityEvent::LOVE_HEARTS); if (villager->getRandom()->nextInt(35) == 0)
level->broadcastEntityEvent(villager->shared_from_this(),
EntityEvent::LOVE_HEARTS);
} }
bool MakeLoveGoal::villageNeedsMoreVillagers() bool MakeLoveGoal::villageNeedsMoreVillagers() {
{
std::shared_ptr<Village> _village = village.lock(); std::shared_ptr<Village> _village = village.lock();
if (_village == NULL) return false; if (_village == NULL) return false;
@ -84,18 +82,19 @@ bool MakeLoveGoal::villageNeedsMoreVillagers()
return _village->getPopulationSize() < idealSize; return _village->getPopulationSize() < idealSize;
} }
void MakeLoveGoal::breed() void MakeLoveGoal::breed() {
{ // 4J Stu - This sets a timer that stops these villagers from trying to
// 4J Stu - This sets a timer that stops these villagers from trying to breed again // breed again We should do this even if breeding fails due to vilalger
// We should do this even if breeding fails due to vilalger count to stop them continually trying to breed // count to stop them continually trying to breed
partner.lock()->setAge(5 * 60 * 20); partner.lock()->setAge(5 * 60 * 20);
villager->setAge(5 * 60 * 20); villager->setAge(5 * 60 * 20);
// 4J - added limit to number of animals that can be bred // 4J - added limit to number of animals that can be bred
if(level->canCreateMore( eTYPE_VILLAGER, Level::eSpawnType_Breed) ) if (level->canCreateMore(eTYPE_VILLAGER, Level::eSpawnType_Breed)) {
{ std::shared_ptr<Villager> child =
std::shared_ptr<Villager> child = std::shared_ptr<Villager>( new Villager(level) ); std::shared_ptr<Villager>(new Villager(level));
child->setAge(-20 * 60 * 20); child->setAge(-20 * 60 * 20);
child->setProfession(villager->getRandom()->nextInt(Villager::PROFESSION_MAX)); child->setProfession(
villager->getRandom()->nextInt(Villager::PROFESSION_MAX));
child->moveTo(villager->x, villager->y, villager->z, 0, 0); child->moveTo(villager->x, villager->y, villager->z, 0, 0);
level->addEntity(child); level->addEntity(child);
level->broadcastEntityEvent(child, EntityEvent::LOVE_HEARTS); level->broadcastEntityEvent(child, EntityEvent::LOVE_HEARTS);

View file

@ -5,8 +5,7 @@
class Villager; class Villager;
class Village; class Village;
class MakeLoveGoal : public Goal class MakeLoveGoal : public Goal {
{
private: private:
Villager* villager; // Owner of this goal Villager* villager; // Owner of this goal
std::weak_ptr<Villager> partner; std::weak_ptr<Villager> partner;
@ -28,6 +27,7 @@ private:
void breed(); void breed();
public: public:
// 4J Added override to update ai elements when loading entity from schematics // 4J Added override to update ai elements when loading entity from
// schematics
virtual void setLevel(Level* level) { this->level = level; } virtual void setLevel(Level* level) { this->level = level; }
}; };

View file

@ -9,79 +9,74 @@
#include "MeleeAttackGoal.h" #include "MeleeAttackGoal.h"
#include "../Navigation/Path.h" #include "../Navigation/Path.h"
void MeleeAttackGoal::_init(Mob *mob, float speed, bool trackTarget) void MeleeAttackGoal::_init(Mob* mob, float speed, bool trackTarget) {
{
this->attackType = eTYPE_NOTSET; this->attackType = eTYPE_NOTSET;
this->mob = mob; this->mob = mob;
this->level = mob->level; this->level = mob->level;
this->speed = speed; this->speed = speed;
this->trackTarget = trackTarget; this->trackTarget = trackTarget;
setRequiredControlFlags(Control::MoveControlFlag | Control::LookControlFlag); setRequiredControlFlags(Control::MoveControlFlag |
Control::LookControlFlag);
attackTime = 0; attackTime = 0;
path = NULL; path = NULL;
timeToRecalcPath = 0; timeToRecalcPath = 0;
} }
MeleeAttackGoal::MeleeAttackGoal(Mob *mob, eINSTANCEOF attackType, float speed, bool trackTarget) MeleeAttackGoal::MeleeAttackGoal(Mob* mob, eINSTANCEOF attackType, float speed,
{ bool trackTarget) {
_init(mob, speed, trackTarget); _init(mob, speed, trackTarget);
this->attackType = attackType; this->attackType = attackType;
} }
MeleeAttackGoal::MeleeAttackGoal(Mob *mob, float speed, bool trackTarget) MeleeAttackGoal::MeleeAttackGoal(Mob* mob, float speed, bool trackTarget) {
{
_init(mob, speed, trackTarget); _init(mob, speed, trackTarget);
} }
MeleeAttackGoal::~MeleeAttackGoal() MeleeAttackGoal::~MeleeAttackGoal() {
{
if (path != NULL) delete path; if (path != NULL) delete path;
} }
bool MeleeAttackGoal::canUse() bool MeleeAttackGoal::canUse() {
{
std::shared_ptr<Mob> bestTarget = mob->getTarget(); std::shared_ptr<Mob> bestTarget = mob->getTarget();
if (bestTarget == NULL) return false; if (bestTarget == NULL) return false;
if (!bestTarget->isAlive()) return false; if (!bestTarget->isAlive()) return false;
if (attackType != eTYPE_NOTSET && (attackType & bestTarget->GetType()) != attackType) return false; if (attackType != eTYPE_NOTSET &&
(attackType & bestTarget->GetType()) != attackType)
return false;
target = std::weak_ptr<Mob>(bestTarget); target = std::weak_ptr<Mob>(bestTarget);
delete path; delete path;
path = mob->getNavigation()->createPath(target.lock()); path = mob->getNavigation()->createPath(target.lock());
return path != NULL; return path != NULL;
} }
bool MeleeAttackGoal::canContinueToUse() bool MeleeAttackGoal::canContinueToUse() {
{
std::shared_ptr<Mob> bestTarget = mob->getTarget(); std::shared_ptr<Mob> bestTarget = mob->getTarget();
if (bestTarget == NULL) return false; if (bestTarget == NULL) return false;
if (target.lock() == NULL || !target.lock()->isAlive()) return false; if (target.lock() == NULL || !target.lock()->isAlive()) return false;
if (!trackTarget) return !mob->getNavigation()->isDone(); if (!trackTarget) return !mob->getNavigation()->isDone();
if (!mob->isWithinRestriction(Mth::floor(target.lock()->x), Mth::floor(target.lock()->y), Mth::floor(target.lock()->z))) return false; if (!mob->isWithinRestriction(Mth::floor(target.lock()->x),
Mth::floor(target.lock()->y),
Mth::floor(target.lock()->z)))
return false;
return true; return true;
} }
void MeleeAttackGoal::start() void MeleeAttackGoal::start() {
{
mob->getNavigation()->moveTo(path, speed); mob->getNavigation()->moveTo(path, speed);
path = NULL; path = NULL;
timeToRecalcPath = 0; timeToRecalcPath = 0;
} }
void MeleeAttackGoal::stop() void MeleeAttackGoal::stop() {
{
target = std::weak_ptr<Mob>(); target = std::weak_ptr<Mob>();
mob->getNavigation()->stop(); mob->getNavigation()->stop();
} }
void MeleeAttackGoal::tick() void MeleeAttackGoal::tick() {
{
mob->getLookControl()->setLookAt(target.lock(), 30, 30); mob->getLookControl()->setLookAt(target.lock(), 30, 30);
if (trackTarget || mob->getSensing()->canSee(target.lock())) if (trackTarget || mob->getSensing()->canSee(target.lock())) {
{ if (--timeToRecalcPath <= 0) {
if (--timeToRecalcPath <= 0)
{
timeToRecalcPath = 4 + mob->getRandom()->nextInt(7); timeToRecalcPath = 4 + mob->getRandom()->nextInt(7);
mob->getNavigation()->moveTo(target.lock(), speed); mob->getNavigation()->moveTo(target.lock(), speed);
} }
@ -90,7 +85,9 @@ void MeleeAttackGoal::tick()
attackTime = std::max(attackTime - 1, 0); attackTime = std::max(attackTime - 1, 0);
double meleeRadiusSqr = (mob->bbWidth * 2) * (mob->bbWidth * 2); double meleeRadiusSqr = (mob->bbWidth * 2) * (mob->bbWidth * 2);
if (mob->distanceToSqr(target.lock()->x, target.lock()->bb->y0, target.lock()->z) > meleeRadiusSqr) return; if (mob->distanceToSqr(target.lock()->x, target.lock()->bb->y0,
target.lock()->z) > meleeRadiusSqr)
return;
if (attackTime > 0) return; if (attackTime > 0) return;
attackTime = 20; attackTime = 20;
mob->doHurtTarget(target.lock()); mob->doHurtTarget(target.lock());

View file

@ -6,8 +6,7 @@ class Level;
class Mob; class Mob;
class Path; class Path;
class MeleeAttackGoal : public Goal class MeleeAttackGoal : public Goal {
{
private: private:
Level* level; Level* level;
Mob* mob; // Owner of this goal Mob* mob; // Owner of this goal
@ -23,7 +22,8 @@ private:
void _init(Mob* mob, float speed, bool trackTarget); void _init(Mob* mob, float speed, bool trackTarget);
public: public:
MeleeAttackGoal(Mob *mob, eINSTANCEOF attackType, float speed, bool trackTarget); MeleeAttackGoal(Mob* mob, eINSTANCEOF attackType, float speed,
bool trackTarget);
MeleeAttackGoal(Mob* mob, float speed, bool trackTarget); MeleeAttackGoal(Mob* mob, float speed, bool trackTarget);
~MeleeAttackGoal(); ~MeleeAttackGoal();
@ -33,6 +33,7 @@ public:
virtual void stop(); virtual void stop();
virtual void tick(); virtual void tick();
// 4J Added override to update ai elements when loading entity from schematics // 4J Added override to update ai elements when loading entity from
// schematics
virtual void setLevel(Level* level) { this->level = level; } virtual void setLevel(Level* level) { this->level = level; }
}; };

View file

@ -8,53 +8,59 @@
#include "../../Headers/net.minecraft.world.level.dimension.h" #include "../../Headers/net.minecraft.world.level.dimension.h"
#include "MoveIndoorsGoal.h" #include "MoveIndoorsGoal.h"
MoveIndoorsGoal::MoveIndoorsGoal(PathfinderMob *mob) MoveIndoorsGoal::MoveIndoorsGoal(PathfinderMob* mob) {
{
insideX = insideZ = -1; insideX = insideZ = -1;
this->mob = mob; this->mob = mob;
setRequiredControlFlags(Control::MoveControlFlag); setRequiredControlFlags(Control::MoveControlFlag);
} }
bool MoveIndoorsGoal::canUse() bool MoveIndoorsGoal::canUse() {
{ if ((mob->level->isDay() && !mob->level->isRaining()) ||
if ((mob->level->isDay() && !mob->level->isRaining()) || mob->level->dimension->hasCeiling) return false; mob->level->dimension->hasCeiling)
return false;
if (mob->getRandom()->nextInt(50) != 0) return false; if (mob->getRandom()->nextInt(50) != 0) return false;
if (insideX != -1 && mob->distanceToSqr(insideX, mob->y, insideZ) < 2 * 2) return false; if (insideX != -1 && mob->distanceToSqr(insideX, mob->y, insideZ) < 2 * 2)
std::shared_ptr<Village> village = mob->level->villages->getClosestVillage(Mth::floor(mob->x), Mth::floor(mob->y), Mth::floor(mob->z), 14); return false;
std::shared_ptr<Village> village = mob->level->villages->getClosestVillage(
Mth::floor(mob->x), Mth::floor(mob->y), Mth::floor(mob->z), 14);
if (village == NULL) return false; if (village == NULL) return false;
std::shared_ptr<DoorInfo> _doorInfo = village->getBestDoorInfo(Mth::floor(mob->x), Mth::floor(mob->y), Mth::floor(mob->z)); std::shared_ptr<DoorInfo> _doorInfo = village->getBestDoorInfo(
Mth::floor(mob->x), Mth::floor(mob->y), Mth::floor(mob->z));
doorInfo = _doorInfo; doorInfo = _doorInfo;
return _doorInfo != NULL; return _doorInfo != NULL;
} }
bool MoveIndoorsGoal::canContinueToUse() bool MoveIndoorsGoal::canContinueToUse() {
{
return !mob->getNavigation()->isDone(); return !mob->getNavigation()->isDone();
} }
void MoveIndoorsGoal::start() void MoveIndoorsGoal::start() {
{
insideX = -1; insideX = -1;
std::shared_ptr<DoorInfo> _doorInfo = doorInfo.lock(); std::shared_ptr<DoorInfo> _doorInfo = doorInfo.lock();
if( _doorInfo == NULL ) if (_doorInfo == NULL) {
{
doorInfo = std::weak_ptr<DoorInfo>(); doorInfo = std::weak_ptr<DoorInfo>();
return; return;
} }
if (mob->distanceToSqr(_doorInfo->getIndoorX(), _doorInfo->y, _doorInfo->getIndoorZ()) > 16 * 16) if (mob->distanceToSqr(_doorInfo->getIndoorX(), _doorInfo->y,
{ _doorInfo->getIndoorZ()) > 16 * 16) {
Vec3 *pos = RandomPos::getPosTowards(std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()), 14, 3, Vec3::newTemp(_doorInfo->getIndoorX() + 0.5, _doorInfo->getIndoorY(), _doorInfo->getIndoorZ() + 0.5)); Vec3* pos = RandomPos::getPosTowards(
if (pos != NULL) mob->getNavigation()->moveTo(pos->x, pos->y, pos->z, 0.3f); std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()),
} 14, 3,
else mob->getNavigation()->moveTo(_doorInfo->getIndoorX() + 0.5, _doorInfo->getIndoorY(), _doorInfo->getIndoorZ() + 0.5, 0.3f); Vec3::newTemp(_doorInfo->getIndoorX() + 0.5,
_doorInfo->getIndoorY(),
_doorInfo->getIndoorZ() + 0.5));
if (pos != NULL)
mob->getNavigation()->moveTo(pos->x, pos->y, pos->z, 0.3f);
} else
mob->getNavigation()->moveTo(_doorInfo->getIndoorX() + 0.5,
_doorInfo->getIndoorY(),
_doorInfo->getIndoorZ() + 0.5, 0.3f);
} }
void MoveIndoorsGoal::stop() void MoveIndoorsGoal::stop() {
{
std::shared_ptr<DoorInfo> _doorInfo = doorInfo.lock(); std::shared_ptr<DoorInfo> _doorInfo = doorInfo.lock();
if( _doorInfo == NULL ) if (_doorInfo == NULL) {
{
doorInfo = std::weak_ptr<DoorInfo>(); doorInfo = std::weak_ptr<DoorInfo>();
return; return;
} }

View file

@ -5,8 +5,7 @@
class PathfinderMob; class PathfinderMob;
class DoorInfo; class DoorInfo;
class MoveIndoorsGoal : public Goal class MoveIndoorsGoal : public Goal {
{
private: private:
PathfinderMob* mob; PathfinderMob* mob;
std::weak_ptr<DoorInfo> doorInfo; std::weak_ptr<DoorInfo> doorInfo;

View file

@ -9,8 +9,8 @@
#include "MoveThroughVillageGoal.h" #include "MoveThroughVillageGoal.h"
#include "../Navigation/Path.h" #include "../Navigation/Path.h"
MoveThroughVillageGoal::MoveThroughVillageGoal(PathfinderMob *mob, float speed, bool onlyAtNight) MoveThroughVillageGoal::MoveThroughVillageGoal(PathfinderMob* mob, float speed,
{ bool onlyAtNight) {
path = NULL; path = NULL;
doorInfo = std::weak_ptr<DoorInfo>(); doorInfo = std::weak_ptr<DoorInfo>();
@ -20,18 +20,17 @@ MoveThroughVillageGoal::MoveThroughVillageGoal(PathfinderMob *mob, float speed,
setRequiredControlFlags(Control::MoveControlFlag); setRequiredControlFlags(Control::MoveControlFlag);
} }
MoveThroughVillageGoal::~MoveThroughVillageGoal() MoveThroughVillageGoal::~MoveThroughVillageGoal() {
{
if (path != NULL) delete path; if (path != NULL) delete path;
} }
bool MoveThroughVillageGoal::canUse() bool MoveThroughVillageGoal::canUse() {
{
updateVisited(); updateVisited();
if (onlyAtNight && mob->level->isDay()) return false; if (onlyAtNight && mob->level->isDay()) return false;
std::shared_ptr<Village> village = mob->level->villages->getClosestVillage(Mth::floor(mob->x), Mth::floor(mob->y), Mth::floor(mob->z), 0); std::shared_ptr<Village> village = mob->level->villages->getClosestVillage(
Mth::floor(mob->x), Mth::floor(mob->y), Mth::floor(mob->z), 0);
if (village == NULL) return false; if (village == NULL) return false;
std::shared_ptr<DoorInfo> _doorInfo = getNextDoorInfo(village); std::shared_ptr<DoorInfo> _doorInfo = getNextDoorInfo(village);
@ -42,11 +41,14 @@ bool MoveThroughVillageGoal::canUse()
mob->getNavigation()->setCanOpenDoors(false); mob->getNavigation()->setCanOpenDoors(false);
delete path; delete path;
path = mob->getNavigation()->createPath(_doorInfo->x, _doorInfo->y, _doorInfo->z); path = mob->getNavigation()->createPath(_doorInfo->x, _doorInfo->y,
_doorInfo->z);
mob->getNavigation()->setCanOpenDoors(oldCanOpenDoors); mob->getNavigation()->setCanOpenDoors(oldCanOpenDoors);
if (path != NULL) return true; if (path != NULL) return true;
Vec3 *pos = RandomPos::getPosTowards(std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()), 10, 7, Vec3::newTemp(_doorInfo->x, _doorInfo->y, _doorInfo->z)); Vec3* pos = RandomPos::getPosTowards(
std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()), 10,
7, Vec3::newTemp(_doorInfo->x, _doorInfo->y, _doorInfo->z));
if (pos == NULL) return false; if (pos == NULL) return false;
mob->getNavigation()->setCanOpenDoors(false); mob->getNavigation()->setCanOpenDoors(false);
delete path; delete path;
@ -55,45 +57,43 @@ bool MoveThroughVillageGoal::canUse()
return path != NULL; return path != NULL;
} }
bool MoveThroughVillageGoal::canContinueToUse() bool MoveThroughVillageGoal::canContinueToUse() {
{
if (mob->getNavigation()->isDone()) return false; if (mob->getNavigation()->isDone()) return false;
float dist = mob->bbWidth + 4.f; float dist = mob->bbWidth + 4.f;
std::shared_ptr<DoorInfo> _doorInfo = doorInfo.lock(); std::shared_ptr<DoorInfo> _doorInfo = doorInfo.lock();
if (_doorInfo == NULL) return false; if (_doorInfo == NULL) return false;
return mob->distanceToSqr(_doorInfo->x, _doorInfo->y, _doorInfo->z) > dist * dist; return mob->distanceToSqr(_doorInfo->x, _doorInfo->y, _doorInfo->z) >
dist * dist;
} }
void MoveThroughVillageGoal::start() void MoveThroughVillageGoal::start() {
{
mob->getNavigation()->moveTo(path, speed); mob->getNavigation()->moveTo(path, speed);
path = NULL; path = NULL;
} }
void MoveThroughVillageGoal::stop() void MoveThroughVillageGoal::stop() {
{
std::shared_ptr<DoorInfo> _doorInfo = doorInfo.lock(); std::shared_ptr<DoorInfo> _doorInfo = doorInfo.lock();
if (_doorInfo == NULL) return; if (_doorInfo == NULL) return;
if (mob->getNavigation()->isDone() || mob->distanceToSqr(_doorInfo->x, _doorInfo->y, _doorInfo->z) < 4 * 4) if (mob->getNavigation()->isDone() ||
{ mob->distanceToSqr(_doorInfo->x, _doorInfo->y, _doorInfo->z) < 4 * 4) {
visited.push_back(doorInfo); visited.push_back(doorInfo);
} }
} }
std::shared_ptr<DoorInfo> MoveThroughVillageGoal::getNextDoorInfo(std::shared_ptr<Village> village) std::shared_ptr<DoorInfo> MoveThroughVillageGoal::getNextDoorInfo(
{ std::shared_ptr<Village> village) {
std::shared_ptr<DoorInfo> closest = nullptr; std::shared_ptr<DoorInfo> closest = nullptr;
int closestDistSqr = Integer::MAX_VALUE; int closestDistSqr = Integer::MAX_VALUE;
std::vector<std::shared_ptr<DoorInfo> > *doorInfos = village->getDoorInfos(); std::vector<std::shared_ptr<DoorInfo> >* doorInfos =
village->getDoorInfos();
// for (DoorInfo di : doorInfos) // for (DoorInfo di : doorInfos)
for(AUTO_VAR(it, doorInfos->begin()); it != doorInfos->end(); ++it) for (AUTO_VAR(it, doorInfos->begin()); it != doorInfos->end(); ++it) {
{
std::shared_ptr<DoorInfo> di = *it; std::shared_ptr<DoorInfo> di = *it;
int distSqr = di->distanceToSqr(Mth::floor(mob->x), Mth::floor(mob->y), Mth::floor(mob->z)); int distSqr = di->distanceToSqr(Mth::floor(mob->x), Mth::floor(mob->y),
if (distSqr < closestDistSqr) Mth::floor(mob->z));
{ if (distSqr < closestDistSqr) {
if (hasVisited(di)) continue; if (hasVisited(di)) continue;
closest = di; closest = di;
closestDistSqr = distSqr; closestDistSqr = distSqr;
@ -102,26 +102,21 @@ std::shared_ptr<DoorInfo> MoveThroughVillageGoal::getNextDoorInfo(std::shared_pt
return closest; return closest;
} }
bool MoveThroughVillageGoal::hasVisited(std::shared_ptr<DoorInfo>di) bool MoveThroughVillageGoal::hasVisited(std::shared_ptr<DoorInfo> di) {
{
// for (DoorInfo di2 : visited) // for (DoorInfo di2 : visited)
for(AUTO_VAR(it, visited.begin()); it != visited.end(); ) for (AUTO_VAR(it, visited.begin()); it != visited.end();) {
{
std::shared_ptr<DoorInfo> di2 = (*it).lock(); std::shared_ptr<DoorInfo> di2 = (*it).lock();
if( di2 == NULL ) if (di2 == NULL) {
{
it = visited.erase(it); it = visited.erase(it);
} } else {
else if (di->x == di2->x && di->y == di2->y && di->z == di2->z)
{ return true;
if (di->x == di2->x && di->y == di2->y && di->z == di2->z) return true;
++it; ++it;
} }
} }
return false; return false;
} }
void MoveThroughVillageGoal::updateVisited() void MoveThroughVillageGoal::updateVisited() {
{
if (visited.size() > 15) visited.erase(visited.begin()); if (visited.size() > 15) visited.erase(visited.begin());
} }

View file

@ -6,8 +6,7 @@ class PathfinderMob;
class Path; class Path;
class DoorInfo; class DoorInfo;
class MoveThroughVillageGoal : public Goal class MoveThroughVillageGoal : public Goal {
{
private: private:
PathfinderMob* mob; PathfinderMob* mob;
float speed; float speed;

View file

@ -6,8 +6,8 @@
#include "../../Headers/net.minecraft.world.level.h" #include "../../Headers/net.minecraft.world.level.h"
#include "MoveTowardsRestrictionGoal.h" #include "MoveTowardsRestrictionGoal.h"
MoveTowardsRestrictionGoal::MoveTowardsRestrictionGoal(PathfinderMob *mob, float speed) MoveTowardsRestrictionGoal::MoveTowardsRestrictionGoal(PathfinderMob* mob,
{ float speed) {
wantedX = wantedY = wantedZ = 0.0; wantedX = wantedY = wantedZ = 0.0;
this->mob = mob; this->mob = mob;
@ -15,11 +15,12 @@ MoveTowardsRestrictionGoal::MoveTowardsRestrictionGoal(PathfinderMob *mob, float
setRequiredControlFlags(Control::MoveControlFlag); setRequiredControlFlags(Control::MoveControlFlag);
} }
bool MoveTowardsRestrictionGoal::canUse() bool MoveTowardsRestrictionGoal::canUse() {
{
if (mob->isWithinRestriction()) return false; if (mob->isWithinRestriction()) return false;
Pos* towards = mob->getRestrictCenter(); Pos* towards = mob->getRestrictCenter();
Vec3 *pos = RandomPos::getPosTowards(std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()), 16, 7, Vec3::newTemp(towards->x, towards->y, towards->z)); Vec3* pos = RandomPos::getPosTowards(
std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()), 16,
7, Vec3::newTemp(towards->x, towards->y, towards->z));
if (pos == NULL) return false; if (pos == NULL) return false;
wantedX = pos->x; wantedX = pos->x;
wantedY = pos->y; wantedY = pos->y;
@ -27,12 +28,10 @@ bool MoveTowardsRestrictionGoal::canUse()
return true; return true;
} }
bool MoveTowardsRestrictionGoal::canContinueToUse() bool MoveTowardsRestrictionGoal::canContinueToUse() {
{
return !mob->getNavigation()->isDone(); return !mob->getNavigation()->isDone();
} }
void MoveTowardsRestrictionGoal::start() void MoveTowardsRestrictionGoal::start() {
{
mob->getNavigation()->moveTo(wantedX, wantedY, wantedZ, speed); mob->getNavigation()->moveTo(wantedX, wantedY, wantedZ, speed);
} }

View file

@ -2,8 +2,7 @@
#include "Goal.h" #include "Goal.h"
class MoveTowardsRestrictionGoal : public Goal class MoveTowardsRestrictionGoal : public Goal {
{
private: private:
PathfinderMob* mob; PathfinderMob* mob;
double wantedX, wantedY, wantedZ; double wantedX, wantedY, wantedZ;

View file

@ -6,20 +6,22 @@
#include "../../Headers/net.minecraft.world.phys.h" #include "../../Headers/net.minecraft.world.phys.h"
#include "MoveTowardsTargetGoal.h" #include "MoveTowardsTargetGoal.h"
MoveTowardsTargetGoal::MoveTowardsTargetGoal(PathfinderMob *mob, float speed, float within) MoveTowardsTargetGoal::MoveTowardsTargetGoal(PathfinderMob* mob, float speed,
{ float within) {
this->mob = mob; this->mob = mob;
this->speed = speed; this->speed = speed;
this->within = within; this->within = within;
setRequiredControlFlags(Control::MoveControlFlag); setRequiredControlFlags(Control::MoveControlFlag);
} }
bool MoveTowardsTargetGoal::canUse() bool MoveTowardsTargetGoal::canUse() {
{
target = std::weak_ptr<Mob>(mob->getTarget()); target = std::weak_ptr<Mob>(mob->getTarget());
if (target.lock() == NULL) return false; if (target.lock() == NULL) return false;
if (target.lock()->distanceToSqr(mob->shared_from_this()) > within * within) return false; if (target.lock()->distanceToSqr(mob->shared_from_this()) > within * within)
Vec3 *pos = RandomPos::getPosTowards(std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()), 16, 7, Vec3::newTemp(target.lock()->x, target.lock()->y, target.lock()->z)); return false;
Vec3* pos = RandomPos::getPosTowards(
std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()), 16,
7, Vec3::newTemp(target.lock()->x, target.lock()->y, target.lock()->z));
if (pos == NULL) return false; if (pos == NULL) return false;
wantedX = pos->x; wantedX = pos->x;
wantedY = pos->y; wantedY = pos->y;
@ -27,17 +29,15 @@ bool MoveTowardsTargetGoal::canUse()
return true; return true;
} }
bool MoveTowardsTargetGoal::canContinueToUse() bool MoveTowardsTargetGoal::canContinueToUse() {
{ return target.lock() != NULL && !mob->getNavigation()->isDone() &&
return target.lock() != NULL && !mob->getNavigation()->isDone() && target.lock()->isAlive() && target.lock()->distanceToSqr(mob->shared_from_this()) < within * within; target.lock()->isAlive() &&
target.lock()->distanceToSqr(mob->shared_from_this()) <
within * within;
} }
void MoveTowardsTargetGoal::stop() void MoveTowardsTargetGoal::stop() { target = std::weak_ptr<Mob>(); }
{
target = std::weak_ptr<Mob>();
}
void MoveTowardsTargetGoal::start() void MoveTowardsTargetGoal::start() {
{
mob->getNavigation()->moveTo(wantedX, wantedY, wantedZ, speed); mob->getNavigation()->moveTo(wantedX, wantedY, wantedZ, speed);
} }

View file

@ -2,8 +2,7 @@
#include "Goal.h" #include "Goal.h"
class MoveTowardsTargetGoal : public Goal class MoveTowardsTargetGoal : public Goal {
{
private: private:
PathfinderMob* mob; PathfinderMob* mob;
std::weak_ptr<Mob> target; std::weak_ptr<Mob> target;

View file

@ -4,13 +4,12 @@
#include "../../Headers/net.minecraft.world.phys.h" #include "../../Headers/net.minecraft.world.phys.h"
#include "NearestAttackableTargetGoal.h" #include "NearestAttackableTargetGoal.h"
NearestAttackableTargetGoal::DistComp::DistComp(Entity *source) NearestAttackableTargetGoal::DistComp::DistComp(Entity* source) {
{
this->source = source; this->source = source;
} }
bool NearestAttackableTargetGoal::DistComp::operator() (std::shared_ptr<Entity> e1, std::shared_ptr<Entity> e2) bool NearestAttackableTargetGoal::DistComp::operator()(
{ std::shared_ptr<Entity> e1, std::shared_ptr<Entity> e2) {
// Should return true if e1 comes before e2 in the sorted list // Should return true if e1 comes before e2 in the sorted list
double distSqr1 = source->distanceToSqr(e1); double distSqr1 = source->distanceToSqr(e1);
double distSqr2 = source->distanceToSqr(e2); double distSqr2 = source->distanceToSqr(e2);
@ -19,8 +18,10 @@ bool NearestAttackableTargetGoal::DistComp::operator() (std::shared_ptr<Entity>
return true; return true;
} }
NearestAttackableTargetGoal::NearestAttackableTargetGoal(Mob *mob, const std::type_info& targetType, float within, int randomInterval, bool mustSee, bool mustReach /*= false*/) : TargetGoal(mob, within, mustSee, mustReach), targetType(targetType) NearestAttackableTargetGoal::NearestAttackableTargetGoal(
{ Mob* mob, const std::type_info& targetType, float within,
int randomInterval, bool mustSee, bool mustReach /*= false*/)
: TargetGoal(mob, within, mustSee, mustReach), targetType(targetType) {
// this->targetType = targetType; // this->targetType = targetType;
this->within = within; this->within = within;
this->randomInterval = randomInterval; this->randomInterval = randomInterval;
@ -28,33 +29,29 @@ NearestAttackableTargetGoal::NearestAttackableTargetGoal(Mob *mob, const std::ty
setRequiredControlFlags(TargetGoal::TargetFlag); setRequiredControlFlags(TargetGoal::TargetFlag);
} }
NearestAttackableTargetGoal::~NearestAttackableTargetGoal() NearestAttackableTargetGoal::~NearestAttackableTargetGoal() { delete distComp; }
{
delete distComp;
}
bool NearestAttackableTargetGoal::canUse() bool NearestAttackableTargetGoal::canUse() {
{ if (randomInterval > 0 && mob->getRandom()->nextInt(randomInterval) != 0)
if (randomInterval > 0 && mob->getRandom()->nextInt(randomInterval) != 0) return false; return false;
if (targetType == typeid(Player)) if (targetType == typeid(Player)) {
{ std::shared_ptr<Mob> potentialTarget =
std::shared_ptr<Mob> potentialTarget = mob->level->getNearestAttackablePlayer(mob->shared_from_this(), within); mob->level->getNearestAttackablePlayer(mob->shared_from_this(),
if (canAttack(potentialTarget, false)) within);
{ if (canAttack(potentialTarget, false)) {
target = std::weak_ptr<Mob>(potentialTarget); target = std::weak_ptr<Mob>(potentialTarget);
return true; return true;
} }
} } else {
else std::vector<std::shared_ptr<Entity> >* entities =
{ mob->level->getEntitiesOfClass(targetType,
std::vector<std::shared_ptr<Entity> > *entities = mob->level->getEntitiesOfClass(targetType, mob->bb->grow(within, 4, within)); mob->bb->grow(within, 4, within));
// Collections.sort(entities, distComp); // Collections.sort(entities, distComp);
std::sort(entities->begin(), entities->end(), *distComp); std::sort(entities->begin(), entities->end(), *distComp);
for(AUTO_VAR(it, entities->begin()); it != entities->end(); ++it) for (AUTO_VAR(it, entities->begin()); it != entities->end(); ++it) {
{ std::shared_ptr<Mob> potTarget =
std::shared_ptr<Mob> potTarget = std::dynamic_pointer_cast<Mob>(*it); std::dynamic_pointer_cast<Mob>(*it);
if (canAttack(potTarget, false)) if (canAttack(potTarget, false)) {
{
target = std::weak_ptr<Mob>(potTarget); target = std::weak_ptr<Mob>(potTarget);
return true; return true;
} }
@ -64,8 +61,7 @@ bool NearestAttackableTargetGoal::canUse()
return false; return false;
} }
void NearestAttackableTargetGoal::start() void NearestAttackableTargetGoal::start() {
{
mob->setTarget(target.lock()); mob->setTarget(target.lock());
TargetGoal::start(); TargetGoal::start();
} }

View file

@ -2,11 +2,9 @@
#include "TargetGoal.h" #include "TargetGoal.h"
class NearestAttackableTargetGoal : public TargetGoal class NearestAttackableTargetGoal : public TargetGoal {
{
public: public:
class DistComp class DistComp {
{
private: private:
Entity* source; Entity* source;
@ -23,12 +21,15 @@ private:
DistComp* distComp; DistComp* distComp;
public: public:
//public NearestAttackableTargetGoal(Mob mob, const std::type_info& targetType, float within, int randomInterval, bool mustSee) // public NearestAttackableTargetGoal(Mob mob, const std::type_info&
// targetType, float within, int randomInterval, bool mustSee)
//{ //{
// this(mob, targetType, within, randomInterval, mustSee, false); // this(mob, targetType, within, randomInterval, mustSee, false);
// } // }
NearestAttackableTargetGoal(Mob *mob, const std::type_info& targetType, float within, int randomInterval, bool mustSee, bool mustReach = false); NearestAttackableTargetGoal(Mob* mob, const std::type_info& targetType,
float within, int randomInterval, bool mustSee,
bool mustReach = false);
virtual ~NearestAttackableTargetGoal(); virtual ~NearestAttackableTargetGoal();
virtual bool canUse(); virtual bool canUse();

View file

@ -2,13 +2,15 @@
#include "../../Headers/net.minecraft.world.entity.animal.h" #include "../../Headers/net.minecraft.world.entity.animal.h"
#include "NonTameRandomTargetGoal.h" #include "NonTameRandomTargetGoal.h"
NonTameRandomTargetGoal::NonTameRandomTargetGoal(TamableAnimal *mob, const std::type_info& targetType, float within, int randomInterval, bool mustSee) : NearestAttackableTargetGoal(mob, targetType, within, randomInterval, mustSee) NonTameRandomTargetGoal::NonTameRandomTargetGoal(
{ TamableAnimal* mob, const std::type_info& targetType, float within,
int randomInterval, bool mustSee)
: NearestAttackableTargetGoal(mob, targetType, within, randomInterval,
mustSee) {
this->tamableMob = mob; this->tamableMob = mob;
} }
bool NonTameRandomTargetGoal::canUse() bool NonTameRandomTargetGoal::canUse() {
{
if (tamableMob->isTame()) return false; if (tamableMob->isTame()) return false;
return NearestAttackableTargetGoal::canUse(); return NearestAttackableTargetGoal::canUse();
} }

View file

@ -4,13 +4,14 @@
class TamableAnimal; class TamableAnimal;
class NonTameRandomTargetGoal : public NearestAttackableTargetGoal class NonTameRandomTargetGoal : public NearestAttackableTargetGoal {
{
private: private:
TamableAnimal* tamableMob; // Owner of this goal TamableAnimal* tamableMob; // Owner of this goal
public: public:
NonTameRandomTargetGoal(TamableAnimal *mob, const std::type_info& targetType, float within, int randomInterval, bool mustSee); NonTameRandomTargetGoal(TamableAnimal* mob,
const std::type_info& targetType, float within,
int randomInterval, bool mustSee);
bool canUse(); bool canUse();
}; };

View file

@ -6,8 +6,7 @@
#include "../../Headers/net.minecraft.world.phys.h" #include "../../Headers/net.minecraft.world.phys.h"
#include "OcelotAttackGoal.h" #include "OcelotAttackGoal.h"
OzelotAttackGoal::OzelotAttackGoal(Mob *mob) OzelotAttackGoal::OzelotAttackGoal(Mob* mob) {
{
target = std::weak_ptr<Mob>(); target = std::weak_ptr<Mob>();
attackTime = 0; attackTime = 0;
speed = 0; speed = 0;
@ -15,40 +14,40 @@ OzelotAttackGoal::OzelotAttackGoal(Mob *mob)
this->mob = mob; this->mob = mob;
this->level = mob->level; this->level = mob->level;
setRequiredControlFlags(Control::MoveControlFlag | Control::LookControlFlag); setRequiredControlFlags(Control::MoveControlFlag |
Control::LookControlFlag);
} }
bool OzelotAttackGoal::canUse() bool OzelotAttackGoal::canUse() {
{
std::shared_ptr<Mob> bestTarget = mob->getTarget(); std::shared_ptr<Mob> bestTarget = mob->getTarget();
if (bestTarget == NULL) return false; if (bestTarget == NULL) return false;
target = std::weak_ptr<Mob>(bestTarget); target = std::weak_ptr<Mob>(bestTarget);
return true; return true;
} }
bool OzelotAttackGoal::canContinueToUse() bool OzelotAttackGoal::canContinueToUse() {
{
if (target.lock() == NULL || !target.lock()->isAlive()) return false; if (target.lock() == NULL || !target.lock()->isAlive()) return false;
if (mob->distanceToSqr(target.lock()) > 15 * 15) return false; if (mob->distanceToSqr(target.lock()) > 15 * 15) return false;
return !mob->getNavigation()->isDone() || canUse(); return !mob->getNavigation()->isDone() || canUse();
} }
void OzelotAttackGoal::stop() void OzelotAttackGoal::stop() {
{
target = std::weak_ptr<Mob>(); target = std::weak_ptr<Mob>();
mob->getNavigation()->stop(); mob->getNavigation()->stop();
} }
void OzelotAttackGoal::tick() void OzelotAttackGoal::tick() {
{
mob->getLookControl()->setLookAt(target.lock(), 30, 30); mob->getLookControl()->setLookAt(target.lock(), 30, 30);
double meleeRadiusSqr = (mob->bbWidth * 2) * (mob->bbWidth * 2); double meleeRadiusSqr = (mob->bbWidth * 2) * (mob->bbWidth * 2);
double distSqr = mob->distanceToSqr(target.lock()->x, target.lock()->bb->y0, target.lock()->z); double distSqr = mob->distanceToSqr(target.lock()->x, target.lock()->bb->y0,
target.lock()->z);
float speed = Ozelot::WALK_SPEED; float speed = Ozelot::WALK_SPEED;
if (distSqr > meleeRadiusSqr && distSqr < 4 * 4) speed = Ozelot::SPRINT_SPEED; if (distSqr > meleeRadiusSqr && distSqr < 4 * 4)
else if (distSqr < 15 * 15) speed = Ozelot::SNEAK_SPEED; speed = Ozelot::SPRINT_SPEED;
else if (distSqr < 15 * 15)
speed = Ozelot::SNEAK_SPEED;
mob->getNavigation()->moveTo(target.lock(), speed); mob->getNavigation()->moveTo(target.lock(), speed);

View file

@ -2,8 +2,7 @@
#include "Goal.h" #include "Goal.h"
class OzelotAttackGoal : public Goal class OzelotAttackGoal : public Goal {
{
private: private:
Level* level; Level* level;
Mob* mob; Mob* mob;
@ -20,6 +19,7 @@ public:
virtual void stop(); virtual void stop();
virtual void tick(); virtual void tick();
// 4J Added override to update ai elements when loading entity from schematics // 4J Added override to update ai elements when loading entity from
// schematics
virtual void setLevel(Level* level) { this->level = level; } virtual void setLevel(Level* level) { this->level = level; }
}; };

View file

@ -10,13 +10,14 @@
#include "../../Util/Arrays.h" #include "../../Util/Arrays.h"
#include "OcelotSitOnTileGoal.h" #include "OcelotSitOnTileGoal.h"
const int OcelotSitOnTileGoal::GIVE_UP_TICKS = 3 * SharedConstants::TICKS_PER_SECOND; const int OcelotSitOnTileGoal::GIVE_UP_TICKS =
const int OcelotSitOnTileGoal::SIT_TICKS = 60 * SharedConstants::TICKS_PER_SECOND; 3 * SharedConstants::TICKS_PER_SECOND;
const int OcelotSitOnTileGoal::SIT_TICKS =
60 * SharedConstants::TICKS_PER_SECOND;
const int OcelotSitOnTileGoal::SEARCH_RANGE = 8; const int OcelotSitOnTileGoal::SEARCH_RANGE = 8;
const double OcelotSitOnTileGoal::SIT_CHANCE = 0.0065f; const double OcelotSitOnTileGoal::SIT_CHANCE = 0.0065f;
OcelotSitOnTileGoal::OcelotSitOnTileGoal(Ozelot *ocelot, float speed) OcelotSitOnTileGoal::OcelotSitOnTileGoal(Ozelot* ocelot, float speed) {
{
_tick = 0; _tick = 0;
tryTicks = 0; tryTicks = 0;
maxTicks = 0; maxTicks = 0;
@ -26,68 +27,61 @@ OcelotSitOnTileGoal::OcelotSitOnTileGoal(Ozelot *ocelot, float speed)
this->ocelot = ocelot; this->ocelot = ocelot;
this->speed = speed; this->speed = speed;
setRequiredControlFlags(Control::MoveControlFlag | Control::JumpControlFlag); setRequiredControlFlags(Control::MoveControlFlag |
Control::JumpControlFlag);
} }
bool OcelotSitOnTileGoal::canUse() bool OcelotSitOnTileGoal::canUse() {
{ return ocelot->isTame() && !ocelot->isSitting() &&
return ocelot->isTame() && !ocelot->isSitting() && ocelot->getRandom()->nextDouble() <= SIT_CHANCE && findNearestTile(); ocelot->getRandom()->nextDouble() <= SIT_CHANCE && findNearestTile();
} }
bool OcelotSitOnTileGoal::canContinueToUse() bool OcelotSitOnTileGoal::canContinueToUse() {
{ return _tick <= maxTicks && tryTicks <= GIVE_UP_TICKS &&
return _tick <= maxTicks && tryTicks <= GIVE_UP_TICKS && isValidTarget(ocelot->level, tileX, tileY, tileZ); isValidTarget(ocelot->level, tileX, tileY, tileZ);
} }
void OcelotSitOnTileGoal::start() void OcelotSitOnTileGoal::start() {
{ ocelot->getNavigation()->moveTo((float)tileX + 0.5, tileY + 1,
ocelot->getNavigation()->moveTo((float) tileX + 0.5, tileY + 1, (float) tileZ + 0.5, speed); (float)tileZ + 0.5, speed);
_tick = 0; _tick = 0;
tryTicks = 0; tryTicks = 0;
maxTicks = ocelot->getRandom()->nextInt(ocelot->getRandom()->nextInt(SIT_TICKS) + SIT_TICKS) + SIT_TICKS; maxTicks = ocelot->getRandom()->nextInt(
ocelot->getRandom()->nextInt(SIT_TICKS) + SIT_TICKS) +
SIT_TICKS;
ocelot->getSitGoal()->wantToSit(false); ocelot->getSitGoal()->wantToSit(false);
} }
void OcelotSitOnTileGoal::stop() void OcelotSitOnTileGoal::stop() { ocelot->setSitting(false); }
{
ocelot->setSitting(false);
}
void OcelotSitOnTileGoal::tick() void OcelotSitOnTileGoal::tick() {
{
_tick++; _tick++;
ocelot->getSitGoal()->wantToSit(false); ocelot->getSitGoal()->wantToSit(false);
if (ocelot->distanceToSqr(tileX, tileY + 1, tileZ) > 1) if (ocelot->distanceToSqr(tileX, tileY + 1, tileZ) > 1) {
{
ocelot->setSitting(false); ocelot->setSitting(false);
ocelot->getNavigation()->moveTo((float) tileX + 0.5, tileY + 1, (float) tileZ + 0.5, speed); ocelot->getNavigation()->moveTo((float)tileX + 0.5, tileY + 1,
(float)tileZ + 0.5, speed);
tryTicks++; tryTicks++;
} } else if (!ocelot->isSitting()) {
else if (!ocelot->isSitting())
{
ocelot->setSitting(true); ocelot->setSitting(true);
} } else {
else
{
tryTicks--; tryTicks--;
} }
} }
bool OcelotSitOnTileGoal::findNearestTile() bool OcelotSitOnTileGoal::findNearestTile() {
{
int y = (int)ocelot->y; int y = (int)ocelot->y;
double distSqr = Integer::MAX_VALUE; double distSqr = Integer::MAX_VALUE;
for (int x = (int) ocelot->x - SEARCH_RANGE; x < ocelot->x + SEARCH_RANGE; x++) for (int x = (int)ocelot->x - SEARCH_RANGE; x < ocelot->x + SEARCH_RANGE;
{ x++) {
for (int z = (int) ocelot->z - SEARCH_RANGE; z < ocelot->z + SEARCH_RANGE; z++) for (int z = (int)ocelot->z - SEARCH_RANGE;
{ z < ocelot->z + SEARCH_RANGE; z++) {
if (isValidTarget(ocelot->level, x, y, z) && ocelot->level->isEmptyTile(x, y + 1, z)) if (isValidTarget(ocelot->level, x, y, z) &&
{ ocelot->level->isEmptyTile(x, y + 1, z)) {
double dist = ocelot->distanceToSqr(x, y, z); double dist = ocelot->distanceToSqr(x, y, z);
if (dist < distSqr) if (dist < distSqr) {
{
this->tileX = x; this->tileX = x;
this->tileY = y; this->tileY = y;
this->tileZ = z; this->tileZ = z;
@ -100,26 +94,21 @@ bool OcelotSitOnTileGoal::findNearestTile()
return distSqr < Integer::MAX_VALUE; return distSqr < Integer::MAX_VALUE;
} }
bool OcelotSitOnTileGoal::isValidTarget(Level *level, int x, int y, int z) bool OcelotSitOnTileGoal::isValidTarget(Level* level, int x, int y, int z) {
{
int tile = level->getTile(x, y, z); int tile = level->getTile(x, y, z);
int data = level->getData(x, y, z); int data = level->getData(x, y, z);
if (tile == Tile::chest_Id) if (tile == Tile::chest_Id) {
{ std::shared_ptr<ChestTileEntity> chest =
std::shared_ptr<ChestTileEntity> chest = std::dynamic_pointer_cast<ChestTileEntity>(level->getTileEntity(x, y, z)); std::dynamic_pointer_cast<ChestTileEntity>(
level->getTileEntity(x, y, z));
if (chest->openCount < 1) if (chest->openCount < 1) {
{
return true; return true;
} }
} } else if (tile == Tile::furnace_lit_Id) {
else if (tile == Tile::furnace_lit_Id)
{
return true; return true;
} } else if (tile == Tile::bed_Id && !BedTile::isHeadPiece(data)) {
else if (tile == Tile::bed_Id && !BedTile::isHeadPiece(data))
{
return true; return true;
} }

View file

@ -4,8 +4,7 @@
class Ozelot; class Ozelot;
class OcelotSitOnTileGoal : public Goal class OcelotSitOnTileGoal : public Goal {
{
private: private:
static const int GIVE_UP_TICKS; static const int GIVE_UP_TICKS;
static const int SIT_TICKS; static const int SIT_TICKS;

View file

@ -6,39 +6,37 @@
#include "../../Headers/net.minecraft.world.phys.h" #include "../../Headers/net.minecraft.world.phys.h"
#include "OfferFlowerGoal.h" #include "OfferFlowerGoal.h"
OfferFlowerGoal::OfferFlowerGoal(VillagerGolem *golem) OfferFlowerGoal::OfferFlowerGoal(VillagerGolem* golem) {
{
this->golem = golem; this->golem = golem;
setRequiredControlFlags(Control::MoveControlFlag | Control::LookControlFlag); setRequiredControlFlags(Control::MoveControlFlag |
Control::LookControlFlag);
} }
bool OfferFlowerGoal::canUse() bool OfferFlowerGoal::canUse() {
{
if (!golem->level->isDay()) return false; if (!golem->level->isDay()) return false;
if (golem->getRandom()->nextInt(8000) != 0) return false; if (golem->getRandom()->nextInt(8000) != 0) return false;
villager = std::weak_ptr<Villager>(std::dynamic_pointer_cast<Villager>( golem->level->getClosestEntityOfClass(typeid(Villager), golem->bb->grow(6, 2, 6), golem->shared_from_this()) )); villager = std::weak_ptr<Villager>(std::dynamic_pointer_cast<Villager>(
golem->level->getClosestEntityOfClass(typeid(Villager),
golem->bb->grow(6, 2, 6),
golem->shared_from_this())));
return villager.lock() != NULL; return villager.lock() != NULL;
} }
bool OfferFlowerGoal::canContinueToUse() bool OfferFlowerGoal::canContinueToUse() {
{
return _tick > 0 && villager.lock() != NULL; return _tick > 0 && villager.lock() != NULL;
} }
void OfferFlowerGoal::start() void OfferFlowerGoal::start() {
{
_tick = OFFER_TICKS; _tick = OFFER_TICKS;
golem->offerFlower(true); golem->offerFlower(true);
} }
void OfferFlowerGoal::stop() void OfferFlowerGoal::stop() {
{
golem->offerFlower(false); golem->offerFlower(false);
villager = std::weak_ptr<Villager>(); villager = std::weak_ptr<Villager>();
} }
void OfferFlowerGoal::tick() void OfferFlowerGoal::tick() {
{
golem->getLookControl()->setLookAt(villager.lock(), 30, 30); golem->getLookControl()->setLookAt(villager.lock(), 30, 30);
--_tick; --_tick;
} }

View file

@ -4,8 +4,7 @@
class VillagerGolem; class VillagerGolem;
class OfferFlowerGoal : public Goal class OfferFlowerGoal : public Goal {
{
public: public:
static const int OFFER_TICKS = 400; static const int OFFER_TICKS = 400;

View file

@ -3,33 +3,28 @@
#include "../../Headers/net.minecraft.world.level.tile.h" #include "../../Headers/net.minecraft.world.level.tile.h"
#include "OpenDoorGoal.h" #include "OpenDoorGoal.h"
OpenDoorGoal::OpenDoorGoal(Mob *mob, bool closeDoorAfter) : DoorInteractGoal(mob) OpenDoorGoal::OpenDoorGoal(Mob* mob, bool closeDoorAfter)
{ : DoorInteractGoal(mob) {
this->mob = mob; this->mob = mob;
this->closeDoor = closeDoorAfter; this->closeDoor = closeDoorAfter;
} }
bool OpenDoorGoal::canContinueToUse() bool OpenDoorGoal::canContinueToUse() {
{
return closeDoor && forgetTime > 0 && DoorInteractGoal::canContinueToUse(); return closeDoor && forgetTime > 0 && DoorInteractGoal::canContinueToUse();
} }
void OpenDoorGoal::start() void OpenDoorGoal::start() {
{
forgetTime = 20; forgetTime = 20;
doorTile->setOpen(mob->level, doorX, doorY, doorZ, true); doorTile->setOpen(mob->level, doorX, doorY, doorZ, true);
} }
void OpenDoorGoal::stop() void OpenDoorGoal::stop() {
{ if (closeDoor) {
if (closeDoor)
{
doorTile->setOpen(mob->level, doorX, doorY, doorZ, false); doorTile->setOpen(mob->level, doorX, doorY, doorZ, false);
} }
} }
void OpenDoorGoal::tick() void OpenDoorGoal::tick() {
{
--forgetTime; --forgetTime;
DoorInteractGoal::tick(); DoorInteractGoal::tick();
} }

View file

@ -2,8 +2,7 @@
#include "DoorInteractGoal.h" #include "DoorInteractGoal.h"
class OpenDoorGoal : public DoorInteractGoal class OpenDoorGoal : public DoorInteractGoal {
{
private: private:
bool closeDoor; bool closeDoor;
int forgetTime; int forgetTime;

View file

@ -3,14 +3,13 @@
#include "../../Headers/net.minecraft.world.entity.animal.h" #include "../../Headers/net.minecraft.world.entity.animal.h"
#include "OwnerHurtByTargetGoal.h" #include "OwnerHurtByTargetGoal.h"
OwnerHurtByTargetGoal::OwnerHurtByTargetGoal(TamableAnimal *tameAnimal) : TargetGoal(tameAnimal, 32, false) OwnerHurtByTargetGoal::OwnerHurtByTargetGoal(TamableAnimal* tameAnimal)
{ : TargetGoal(tameAnimal, 32, false) {
this->tameAnimal = tameAnimal; this->tameAnimal = tameAnimal;
setRequiredControlFlags(TargetGoal::TargetFlag); setRequiredControlFlags(TargetGoal::TargetFlag);
} }
bool OwnerHurtByTargetGoal::canUse() bool OwnerHurtByTargetGoal::canUse() {
{
if (!tameAnimal->isTame()) return false; if (!tameAnimal->isTame()) return false;
std::shared_ptr<Mob> owner = tameAnimal->getOwner(); std::shared_ptr<Mob> owner = tameAnimal->getOwner();
if (owner == NULL) return false; if (owner == NULL) return false;
@ -18,8 +17,7 @@ bool OwnerHurtByTargetGoal::canUse()
return canAttack(ownerLastHurtBy.lock(), false); return canAttack(ownerLastHurtBy.lock(), false);
} }
void OwnerHurtByTargetGoal::start() void OwnerHurtByTargetGoal::start() {
{
mob->setTarget(ownerLastHurtBy.lock()); mob->setTarget(ownerLastHurtBy.lock());
TargetGoal::start(); TargetGoal::start();
} }

View file

@ -4,8 +4,7 @@
class TamableAnimal; class TamableAnimal;
class OwnerHurtByTargetGoal : public TargetGoal class OwnerHurtByTargetGoal : public TargetGoal {
{
private: private:
TamableAnimal* tameAnimal; // Owner of this goal TamableAnimal* tameAnimal; // Owner of this goal
std::weak_ptr<Mob> ownerLastHurtBy; std::weak_ptr<Mob> ownerLastHurtBy;

View file

@ -3,14 +3,13 @@
#include "../../Headers/net.minecraft.world.entity.animal.h" #include "../../Headers/net.minecraft.world.entity.animal.h"
#include "OwnerHurtTargetGoal.h" #include "OwnerHurtTargetGoal.h"
OwnerHurtTargetGoal::OwnerHurtTargetGoal(TamableAnimal *tameAnimal) : TargetGoal(tameAnimal, 32, false) OwnerHurtTargetGoal::OwnerHurtTargetGoal(TamableAnimal* tameAnimal)
{ : TargetGoal(tameAnimal, 32, false) {
this->tameAnimal = tameAnimal; this->tameAnimal = tameAnimal;
setRequiredControlFlags(TargetGoal::TargetFlag); setRequiredControlFlags(TargetGoal::TargetFlag);
} }
bool OwnerHurtTargetGoal::canUse() bool OwnerHurtTargetGoal::canUse() {
{
if (!tameAnimal->isTame()) return false; if (!tameAnimal->isTame()) return false;
std::shared_ptr<Mob> owner = tameAnimal->getOwner(); std::shared_ptr<Mob> owner = tameAnimal->getOwner();
if (owner == NULL) return false; if (owner == NULL) return false;
@ -18,8 +17,7 @@ bool OwnerHurtTargetGoal::canUse()
return canAttack(ownerLastHurt.lock(), false); return canAttack(ownerLastHurt.lock(), false);
} }
void OwnerHurtTargetGoal::start() void OwnerHurtTargetGoal::start() {
{
mob->setTarget(ownerLastHurt.lock()); mob->setTarget(ownerLastHurt.lock());
TargetGoal::start(); TargetGoal::start();
} }

View file

@ -4,8 +4,7 @@
class TamableAnimal; class TamableAnimal;
class OwnerHurtTargetGoal : public TargetGoal class OwnerHurtTargetGoal : public TargetGoal {
{
private: private:
TamableAnimal* tameAnimal; // Owner of this goal TamableAnimal* tameAnimal; // Owner of this goal
std::weak_ptr<Mob> ownerLastHurt; std::weak_ptr<Mob> ownerLastHurt;

View file

@ -6,17 +6,17 @@
#include "../../Headers/net.minecraft.world.phys.h" #include "../../Headers/net.minecraft.world.phys.h"
#include "PanicGoal.h" #include "PanicGoal.h"
PanicGoal::PanicGoal(PathfinderMob *mob, float speed) PanicGoal::PanicGoal(PathfinderMob* mob, float speed) {
{
this->mob = mob; this->mob = mob;
this->speed = speed; this->speed = speed;
setRequiredControlFlags(Control::MoveControlFlag); setRequiredControlFlags(Control::MoveControlFlag);
} }
bool PanicGoal::canUse() bool PanicGoal::canUse() {
{
if (mob->getLastHurtByMob() == NULL) return false; if (mob->getLastHurtByMob() == NULL) return false;
Vec3 *pos = RandomPos::getPos(std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()), 5, 4); Vec3* pos = RandomPos::getPos(
std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()), 5,
4);
if (pos == NULL) return false; if (pos == NULL) return false;
posX = pos->x; posX = pos->x;
posY = pos->y; posY = pos->y;
@ -24,12 +24,8 @@ bool PanicGoal::canUse()
return true; return true;
} }
void PanicGoal::start() void PanicGoal::start() {
{
mob->getNavigation()->moveTo(posX, posY, posZ, speed); mob->getNavigation()->moveTo(posX, posY, posZ, speed);
} }
bool PanicGoal::canContinueToUse() bool PanicGoal::canContinueToUse() { return !mob->getNavigation()->isDone(); }
{
return !mob->getNavigation()->isDone();
}

View file

@ -4,8 +4,7 @@
class PathfinderMob; class PathfinderMob;
class PanicGoal : public Goal class PanicGoal : public Goal {
{
private: private:
PathfinderMob* mob; PathfinderMob* mob;
float speed; float speed;

View file

@ -9,8 +9,7 @@
#include "../../Util/BasicTypeContainers.h" #include "../../Util/BasicTypeContainers.h"
#include "PlayGoal.h" #include "PlayGoal.h"
PlayGoal::PlayGoal(Villager *mob, float speed) PlayGoal::PlayGoal(Villager* mob, float speed) {
{
followFriend = std::weak_ptr<Mob>(); followFriend = std::weak_ptr<Mob>();
wantedX = wantedY = wantedZ = 0.0; wantedX = wantedY = wantedZ = 0.0;
playTime = 0; playTime = 0;
@ -20,19 +19,20 @@ PlayGoal::PlayGoal(Villager *mob, float speed)
setRequiredControlFlags(Control::MoveControlFlag); setRequiredControlFlags(Control::MoveControlFlag);
} }
bool PlayGoal::canUse() bool PlayGoal::canUse() {
{
if (mob->getAge() >= 0) return false; if (mob->getAge() >= 0) return false;
if (mob->getRandom()->nextInt(400) != 0) return false; if (mob->getRandom()->nextInt(400) != 0) return false;
std::vector<std::shared_ptr<Entity> > *children = mob->level->getEntitiesOfClass(typeid(Villager), mob->bb->grow(6, 3, 6)); std::vector<std::shared_ptr<Entity> >* children =
mob->level->getEntitiesOfClass(typeid(Villager),
mob->bb->grow(6, 3, 6));
double closestDistSqr = Double::MAX_VALUE; double closestDistSqr = Double::MAX_VALUE;
// for (Entity c : children) // for (Entity c : children)
for(AUTO_VAR(it, children->begin()); it != children->end(); ++it) for (AUTO_VAR(it, children->begin()); it != children->end(); ++it) {
{
std::shared_ptr<Entity> c = *it; std::shared_ptr<Entity> c = *it;
if (c.get() == mob) continue; if (c.get() == mob) continue;
std::shared_ptr<Villager> friendV = std::dynamic_pointer_cast<Villager>(c); std::shared_ptr<Villager> friendV =
std::dynamic_pointer_cast<Villager>(c);
if (friendV->isChasing()) continue; if (friendV->isChasing()) continue;
if (friendV->getAge() >= 0) continue; if (friendV->getAge() >= 0) continue;
double distSqr = friendV->distanceToSqr(mob->shared_from_this()); double distSqr = friendV->distanceToSqr(mob->shared_from_this());
@ -42,43 +42,40 @@ bool PlayGoal::canUse()
} }
delete children; delete children;
if (followFriend.lock() == NULL) if (followFriend.lock() == NULL) {
{ Vec3* pos = RandomPos::getPos(
Vec3 *pos = RandomPos::getPos(std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()), 16, 3); std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()),
16, 3);
if (pos == NULL) return false; if (pos == NULL) return false;
} }
return true; return true;
} }
bool PlayGoal::canContinueToUse() bool PlayGoal::canContinueToUse() {
{
return playTime > 0 && followFriend.lock() != NULL; return playTime > 0 && followFriend.lock() != NULL;
} }
void PlayGoal::start() void PlayGoal::start() {
{
if (followFriend.lock() != NULL) mob->setChasing(true); if (followFriend.lock() != NULL) mob->setChasing(true);
playTime = 1000; playTime = 1000;
} }
void PlayGoal::stop() void PlayGoal::stop() {
{
mob->setChasing(false); mob->setChasing(false);
followFriend = std::weak_ptr<Mob>(); followFriend = std::weak_ptr<Mob>();
} }
void PlayGoal::tick() void PlayGoal::tick() {
{
--playTime; --playTime;
if (followFriend.lock() != NULL) if (followFriend.lock() != NULL) {
{ if (mob->distanceToSqr(followFriend.lock()) > 2 * 2)
if (mob->distanceToSqr(followFriend.lock()) > 2 * 2) mob->getNavigation()->moveTo(followFriend.lock(), speed); mob->getNavigation()->moveTo(followFriend.lock(), speed);
} } else {
else if (mob->getNavigation()->isDone()) {
{ Vec3* pos =
if (mob->getNavigation()->isDone()) RandomPos::getPos(std::dynamic_pointer_cast<PathfinderMob>(
{ mob->shared_from_this()),
Vec3 *pos = RandomPos::getPos(std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()), 16, 3); 16, 3);
if (pos == NULL) return; if (pos == NULL) return;
mob->getNavigation()->moveTo(pos->x, pos->y, pos->z, speed); mob->getNavigation()->moveTo(pos->x, pos->y, pos->z, speed);
} }

View file

@ -2,8 +2,7 @@
#include "Goal.h" #include "Goal.h"
class PlayGoal : public Goal class PlayGoal : public Goal {
{
private: private:
Villager* mob; Villager* mob;
std::weak_ptr<Mob> followFriend; std::weak_ptr<Mob> followFriend;

View file

@ -3,35 +3,31 @@
#include "../../Headers/net.minecraft.world.entity.ai.control.h" #include "../../Headers/net.minecraft.world.entity.ai.control.h"
#include "RandomLookAroundGoal.h" #include "RandomLookAroundGoal.h"
RandomLookAroundGoal::RandomLookAroundGoal(Mob *mob) RandomLookAroundGoal::RandomLookAroundGoal(Mob* mob) {
{
relX = relZ = 0.0; relX = relZ = 0.0;
lookTime = 0; lookTime = 0;
this->mob = mob; this->mob = mob;
setRequiredControlFlags(Control::MoveControlFlag | Control::LookControlFlag); setRequiredControlFlags(Control::MoveControlFlag |
Control::LookControlFlag);
} }
bool RandomLookAroundGoal::canUse() bool RandomLookAroundGoal::canUse() {
{
return mob->getRandom()->nextFloat() < 0.02f; return mob->getRandom()->nextFloat() < 0.02f;
} }
bool RandomLookAroundGoal::canContinueToUse() bool RandomLookAroundGoal::canContinueToUse() { return lookTime >= 0; }
{
return lookTime >= 0;
}
void RandomLookAroundGoal::start() void RandomLookAroundGoal::start() {
{
double rnd = 2 * PI * mob->getRandom()->nextDouble(); double rnd = 2 * PI * mob->getRandom()->nextDouble();
relX = cos(rnd); relX = cos(rnd);
relZ = sin(rnd); relZ = sin(rnd);
lookTime = 20 + mob->getRandom()->nextInt(20); lookTime = 20 + mob->getRandom()->nextInt(20);
} }
void RandomLookAroundGoal::tick() void RandomLookAroundGoal::tick() {
{
--lookTime; --lookTime;
mob->getLookControl()->setLookAt(mob->x + relX, mob->y + mob->getHeadHeight(), mob->z + relZ, 10, mob->getMaxHeadXRot()); mob->getLookControl()->setLookAt(mob->x + relX,
mob->y + mob->getHeadHeight(),
mob->z + relZ, 10, mob->getMaxHeadXRot());
} }

View file

@ -2,8 +2,7 @@
#include "Goal.h" #include "Goal.h"
class RandomLookAroundGoal : public Goal class RandomLookAroundGoal : public Goal {
{
private: private:
Mob* mob; Mob* mob;
double relX, relZ; double relX, relZ;

View file

@ -7,54 +7,55 @@
#include "../../Util/SharedConstants.h" #include "../../Util/SharedConstants.h"
#include "RandomStrollGoal.h" #include "RandomStrollGoal.h"
RandomStrollGoal::RandomStrollGoal(PathfinderMob *mob, float speed) RandomStrollGoal::RandomStrollGoal(PathfinderMob* mob, float speed) {
{
this->mob = mob; this->mob = mob;
this->speed = speed; this->speed = speed;
setRequiredControlFlags(Control::MoveControlFlag | Control::LookControlFlag); setRequiredControlFlags(Control::MoveControlFlag |
Control::LookControlFlag);
} }
bool RandomStrollGoal::canUse() bool RandomStrollGoal::canUse() {
{ // 4J - altered a little so we can do some more random strolling when
// 4J - altered a little so we can do some more random strolling when appropriate, to try and move any animals that aren't confined to a fenced-off region far enough to determine we can despawn them // appropriate, to try and move any animals that aren't confined to a
if (mob->getNoActionTime() < SharedConstants::TICKS_PER_SECOND * 5) // fenced-off region far enough to determine we can despawn them
{ if (mob->getNoActionTime() < SharedConstants::TICKS_PER_SECOND * 5) {
if (mob->getRandom()->nextInt(120) == 0) if (mob->getRandom()->nextInt(120) == 0) {
{ Vec3* pos =
Vec3 *pos = RandomPos::getPos(std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()), 10, 7); RandomPos::getPos(std::dynamic_pointer_cast<PathfinderMob>(
mob->shared_from_this()),
10, 7);
if (pos == NULL) return false; if (pos == NULL) return false;
wantedX = pos->x; wantedX = pos->x;
wantedY = pos->y; wantedY = pos->y;
wantedZ = pos->z; wantedZ = pos->z;
return true; return true;
} }
} } else {
else // This entity wouldn't normally be randomly strolling. However, if our
{ // management system says that it should do, then do. Don't bother
// This entity wouldn't normally be randomly strolling. However, if our management system says that it should do, then do. Don't // waiting for random conditions to be met before picking a direction
// bother waiting for random conditions to be met before picking a direction though as the point here is to see if it is possible to // though as the point here is to see if it is possible to stroll out of
// stroll out of a given area and so waiting around is just wasting time // a given area and so waiting around is just wasting time
if( mob->isExtraWanderingEnabled() ) if (mob->isExtraWanderingEnabled()) {
{ Vec3* pos =
Vec3 *pos = RandomPos::getPos(std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()), 10, 7,mob->getWanderingQuadrant()); RandomPos::getPos(std::dynamic_pointer_cast<PathfinderMob>(
mob->shared_from_this()),
10, 7, mob->getWanderingQuadrant());
if (pos == NULL) return false; if (pos == NULL) return false;
wantedX = pos->x; wantedX = pos->x;
wantedY = pos->y; wantedY = pos->y;
wantedZ = pos->z; wantedZ = pos->z;
return true; return true;
} }
} }
return false; return false;
} }
bool RandomStrollGoal::canContinueToUse() bool RandomStrollGoal::canContinueToUse() {
{
return !mob->getNavigation()->isDone(); return !mob->getNavigation()->isDone();
} }
void RandomStrollGoal::start() void RandomStrollGoal::start() {
{
mob->getNavigation()->moveTo(wantedX, wantedY, wantedZ, speed); mob->getNavigation()->moveTo(wantedX, wantedY, wantedZ, speed);
} }

View file

@ -4,8 +4,7 @@
class PathfinderMob; class PathfinderMob;
class RandomStrollGoal : public Goal class RandomStrollGoal : public Goal {
{
private: private:
PathfinderMob* mob; PathfinderMob* mob;
double wantedX, wantedY, wantedZ; double wantedX, wantedY, wantedZ;

View file

@ -5,45 +5,44 @@
#include "../../Headers/net.minecraft.world.level.h" #include "../../Headers/net.minecraft.world.level.h"
#include "RestrictOpenDoorGoal.h" #include "RestrictOpenDoorGoal.h"
RestrictOpenDoorGoal::RestrictOpenDoorGoal(PathfinderMob *mob) RestrictOpenDoorGoal::RestrictOpenDoorGoal(PathfinderMob* mob) {
{
this->mob = mob; this->mob = mob;
} }
bool RestrictOpenDoorGoal::canUse() bool RestrictOpenDoorGoal::canUse() {
{
if (mob->level->isDay()) return false; if (mob->level->isDay()) return false;
std::shared_ptr<Village> village = mob->level->villages->getClosestVillage(Mth::floor(mob->x), Mth::floor(mob->y), Mth::floor(mob->z), 16); std::shared_ptr<Village> village = mob->level->villages->getClosestVillage(
Mth::floor(mob->x), Mth::floor(mob->y), Mth::floor(mob->z), 16);
if (village == NULL) return false; if (village == NULL) return false;
std::shared_ptr<DoorInfo> _doorInfo = village->getClosestDoorInfo(Mth::floor(mob->x), Mth::floor(mob->y), Mth::floor(mob->z)); std::shared_ptr<DoorInfo> _doorInfo = village->getClosestDoorInfo(
Mth::floor(mob->x), Mth::floor(mob->y), Mth::floor(mob->z));
if (_doorInfo == NULL) return false; if (_doorInfo == NULL) return false;
doorInfo = _doorInfo; doorInfo = _doorInfo;
return _doorInfo->distanceToInsideSqr(Mth::floor(mob->x), Mth::floor(mob->y), Mth::floor(mob->z)) < 1.5 * 1.5; return _doorInfo->distanceToInsideSqr(Mth::floor(mob->x),
Mth::floor(mob->y),
Mth::floor(mob->z)) < 1.5 * 1.5;
} }
bool RestrictOpenDoorGoal::canContinueToUse() bool RestrictOpenDoorGoal::canContinueToUse() {
{
if (mob->level->isDay()) return false; if (mob->level->isDay()) return false;
std::shared_ptr<DoorInfo> _doorInfo = doorInfo.lock(); std::shared_ptr<DoorInfo> _doorInfo = doorInfo.lock();
if (_doorInfo == NULL) return false; if (_doorInfo == NULL) return false;
return !_doorInfo->removed && _doorInfo->isInsideSide(Mth::floor(mob->x), Mth::floor(mob->z)); return !_doorInfo->removed &&
_doorInfo->isInsideSide(Mth::floor(mob->x), Mth::floor(mob->z));
} }
void RestrictOpenDoorGoal::start() void RestrictOpenDoorGoal::start() {
{
mob->getNavigation()->setCanOpenDoors(false); mob->getNavigation()->setCanOpenDoors(false);
mob->getNavigation()->setCanPassDoors(false); mob->getNavigation()->setCanPassDoors(false);
} }
void RestrictOpenDoorGoal::stop() void RestrictOpenDoorGoal::stop() {
{
mob->getNavigation()->setCanOpenDoors(true); mob->getNavigation()->setCanOpenDoors(true);
mob->getNavigation()->setCanPassDoors(true); mob->getNavigation()->setCanPassDoors(true);
doorInfo = std::weak_ptr<DoorInfo>(); doorInfo = std::weak_ptr<DoorInfo>();
} }
void RestrictOpenDoorGoal::tick() void RestrictOpenDoorGoal::tick() {
{
std::shared_ptr<DoorInfo> _doorInfo = doorInfo.lock(); std::shared_ptr<DoorInfo> _doorInfo = doorInfo.lock();
if (_doorInfo) _doorInfo->incBookingCount(); if (_doorInfo) _doorInfo->incBookingCount();
} }

View file

@ -5,8 +5,7 @@
class PathfinderMob; class PathfinderMob;
class DoorInfo; class DoorInfo;
class RestrictOpenDoorGoal : public Goal class RestrictOpenDoorGoal : public Goal {
{
private: private:
PathfinderMob* mob; PathfinderMob* mob;
std::weak_ptr<DoorInfo> doorInfo; std::weak_ptr<DoorInfo> doorInfo;

View file

@ -4,22 +4,10 @@
#include "../../Headers/net.minecraft.world.level.h" #include "../../Headers/net.minecraft.world.level.h"
#include "RestrictSunGoal.h" #include "RestrictSunGoal.h"
RestrictSunGoal::RestrictSunGoal(PathfinderMob *mob) RestrictSunGoal::RestrictSunGoal(PathfinderMob* mob) { this->mob = mob; }
{
this->mob = mob;
}
bool RestrictSunGoal::canUse() bool RestrictSunGoal::canUse() { return mob->level->isDay(); }
{
return mob->level->isDay();
}
void RestrictSunGoal::start() void RestrictSunGoal::start() { mob->getNavigation()->setAvoidSun(true); }
{
mob->getNavigation()->setAvoidSun(true);
}
void RestrictSunGoal::stop() void RestrictSunGoal::stop() { mob->getNavigation()->setAvoidSun(false); }
{
mob->getNavigation()->setAvoidSun(false);
}

View file

@ -2,8 +2,7 @@
#include "Goal.h" #include "Goal.h"
class RestrictSunGoal : public Goal class RestrictSunGoal : public Goal {
{
private: private:
PathfinderMob* mob; PathfinderMob* mob;

View file

@ -6,16 +6,15 @@
#include "../../Headers/net.minecraft.world.entity.animal.h" #include "../../Headers/net.minecraft.world.entity.animal.h"
#include "SitGoal.h" #include "SitGoal.h"
SitGoal::SitGoal(TamableAnimal *mob) SitGoal::SitGoal(TamableAnimal* mob) {
{
_wantToSit = false; _wantToSit = false;
this->mob = mob; this->mob = mob;
setRequiredControlFlags(Control::JumpControlFlag | Control::MoveControlFlag); setRequiredControlFlags(Control::JumpControlFlag |
Control::MoveControlFlag);
} }
bool SitGoal::canUse() bool SitGoal::canUse() {
{
if (!mob->isTame()) return false; if (!mob->isTame()) return false;
if (mob->isInWater()) return false; if (mob->isInWater()) return false;
if (!mob->onGround) return false; if (!mob->onGround) return false;
@ -23,23 +22,19 @@ bool SitGoal::canUse()
std::shared_ptr<Mob> owner = mob->getOwner(); std::shared_ptr<Mob> owner = mob->getOwner();
if (owner == NULL) return true; // owner not on level if (owner == NULL) return true; // owner not on level
if (mob->distanceToSqr(owner) < FollowOwnerGoal::TeleportDistance * FollowOwnerGoal::TeleportDistance && owner->getLastHurtByMob() != NULL) return false; if (mob->distanceToSqr(owner) < FollowOwnerGoal::TeleportDistance *
FollowOwnerGoal::TeleportDistance &&
owner->getLastHurtByMob() != NULL)
return false;
return _wantToSit; return _wantToSit;
} }
void SitGoal::start() void SitGoal::start() {
{
mob->getNavigation()->stop(); mob->getNavigation()->stop();
mob->setSitting(true); mob->setSitting(true);
} }
void SitGoal::stop() void SitGoal::stop() { mob->setSitting(false); }
{
mob->setSitting(false);
}
void SitGoal::wantToSit(bool _wantToSit) void SitGoal::wantToSit(bool _wantToSit) { this->_wantToSit = _wantToSit; }
{
this->_wantToSit = _wantToSit;
}

View file

@ -2,8 +2,7 @@
#include "Goal.h" #include "Goal.h"
class SitGoal : public Goal class SitGoal : public Goal {
{
private: private:
TamableAnimal* mob; TamableAnimal* mob;
bool _wantToSit; bool _wantToSit;

View file

@ -5,47 +5,38 @@
#include "../../Headers/net.minecraft.world.entity.monster.h" #include "../../Headers/net.minecraft.world.entity.monster.h"
#include "SwellGoal.h" #include "SwellGoal.h"
SwellGoal::SwellGoal(Creeper *creeper) SwellGoal::SwellGoal(Creeper* creeper) {
{
target = std::weak_ptr<Mob>(); target = std::weak_ptr<Mob>();
this->creeper = creeper; this->creeper = creeper;
setRequiredControlFlags(Control::MoveControlFlag); setRequiredControlFlags(Control::MoveControlFlag);
} }
bool SwellGoal::canUse() bool SwellGoal::canUse() {
{
std::shared_ptr<Mob> target = creeper->getTarget(); std::shared_ptr<Mob> target = creeper->getTarget();
return creeper->getSwellDir() > 0 || (target != NULL && (creeper->distanceToSqr(target) < 3 * 3)); return creeper->getSwellDir() > 0 ||
(target != NULL && (creeper->distanceToSqr(target) < 3 * 3));
} }
void SwellGoal::start() void SwellGoal::start() {
{
creeper->getNavigation()->stop(); creeper->getNavigation()->stop();
target = std::weak_ptr<Mob>(creeper->getTarget()); target = std::weak_ptr<Mob>(creeper->getTarget());
} }
void SwellGoal::stop() void SwellGoal::stop() { target = std::weak_ptr<Mob>(); }
{
target = std::weak_ptr<Mob>();
}
void SwellGoal::tick() void SwellGoal::tick() {
{ if (target.lock() == NULL) {
if (target.lock() == NULL)
{
creeper->setSwellDir(-1); creeper->setSwellDir(-1);
return; return;
} }
if (creeper->distanceToSqr(target.lock()) > 7 * 7) if (creeper->distanceToSqr(target.lock()) > 7 * 7) {
{
creeper->setSwellDir(-1); creeper->setSwellDir(-1);
return; return;
} }
if (!creeper->getSensing()->canSee(target.lock())) if (!creeper->getSensing()->canSee(target.lock())) {
{
creeper->setSwellDir(-1); creeper->setSwellDir(-1);
return; return;
} }

View file

@ -4,8 +4,7 @@
class Creeper; class Creeper;
class SwellGoal : public Goal class SwellGoal : public Goal {
{
private: private:
Creeper* creeper; Creeper* creeper;
std::weak_ptr<Mob> target; std::weak_ptr<Mob> target;

View file

@ -8,34 +8,33 @@
#include "../../Headers/net.minecraft.world.phys.h" #include "../../Headers/net.minecraft.world.phys.h"
#include "TakeFlowerGoal.h" #include "TakeFlowerGoal.h"
TakeFlowerGoal::TakeFlowerGoal(Villager *villager) TakeFlowerGoal::TakeFlowerGoal(Villager* villager) {
{
takeFlower = false; takeFlower = false;
pickupTick = 0; pickupTick = 0;
golem = std::weak_ptr<VillagerGolem>(); golem = std::weak_ptr<VillagerGolem>();
this->villager = villager; this->villager = villager;
setRequiredControlFlags(Control::MoveControlFlag | Control::LookControlFlag); setRequiredControlFlags(Control::MoveControlFlag |
Control::LookControlFlag);
} }
bool TakeFlowerGoal::canUse() bool TakeFlowerGoal::canUse() {
{
if (villager->getAge() >= 0) return false; if (villager->getAge() >= 0) return false;
if (!villager->level->isDay()) return false; if (!villager->level->isDay()) return false;
std::vector<std::shared_ptr<Entity> > *golems = villager->level->getEntitiesOfClass(typeid(VillagerGolem), villager->bb->grow(6, 2, 6)); std::vector<std::shared_ptr<Entity> >* golems =
if (golems->size() == 0) villager->level->getEntitiesOfClass(typeid(VillagerGolem),
{ villager->bb->grow(6, 2, 6));
if (golems->size() == 0) {
delete golems; delete golems;
return false; return false;
} }
// for (Entity e : golems) // for (Entity e : golems)
for(AUTO_VAR(it,golems->begin()); it != golems->end(); ++it) for (AUTO_VAR(it, golems->begin()); it != golems->end(); ++it) {
{ std::shared_ptr<VillagerGolem> vg =
std::shared_ptr<VillagerGolem> vg = std::dynamic_pointer_cast<VillagerGolem>(*it); std::dynamic_pointer_cast<VillagerGolem>(*it);
if (vg->getOfferFlowerTick() > 0) if (vg->getOfferFlowerTick() > 0) {
{
golem = std::weak_ptr<VillagerGolem>(vg); golem = std::weak_ptr<VillagerGolem>(vg);
break; break;
} }
@ -44,37 +43,31 @@ bool TakeFlowerGoal::canUse()
return golem.lock() != NULL; return golem.lock() != NULL;
} }
bool TakeFlowerGoal::canContinueToUse() bool TakeFlowerGoal::canContinueToUse() {
{
return golem.lock() != NULL && golem.lock()->getOfferFlowerTick() > 0; return golem.lock() != NULL && golem.lock()->getOfferFlowerTick() > 0;
} }
void TakeFlowerGoal::start() void TakeFlowerGoal::start() {
{ pickupTick = villager->getRandom()->nextInt(
pickupTick = villager->getRandom()->nextInt((int) (OfferFlowerGoal::OFFER_TICKS * 0.8)); (int)(OfferFlowerGoal::OFFER_TICKS * 0.8));
takeFlower = false; takeFlower = false;
golem.lock()->getNavigation()->stop(); golem.lock()->getNavigation()->stop();
} }
void TakeFlowerGoal::stop() void TakeFlowerGoal::stop() {
{
golem = std::weak_ptr<VillagerGolem>(); golem = std::weak_ptr<VillagerGolem>();
villager->getNavigation()->stop(); villager->getNavigation()->stop();
} }
void TakeFlowerGoal::tick() void TakeFlowerGoal::tick() {
{
villager->getLookControl()->setLookAt(golem.lock(), 30, 30); villager->getLookControl()->setLookAt(golem.lock(), 30, 30);
if (golem.lock()->getOfferFlowerTick() == pickupTick) if (golem.lock()->getOfferFlowerTick() == pickupTick) {
{
villager->getNavigation()->moveTo(golem.lock(), 0.15f); villager->getNavigation()->moveTo(golem.lock(), 0.15f);
takeFlower = true; takeFlower = true;
} }
if (takeFlower) if (takeFlower) {
{ if (villager->distanceToSqr(golem.lock()) < 2 * 2) {
if (villager->distanceToSqr(golem.lock()) < 2 * 2)
{
golem.lock()->offerFlower(false); golem.lock()->offerFlower(false);
villager->getNavigation()->stop(); villager->getNavigation()->stop();
} }

View file

@ -2,8 +2,7 @@
#include "Goal.h" #include "Goal.h"
class TakeFlowerGoal : public Goal class TakeFlowerGoal : public Goal {
{
private: private:
Villager* villager; Villager* villager;
std::weak_ptr<VillagerGolem> golem; std::weak_ptr<VillagerGolem> golem;

View file

@ -8,8 +8,7 @@
#include "../../Headers/net.minecraft.world.phys.h" #include "../../Headers/net.minecraft.world.phys.h"
#include "TargetGoal.h" #include "TargetGoal.h"
void TargetGoal::_init(Mob *mob, float within, bool mustSee, bool mustReach) void TargetGoal::_init(Mob* mob, float within, bool mustSee, bool mustReach) {
{
reachCache = EmptyReachCache; reachCache = EmptyReachCache;
reachCacheTime = 0; reachCacheTime = 0;
unseenTicks = 0; unseenTicks = 0;
@ -20,89 +19,79 @@ void TargetGoal::_init(Mob *mob, float within, bool mustSee, bool mustReach)
this->mustReach = mustReach; this->mustReach = mustReach;
} }
TargetGoal::TargetGoal(Mob *mob, float within, bool mustSee) TargetGoal::TargetGoal(Mob* mob, float within, bool mustSee) {
{
_init(mob, within, mustSee, false); _init(mob, within, mustSee, false);
} }
TargetGoal::TargetGoal(Mob *mob, float within, bool mustSee, bool mustReach) TargetGoal::TargetGoal(Mob* mob, float within, bool mustSee, bool mustReach) {
{
_init(mob, within, mustSee, mustReach); _init(mob, within, mustSee, mustReach);
} }
bool TargetGoal::canContinueToUse() bool TargetGoal::canContinueToUse() {
{
std::shared_ptr<Mob> target = mob->getTarget(); std::shared_ptr<Mob> target = mob->getTarget();
if (target == NULL) return false; if (target == NULL) return false;
if (!target->isAlive()) return false; if (!target->isAlive()) return false;
if (mob->distanceToSqr(target) > within * within) return false; if (mob->distanceToSqr(target) > within * within) return false;
if (mustSee) if (mustSee) {
{ if (mob->getSensing()->canSee(target)) {
if (mob->getSensing()->canSee(target))
{
unseenTicks = 0; unseenTicks = 0;
} } else {
else
{
if (++unseenTicks > UnseenMemoryTicks) return false; if (++unseenTicks > UnseenMemoryTicks) return false;
} }
} }
return true; return true;
} }
void TargetGoal::start() void TargetGoal::start() {
{
reachCache = EmptyReachCache; reachCache = EmptyReachCache;
reachCacheTime = 0; reachCacheTime = 0;
unseenTicks = 0; unseenTicks = 0;
} }
void TargetGoal::stop() void TargetGoal::stop() { mob->setTarget(nullptr); }
{
mob->setTarget(nullptr);
}
bool TargetGoal::canAttack(std::shared_ptr<Mob> target, bool allowInvulnerable) bool TargetGoal::canAttack(std::shared_ptr<Mob> target,
{ bool allowInvulnerable) {
if (target == NULL) return false; if (target == NULL) return false;
if (target == mob->shared_from_this()) return false; if (target == mob->shared_from_this()) return false;
if (!target->isAlive()) return false; if (!target->isAlive()) return false;
if (!mob->canAttackType(target->GetType())) return false; if (!mob->canAttackType(target->GetType())) return false;
std::shared_ptr<TamableAnimal> tamableAnimal = std::dynamic_pointer_cast<TamableAnimal>(mob->shared_from_this()); std::shared_ptr<TamableAnimal> tamableAnimal =
if (tamableAnimal != NULL && tamableAnimal->isTame()) std::dynamic_pointer_cast<TamableAnimal>(mob->shared_from_this());
{ if (tamableAnimal != NULL && tamableAnimal->isTame()) {
std::shared_ptr<TamableAnimal> tamableTarget = std::dynamic_pointer_cast<TamableAnimal>(target); std::shared_ptr<TamableAnimal> tamableTarget =
std::dynamic_pointer_cast<TamableAnimal>(target);
if (tamableTarget != NULL && tamableTarget->isTame()) return false; if (tamableTarget != NULL && tamableTarget->isTame()) return false;
if (target == tamableAnimal->getOwner()) return false; if (target == tamableAnimal->getOwner()) return false;
} } else if (std::dynamic_pointer_cast<Player>(target) != NULL) {
else if (std::dynamic_pointer_cast<Player>(target) != NULL) if (!allowInvulnerable &&
{ (std::dynamic_pointer_cast<Player>(target))->abilities.invulnerable)
if (!allowInvulnerable && (std::dynamic_pointer_cast<Player>(target))->abilities.invulnerable) return false; return false;
} }
if (!mob->isWithinRestriction(Mth::floor(target->x), Mth::floor(target->y), Mth::floor(target->z))) return false; if (!mob->isWithinRestriction(Mth::floor(target->x), Mth::floor(target->y),
Mth::floor(target->z)))
return false;
if (mustSee && !mob->getSensing()->canSee(target)) return false; if (mustSee && !mob->getSensing()->canSee(target)) return false;
if (mustReach) if (mustReach) {
{
if (--reachCacheTime <= 0) reachCache = EmptyReachCache; if (--reachCacheTime <= 0) reachCache = EmptyReachCache;
if (reachCache == EmptyReachCache) reachCache = canReach(target) ? CanReachCache : CantReachCache; if (reachCache == EmptyReachCache)
reachCache = canReach(target) ? CanReachCache : CantReachCache;
if (reachCache == CantReachCache) return false; if (reachCache == CantReachCache) return false;
} }
return true; return true;
} }
bool TargetGoal::canReach(std::shared_ptr<Mob> target) bool TargetGoal::canReach(std::shared_ptr<Mob> target) {
{
reachCacheTime = 10 + mob->getRandom()->nextInt(5); reachCacheTime = 10 + mob->getRandom()->nextInt(5);
Path* path = mob->getNavigation()->createPath(target); Path* path = mob->getNavigation()->createPath(target);
if (path == NULL) return false; if (path == NULL) return false;
Node* last = path->last(); Node* last = path->last();
if (last == NULL) if (last == NULL) {
{
delete path; delete path;
return false; return false;
} }

View file

@ -2,9 +2,7 @@
#include "Goal.h" #include "Goal.h"
class TargetGoal : public Goal class TargetGoal : public Goal {
{
public: public:
static const int TargetFlag = 1; static const int TargetFlag = 1;

View file

@ -6,8 +6,8 @@
#include "../../Headers/net.minecraft.world.level.h" #include "../../Headers/net.minecraft.world.level.h"
#include "TemptGoal.h" #include "TemptGoal.h"
TemptGoal::TemptGoal(PathfinderMob *mob, float speed, int itemId, bool canScare) TemptGoal::TemptGoal(PathfinderMob* mob, float speed, int itemId,
{ bool canScare) {
px = py = pz = pRotX = pRotY = 0.0; px = py = pz = pRotX = pRotY = 0.0;
player = std::weak_ptr<Player>(); player = std::weak_ptr<Player>();
calmDown = 0; calmDown = 0;
@ -18,37 +18,37 @@ TemptGoal::TemptGoal(PathfinderMob *mob, float speed, int itemId, bool canScare)
this->speed = speed; this->speed = speed;
this->itemId = itemId; this->itemId = itemId;
this->canScare = canScare; this->canScare = canScare;
setRequiredControlFlags(Control::MoveControlFlag | Control::LookControlFlag); setRequiredControlFlags(Control::MoveControlFlag |
Control::LookControlFlag);
} }
bool TemptGoal::canUse() bool TemptGoal::canUse() {
{ if (calmDown > 0) {
if (calmDown > 0)
{
--calmDown; --calmDown;
return false; return false;
} }
player = std::weak_ptr<Player>(mob->level->getNearestPlayer(mob->shared_from_this(), 10)); player = std::weak_ptr<Player>(
mob->level->getNearestPlayer(mob->shared_from_this(), 10));
if (player.lock() == NULL) return false; if (player.lock() == NULL) return false;
mob->setDespawnProtected(); // If we've got a nearby player, then consider this mob as something we'd miss if it despawned mob->setDespawnProtected(); // If we've got a nearby player, then consider
// this mob as something we'd miss if it
// despawned
std::shared_ptr<ItemInstance> item = player.lock()->getSelectedItem(); std::shared_ptr<ItemInstance> item = player.lock()->getSelectedItem();
if (item == NULL) return false; if (item == NULL) return false;
if (item->id != itemId) return false; if (item->id != itemId) return false;
return true; return true;
} }
bool TemptGoal::canContinueToUse() bool TemptGoal::canContinueToUse() {
{ if (canScare) {
if (canScare)
{
if (player.lock() == NULL) return false; if (player.lock() == NULL) return false;
if (mob->distanceToSqr(player.lock()) < 6 * 6) if (mob->distanceToSqr(player.lock()) < 6 * 6) {
{ if (player.lock()->distanceToSqr(px, py, pz) > 0.1 * 0.1)
if (player.lock()->distanceToSqr(px, py, pz) > 0.1 * 0.1) return false; return false;
if (abs(player.lock()->xRot - pRotX) > 5 || abs(player.lock()->yRot - pRotY) > 5) return false; if (abs(player.lock()->xRot - pRotX) > 5 ||
} abs(player.lock()->yRot - pRotY) > 5)
else return false;
{ } else {
px = player.lock()->x; px = player.lock()->x;
py = player.lock()->y; py = player.lock()->y;
pz = player.lock()->z; pz = player.lock()->z;
@ -59,8 +59,7 @@ bool TemptGoal::canContinueToUse()
return canUse(); return canUse();
} }
void TemptGoal::start() void TemptGoal::start() {
{
px = player.lock()->x; px = player.lock()->x;
py = player.lock()->y; py = player.lock()->y;
pz = player.lock()->z; pz = player.lock()->z;
@ -69,8 +68,7 @@ void TemptGoal::start()
mob->getNavigation()->setAvoidWater(false); mob->getNavigation()->setAvoidWater(false);
} }
void TemptGoal::stop() void TemptGoal::stop() {
{
player = std::weak_ptr<Player>(); player = std::weak_ptr<Player>();
mob->getNavigation()->stop(); mob->getNavigation()->stop();
calmDown = 100; calmDown = 100;
@ -78,14 +76,12 @@ void TemptGoal::stop()
mob->getNavigation()->setAvoidWater(oldAvoidWater); mob->getNavigation()->setAvoidWater(oldAvoidWater);
} }
void TemptGoal::tick() void TemptGoal::tick() {
{
mob->getLookControl()->setLookAt(player.lock(), 30, mob->getMaxHeadXRot()); mob->getLookControl()->setLookAt(player.lock(), 30, mob->getMaxHeadXRot());
if (mob->distanceToSqr(player.lock()) < 2.5 * 2.5) mob->getNavigation()->stop(); if (mob->distanceToSqr(player.lock()) < 2.5 * 2.5)
else mob->getNavigation()->moveTo(player.lock(), speed); mob->getNavigation()->stop();
else
mob->getNavigation()->moveTo(player.lock(), speed);
} }
bool TemptGoal::isRunning() bool TemptGoal::isRunning() { return _isRunning; }
{
return _isRunning;
}

Some files were not shown because too many files have changed in this diff Show more