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,50 +5,46 @@
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); lastHeadY = mob->yHeadRot;
lastHeadY = mob->yHeadRot; timeStill = 0;
timeStill = 0; return;
return; }
}
// 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 {
} ++timeStill;
else static const int timeStillBeforeTurn = 10;
{ if (timeStill > timeStillBeforeTurn)
++timeStill; clampAngle =
static const int timeStillBeforeTurn = 10; std::max(1 - (timeStill - timeStillBeforeTurn) / 10.f, 0.0f) *
if (timeStill > timeStillBeforeTurn) clampAngle = std::max(1 - (timeStill - timeStillBeforeTurn) / 10.f, 0.0f) * maxClampAngle; 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; return clampTo - headDiffBody;
return clampTo - headDiffBody;
} }

View file

@ -2,19 +2,18 @@
#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;
int timeStill; int timeStill;
float lastHeadY; float lastHeadY;
public: public:
BodyControl(Mob *mob); BodyControl(Mob* mob);
void clientTick(); void clientTick();
private: private:
float clamp(float clampTo, float clampFrom, float clampAngle); float clamp(float clampTo, float clampFrom, float clampAngle);
}; };

View file

@ -1,9 +1,8 @@
#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;
static const int JumpControlFlag = 4; static const int JumpControlFlag = 4;
}; };

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,17 +4,16 @@
class Mob; class Mob;
class JumpControl : public Control class JumpControl : public Control {
{
private: private:
Mob *mob; Mob* mob;
bool _jump; bool _jump;
public: public:
JumpControl(Mob *mob); JumpControl(Mob* mob);
virtual ~JumpControl(){} virtual ~JumpControl() {}
void jump(); void jump();
//genuinly, why tf is this VIRTUAL // genuinly, why tf is this VIRTUAL
virtual void tick(); virtual void tick();
}; };

View file

@ -4,114 +4,87 @@
#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;
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();
this->wantedZ = target->z; else
this->yMax = yMax; this->wantedY = (target->bb->y0 + target->bb->y1) / 2;
this->xMax = xMax; this->wantedZ = target->z;
hasWanted = true; this->yMax = yMax;
this->xMax = xMax;
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;
this->yMax = yMax; this->yMax = yMax;
this->xMax = xMax; this->xMax = 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;
double yd = wantedY - (mob->y + mob->getHeadHeight()); double yd = wantedY - (mob->y + mob->getHeadHeight());
double zd = wantedZ - mob->z; double zd = wantedZ - mob->z;
double sd = sqrt(xd * xd + zd * zd); double sd = sqrt(xd * xd + zd * zd);
float yRotD = (float) (atan2(zd, xd) * 180 / PI) - 90; float yRotD = (float)(atan2(zd, xd) * 180 / PI) - 90;
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) diff += 360;
while (diff < -180) while (diff >= 180) diff -= 360;
diff += 360; if (diff > max) {
while (diff >= 180) diff = max;
diff -= 360; }
if (diff > max) if (diff < -max) {
{ diff = -max;
diff = max; }
} return a + diff;
if (diff < -max)
{
diff = -max;
}
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,31 +4,30 @@
class Mob; class Mob;
class LookControl : public Control class LookControl : public Control {
{
private: private:
Mob *mob; Mob* mob;
float yMax, xMax; float yMax, xMax;
bool hasWanted; bool hasWanted;
double wantedX, wantedY, wantedZ; double wantedX, wantedY, wantedZ;
public: public:
LookControl(Mob *mob); LookControl(Mob* mob);
virtual ~LookControl(){} virtual ~LookControl() {}
void setLookAt(std::shared_ptr<Entity> target, float yMax, float xMax); void setLookAt(std::shared_ptr<Entity> target, float yMax, float xMax);
void setLookAt(double x, double y, double z, float yMax, float xMax); void setLookAt(double x, double y, double z, float yMax, float xMax);
virtual void tick(); virtual void tick();
private: private:
float rotlerp(float a, float b, float max); float rotlerp(float a, float b, float max);
public: public:
bool isHasWanted(); bool isHasWanted();
float getYMax(); float getYMax();
float getXMax(); float getXMax();
double getWantedX(); double getWantedX();
double getWantedY(); double getWantedY();
double getWantedZ(); double getWantedZ();
}; };

View file

@ -7,69 +7,57 @@
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; wantedZ = mob->z;
wantedZ = mob->z;
speed = 0.0f; speed = 0.0f;
_hasWanted = false; _hasWanted = false;
} }
bool MoveControl::hasWanted() bool MoveControl::hasWanted() { return _hasWanted; }
{
return _hasWanted; float MoveControl::getSpeed() { return speed; }
void MoveControl::setWantedPosition(double x, double y, double z, float speed) {
wantedX = x;
wantedY = y;
wantedZ = z;
this->speed = speed;
_hasWanted = true;
} }
float MoveControl::getSpeed() void MoveControl::tick() {
{ mob->setYya(0);
return speed; if (!_hasWanted) return;
_hasWanted = false;
int yFloor = floor(mob->bb->y0 + .5f);
double xd = wantedX - mob->x;
double zd = wantedZ - mob->z;
double yd = wantedY - yFloor;
double dd = xd * xd + yd * yd + zd * zd;
if (dd < MIN_SPEED_SQR) return;
float yRotD = (float)(atan2(zd, xd) * 180 / PI) - 90;
mob->yRot = rotlerp(mob->yRot, yRotD, MAX_TURN);
mob->setSpeed(speed * mob->getWalkingSpeedModifier());
if (yd > 0 && xd * xd + zd * zd < 1) mob->getJumpControl()->jump();
} }
void MoveControl::setWantedPosition(double x, double y, double z, float speed) float MoveControl::rotlerp(float a, float b, float max) {
{ float diff = Mth::wrapDegrees(b - a);
wantedX = x; if (diff > max) {
wantedY = y; diff = max;
wantedZ = z; }
this->speed = speed; if (diff < -max) {
_hasWanted = true; diff = -max;
} }
return a + diff;
void MoveControl::tick()
{
mob->setYya(0);
if (!_hasWanted) return;
_hasWanted = false;
int yFloor = floor(mob->bb->y0 + .5f);
double xd = wantedX - mob->x;
double zd = wantedZ - mob->z;
double yd = wantedY - yFloor;
double dd = xd * xd + yd * yd + zd * zd;
if (dd < MIN_SPEED_SQR) return;
float yRotD = (float) (atan2(zd, xd) * 180 / PI) - 90;
mob->yRot = rotlerp(mob->yRot, yRotD, MAX_TURN);
mob->setSpeed(speed * mob->getWalkingSpeedModifier());
if (yd > 0 && xd * xd + zd * zd < 1) mob->getJumpControl()->jump();
}
float MoveControl::rotlerp(float a, float b, float max)
{
float diff = Mth::wrapDegrees(b - a);
if (diff > max)
{
diff = max;
}
if (diff < -max)
{
diff = -max;
}
return a + diff;
} }

View file

@ -4,32 +4,31 @@
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;
private: private:
static const int MAX_TURN = 30; static const int MAX_TURN = 30;
Mob *mob; Mob* mob;
double wantedX; double wantedX;
double wantedY; double wantedY;
double wantedZ; double wantedZ;
float speed; float speed;
bool _hasWanted; bool _hasWanted;
public: public:
MoveControl(Mob *mob); MoveControl(Mob* mob);
virtual ~MoveControl(){} virtual ~MoveControl() {}
bool hasWanted(); bool hasWanted();
float getSpeed(); float getSpeed();
void setWantedPosition(double x, double y, double z, float speed); void setWantedPosition(double x, double y, double z, float speed);
void setSpeed(float speed); void setSpeed(float speed);
virtual void tick(); virtual void tick();
private: private:
float rotlerp(float a, float b, float max); float rotlerp(float a, float b, float max);
}; };

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() {
seen.clear();
unseen.clear();
} }
void Sensing::tick() bool Sensing::canSee(std::shared_ptr<Entity> target) {
{ // if ( find(seen.begin(), seen.end(), target) != seen.end() ) return true;
seen.clear(); // if ( find(unseen.begin(), unseen.end(), target) != unseen.end()) return
unseen.clear(); // false;
} for (AUTO_VAR(it, seen.begin()); it != seen.end(); ++it) {
if (target == (*it).lock()) return true;
}
for (AUTO_VAR(it, unseen.begin()); it != unseen.end(); ++it) {
if (target == (*it).lock()) return false;
}
bool Sensing::canSee(std::shared_ptr<Entity> target) // util.Timer.push("canSee");
{ bool canSee = mob->canSee(target);
//if ( find(seen.begin(), seen.end(), target) != seen.end() ) return true; // util.Timer.pop();
//if ( find(unseen.begin(), unseen.end(), target) != unseen.end()) return false; if (canSee)
for(AUTO_VAR(it, seen.begin()); it != seen.end(); ++it) seen.push_back(std::weak_ptr<Entity>(target));
{ else
if(target == (*it).lock()) return true; unseen.push_back(std::weak_ptr<Entity>(target));
} return canSee;
for(AUTO_VAR(it, unseen.begin()); it != unseen.end(); ++it)
{
if(target == (*it).lock()) return false;
}
//util.Timer.push("canSee");
bool canSee = mob->canSee(target);
//util.Timer.pop();
if (canSee) seen.push_back(std::weak_ptr<Entity>(target));
else unseen.push_back(std::weak_ptr<Entity>(target));
return canSee;
} }

View file

@ -1,15 +1,14 @@
#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;
std::vector<std::weak_ptr<Entity> > unseen; std::vector<std::weak_ptr<Entity> > unseen;
public: public:
Sensing(Mob *mob); Sensing(Mob* mob);
void tick(); void tick();
bool canSee(std::shared_ptr<Entity> target); bool canSee(std::shared_ptr<Entity> target);
}; };

View file

@ -9,83 +9,82 @@
#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;
seeTime = 0; seeTime = 0;
this->mob = mob; this->mob = mob;
this->level = mob->level; this->level = mob->level;
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() {
double attackRadiusSqr = 10 * 10;
std::shared_ptr<Mob> tar = target.lock();
double targetDistSqr = mob->distanceToSqr(tar->x, tar->bb->y0, tar->z);
bool canSee = mob->getSensing()->canSee(tar);
if (canSee) {
++seeTime;
} else
seeTime = 0;
if (targetDistSqr > attackRadiusSqr || seeTime < 20)
mob->getNavigation()->moveTo(tar, speed);
else
mob->getNavigation()->stop();
mob->getLookControl()->setLookAt(tar, 30, 30);
attackTime = std::max(attackTime - 1, 0);
if (attackTime > 0) return;
if (targetDistSqr > attackRadiusSqr || !canSee) return;
fireAtTarget();
attackTime = attackInterval;
} }
void ArrowAttackGoal::tick() void ArrowAttackGoal::fireAtTarget() {
{ std::shared_ptr<Mob> tar = target.lock();
double attackRadiusSqr = 10 * 10; if (projectileType == ArrowType) {
std::shared_ptr<Mob> tar = target.lock(); std::shared_ptr<Arrow> arrow = std::shared_ptr<Arrow>(new Arrow(
double targetDistSqr = mob->distanceToSqr(tar->x, tar->bb->y0, tar->z); level, std::dynamic_pointer_cast<Mob>(mob->shared_from_this()), tar,
bool canSee = mob->getSensing()->canSee(tar); 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);
} else if (projectileType == SnowballType) {
std::shared_ptr<Snowball> snowball = std::shared_ptr<Snowball>(
new Snowball(level, std::dynamic_pointer_cast<Mob>(
mob->shared_from_this())));
double xd = tar->x - mob->x;
double yd = (tar->y + tar->getHeadHeight() - 1.1f) - snowball->y;
double zd = tar->z - mob->z;
float yo = sqrt(xd * xd + zd * zd) * 0.2f;
snowball->shoot(xd, yd + yo, zd, 1.60f, 12);
if (canSee) level->playSound(mob->shared_from_this(), eSoundType_RANDOM_BOW, 1.0f,
{ 1 / (mob->getRandom()->nextFloat() * 0.4f + 0.8f));
++seeTime; level->addEntity(snowball);
} }
else seeTime = 0;
if (targetDistSqr > attackRadiusSqr || seeTime < 20) mob->getNavigation()->moveTo(tar, speed);
else mob->getNavigation()->stop();
mob->getLookControl()->setLookAt(tar, 30, 30);
attackTime = std::max(attackTime - 1, 0);
if (attackTime > 0) return;
if (targetDistSqr > attackRadiusSqr || !canSee) return;
fireAtTarget();
attackTime = attackInterval;
}
void ArrowAttackGoal::fireAtTarget()
{
std::shared_ptr<Mob> tar = target.lock();
if (projectileType == ArrowType)
{
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->playSound(mob->shared_from_this(), eSoundType_RANDOM_BOW, 1.0f, 1 / (mob->getRandom()->nextFloat() * 0.4f + 0.8f));
level->addEntity(arrow);
}
else if (projectileType == SnowballType)
{
std::shared_ptr<Snowball> snowball = std::shared_ptr<Snowball>( new Snowball(level, std::dynamic_pointer_cast<Mob>(mob->shared_from_this())) );
double xd = tar->x - mob->x;
double yd = (tar->y + tar->getHeadHeight() - 1.1f) - snowball->y;
double zd = tar->z - mob->z;
float yo = sqrt(xd * xd + zd * zd) * 0.2f;
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->addEntity(snowball);
}
} }

View file

@ -2,32 +2,33 @@
#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;
Level *level; Level* level;
Mob *mob; // Owner of this goal Mob* mob; // Owner of this goal
std::weak_ptr<Mob> target; std::weak_ptr<Mob> target;
int attackTime; int attackTime;
float speed; float speed;
int seeTime; int seeTime;
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();
virtual void stop(); virtual void stop();
virtual void tick(); virtual void tick();
private: 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
virtual void setLevel(Level *level) { this->level = level; } // schematics
virtual void setLevel(Level* level) { this->level = level; }
}; };

View file

@ -10,76 +10,77 @@
#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,
this->mob = mob; float walkSpeed, float sprintSpeed)
//this->avoidType = avoidType; : avoidType(avoidType) {
this->maxDist = maxDist; this->mob = mob;
this->walkSpeed = walkSpeed; // this->avoidType = avoidType;
this->sprintSpeed = sprintSpeed; this->maxDist = maxDist;
this->pathNav = mob->getNavigation(); this->walkSpeed = walkSpeed;
setRequiredControlFlags(Control::MoveControlFlag); this->sprintSpeed = sprintSpeed;
this->pathNav = mob->getNavigation();
setRequiredControlFlags(Control::MoveControlFlag);
toAvoid = std::weak_ptr<Entity>(); toAvoid = std::weak_ptr<Entity>();
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>(
toAvoid = std::weak_ptr<Entity>(mob->level->getNearestPlayer(mob->shared_from_this(), maxDist)); 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; }
} toAvoid = std::weak_ptr<Entity>(entities->at(0));
toAvoid = std::weak_ptr<Entity>(entities->at(0)); delete entities;
delete entities; }
}
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(
if (pos == NULL) return false; std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()), 16,
if (toAvoid.lock()->distanceToSqr(pos->x, pos->y, pos->z) < toAvoid.lock()->distanceToSqr(mob->shared_from_this())) return false; 7,
delete path; Vec3::newTemp(toAvoid.lock()->x, toAvoid.lock()->y, toAvoid.lock()->z));
path = pathNav->createPath(pos->x, pos->y, pos->z); if (pos == NULL) return false;
if (path == NULL) return false; if (toAvoid.lock()->distanceToSqr(pos->x, pos->y, pos->z) <
if (!path->endsInXZ(pos)) return false; toAvoid.lock()->distanceToSqr(mob->shared_from_this()))
return true; return false;
delete path;
path = pathNav->createPath(pos->x, pos->y, pos->z);
if (path == NULL) return false;
if (!path->endsInXZ(pos)) return false;
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,24 +6,24 @@ 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;
std::weak_ptr<Entity> toAvoid; std::weak_ptr<Entity> toAvoid;
float maxDist; float maxDist;
Path *path; Path* path;
PathNavigation *pathNav; PathNavigation* pathNav;
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,
~AvoidPlayerGoal(); float maxDist, float walkSpeed, float sprintSpeed);
~AvoidPlayerGoal();
virtual bool canUse(); virtual bool canUse();
virtual bool canContinueToUse(); virtual bool canContinueToUse();
virtual void start(); virtual void start();
virtual void stop(); virtual void stop();
virtual void tick(); virtual void tick();
}; };

View file

@ -6,55 +6,52 @@
#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;
this->wolf = wolf; this->wolf = wolf;
this->level = wolf->level; this->level = wolf->level;
this->lookDistance = lookDistance; this->lookDistance = 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)
if (wolf->distanceToSqr(player.lock()) > lookDistance * lookDistance) return false; 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(),
--lookTime; player.lock()->z, 10, wolf->getMaxHeadXRot());
--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; return wolf->isFood(item);
return wolf->isFood(item);
} }

View file

@ -4,28 +4,28 @@
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;
Level *level; Level* level;
float lookDistance; float lookDistance;
int lookTime; int lookTime;
public: public:
BegGoal(Wolf *wolf, float lookDistance); BegGoal(Wolf* wolf, float lookDistance);
virtual bool canUse(); virtual bool canUse();
virtual bool canContinueToUse(); virtual bool canContinueToUse();
virtual void start(); virtual void start();
virtual void stop(); virtual void stop();
virtual void tick(); virtual void tick();
private: 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
virtual void setLevel(Level *level) { this->level = level; } // schematics
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 &&
return breakTime <= DOOR_BREAK_TIME && !doorTile->isOpen(mob->level, doorX, doorY, doorZ) && d < 2 * 2; !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,
{ doorY, doorZ, 0);
mob->level->levelEvent(LevelEvent::SOUND_ZOMBIE_WOODEN_DOOR, doorX, 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->levelEvent(LevelEvent::SOUND_ZOMBIE_DOOR_CRASH, doorX,
mob->level->setTile(doorX, doorY, doorZ, 0); doorY, doorZ, 0);
mob->level->levelEvent(LevelEvent::SOUND_ZOMBIE_DOOR_CRASH, doorX, doorY, doorZ, 0); mob->level->levelEvent(LevelEvent::PARTICLES_DESTROY_BLOCK, doorX,
mob->level->levelEvent(LevelEvent::PARTICLES_DESTROY_BLOCK, doorX, doorY, doorZ, doorTile->id); doorY, doorZ, doorTile->id);
} }
} }
} }

View file

@ -3,20 +3,19 @@
#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;
int breakTime; int breakTime;
int lastBreakProgress; int lastBreakProgress;
public: public:
BreakDoorGoal(Mob *mob); BreakDoorGoal(Mob* mob);
virtual bool canUse(); virtual bool canUse();
virtual void start(); virtual void start();
virtual void stop(); virtual void stop();
virtual bool canContinueToUse(); virtual bool canContinueToUse();
virtual void tick(); virtual void tick();
}; };

View file

@ -9,108 +9,111 @@
#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 =
std::vector<std::shared_ptr<Entity> > *others = level->getEntitiesOfClass(typeid(*animal), animal->bb->grow(r, r, r)); level->getEntitiesOfClass(typeid(*animal), animal->bb->grow(r, r, r));
for(AUTO_VAR(it, others->begin()); it != others->end(); ++it) 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;
{ return p;
delete others; }
return p; }
} delete others;
} return nullptr;
delete others;
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
animal->resetLove(); // actually producing any offspring
partner.lock()->resetLove(); animal->resetLove();
return; partner.lock()->resetLove();
} 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(
loveCause->awardStat(GenericStats::breedEntity(offspring->GetType()),GenericStats::param_breedEntity(offspring->GetType())); 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); }
} }
}
animal->setAge(5 * 60 * 20); animal->setAge(5 * 60 * 20);
partner.lock()->setAge(5 * 60 * 20); partner.lock()->setAge(5 * 60 * 20);
animal->resetLove(); animal->resetLove();
partner.lock()->resetLove(); partner.lock()->resetLove();
offspring->setAge(-20 * 60 * 20); offspring->setAge(-20 * 60 * 20);
offspring->moveTo(animal->x, animal->y, animal->z, 0, 0); offspring->moveTo(animal->x, animal->y, animal->z, 0, 0);
offspring->setDespawnProtected(); offspring->setDespawnProtected();
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(
level->addParticle(eParticleType_heart, animal->x + random->nextFloat() * animal->bbWidth * 2 - animal->bbWidth, animal->y + .5f + random->nextFloat() * animal->bbHeight, animal->z + random->nextFloat() eParticleType_heart,
* animal->bbWidth * 2 - animal->bbWidth, xa, ya, za); animal->x + random->nextFloat() * animal->bbWidth * 2 -
} animal->bbWidth,
// 4J-PB - Fix for 106869- Customer Encountered: TU12: Content: Gameplay: Breeding animals does not give any Experience Orbs. animal->y + .5f + random->nextFloat() * animal->bbHeight,
level->addEntity( std::shared_ptr<ExperienceOrb>( new ExperienceOrb(level, animal->x, animal->y, animal->z, random->nextInt(7) + 1) ) ); 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.
level->addEntity(std::shared_ptr<ExperienceOrb>(new ExperienceOrb(
level, animal->x, animal->y, animal->z, random->nextInt(7) + 1)));
} }

View file

@ -5,28 +5,28 @@
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;
std::weak_ptr<Animal> partner; std::weak_ptr<Animal> partner;
int loveTime; int loveTime;
float speed; float speed;
public: public:
BreedGoal(Animal *animal, float speed); BreedGoal(Animal* animal, float speed);
virtual bool canUse(); virtual bool canUse();
virtual bool canContinueToUse(); virtual bool canContinueToUse();
virtual void stop(); virtual void stop();
virtual void tick(); virtual void tick();
private: private:
std::shared_ptr<Animal> getFreePartner(); std::shared_ptr<Animal> getFreePartner();
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
virtual void setLevel(Level *level) { this->level = level; } // schematics
virtual void setLevel(Level* level) { this->level = level; }
}; };

View file

@ -8,145 +8,143 @@
#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;
speed = 0; speed = 0;
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
if(mob->getSpeed() < walkSpeed) mob->setSpeed(walkSpeed); // jump on before another goal has made it move and set the speed
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;
if (yrd > 5) yrd = 5; if (yrd > 5) yrd = 5;
if (yrd < -5) yrd = -5; if (yrd < -5) yrd = -5;
mob->yRot = Mth::wrapDegrees(mob->yRot + yrd); mob->yRot = Mth::wrapDegrees(mob->yRot + yrd);
if (speed < maxSpeed) speed += (maxSpeed - speed) * 0.01f; if (speed < maxSpeed) speed += (maxSpeed - speed) * 0.01f;
if (speed > maxSpeed) speed = maxSpeed; if (speed > maxSpeed) speed = maxSpeed;
int x = Mth::floor(mob->x); int x = Mth::floor(mob->x);
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; float dist = std::max((int)moveSpeed, 1);
float dist = std::max((int)moveSpeed, 1); dist = aproxSpeed / dist;
dist = aproxSpeed / dist; float normMoveSpeed = moveSpeed * dist;
float normMoveSpeed = moveSpeed * dist; 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 {
} xa = 0;
else if (za < 0) za -= mob->bbWidth / 2.0f;
{ if (za > 0) za += mob->bbWidth / 2.0f;
xa = 0; }
if (za < 0) za -= mob->bbWidth / 2.0f;
if (za > 0) za += mob->bbWidth / 2.0f;
}
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) ==
pig->getJumpControl()->jump(); PathFinder::TYPE_OPEN) {
} 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>(
replacement->setTag(carriedItem->tag); new ItemInstance(Item::fishingRod));
player->inventory->items[player->inventory->selected] = replacement; replacement->setTag(carriedItem->tag);
} player->inventory->items[player->inventory->selected] =
} replacement;
} }
}
}
mob->travel(0, moveSpeed); mob->travel(0, moveSpeed);
} }
bool ControlledByPlayerGoal::isBoosting() bool ControlledByPlayerGoal::isBoosting() { return boosting; }
{
return boosting; void ControlledByPlayerGoal::boost() {
boosting = true;
boostTime = 0;
boostTimeTotal =
mob->getRandom()->nextInt(MAX_BOOST_TIME + MIN_BOOST_TIME + 1) +
MIN_BOOST_TIME;
} }
void ControlledByPlayerGoal::boost() bool ControlledByPlayerGoal::canBoost() {
{ return !isBoosting() && speed > maxSpeed * 0.3f;
boosting = true;
boostTime = 0;
boostTimeTotal = mob->getRandom()->nextInt(MAX_BOOST_TIME + MIN_BOOST_TIME + 1) + MIN_BOOST_TIME;
}
bool ControlledByPlayerGoal::canBoost()
{
return !isBoosting() && speed > maxSpeed * 0.3f;
} }

View file

@ -5,28 +5,28 @@
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;
Mob *mob; // Owner of this goal Mob* mob; // Owner of this goal
float maxSpeed; float maxSpeed;
float walkSpeed; float walkSpeed;
float speed; float speed;
bool boosting; bool boosting;
int boostTime; int boostTime;
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();
bool canUse(); bool canUse();
void tick(); void tick();
bool isBoosting(); bool isBoosting();
void boost(); void boost();
bool canBoost(); bool canBoost();
}; };

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(
potentialTarget = std::weak_ptr<Mob>(village->getClosestAggressor(std::dynamic_pointer_cast<Mob>(golem->shared_from_this()))); 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,15 +4,14 @@
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;
public: public:
DefendVillageTargetGoal(VillagerGolem *golem); DefendVillageTargetGoal(VillagerGolem* golem);
bool canUse(); bool canUse();
void start(); void start();
}; };

View file

@ -6,68 +6,59 @@
#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; doorOpenDirX = doorOpenDirZ = 0.0f;
doorOpenDirX = doorOpenDirZ = 0.0f;
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())
if (path == NULL || path->isDone() || !pathNav->canOpenDoors()) return false; 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; doorZ = n->z;
doorZ = n->z; if (mob->distanceToSqr(doorX, mob->y, doorZ) > 1.5 * 1.5) continue;
if (mob->distanceToSqr(doorX, mob->y, doorZ) > 1.5 * 1.5) continue; doorTile = getDoorTile(doorX, doorY, doorZ);
doorTile = getDoorTile(doorX, doorY, doorZ); if (doorTile == NULL) continue;
if (doorTile == NULL) continue; return true;
return true; }
}
doorX = Mth::floor(mob->x); doorX = Mth::floor(mob->x);
doorY = Mth::floor(mob->y + 1); doorY = Mth::floor(mob->y + 1);
doorZ = Mth::floor(mob->z); doorZ = Mth::floor(mob->z);
doorTile = getDoorTile(doorX, doorY, doorZ); doorTile = getDoorTile(doorX, doorY, doorZ);
return doorTile != NULL; return doorTile != NULL;
} }
bool DoorInteractGoal::canContinueToUse() bool DoorInteractGoal::canContinueToUse() { return !passed; }
{
return !passed; void DoorInteractGoal::start() {
passed = false;
doorOpenDirX = (float)(doorX + 0.5f - mob->x);
doorOpenDirZ = (float)(doorZ + 0.5f - mob->z);
} }
void DoorInteractGoal::start() void DoorInteractGoal::tick() {
{ float newDoorDirX = (float)(doorX + 0.5f - mob->x);
passed = false; float newDoorDirZ = (float)(doorZ + 0.5f - mob->z);
doorOpenDirX = (float) (doorX + 0.5f - mob->x); float dot = doorOpenDirX * newDoorDirX + doorOpenDirZ * newDoorDirZ;
doorOpenDirZ = (float) (doorZ + 0.5f - mob->z); if (dot < 0) {
passed = true;
}
} }
void DoorInteractGoal::tick() DoorTile* DoorInteractGoal::getDoorTile(int x, int y, int z) {
{ int tileId = mob->level->getTile(x, y, z);
float newDoorDirX = (float) (doorX + 0.5f - mob->x); if (tileId != Tile::door_wood_Id) return NULL;
float newDoorDirZ = (float) (doorZ + 0.5f - mob->z); return (DoorTile*)Tile::tiles[tileId];
float dot = doorOpenDirX * newDoorDirX + doorOpenDirZ * newDoorDirZ;
if (dot < 0)
{
passed = true;
}
}
DoorTile *DoorInteractGoal::getDoorTile(int x, int y, int z)
{
int tileId = mob->level->getTile(x, y, z);
if (tileId != Tile::door_wood_Id) return NULL;
return (DoorTile *) Tile::tiles[tileId];
} }

View file

@ -4,26 +4,25 @@
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;
DoorTile *doorTile; DoorTile* doorTile;
private: private:
bool passed; bool passed;
float doorOpenDirX, doorOpenDirZ; float doorOpenDirX, doorOpenDirZ;
public: public:
DoorInteractGoal(Mob *mob); DoorInteractGoal(Mob* mob);
virtual ~DoorInteractGoal() {} virtual ~DoorInteractGoal() {}
virtual bool canUse(); virtual bool canUse();
virtual bool canContinueToUse(); virtual bool canContinueToUse();
virtual void start(); virtual void start();
virtual void tick(); virtual void tick();
private: private:
DoorTile *getDoorTile(int x, int y, int z); DoorTile* getDoorTile(int x, int y, int z);
}; };

View file

@ -6,68 +6,60 @@
#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 &&
if (level->getTile(xx, yy - 1, zz) == Tile::grass_Id) return true; level->getData(xx, yy, zz) == TallGrass::TALL_GRASS)
return false; return true;
if (level->getTile(xx, yy - 1, zz) == Tile::grass_Id) return true;
return false;
} }
void EatTileGoal::start() void EatTileGoal::start() {
{ eatAnimationTick = EAT_ANIMATION_TICKS;
eatAnimationTick = EAT_ANIMATION_TICKS; level->broadcastEntityEvent(mob->shared_from_this(),
level->broadcastEntityEvent(mob->shared_from_this(), EntityEvent::EAT_GRASS); 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;
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) 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 +
level->setTile(xx, yy, zz, 0); (TallGrass::TALL_GRASS << Tile::TILE_NUM_SHIFT));
mob->ate(); level->setTile(xx, yy, zz, 0);
} 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,
level->levelEvent(LevelEvent::PARTICLES_DESTROY_BLOCK, xx, yy - 1, zz, Tile::grass_Id); 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,26 +3,28 @@
#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;
int eatAnimationTick; int eatAnimationTick;
public: public:
EatTileGoal(Mob *mob); EatTileGoal(Mob* mob);
virtual bool canUse(); virtual bool canUse();
virtual void start(); virtual void start();
virtual void stop(); virtual void stop();
virtual bool canContinueToUse(); virtual bool canContinueToUse();
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
virtual void setLevel(Level *level) { this->level = level; } // schematics
virtual void setLevel(Level* level) { this->level = level; }
}; };

View file

@ -6,47 +6,43 @@
#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,
if (!level->canSeeSky(Mth::floor(mob->x), (int) mob->bb->y0, Mth::floor(mob->z))) return false; Mth::floor(mob->z)))
return false;
Vec3 *pos = getHidePos(); Vec3* pos = getHidePos();
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;
} }
bool FleeSunGoal::canContinueToUse() bool FleeSunGoal::canContinueToUse() { return !mob->getNavigation()->isDone(); }
{
return !mob->getNavigation()->isDone(); void FleeSunGoal::start() {
mob->getNavigation()->moveTo(wantedX, wantedY, wantedZ, speed);
} }
void FleeSunGoal::start() Vec3* FleeSunGoal::getHidePos() {
{ Random* random = mob->getRandom();
mob->getNavigation()->moveTo(wantedX, wantedY, wantedZ, speed); for (int i = 0; i < 10; i++) {
} int xt = Mth::floor(mob->x + random->nextInt(20) - 10);
int yt = Mth::floor(mob->bb->y0 + random->nextInt(6) - 3);
Vec3 *FleeSunGoal::getHidePos() int zt = Mth::floor(mob->z + random->nextInt(20) - 10);
{ if (!level->canSeeSky(xt, yt, zt) &&
Random *random = mob->getRandom(); mob->getWalkTargetValue(xt, yt, zt) < 0)
for (int i = 0; i < 10; i++) return Vec3::newTemp(xt, yt, zt);
{ }
int xt = Mth::floor(mob->x + random->nextInt(20) - 10); return NULL;
int yt = Mth::floor(mob->bb->y0 + random->nextInt(6) - 3);
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);
}
return NULL;
} }

View file

@ -2,25 +2,25 @@
#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;
float speed; float speed;
Level *level; Level* level;
public: public:
FleeSunGoal(PathfinderMob *mob, float speed); FleeSunGoal(PathfinderMob* mob, float speed);
virtual bool canUse(); virtual bool canUse();
virtual bool canContinueToUse(); virtual bool canContinueToUse();
virtual void start(); virtual void start();
private: 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
virtual void setLevel(Level *level) { this->level = level; } // schematics
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,14 +4,13 @@
class Mob; class Mob;
class FloatGoal : public Goal class FloatGoal : public Goal {
{
private: private:
Mob *mob; Mob* mob;
public: public:
FloatGoal(Mob *mob); FloatGoal(Mob* mob);
virtual bool canUse(); virtual bool canUse();
virtual void tick(); virtual void tick();
}; };

View file

@ -7,79 +7,80 @@
#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;
this->tamable = tamable; this->tamable = tamable;
this->level = tamable->level; this->level = tamable->level;
this->speed = speed; this->speed = speed;
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)
if (tamable->distanceToSqr(owner) < startDistance * startDistance) return false; 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) {
{ continue;
if (x >= 1 && z >= 1 && x <= 3 && z <= 3) }
{ if (level->isTopSolidBlocking(sx + x, y - 1, sz + z) &&
continue; !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) && !level->isSolidBlockingTile(sx + x, y + 1, sz + z)) tamable->moveTo(sx + x + .5f, y, sz + z + .5f, tamable->yRot,
{ tamable->xRot);
tamable->moveTo(sx + x + .5f, y, sz + z + .5f, tamable->yRot, tamable->xRot); navigation->stop();
navigation->stop(); return;
return; }
} }
} }
}
} }

View file

@ -5,30 +5,31 @@
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;
private: private:
TamableAnimal *tamable; // Owner of this goal TamableAnimal* tamable; // Owner of this goal
std::weak_ptr<Mob> owner; std::weak_ptr<Mob> owner;
Level *level; Level* level;
float speed; float speed;
PathNavigation *navigation; PathNavigation* navigation;
int timeToRecalcPath; int timeToRecalcPath;
float stopDistance, startDistance; float stopDistance, startDistance;
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();
virtual void start(); virtual void start();
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
virtual void setLevel(Level *level) { this->level = level; } // schematics
virtual void setLevel(Level* level) { this->level = level; }
}; };

View file

@ -6,60 +6,51 @@
#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); if (distSqr > closestDistSqr) continue;
if (distSqr > closestDistSqr) continue; closestDistSqr = distSqr;
closestDistSqr = distSqr; closest = parent;
closest = parent; }
} delete parents;
delete parents;
if (closest == NULL) return false; if (closest == NULL) return false;
if (closestDistSqr < 3 * 3) return false; if (closestDistSqr < 3 * 3) return false;
parent = std::weak_ptr<Animal>(closest); parent = std::weak_ptr<Animal>(closest);
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,20 +4,19 @@
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;
float speed; float speed;
int timeToRecalcPath; int timeToRecalcPath;
public: public:
FollowParentGoal(Animal *animal, float speed); FollowParentGoal(Animal* animal, float speed);
virtual bool canUse(); virtual bool canUse();
virtual bool canContinueToUse(); virtual bool canContinueToUse();
virtual void start(); virtual void start();
virtual void stop(); virtual void stop();
virtual void tick(); virtual void tick();
}; };

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() { return canUse(); }
bool Goal::canInterrupt() { return true; }
void Goal::start() {}
void Goal::stop() {}
void Goal::tick() {}
void Goal::setRequiredControlFlags(int requiredControlFlags) {
_requiredControlFlags = requiredControlFlags;
} }
bool Goal::canContinueToUse() int Goal::getRequiredControlFlags() { return _requiredControlFlags; }
{
return canUse();
}
bool Goal::canInterrupt()
{
return true;
}
void Goal::start()
{
}
void Goal::stop()
{
}
void Goal::tick()
{
}
void Goal::setRequiredControlFlags(int requiredControlFlags)
{
_requiredControlFlags = requiredControlFlags;
}
int Goal::getRequiredControlFlags()
{
return _requiredControlFlags;
}

View file

@ -1,23 +1,24 @@
#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;
virtual bool canContinueToUse(); virtual bool canContinueToUse();
virtual bool canInterrupt(); virtual bool canInterrupt();
virtual void start(); virtual void start();
virtual void stop(); virtual void stop();
virtual void tick(); virtual void tick();
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
virtual void setLevel(Level *level) {}; // schematics
virtual void setLevel(Level* level) {};
}; };

View file

@ -2,146 +2,124 @@
#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;
{ delete (*it);
if((*it)->canDeletePointer) delete (*it)->goal; }
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;
{ // bool isUsing = usingGoals.contains(ig);
InternalGoal *ig = *it; AUTO_VAR(usingIt, find(usingGoals.begin(), usingGoals.end(), ig));
//bool isUsing = usingGoals.contains(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();
{ // usingGoals.remove(ig);
ig->goal->stop(); usingGoals.erase(usingIt);
//usingGoals.remove(ig); } else
usingGoals.erase(usingIt); continue;
} }
else continue;
}
if (!canUseInSystem(ig) || !ig->goal->canUse()) continue; if (!canUseInSystem(ig) || !ig->goal->canUse()) continue;
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();) {
{ InternalGoal* ig = *it;
for(AUTO_VAR(it, usingGoals.begin() ); it != usingGoals.end(); ) if (!ig->goal->canContinueToUse()) {
{ ig->goal->stop();
InternalGoal *ig = *it; it = usingGoals.erase(it);
if (!ig->goal->canContinueToUse()) } else {
{ ++it;
ig->goal->stop(); }
it = usingGoals.erase(it); }
} }
else
{
++it;
}
}
}
// bool debug = false;
// if (debug && toStart.size() > 0) System.out.println("Starting: ");
// for (InternalGoal ig : toStart)
for (AUTO_VAR(it, toStart.begin()); it != toStart.end(); ++it) {
// if (debug) System.out.println(ig.goal.toString() + ", ");
(*it)->goal->start();
}
//bool debug = false; // if (debug && usingGoals.size() > 0) System.out.println("Running: ");
//if (debug && toStart.size() > 0) System.out.println("Starting: "); // for (InternalGoal ig : usingGoals)
//for (InternalGoal ig : toStart) for (AUTO_VAR(it, usingGoals.begin()); it != usingGoals.end(); ++it) {
for(AUTO_VAR(it, toStart.begin()); it != toStart.end(); ++it) // if (debug) System.out.println(ig.goal.toString());
{ (*it)->goal->tick();
//if (debug) System.out.println(ig.goal.toString() + ", "); }
(*it)->goal->start();
}
//if (debug && usingGoals.size() > 0) System.out.println("Running: ");
//for (InternalGoal ig : usingGoals)
for(AUTO_VAR(it, usingGoals.begin()); it != usingGoals.end(); ++it)
{
//if (debug) System.out.println(ig.goal.toString());
(*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;
{ if (ig == goal) continue;
InternalGoal *ig = *it;
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;
{ ig->goal->setLevel(level);
InternalGoal *ig = *it; }
ig->goal->setLevel(level);
}
} }

View file

@ -1,45 +1,43 @@
#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);
Goal *goal; Goal* goal;
int prio; int prio;
bool canDeletePointer; bool canDeletePointer;
}; };
private: private:
std::vector<InternalGoal *> goals; std::vector<InternalGoal*> goals;
std::vector<InternalGoal *> usingGoals; std::vector<InternalGoal*> usingGoals;
int tickCount; int tickCount;
int newGoalRate; int newGoalRate;
public: public:
GoalSelector(); GoalSelector();
~GoalSelector(); ~GoalSelector();
// 4J Added canDelete param // 4J Added canDelete param
void addGoal(int prio, Goal *goal, bool canDeletePointer = true); void addGoal(int prio, Goal* goal, bool canDeletePointer = true);
void tick(); void tick();
std::vector<InternalGoal *> *getRunningGoals(); std::vector<InternalGoal*>* getRunningGoals();
private: private:
bool canContinueToUse(InternalGoal *ig); bool canContinueToUse(InternalGoal* ig);
bool canUseInSystem(InternalGoal *goal); bool canUseInSystem(InternalGoal* goal);
bool canCoExist(InternalGoal *goalA, InternalGoal *goalB); bool canCoExist(InternalGoal* goalA, InternalGoal* goalB);
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
void setLevel(Level *level); // schematics
void setLevel(Level* level);
}; };

View file

@ -4,42 +4,41 @@
#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)
std::shared_ptr<Mob> other = std::dynamic_pointer_cast<Mob>(*it); ->grow(within, 4, within));
if (this->mob->shared_from_this() == other) continue; for (AUTO_VAR(it, nearby->begin()); it != nearby->end(); ++it) {
if (other->getTarget() != NULL) continue; std::shared_ptr<Mob> other = std::dynamic_pointer_cast<Mob>(*it);
other->setTarget(mob->getLastHurtByMob()); if (this->mob->shared_from_this() == other) continue;
} if (other->getTarget() != NULL) continue;
delete nearby; other->setTarget(mob->getLastHurtByMob());
} }
delete nearby;
}
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,16 +2,15 @@
#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;
public: public:
HurtByTargetGoal(Mob *mob, bool alertSameType); HurtByTargetGoal(Mob* mob, bool alertSameType);
bool canUse(); bool canUse();
void start(); void start();
void tick(); void tick();
}; };

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,38 +3,35 @@
#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()); if (d < 2 * 2 || d > 4 * 4) return false;
if (d < 2 * 2 || d > 4 * 4) return false; if (!mob->onGround) return false;
if (!mob->onGround) return false; if (mob->getRandom()->nextInt(5) != 0) return false;
if (mob->getRandom()->nextInt(5) != 0) return false; 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; float dd = sqrt(xdd * xdd + zdd * zdd);
float dd = sqrt(xdd * xdd + zdd * zdd); mob->xd += (xdd / dd * 0.5f) * 0.8f + mob->xd * 0.2f;
mob->xd += (xdd / dd * 0.5f) * 0.8f + mob->xd * 0.2f; mob->zd += (zdd / dd * 0.5f) * 0.8f + mob->zd * 0.2f;
mob->zd += (zdd / dd * 0.5f) * 0.8f + mob->zd * 0.2f; mob->yd = yd;
mob->yd = yd;
} }

View file

@ -2,15 +2,14 @@
#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;
float yd; float yd;
public: public:
LeapAtTargetGoal(Mob *mob, float yd); LeapAtTargetGoal(Mob* mob, float yd);
virtual bool canUse(); virtual bool canUse();
virtual bool canContinueToUse(); virtual bool canContinueToUse();

View file

@ -5,53 +5,56 @@
#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)
this->mob = mob; : lookAtType(lookAtType) {
this->lookDistance = lookDistance; this->mob = mob;
this->probability = 0.02f; this->lookDistance = lookDistance;
setRequiredControlFlags(Control::LookControlFlag); this->probability = 0.02f;
setRequiredControlFlags(Control::LookControlFlag);
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)
this->mob = mob; : lookAtType(lookAtType) {
this->lookDistance = lookDistance; this->mob = mob;
this->probability = probability; this->lookDistance = lookDistance;
setRequiredControlFlags(Control::LookControlFlag); this->probability = probability;
setRequiredControlFlags(Control::LookControlFlag);
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))
if (lookAtType == typeid(Player)) lookAt = mob->level->getNearestPlayer(mob->shared_from_this(), lookDistance); lookAt =
else lookAt = std::weak_ptr<Entity>(mob->level->getClosestEntityOfClass(lookAtType, mob->bb->grow(lookDistance, 3, lookDistance), mob->shared_from_this())); mob->level->getNearestPlayer(mob->shared_from_this(), lookDistance);
return lookAt.lock() != NULL; else
lookAt = std::weak_ptr<Entity>(mob->level->getClosestEntityOfClass(
lookAtType, mob->bb->grow(lookDistance, 3, lookDistance),
mob->shared_from_this()));
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)
if (mob->distanceToSqr(lookAt.lock()) > lookDistance * lookDistance) return false; 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(),
--lookTime; lookAt.lock()->z, 10, mob->getMaxHeadXRot());
--lookTime;
} }

View file

@ -5,28 +5,29 @@
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
protected: protected:
std::weak_ptr<Entity> lookAt; std::weak_ptr<Entity> lookAt;
private: private:
float lookDistance; float lookDistance;
int lookTime; int lookTime;
float probability; float probability;
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);
virtual ~LookAtPlayerGoal() {} LookAtPlayerGoal(Mob* mob, const std::type_info& lookAtType,
float lookDistance, float probability);
virtual ~LookAtPlayerGoal() {}
virtual bool canUse(); virtual bool canUse();
virtual bool canContinueToUse(); virtual bool canContinueToUse();
virtual void start(); virtual void start();
virtual void stop(); virtual void stop();
virtual void tick(); virtual void tick();
}; };

View file

@ -3,17 +3,16 @@
#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,13 +4,12 @@
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
public: public:
LookAtTradingPlayerGoal(Villager *villager); LookAtTradingPlayerGoal(Villager* villager);
virtual bool canUse(); virtual bool canUse();
}; };

View file

@ -8,96 +8,95 @@
#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->getRandom()->nextInt(500) != 0) return false;
if (villager->getAge() != 0) return false; village = level->villages->getClosestVillage(Mth::floor(villager->x),
if (villager->getRandom()->nextInt(500) != 0) return false; Mth::floor(villager->y),
Mth::floor(villager->z), 0);
if (village.lock() == NULL) return false;
if (!villageNeedsMoreVillagers()) return false;
village = level->villages->getClosestVillage(Mth::floor(villager->x), Mth::floor(villager->y), Mth::floor(villager->z), 0); std::shared_ptr<Entity> mate = level->getClosestEntityOfClass(
if (village.lock() == NULL) return false; typeid(Villager), villager->bb->grow(8, 3, 8),
if (!villageNeedsMoreVillagers()) return false; villager->shared_from_this());
if (mate == NULL) return false;
std::shared_ptr<Entity> mate = level->getClosestEntityOfClass(typeid(Villager), villager->bb->grow(8, 3, 8), villager->shared_from_this()); partner =
if (mate == NULL) return false; std::weak_ptr<Villager>(std::dynamic_pointer_cast<Villager>(mate));
if (partner.lock()->getAge() != 0) return false;
partner = std::weak_ptr<Villager>(std::dynamic_pointer_cast<Villager>(mate)); return true;
if (partner.lock()->getAge() != 0) return false;
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 {
} if (loveMakingTime == 0 && partner.lock()->isInLove()) breed();
else }
{
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;
int idealSize = (int) ((float) _village->getDoorCount() * 0.35); int idealSize = (int)((float)_village->getDoorCount() * 0.35);
// System.out.println("idealSize: " + idealSize + " pop: " + // System.out.println("idealSize: " + idealSize + " pop: " +
// village.getPopulationSize()); // village.getPopulationSize());
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(
child->moveTo(villager->x, villager->y, villager->z, 0, 0); villager->getRandom()->nextInt(Villager::PROFESSION_MAX));
level->addEntity(child); child->moveTo(villager->x, villager->y, villager->z, 0, 0);
level->broadcastEntityEvent(child, EntityEvent::LOVE_HEARTS); level->addEntity(child);
} level->broadcastEntityEvent(child, EntityEvent::LOVE_HEARTS);
}
} }

View file

@ -5,29 +5,29 @@
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;
Level *level; Level* level;
int loveMakingTime; int loveMakingTime;
std::weak_ptr<Village> village; std::weak_ptr<Village> village;
public: public:
MakeLoveGoal(Villager *villager); MakeLoveGoal(Villager* villager);
bool canUse(); bool canUse();
void start(); void start();
void stop(); void stop();
bool canContinueToUse(); bool canContinueToUse();
void tick(); void tick();
private: private:
bool villageNeedsMoreVillagers(); bool villageNeedsMoreVillagers();
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
virtual void setLevel(Level *level) { this->level = level; } // schematics
virtual void setLevel(Level* level) { this->level = level; }
}; };

View file

@ -9,89 +9,86 @@
#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 |
setRequiredControlFlags(Control::MoveControlFlag | Control::LookControlFlag); 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 &&
if (attackType != eTYPE_NOTSET && (attackType & bestTarget->GetType()) != attackType) return false; (attackType & bestTarget->GetType()) != attackType)
target = std::weak_ptr<Mob>(bestTarget); return false;
delete path; target = std::weak_ptr<Mob>(bestTarget);
path = mob->getNavigation()->createPath(target.lock()); delete path;
return path != NULL; path = mob->getNavigation()->createPath(target.lock());
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),
if (!mob->isWithinRestriction(Mth::floor(target.lock()->x), Mth::floor(target.lock()->y), Mth::floor(target.lock()->z))) return false; Mth::floor(target.lock()->y),
return true; Mth::floor(target.lock()->z)))
return false;
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) {
{ timeToRecalcPath = 4 + mob->getRandom()->nextInt(7);
if (--timeToRecalcPath <= 0) mob->getNavigation()->moveTo(target.lock(), speed);
{ }
timeToRecalcPath = 4 + mob->getRandom()->nextInt(7); }
mob->getNavigation()->moveTo(target.lock(), speed);
}
}
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,
if (attackTime > 0) return; target.lock()->z) > meleeRadiusSqr)
attackTime = 20; return;
mob->doHurtTarget(target.lock()); if (attackTime > 0) return;
attackTime = 20;
mob->doHurtTarget(target.lock());
} }

View file

@ -6,33 +6,34 @@ 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
std::weak_ptr<Mob> target; std::weak_ptr<Mob> target;
int attackTime; int attackTime;
float speed; float speed;
bool trackTarget; bool trackTarget;
Path *path; Path* path;
eINSTANCEOF attackType; eINSTANCEOF attackType;
int timeToRecalcPath; int timeToRecalcPath;
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,
MeleeAttackGoal(Mob *mob, float speed, bool trackTarget); bool trackTarget);
~MeleeAttackGoal(); MeleeAttackGoal(Mob* mob, float speed, bool trackTarget);
~MeleeAttackGoal();
virtual bool canUse(); virtual bool canUse();
virtual bool canContinueToUse(); virtual bool canContinueToUse();
virtual void start(); virtual void start();
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
virtual void setLevel(Level *level) { this->level = level; } // schematics
virtual void setLevel(Level* level) { this->level = level; }
}; };

View file

@ -8,58 +8,64 @@
#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)
if (mob->getRandom()->nextInt(50) != 0) return false; return false;
if (insideX != -1 && mob->distanceToSqr(insideX, mob->y, insideZ) < 2 * 2) return false; if (mob->getRandom()->nextInt(50) != 0) 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 (insideX != -1 && mob->distanceToSqr(insideX, mob->y, insideZ) < 2 * 2)
if (village == NULL) return false; return false;
std::shared_ptr<DoorInfo> _doorInfo = village->getBestDoorInfo(Mth::floor(mob->x), Mth::floor(mob->y), Mth::floor(mob->z)); std::shared_ptr<Village> village = mob->level->villages->getClosestVillage(
doorInfo = _doorInfo; Mth::floor(mob->x), Mth::floor(mob->y), Mth::floor(mob->z), 14);
return _doorInfo != NULL; if (village == NULL) return false;
std::shared_ptr<DoorInfo> _doorInfo = village->getBestDoorInfo(
Mth::floor(mob->x), Mth::floor(mob->y), Mth::floor(mob->z));
doorInfo = _doorInfo;
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>();
{ return;
doorInfo = std::weak_ptr<DoorInfo>(); }
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()),
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)); 14, 3,
if (pos != NULL) mob->getNavigation()->moveTo(pos->x, pos->y, pos->z, 0.3f); Vec3::newTemp(_doorInfo->getIndoorX() + 0.5,
} _doorInfo->getIndoorY(),
else mob->getNavigation()->moveTo(_doorInfo->getIndoorX() + 0.5, _doorInfo->getIndoorY(), _doorInfo->getIndoorZ() + 0.5, 0.3f); _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>();
{ return;
doorInfo = std::weak_ptr<DoorInfo>(); }
return;
}
insideX = _doorInfo->getIndoorX(); insideX = _doorInfo->getIndoorX();
insideZ = _doorInfo->getIndoorZ(); insideZ = _doorInfo->getIndoorZ();
doorInfo = std::weak_ptr<DoorInfo>(); doorInfo = std::weak_ptr<DoorInfo>();
} }

View file

@ -5,18 +5,17 @@
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;
int insideX, insideZ; int insideX, insideZ;
public: public:
MoveIndoorsGoal(PathfinderMob *mob); MoveIndoorsGoal(PathfinderMob* mob);
bool canUse(); bool canUse();
bool canContinueToUse(); bool canContinueToUse();
void start(); void start();
void stop(); void stop();
}; };

View file

@ -9,119 +9,114 @@
#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>();
this->mob = mob; this->mob = mob;
this->speed = speed; this->speed = speed;
this->onlyAtNight = onlyAtNight; this->onlyAtNight = onlyAtNight;
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(
if (village == NULL) return false; Mth::floor(mob->x), Mth::floor(mob->y), Mth::floor(mob->z), 0);
if (village == NULL) return false;
std::shared_ptr<DoorInfo> _doorInfo = getNextDoorInfo(village); std::shared_ptr<DoorInfo> _doorInfo = getNextDoorInfo(village);
if (_doorInfo == NULL) return false; if (_doorInfo == NULL) return false;
doorInfo = _doorInfo; doorInfo = _doorInfo;
bool oldCanOpenDoors = mob->getNavigation()->canOpenDoors(); bool oldCanOpenDoors = mob->getNavigation()->canOpenDoors();
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,
mob->getNavigation()->setCanOpenDoors(oldCanOpenDoors); _doorInfo->z);
if (path != NULL) return true; mob->getNavigation()->setCanOpenDoors(oldCanOpenDoors);
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(
if (pos == NULL) return false; std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()), 10,
mob->getNavigation()->setCanOpenDoors(false); 7, Vec3::newTemp(_doorInfo->x, _doorInfo->y, _doorInfo->z));
delete path; if (pos == NULL) return false;
path = mob->getNavigation()->createPath(pos->x, pos->y, pos->z); mob->getNavigation()->setCanOpenDoors(false);
mob->getNavigation()->setCanOpenDoors(oldCanOpenDoors); delete path;
return path != NULL; path = mob->getNavigation()->createPath(pos->x, pos->y, pos->z);
mob->getNavigation()->setCanOpenDoors(oldCanOpenDoors);
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 =
//for (DoorInfo di : doorInfos) village->getDoorInfos();
for(AUTO_VAR(it, doorInfos->begin()); it != doorInfos->end(); ++it) // for (DoorInfo di : doorInfos)
{ 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;
} }
} }
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();
{ if (di2 == NULL) {
std::shared_ptr<DoorInfo> di2 = (*it).lock(); it = visited.erase(it);
if( di2 == NULL ) } else {
{ if (di->x == di2->x && di->y == di2->y && di->z == di2->z)
it = visited.erase(it); return true;
} ++it;
else }
{ }
if (di->x == di2->x && di->y == di2->y && di->z == di2->z) return true; return false;
++it;
}
}
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,27 +6,26 @@ 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;
Path *path; Path* path;
std::weak_ptr<DoorInfo> doorInfo; std::weak_ptr<DoorInfo> doorInfo;
bool onlyAtNight; bool onlyAtNight;
std::vector< std::weak_ptr<DoorInfo> > visited; std::vector<std::weak_ptr<DoorInfo> > visited;
public: public:
MoveThroughVillageGoal(PathfinderMob *mob, float speed, bool onlyAtNight); MoveThroughVillageGoal(PathfinderMob* mob, float speed, bool onlyAtNight);
~MoveThroughVillageGoal(); ~MoveThroughVillageGoal();
virtual bool canUse(); virtual bool canUse();
virtual bool canContinueToUse(); virtual bool canContinueToUse();
virtual void start(); virtual void start();
virtual void stop(); virtual void stop();
private: private:
std::shared_ptr<DoorInfo> getNextDoorInfo(std::shared_ptr<Village> village); std::shared_ptr<DoorInfo> getNextDoorInfo(std::shared_ptr<Village> village);
bool hasVisited(std::shared_ptr<DoorInfo> di); bool hasVisited(std::shared_ptr<DoorInfo> di);
void updateVisited(); void updateVisited();
}; };

View file

@ -6,33 +6,32 @@
#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;
this->speed = speed; this->speed = speed;
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(
Vec3 *pos = RandomPos::getPosTowards(std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()), 16, 7, Vec3::newTemp(towards->x, towards->y, towards->z)); std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()), 16,
if (pos == NULL) return false; 7, Vec3::newTemp(towards->x, towards->y, towards->z));
wantedX = pos->x; if (pos == NULL) return false;
wantedY = pos->y; wantedX = pos->x;
wantedZ = pos->z; wantedY = pos->y;
return true; wantedZ = pos->z;
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,17 +2,16 @@
#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;
float speed; float speed;
public: public:
MoveTowardsRestrictionGoal(PathfinderMob *mob, float speed); MoveTowardsRestrictionGoal(PathfinderMob* mob, float speed);
bool canUse(); bool canUse();
bool canContinueToUse(); bool canContinueToUse();
void start(); void start();
}; };

View file

@ -6,38 +6,38 @@
#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)
if (target.lock()->distanceToSqr(mob->shared_from_this()) > within * within) return false; 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)); Vec3* pos = RandomPos::getPosTowards(
if (pos == NULL) return false; std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()), 16,
wantedX = pos->x; 7, Vec3::newTemp(target.lock()->x, target.lock()->y, target.lock()->z));
wantedY = pos->y; if (pos == NULL) return false;
wantedZ = pos->z; wantedX = pos->x;
return true; wantedY = pos->y;
wantedZ = pos->z;
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,19 +2,18 @@
#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;
double wantedX, wantedY, wantedZ; double wantedX, wantedY, wantedZ;
float speed, within; float speed, within;
public: public:
MoveTowardsTargetGoal(PathfinderMob *mob, float speed, float within); MoveTowardsTargetGoal(PathfinderMob* mob, float speed, float within);
bool canUse(); bool canUse();
bool canContinueToUse(); bool canContinueToUse();
void stop(); void stop();
void start(); void start();
}; };

View file

@ -4,68 +4,64 @@
#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);
if (distSqr1 < distSqr2) return true; if (distSqr1 < distSqr2) return true;
if (distSqr1 > distSqr2) return false; if (distSqr1 > distSqr2) return false;
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,
//this->targetType = targetType; int randomInterval, bool mustSee, bool mustReach /*= false*/)
this->within = within; : TargetGoal(mob, within, mustSee, mustReach), targetType(targetType) {
this->randomInterval = randomInterval; // this->targetType = targetType;
this->distComp = new DistComp(mob); this->within = within;
setRequiredControlFlags(TargetGoal::TargetFlag); this->randomInterval = randomInterval;
this->distComp = new DistComp(mob);
setRequiredControlFlags(TargetGoal::TargetFlag);
} }
NearestAttackableTargetGoal::~NearestAttackableTargetGoal() NearestAttackableTargetGoal::~NearestAttackableTargetGoal() { delete distComp; }
{
delete distComp; bool NearestAttackableTargetGoal::canUse() {
if (randomInterval > 0 && mob->getRandom()->nextInt(randomInterval) != 0)
return false;
if (targetType == typeid(Player)) {
std::shared_ptr<Mob> potentialTarget =
mob->level->getNearestAttackablePlayer(mob->shared_from_this(),
within);
if (canAttack(potentialTarget, false)) {
target = std::weak_ptr<Mob>(potentialTarget);
return true;
}
} else {
std::vector<std::shared_ptr<Entity> >* entities =
mob->level->getEntitiesOfClass(targetType,
mob->bb->grow(within, 4, within));
// Collections.sort(entities, distComp);
std::sort(entities->begin(), entities->end(), *distComp);
for (AUTO_VAR(it, entities->begin()); it != entities->end(); ++it) {
std::shared_ptr<Mob> potTarget =
std::dynamic_pointer_cast<Mob>(*it);
if (canAttack(potTarget, false)) {
target = std::weak_ptr<Mob>(potTarget);
return true;
}
}
delete entities;
}
return false;
} }
bool NearestAttackableTargetGoal::canUse() void NearestAttackableTargetGoal::start() {
{ mob->setTarget(target.lock());
if (randomInterval > 0 && mob->getRandom()->nextInt(randomInterval) != 0) return false; TargetGoal::start();
if (targetType == typeid(Player))
{
std::shared_ptr<Mob> potentialTarget = mob->level->getNearestAttackablePlayer(mob->shared_from_this(), within);
if (canAttack(potentialTarget, false))
{
target = std::weak_ptr<Mob>(potentialTarget);
return true;
}
}
else
{
std::vector<std::shared_ptr<Entity> > *entities = mob->level->getEntitiesOfClass(targetType, mob->bb->grow(within, 4, within));
//Collections.sort(entities, distComp);
std::sort(entities->begin(), entities->end(), *distComp);
for(AUTO_VAR(it, entities->begin()); it != entities->end(); ++it)
{
std::shared_ptr<Mob> potTarget = std::dynamic_pointer_cast<Mob>(*it);
if (canAttack(potTarget, false))
{
target = std::weak_ptr<Mob>(potTarget);
return true;
}
}
delete entities;
}
return false;
}
void NearestAttackableTargetGoal::start()
{
mob->setTarget(target.lock());
TargetGoal::start();
} }

View file

@ -2,35 +2,36 @@
#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;
public: public:
DistComp(Entity *source); DistComp(Entity* source);
bool operator() (std::shared_ptr<Entity> e1, std::shared_ptr<Entity> e2); bool operator()(std::shared_ptr<Entity> e1, std::shared_ptr<Entity> e2);
}; };
private: private:
std::weak_ptr<Mob> target; std::weak_ptr<Mob> target;
const std::type_info& targetType; const std::type_info& targetType;
int randomInterval; int randomInterval;
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,
virtual ~NearestAttackableTargetGoal(); float within, int randomInterval, bool mustSee,
bool mustReach = false);
virtual ~NearestAttackableTargetGoal();
virtual bool canUse(); virtual bool canUse();
void start(); void start();
}; };

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,
this->tamableMob = mob; int randomInterval, bool mustSee)
: NearestAttackableTargetGoal(mob, targetType, within, randomInterval,
mustSee) {
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,56 +6,55 @@
#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; trackTarget = false;
trackTarget = false;
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);
attackTime = std::max(attackTime - 1, 0); attackTime = std::max(attackTime - 1, 0);
if (distSqr > meleeRadiusSqr) return; if (distSqr > meleeRadiusSqr) return;
if (attackTime > 0) return; if (attackTime > 0) return;
attackTime = 20; attackTime = 20;
mob->doHurtTarget(target.lock()); mob->doHurtTarget(target.lock());
} }

View file

@ -2,24 +2,24 @@
#include "Goal.h" #include "Goal.h"
class OzelotAttackGoal : public Goal class OzelotAttackGoal : public Goal {
{
private: private:
Level *level; Level* level;
Mob *mob; Mob* mob;
std::weak_ptr<Mob> target; std::weak_ptr<Mob> target;
int attackTime; int attackTime;
float speed; float speed;
bool trackTarget; bool trackTarget;
public: public:
OzelotAttackGoal(Mob *mob); OzelotAttackGoal(Mob* mob);
virtual bool canUse(); virtual bool canUse();
virtual bool canContinueToUse(); virtual bool canContinueToUse();
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
virtual void setLevel(Level *level) { this->level = level; } // schematics
virtual void setLevel(Level* level) { this->level = level; }
}; };

View file

@ -10,118 +10,107 @@
#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; tileX = 0;
tileX = 0; tileY = 0;
tileY = 0; tileZ = 0;
tileZ = 0;
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->getSitGoal()->wantToSit(false); ocelot->getRandom()->nextInt(SIT_TICKS) + SIT_TICKS) +
SIT_TICKS;
ocelot->getSitGoal()->wantToSit(false);
} }
void OcelotSitOnTileGoal::stop() void OcelotSitOnTileGoal::stop() { ocelot->setSitting(false); }
{
ocelot->setSitting(false); void OcelotSitOnTileGoal::tick() {
_tick++;
ocelot->getSitGoal()->wantToSit(false);
if (ocelot->distanceToSqr(tileX, tileY + 1, tileZ) > 1) {
ocelot->setSitting(false);
ocelot->getNavigation()->moveTo((float)tileX + 0.5, tileY + 1,
(float)tileZ + 0.5, speed);
tryTicks++;
} else if (!ocelot->isSitting()) {
ocelot->setSitting(true);
} else {
tryTicks--;
}
} }
void OcelotSitOnTileGoal::tick() bool OcelotSitOnTileGoal::findNearestTile() {
{ int y = (int)ocelot->y;
_tick++; double distSqr = Integer::MAX_VALUE;
ocelot->getSitGoal()->wantToSit(false);
if (ocelot->distanceToSqr(tileX, tileY + 1, tileZ) > 1) for (int x = (int)ocelot->x - SEARCH_RANGE; x < ocelot->x + SEARCH_RANGE;
{ x++) {
ocelot->setSitting(false); for (int z = (int)ocelot->z - SEARCH_RANGE;
ocelot->getNavigation()->moveTo((float) tileX + 0.5, tileY + 1, (float) tileZ + 0.5, speed); z < ocelot->z + SEARCH_RANGE; z++) {
tryTicks++; if (isValidTarget(ocelot->level, x, y, z) &&
} ocelot->level->isEmptyTile(x, y + 1, z)) {
else if (!ocelot->isSitting()) double dist = ocelot->distanceToSqr(x, y, z);
{
ocelot->setSitting(true); if (dist < distSqr) {
} this->tileX = x;
else this->tileY = y;
{ this->tileZ = z;
tryTicks--; distSqr = dist;
} }
}
}
}
return distSqr < Integer::MAX_VALUE;
} }
bool OcelotSitOnTileGoal::findNearestTile() bool OcelotSitOnTileGoal::isValidTarget(Level* level, int x, int y, int z) {
{ int tile = level->getTile(x, y, z);
int y = (int) ocelot->y; int data = level->getData(x, y, z);
double distSqr = Integer::MAX_VALUE;
for (int x = (int) ocelot->x - SEARCH_RANGE; x < ocelot->x + SEARCH_RANGE; x++) if (tile == Tile::chest_Id) {
{ std::shared_ptr<ChestTileEntity> chest =
for (int z = (int) ocelot->z - SEARCH_RANGE; z < ocelot->z + SEARCH_RANGE; z++) std::dynamic_pointer_cast<ChestTileEntity>(
{ level->getTileEntity(x, y, z));
if (isValidTarget(ocelot->level, x, y, z) && ocelot->level->isEmptyTile(x, y + 1, z))
{
double dist = ocelot->distanceToSqr(x, y, z);
if (dist < distSqr) if (chest->openCount < 1) {
{ return true;
this->tileX = x; }
this->tileY = y; } else if (tile == Tile::furnace_lit_Id) {
this->tileZ = z; return true;
distSqr = dist; } else if (tile == Tile::bed_Id && !BedTile::isHeadPiece(data)) {
} return true;
} }
}
}
return distSqr < Integer::MAX_VALUE; return false;
}
bool OcelotSitOnTileGoal::isValidTarget(Level *level, int x, int y, int z)
{
int tile = level->getTile(x, y, z);
int data = level->getData(x, y, z);
if (tile == Tile::chest_Id)
{
std::shared_ptr<ChestTileEntity> chest = std::dynamic_pointer_cast<ChestTileEntity>(level->getTileEntity(x, y, z));
if (chest->openCount < 1)
{
return true;
}
}
else if (tile == Tile::furnace_lit_Id)
{
return true;
}
else if (tile == Tile::bed_Id && !BedTile::isHeadPiece(data))
{
return true;
}
return false;
} }

View file

@ -4,34 +4,33 @@
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;
static const int SEARCH_RANGE; static const int SEARCH_RANGE;
static const double SIT_CHANCE; static const double SIT_CHANCE;
private: private:
Ozelot *ocelot; // Owner of this goal Ozelot* ocelot; // Owner of this goal
float speed; float speed;
int _tick; int _tick;
int tryTicks; int tryTicks;
int maxTicks; int maxTicks;
int tileX; int tileX;
int tileY; int tileY;
int tileZ; int tileZ;
public: public:
OcelotSitOnTileGoal(Ozelot *ocelot, float speed); OcelotSitOnTileGoal(Ozelot* ocelot, float speed);
bool canUse(); bool canUse();
bool canContinueToUse(); bool canContinueToUse();
void start(); void start();
void stop(); void stop();
void tick(); void tick();
private: private:
bool findNearestTile(); bool findNearestTile();
bool isValidTarget(Level *level, int x, int y, int z); bool isValidTarget(Level* level, int x, int y, int z);
}; };

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 |
setRequiredControlFlags(Control::MoveControlFlag | Control::LookControlFlag); 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>(
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()) )); golem->level->getClosestEntityOfClass(typeid(Villager),
return villager.lock() != NULL; golem->bb->grow(6, 2, 6),
golem->shared_from_this())));
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,22 +4,21 @@
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;
private: private:
VillagerGolem *golem; VillagerGolem* golem;
std::weak_ptr<Villager> villager; std::weak_ptr<Villager> villager;
int _tick; int _tick;
public: public:
OfferFlowerGoal(VillagerGolem *golem); OfferFlowerGoal(VillagerGolem* golem);
virtual bool canUse(); virtual bool canUse();
virtual bool canContinueToUse(); virtual bool canContinueToUse();
virtual void start(); virtual void start();
virtual void stop(); virtual void stop();
virtual void tick(); virtual void tick();
}; };

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,17 +2,16 @@
#include "DoorInteractGoal.h" #include "DoorInteractGoal.h"
class OpenDoorGoal : public DoorInteractGoal class OpenDoorGoal : public DoorInteractGoal {
{
private: private:
bool closeDoor; bool closeDoor;
int forgetTime; int forgetTime;
public: public:
OpenDoorGoal(Mob *mob, bool closeDoorAfter); OpenDoorGoal(Mob* mob, bool closeDoorAfter);
virtual bool canContinueToUse(); virtual bool canContinueToUse();
virtual void start(); virtual void start();
virtual void stop(); virtual void stop();
virtual void tick(); virtual void tick();
}; };

View file

@ -3,23 +3,21 @@
#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; ownerLastHurtBy = std::weak_ptr<Mob>(owner->getLastHurtByMob());
ownerLastHurtBy = std::weak_ptr<Mob>(owner->getLastHurtByMob()); 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,15 +4,14 @@
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;
public: public:
OwnerHurtByTargetGoal(TamableAnimal *tameAnimal); OwnerHurtByTargetGoal(TamableAnimal* tameAnimal);
bool canUse(); bool canUse();
void start(); void start();
}; };

View file

@ -3,23 +3,21 @@
#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; ownerLastHurt = std::weak_ptr<Mob>(owner->getLastHurtMob());
ownerLastHurt = std::weak_ptr<Mob>(owner->getLastHurtMob()); 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,15 +4,14 @@
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;
public: public:
OwnerHurtTargetGoal(TamableAnimal *tameAnimal); OwnerHurtTargetGoal(TamableAnimal* tameAnimal);
bool canUse(); bool canUse();
void start(); void start();
}; };

View file

@ -6,30 +6,26 @@
#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(
Vec3 *pos = RandomPos::getPos(std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()), 5, 4); std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()), 5,
if (pos == NULL) return false; 4);
posX = pos->x; if (pos == NULL) return false;
posY = pos->y; posX = pos->x;
posZ = pos->z; posY = pos->y;
return true; posZ = pos->z;
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,17 +4,16 @@
class PathfinderMob; class PathfinderMob;
class PanicGoal : public Goal class PanicGoal : public Goal {
{
private: private:
PathfinderMob *mob; PathfinderMob* mob;
float speed; float speed;
double posX, posY, posZ; double posX, posY, posZ;
public: public:
PanicGoal(PathfinderMob *mob, float speed); PanicGoal(PathfinderMob* mob, float speed);
virtual bool canUse(); virtual bool canUse();
virtual void start(); virtual void start();
virtual bool canContinueToUse(); virtual bool canContinueToUse();
}; };

View file

@ -9,78 +9,75 @@
#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;
this->mob = mob; this->mob = mob;
this->speed = speed; this->speed = 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 =
double closestDistSqr = Double::MAX_VALUE; mob->level->getEntitiesOfClass(typeid(Villager),
//for (Entity c : children) mob->bb->grow(6, 3, 6));
for(AUTO_VAR(it, children->begin()); it != children->end(); ++it) double closestDistSqr = Double::MAX_VALUE;
{ // for (Entity c : children)
std::shared_ptr<Entity> c = *it; for (AUTO_VAR(it, children->begin()); it != children->end(); ++it) {
if (c.get() == mob) continue; std::shared_ptr<Entity> c = *it;
std::shared_ptr<Villager> friendV = std::dynamic_pointer_cast<Villager>(c); if (c.get() == mob) continue;
if (friendV->isChasing()) continue; std::shared_ptr<Villager> friendV =
if (friendV->getAge() >= 0) continue; std::dynamic_pointer_cast<Villager>(c);
double distSqr = friendV->distanceToSqr(mob->shared_from_this()); if (friendV->isChasing()) continue;
if (distSqr > closestDistSqr) continue; if (friendV->getAge() >= 0) continue;
closestDistSqr = distSqr; double distSqr = friendV->distanceToSqr(mob->shared_from_this());
followFriend = std::weak_ptr<Mob>(friendV); if (distSqr > closestDistSqr) continue;
} closestDistSqr = distSqr;
delete children; followFriend = std::weak_ptr<Mob>(friendV);
}
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()),
if (pos == NULL) return false; 16, 3);
} 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)
{ mob->getNavigation()->moveTo(followFriend.lock(), speed);
if (mob->distanceToSqr(followFriend.lock()) > 2 * 2) mob->getNavigation()->moveTo(followFriend.lock(), speed); } else {
} if (mob->getNavigation()->isDone()) {
else Vec3* pos =
{ RandomPos::getPos(std::dynamic_pointer_cast<PathfinderMob>(
if (mob->getNavigation()->isDone()) mob->shared_from_this()),
{ 16, 3);
Vec3 *pos = RandomPos::getPos(std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()), 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,21 +2,20 @@
#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;
float speed; float speed;
double wantedX, wantedY, wantedZ; double wantedX, wantedY, wantedZ;
int playTime; int playTime;
public: public:
PlayGoal(Villager *mob, float speed); PlayGoal(Villager* mob, float speed);
virtual bool canUse(); virtual bool canUse();
virtual bool canContinueToUse(); virtual bool canContinueToUse();
virtual void start(); virtual void start();
virtual void stop(); virtual void stop();
virtual void tick(); virtual void tick();
}; };

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() {
double rnd = 2 * PI * mob->getRandom()->nextDouble();
relX = cos(rnd);
relZ = sin(rnd);
lookTime = 20 + mob->getRandom()->nextInt(20);
} }
void RandomLookAroundGoal::start() void RandomLookAroundGoal::tick() {
{ --lookTime;
double rnd = 2 * PI * mob->getRandom()->nextDouble(); mob->getLookControl()->setLookAt(mob->x + relX,
relX = cos(rnd); mob->y + mob->getHeadHeight(),
relZ = sin(rnd); mob->z + relZ, 10, mob->getMaxHeadXRot());
lookTime = 20 + mob->getRandom()->nextInt(20);
}
void RandomLookAroundGoal::tick()
{
--lookTime;
mob->getLookControl()->setLookAt(mob->x + relX, mob->y + mob->getHeadHeight(), mob->z + relZ, 10, mob->getMaxHeadXRot());
} }

View file

@ -2,18 +2,17 @@
#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;
int lookTime; int lookTime;
public: public:
RandomLookAroundGoal(Mob *mob); RandomLookAroundGoal(Mob* mob);
virtual bool canUse(); virtual bool canUse();
virtual bool canContinueToUse(); virtual bool canContinueToUse();
virtual void start(); virtual void start();
virtual void tick(); virtual void tick();
}; };

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 |
setRequiredControlFlags(Control::MoveControlFlag | Control::LookControlFlag); 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>(
if (pos == NULL) return false; mob->shared_from_this()),
wantedX = pos->x; 10, 7);
wantedY = pos->y; if (pos == NULL) return false;
wantedZ = pos->z; wantedX = pos->x;
return true; wantedY = pos->y;
} wantedZ = pos->z;
} 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 // This entity wouldn't normally be randomly strolling. However, if our
// 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 // management system says that it should do, then do. Don't bother
// stroll out of a given area and so waiting around is just wasting time // waiting for random conditions to be met before picking a direction
// though as the point here is to see if it is possible to stroll out of
// 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>(
if (pos == NULL) return false; mob->shared_from_this()),
wantedX = pos->x; 10, 7, mob->getWanderingQuadrant());
wantedY = pos->y; if (pos == NULL) return false;
wantedZ = pos->z; wantedX = pos->x;
return true; wantedY = pos->y;
} wantedZ = pos->z;
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,17 +4,16 @@
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;
float speed; float speed;
public: public:
RandomStrollGoal(PathfinderMob *mob, float speed); RandomStrollGoal(PathfinderMob* mob, float speed);
virtual bool canUse(); virtual bool canUse();
virtual bool canContinueToUse(); virtual bool canContinueToUse();
virtual void start(); virtual void start();
}; };

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(
std::shared_ptr<Village> village = mob->level->villages->getClosestVillage(Mth::floor(mob->x), Mth::floor(mob->y), Mth::floor(mob->z), 16); 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(
if (_doorInfo == NULL) return false; Mth::floor(mob->x), Mth::floor(mob->y), Mth::floor(mob->z));
doorInfo = _doorInfo; if (_doorInfo == NULL) return false;
return _doorInfo->distanceToInsideSqr(Mth::floor(mob->x), Mth::floor(mob->y), Mth::floor(mob->z)) < 1.5 * 1.5; doorInfo = _doorInfo;
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 &&
return !_doorInfo->removed && _doorInfo->isInsideSide(Mth::floor(mob->x), Mth::floor(mob->z)); _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,18 +5,17 @@
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;
public: public:
RestrictOpenDoorGoal(PathfinderMob *mob); RestrictOpenDoorGoal(PathfinderMob* mob);
virtual bool canUse(); virtual bool canUse();
virtual bool canContinueToUse(); virtual bool canContinueToUse();
virtual void start(); virtual void start();
virtual void stop(); virtual void stop();
virtual void tick(); virtual void tick();
}; };

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,15 +2,14 @@
#include "Goal.h" #include "Goal.h"
class RestrictSunGoal : public Goal class RestrictSunGoal : public Goal {
{
private: private:
PathfinderMob *mob; PathfinderMob* mob;
public: public:
RestrictSunGoal(PathfinderMob *mob); RestrictSunGoal(PathfinderMob* mob);
bool canUse(); bool canUse();
void start(); void start();
void stop(); void stop();
}; };

View file

@ -6,40 +6,35 @@
#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;
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,17 +2,16 @@
#include "Goal.h" #include "Goal.h"
class SitGoal : public Goal class SitGoal : public Goal {
{
private: private:
TamableAnimal *mob; TamableAnimal* mob;
bool _wantToSit; bool _wantToSit;
public: public:
SitGoal(TamableAnimal *mob); SitGoal(TamableAnimal* mob);
bool canUse(); bool canUse();
void start(); void start();
void stop(); void stop();
void wantToSit(bool _wantToSit); void wantToSit(bool _wantToSit);
}; };

View file

@ -5,50 +5,41 @@
#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 ||
return creeper->getSwellDir() > 0 || (target != NULL && (creeper->distanceToSqr(target) < 3 * 3)); (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() {
} if (target.lock() == NULL) {
creeper->setSwellDir(-1);
void SwellGoal::tick() return;
{ }
if (target.lock() == NULL)
{ if (creeper->distanceToSqr(target.lock()) > 7 * 7) {
creeper->setSwellDir(-1); creeper->setSwellDir(-1);
return; return;
} }
if (creeper->distanceToSqr(target.lock()) > 7 * 7) if (!creeper->getSensing()->canSee(target.lock())) {
{ creeper->setSwellDir(-1);
creeper->setSwellDir(-1); return;
return; }
}
creeper->setSwellDir(1);
if (!creeper->getSensing()->canSee(target.lock()))
{
creeper->setSwellDir(-1);
return;
}
creeper->setSwellDir(1);
} }

View file

@ -4,17 +4,16 @@
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;
public: public:
SwellGoal(Creeper *creeper); SwellGoal(Creeper* creeper);
bool canUse(); bool canUse();
void start(); void start();
void stop(); void stop();
void tick(); void tick();
}; };

View file

@ -8,75 +8,68 @@
#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));
delete golems; if (golems->size() == 0) {
return false; delete golems;
} 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; }
} }
} delete golems;
delete golems; 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);
{ takeFlower = true;
villager->getNavigation()->moveTo(golem.lock(), 0.15f); }
takeFlower = true;
}
if (takeFlower) if (takeFlower) {
{ if (villager->distanceToSqr(golem.lock()) < 2 * 2) {
if (villager->distanceToSqr(golem.lock()) < 2 * 2) golem.lock()->offerFlower(false);
{ villager->getNavigation()->stop();
golem.lock()->offerFlower(false); }
villager->getNavigation()->stop(); }
}
}
} }

View file

@ -2,20 +2,19 @@
#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;
int pickupTick; int pickupTick;
bool takeFlower; bool takeFlower;
public: public:
TakeFlowerGoal(Villager *villager); TakeFlowerGoal(Villager* villager);
bool canUse(); bool canUse();
bool canContinueToUse(); bool canContinueToUse();
void start(); void start();
void stop(); void stop();
void tick(); void tick();
}; };

View file

@ -8,106 +8,95 @@
#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;
this->mob = mob; this->mob = mob;
this->within = within; this->within = within;
this->mustSee = mustSee; this->mustSee = mustSee;
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)) {
{ unseenTicks = 0;
if (mob->getSensing()->canSee(target)) } else {
{ if (++unseenTicks > UnseenMemoryTicks) return false;
unseenTicks = 0; }
} }
else return true;
{
if (++unseenTicks > UnseenMemoryTicks) return false;
}
}
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) {
if (target == NULL) return false;
if (target == mob->shared_from_this()) return false;
if (!target->isAlive()) return false;
if (!mob->canAttackType(target->GetType())) return false;
std::shared_ptr<TamableAnimal> tamableAnimal =
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);
if (tamableTarget != NULL && tamableTarget->isTame()) return false;
if (target == tamableAnimal->getOwner()) return false;
} else if (std::dynamic_pointer_cast<Player>(target) != NULL) {
if (!allowInvulnerable &&
(std::dynamic_pointer_cast<Player>(target))->abilities.invulnerable)
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 (mustReach) {
if (--reachCacheTime <= 0) reachCache = EmptyReachCache;
if (reachCache == EmptyReachCache)
reachCache = canReach(target) ? CanReachCache : CantReachCache;
if (reachCache == CantReachCache) return false;
}
return true;
} }
bool TargetGoal::canAttack(std::shared_ptr<Mob> target, bool allowInvulnerable) bool TargetGoal::canReach(std::shared_ptr<Mob> target) {
{ reachCacheTime = 10 + mob->getRandom()->nextInt(5);
if (target == NULL) return false; Path* path = mob->getNavigation()->createPath(target);
if (target == mob->shared_from_this()) return false; if (path == NULL) return false;
if (!target->isAlive()) return false; Node* last = path->last();
if (!mob->canAttackType(target->GetType())) return false; if (last == NULL) {
delete path;
std::shared_ptr<TamableAnimal> tamableAnimal = std::dynamic_pointer_cast<TamableAnimal>(mob->shared_from_this()); return false;
if (tamableAnimal != NULL && tamableAnimal->isTame()) }
{ int xx = last->x - Mth::floor(target->x);
std::shared_ptr<TamableAnimal> tamableTarget = std::dynamic_pointer_cast<TamableAnimal>(target); int zz = last->z - Mth::floor(target->z);
if (tamableTarget != NULL && tamableTarget->isTame()) return false; delete path;
if (target == tamableAnimal->getOwner()) return false; return xx * xx + zz * zz <= 1.5 * 1.5;
}
else if (std::dynamic_pointer_cast<Player>(target) != NULL)
{
if (!allowInvulnerable && (std::dynamic_pointer_cast<Player>(target))->abilities.invulnerable) 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 (mustReach)
{
if (--reachCacheTime <= 0) reachCache = EmptyReachCache;
if (reachCache == EmptyReachCache) reachCache = canReach(target) ? CanReachCache : CantReachCache;
if (reachCache == CantReachCache) return false;
}
return true;
}
bool TargetGoal::canReach(std::shared_ptr<Mob> target)
{
reachCacheTime = 10 + mob->getRandom()->nextInt(5);
Path *path = mob->getNavigation()->createPath(target);
if (path == NULL) return false;
Node *last = path->last();
if (last == NULL)
{
delete path;
return false;
}
int xx = last->x - Mth::floor(target->x);
int zz = last->z - Mth::floor(target->z);
delete path;
return xx * xx + zz * zz <= 1.5 * 1.5;
} }

View file

@ -2,43 +2,41 @@
#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;
private: private:
static const int EmptyReachCache = 0; static const int EmptyReachCache = 0;
static const int CanReachCache = 1; static const int CanReachCache = 1;
static const int CantReachCache = 2; static const int CantReachCache = 2;
static const int UnseenMemoryTicks = 60; static const int UnseenMemoryTicks = 60;
protected: protected:
Mob *mob; // Owner of this goal Mob* mob; // Owner of this goal
float within; float within;
bool mustSee; bool mustSee;
private: private:
bool mustReach; bool mustReach;
int reachCache; int reachCache;
int reachCacheTime; int reachCacheTime;
int unseenTicks; int unseenTicks;
void _init(Mob *mob, float within, bool mustSee, bool mustReach); void _init(Mob* mob, float within, bool mustSee, bool mustReach);
public: public:
TargetGoal(Mob *mob, float within, bool mustSee); TargetGoal(Mob* mob, float within, bool mustSee);
TargetGoal(Mob *mob, float within, bool mustSee, bool mustReach); TargetGoal(Mob* mob, float within, bool mustSee, bool mustReach);
virtual ~TargetGoal() {} virtual ~TargetGoal() {}
virtual bool canContinueToUse(); virtual bool canContinueToUse();
virtual void start(); virtual void start();
virtual void stop(); virtual void stop();
protected: protected:
virtual bool canAttack(std::shared_ptr<Mob> target, bool allowInvulnerable); virtual bool canAttack(std::shared_ptr<Mob> target, bool allowInvulnerable);
private: private:
bool canReach(std::shared_ptr<Mob> target); bool canReach(std::shared_ptr<Mob> target);
}; };

View file

@ -6,86 +6,82 @@
#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;
_isRunning = false; _isRunning = false;
oldAvoidWater = false; oldAvoidWater = false;
this->mob = mob; this->mob = mob;
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;
{ return false;
--calmDown; }
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
mob->setDespawnProtected(); // If we've got a nearby player, then consider this mob as something we'd miss if it despawned // this mob as something we'd miss if it
std::shared_ptr<ItemInstance> item = player.lock()->getSelectedItem(); // despawned
if (item == NULL) return false; std::shared_ptr<ItemInstance> item = player.lock()->getSelectedItem();
if (item->id != itemId) return false; if (item == NULL) return false;
return true; if (item->id != itemId) return false;
return true;
} }
bool TemptGoal::canContinueToUse() bool TemptGoal::canContinueToUse() {
{ if (canScare) {
if (canScare) if (player.lock() == NULL) return false;
{ if (mob->distanceToSqr(player.lock()) < 6 * 6) {
if(player.lock() == NULL) return false; if (player.lock()->distanceToSqr(px, py, pz) > 0.1 * 0.1)
if (mob->distanceToSqr(player.lock()) < 6 * 6) return false;
{ if (abs(player.lock()->xRot - pRotX) > 5 ||
if (player.lock()->distanceToSqr(px, py, pz) > 0.1 * 0.1) return false; abs(player.lock()->yRot - pRotY) > 5)
if (abs(player.lock()->xRot - pRotX) > 5 || abs(player.lock()->yRot - pRotY) > 5) return false; return false;
} } else {
else px = player.lock()->x;
{ py = player.lock()->y;
px = player.lock()->x; pz = player.lock()->z;
py = player.lock()->y; }
pz = player.lock()->z; pRotX = player.lock()->xRot;
} pRotY = player.lock()->yRot;
pRotX = player.lock()->xRot; }
pRotY = player.lock()->yRot; 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; _isRunning = true;
_isRunning = true; oldAvoidWater = mob->getNavigation()->getAvoidWater();
oldAvoidWater = mob->getNavigation()->getAvoidWater(); 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; _isRunning = false;
_isRunning = false; 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)
if (mob->distanceToSqr(player.lock()) < 2.5 * 2.5) mob->getNavigation()->stop(); mob->getNavigation()->stop();
else mob->getNavigation()->moveTo(player.lock(), speed); 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