mirror of
https://github.com/4jcraft/4jcraft.git
synced 2026-04-27 07:13:36 +00:00
chore: format Minecraft.World
This commit is contained in:
parent
bd6284025d
commit
33d0737d1d
|
|
@ -5,50 +5,46 @@
|
|||
|
||||
const float BodyControl::maxClampAngle = 75.0f;
|
||||
|
||||
BodyControl::BodyControl(Mob *mob)
|
||||
{
|
||||
this->mob = mob;
|
||||
BodyControl::BodyControl(Mob* mob) {
|
||||
this->mob = mob;
|
||||
|
||||
timeStill = 0;
|
||||
lastHeadY = 0.0f;
|
||||
timeStill = 0;
|
||||
lastHeadY = 0.0f;
|
||||
}
|
||||
|
||||
void BodyControl::clientTick()
|
||||
{
|
||||
double xd = mob->x - mob->xo;
|
||||
double zd = mob->z - mob->zo;
|
||||
void BodyControl::clientTick() {
|
||||
double xd = mob->x - mob->xo;
|
||||
double zd = mob->z - mob->zo;
|
||||
|
||||
if (xd * xd + zd * zd > MoveControl::MIN_SPEED_SQR)
|
||||
{
|
||||
// we are moving.
|
||||
mob->yBodyRot = mob->yRot;
|
||||
mob->yHeadRot = clamp(mob->yBodyRot, mob->yHeadRot, maxClampAngle);
|
||||
lastHeadY = mob->yHeadRot;
|
||||
timeStill = 0;
|
||||
return;
|
||||
}
|
||||
if (xd * xd + zd * zd > MoveControl::MIN_SPEED_SQR) {
|
||||
// we are moving.
|
||||
mob->yBodyRot = mob->yRot;
|
||||
mob->yHeadRot = clamp(mob->yBodyRot, mob->yHeadRot, maxClampAngle);
|
||||
lastHeadY = mob->yHeadRot;
|
||||
timeStill = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Body will align to head after looking long enough in a direction
|
||||
float clampAngle = maxClampAngle;
|
||||
if (abs(mob->yHeadRot - lastHeadY) > 15)
|
||||
{
|
||||
timeStill = 0;
|
||||
lastHeadY = mob->yHeadRot;
|
||||
}
|
||||
else
|
||||
{
|
||||
++timeStill;
|
||||
static const int timeStillBeforeTurn = 10;
|
||||
if (timeStill > timeStillBeforeTurn) clampAngle = std::max(1 - (timeStill - timeStillBeforeTurn) / 10.f, 0.0f) * maxClampAngle;
|
||||
}
|
||||
// Body will align to head after looking long enough in a direction
|
||||
float clampAngle = maxClampAngle;
|
||||
if (abs(mob->yHeadRot - lastHeadY) > 15) {
|
||||
timeStill = 0;
|
||||
lastHeadY = mob->yHeadRot;
|
||||
} else {
|
||||
++timeStill;
|
||||
static const int timeStillBeforeTurn = 10;
|
||||
if (timeStill > timeStillBeforeTurn)
|
||||
clampAngle =
|
||||
std::max(1 - (timeStill - timeStillBeforeTurn) / 10.f, 0.0f) *
|
||||
maxClampAngle;
|
||||
}
|
||||
|
||||
mob->yBodyRot = clamp(mob->yHeadRot, mob->yBodyRot, clampAngle);
|
||||
mob->yBodyRot = clamp(mob->yHeadRot, mob->yBodyRot, clampAngle);
|
||||
}
|
||||
|
||||
float BodyControl::clamp(float clampTo, float clampFrom, float clampAngle)
|
||||
{
|
||||
float headDiffBody = Mth::wrapDegrees(clampTo - clampFrom);
|
||||
if (headDiffBody < -clampAngle) headDiffBody = -clampAngle;
|
||||
if (headDiffBody >= clampAngle) headDiffBody = +clampAngle;
|
||||
return clampTo - headDiffBody;
|
||||
float BodyControl::clamp(float clampTo, float clampFrom, float clampAngle) {
|
||||
float headDiffBody = Mth::wrapDegrees(clampTo - clampFrom);
|
||||
if (headDiffBody < -clampAngle) headDiffBody = -clampAngle;
|
||||
if (headDiffBody >= clampAngle) headDiffBody = +clampAngle;
|
||||
return clampTo - headDiffBody;
|
||||
}
|
||||
|
|
@ -2,19 +2,18 @@
|
|||
|
||||
#include "Control.h"
|
||||
|
||||
class BodyControl : public Control
|
||||
{
|
||||
class BodyControl : public Control {
|
||||
private:
|
||||
Mob *mob;
|
||||
static const float maxClampAngle;
|
||||
int timeStill;
|
||||
float lastHeadY;
|
||||
Mob* mob;
|
||||
static const float maxClampAngle;
|
||||
int timeStill;
|
||||
float lastHeadY;
|
||||
|
||||
public:
|
||||
BodyControl(Mob *mob);
|
||||
BodyControl(Mob* mob);
|
||||
|
||||
void clientTick();
|
||||
void clientTick();
|
||||
|
||||
private:
|
||||
float clamp(float clampTo, float clampFrom, float clampAngle);
|
||||
float clamp(float clampTo, float clampFrom, float clampAngle);
|
||||
};
|
||||
|
|
@ -1,9 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
class Control
|
||||
{
|
||||
class Control {
|
||||
public:
|
||||
static const int MoveControlFlag = 1;
|
||||
static const int LookControlFlag = 2;
|
||||
static const int JumpControlFlag = 4;
|
||||
static const int MoveControlFlag = 1;
|
||||
static const int LookControlFlag = 2;
|
||||
static const int JumpControlFlag = 4;
|
||||
};
|
||||
|
|
@ -2,20 +2,15 @@
|
|||
#include "../../Headers/net.minecraft.world.entity.h"
|
||||
#include "JumpControl.h"
|
||||
|
||||
JumpControl::JumpControl(Mob *mob)
|
||||
{
|
||||
_jump = false;
|
||||
JumpControl::JumpControl(Mob* mob) {
|
||||
_jump = false;
|
||||
|
||||
this->mob = mob;
|
||||
this->mob = mob;
|
||||
}
|
||||
|
||||
void JumpControl::jump()
|
||||
{
|
||||
_jump = true;
|
||||
}
|
||||
void JumpControl::jump() { _jump = true; }
|
||||
|
||||
void JumpControl::tick()
|
||||
{
|
||||
mob->setJumping(_jump);
|
||||
_jump = false;
|
||||
void JumpControl::tick() {
|
||||
mob->setJumping(_jump);
|
||||
_jump = false;
|
||||
}
|
||||
|
|
@ -4,17 +4,16 @@
|
|||
|
||||
class Mob;
|
||||
|
||||
class JumpControl : public Control
|
||||
{
|
||||
class JumpControl : public Control {
|
||||
private:
|
||||
Mob *mob;
|
||||
bool _jump;
|
||||
Mob* mob;
|
||||
bool _jump;
|
||||
|
||||
public:
|
||||
JumpControl(Mob *mob);
|
||||
virtual ~JumpControl(){}
|
||||
JumpControl(Mob* mob);
|
||||
virtual ~JumpControl() {}
|
||||
|
||||
void jump();
|
||||
//genuinly, why tf is this VIRTUAL
|
||||
virtual void tick();
|
||||
void jump();
|
||||
// genuinly, why tf is this VIRTUAL
|
||||
virtual void tick();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,114 +4,87 @@
|
|||
#include "../../Headers/net.minecraft.world.phys.h"
|
||||
#include "LookControl.h"
|
||||
|
||||
LookControl::LookControl(Mob *mob)
|
||||
{
|
||||
yMax = xMax = 0.0f;
|
||||
hasWanted = false;
|
||||
wantedX = wantedY = wantedZ = 0.0;
|
||||
LookControl::LookControl(Mob* mob) {
|
||||
yMax = xMax = 0.0f;
|
||||
hasWanted = false;
|
||||
wantedX = wantedY = wantedZ = 0.0;
|
||||
|
||||
this->mob = mob;
|
||||
this->mob = mob;
|
||||
}
|
||||
|
||||
void LookControl::setLookAt(std::shared_ptr<Entity> target, float yMax, float xMax)
|
||||
{
|
||||
this->wantedX = target->x;
|
||||
std::shared_ptr<Mob> targetMob = std::dynamic_pointer_cast<Mob>(target);
|
||||
if (targetMob != NULL) this->wantedY = target->y + targetMob->getHeadHeight();
|
||||
else this->wantedY = (target->bb->y0 + target->bb->y1) / 2;
|
||||
this->wantedZ = target->z;
|
||||
this->yMax = yMax;
|
||||
this->xMax = xMax;
|
||||
hasWanted = true;
|
||||
void LookControl::setLookAt(std::shared_ptr<Entity> target, float yMax,
|
||||
float xMax) {
|
||||
this->wantedX = target->x;
|
||||
std::shared_ptr<Mob> targetMob = std::dynamic_pointer_cast<Mob>(target);
|
||||
if (targetMob != NULL)
|
||||
this->wantedY = target->y + targetMob->getHeadHeight();
|
||||
else
|
||||
this->wantedY = (target->bb->y0 + target->bb->y1) / 2;
|
||||
this->wantedZ = target->z;
|
||||
this->yMax = yMax;
|
||||
this->xMax = xMax;
|
||||
hasWanted = true;
|
||||
}
|
||||
|
||||
void LookControl::setLookAt(double x, double y, double z, float yMax, float xMax)
|
||||
{
|
||||
this->wantedX = x;
|
||||
this->wantedY = y;
|
||||
this->wantedZ = z;
|
||||
this->yMax = yMax;
|
||||
this->xMax = xMax;
|
||||
hasWanted = true;
|
||||
void LookControl::setLookAt(double x, double y, double z, float yMax,
|
||||
float xMax) {
|
||||
this->wantedX = x;
|
||||
this->wantedY = y;
|
||||
this->wantedZ = z;
|
||||
this->yMax = yMax;
|
||||
this->xMax = xMax;
|
||||
hasWanted = true;
|
||||
}
|
||||
|
||||
void LookControl::tick()
|
||||
{
|
||||
mob->xRot = 0;
|
||||
void LookControl::tick() {
|
||||
mob->xRot = 0;
|
||||
|
||||
if (hasWanted)
|
||||
{
|
||||
hasWanted = false;
|
||||
if (hasWanted) {
|
||||
hasWanted = false;
|
||||
|
||||
double xd = wantedX - mob->x;
|
||||
double yd = wantedY - (mob->y + mob->getHeadHeight());
|
||||
double zd = wantedZ - mob->z;
|
||||
double sd = sqrt(xd * xd + zd * zd);
|
||||
double xd = wantedX - mob->x;
|
||||
double yd = wantedY - (mob->y + mob->getHeadHeight());
|
||||
double zd = wantedZ - mob->z;
|
||||
double sd = sqrt(xd * xd + zd * zd);
|
||||
|
||||
float yRotD = (float) (atan2(zd, xd) * 180 / PI) - 90;
|
||||
float xRotD = (float) -(atan2(yd, sd) * 180 / PI);
|
||||
mob->xRot = rotlerp(mob->xRot, xRotD, xMax);
|
||||
mob->yHeadRot = rotlerp(mob->yHeadRot, yRotD, yMax);
|
||||
}
|
||||
else
|
||||
{
|
||||
mob->yHeadRot = rotlerp(mob->yHeadRot, mob->yBodyRot, 10);
|
||||
}
|
||||
float yRotD = (float)(atan2(zd, xd) * 180 / PI) - 90;
|
||||
float xRotD = (float)-(atan2(yd, sd) * 180 / PI);
|
||||
mob->xRot = rotlerp(mob->xRot, xRotD, xMax);
|
||||
mob->yHeadRot = rotlerp(mob->yHeadRot, yRotD, yMax);
|
||||
} else {
|
||||
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())
|
||||
{
|
||||
// head clamped to body
|
||||
if (headDiffBody < -75) mob->yHeadRot = mob->yBodyRot - 75;
|
||||
if (headDiffBody > 75) mob->yHeadRot = mob->yBodyRot + 75;
|
||||
}
|
||||
if (!mob->getNavigation()->isDone()) {
|
||||
// head clamped to body
|
||||
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 diff = b - a;
|
||||
while (diff < -180)
|
||||
diff += 360;
|
||||
while (diff >= 180)
|
||||
diff -= 360;
|
||||
if (diff > max)
|
||||
{
|
||||
diff = max;
|
||||
}
|
||||
if (diff < -max)
|
||||
{
|
||||
diff = -max;
|
||||
}
|
||||
return a + diff;
|
||||
float LookControl::rotlerp(float a, float b, float max) {
|
||||
float diff = b - a;
|
||||
while (diff < -180) diff += 360;
|
||||
while (diff >= 180) diff -= 360;
|
||||
if (diff > max) {
|
||||
diff = max;
|
||||
}
|
||||
if (diff < -max) {
|
||||
diff = -max;
|
||||
}
|
||||
return a + diff;
|
||||
}
|
||||
|
||||
bool LookControl::isHasWanted()
|
||||
{
|
||||
return hasWanted;
|
||||
}
|
||||
bool LookControl::isHasWanted() { return hasWanted; }
|
||||
|
||||
float LookControl::getYMax()
|
||||
{
|
||||
return yMax;
|
||||
}
|
||||
float LookControl::getYMax() { return yMax; }
|
||||
|
||||
float LookControl::getXMax()
|
||||
{
|
||||
return xMax;
|
||||
}
|
||||
float LookControl::getXMax() { return xMax; }
|
||||
|
||||
double LookControl::getWantedX()
|
||||
{
|
||||
return wantedX;
|
||||
}
|
||||
double LookControl::getWantedX() { return wantedX; }
|
||||
|
||||
double LookControl::getWantedY()
|
||||
{
|
||||
return wantedY;
|
||||
}
|
||||
double LookControl::getWantedY() { return wantedY; }
|
||||
|
||||
double LookControl::getWantedZ()
|
||||
{
|
||||
return wantedZ;
|
||||
}
|
||||
double LookControl::getWantedZ() { return wantedZ; }
|
||||
|
|
@ -4,31 +4,30 @@
|
|||
|
||||
class Mob;
|
||||
|
||||
class LookControl : public Control
|
||||
{
|
||||
class LookControl : public Control {
|
||||
private:
|
||||
Mob *mob;
|
||||
float yMax, xMax;
|
||||
bool hasWanted;
|
||||
Mob* mob;
|
||||
float yMax, xMax;
|
||||
bool hasWanted;
|
||||
|
||||
double wantedX, wantedY, wantedZ;
|
||||
double wantedX, wantedY, wantedZ;
|
||||
|
||||
public:
|
||||
LookControl(Mob *mob);
|
||||
virtual ~LookControl(){}
|
||||
LookControl(Mob* mob);
|
||||
virtual ~LookControl() {}
|
||||
|
||||
void setLookAt(std::shared_ptr<Entity> target, float yMax, float xMax);
|
||||
void setLookAt(double x, double y, double z, float yMax, float xMax);
|
||||
virtual void tick();
|
||||
void setLookAt(std::shared_ptr<Entity> target, float yMax, float xMax);
|
||||
void setLookAt(double x, double y, double z, float yMax, float xMax);
|
||||
virtual void tick();
|
||||
|
||||
private:
|
||||
float rotlerp(float a, float b, float max);
|
||||
float rotlerp(float a, float b, float max);
|
||||
|
||||
public:
|
||||
bool isHasWanted();
|
||||
float getYMax();
|
||||
float getXMax();
|
||||
double getWantedX();
|
||||
double getWantedY();
|
||||
double getWantedZ();
|
||||
bool isHasWanted();
|
||||
float getYMax();
|
||||
float getXMax();
|
||||
double getWantedX();
|
||||
double getWantedY();
|
||||
double getWantedZ();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,69 +7,57 @@
|
|||
const float MoveControl::MIN_SPEED = 0.0005f;
|
||||
const float MoveControl::MIN_SPEED_SQR = MIN_SPEED * MIN_SPEED;
|
||||
|
||||
MoveControl::MoveControl(Mob *mob)
|
||||
{
|
||||
this->mob = mob;
|
||||
wantedX = mob->x;
|
||||
wantedY = mob->y;
|
||||
wantedZ = mob->z;
|
||||
MoveControl::MoveControl(Mob* mob) {
|
||||
this->mob = mob;
|
||||
wantedX = mob->x;
|
||||
wantedY = mob->y;
|
||||
wantedZ = mob->z;
|
||||
|
||||
speed = 0.0f;
|
||||
speed = 0.0f;
|
||||
|
||||
_hasWanted = false;
|
||||
_hasWanted = false;
|
||||
}
|
||||
|
||||
bool MoveControl::hasWanted()
|
||||
{
|
||||
return _hasWanted;
|
||||
bool MoveControl::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()
|
||||
{
|
||||
return speed;
|
||||
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();
|
||||
}
|
||||
|
||||
void MoveControl::setWantedPosition(double x, double y, double z, float speed)
|
||||
{
|
||||
wantedX = x;
|
||||
wantedY = y;
|
||||
wantedZ = z;
|
||||
this->speed = speed;
|
||||
_hasWanted = true;
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
|
@ -4,32 +4,31 @@
|
|||
|
||||
class Mob;
|
||||
|
||||
class MoveControl : public Control
|
||||
{
|
||||
class MoveControl : public Control {
|
||||
public:
|
||||
static const float MIN_SPEED;
|
||||
static const float MIN_SPEED_SQR;
|
||||
static const float MIN_SPEED;
|
||||
static const float MIN_SPEED_SQR;
|
||||
|
||||
private:
|
||||
static const int MAX_TURN = 30;
|
||||
static const int MAX_TURN = 30;
|
||||
|
||||
Mob *mob;
|
||||
double wantedX;
|
||||
double wantedY;
|
||||
double wantedZ;
|
||||
float speed;
|
||||
bool _hasWanted;
|
||||
Mob* mob;
|
||||
double wantedX;
|
||||
double wantedY;
|
||||
double wantedZ;
|
||||
float speed;
|
||||
bool _hasWanted;
|
||||
|
||||
public:
|
||||
MoveControl(Mob *mob);
|
||||
virtual ~MoveControl(){}
|
||||
MoveControl(Mob* mob);
|
||||
virtual ~MoveControl() {}
|
||||
|
||||
bool hasWanted();
|
||||
float getSpeed();
|
||||
void setWantedPosition(double x, double y, double z, float speed);
|
||||
void setSpeed(float speed);
|
||||
virtual void tick();
|
||||
bool hasWanted();
|
||||
float getSpeed();
|
||||
void setWantedPosition(double x, double y, double z, float speed);
|
||||
void setSpeed(float speed);
|
||||
virtual void tick();
|
||||
|
||||
private:
|
||||
float rotlerp(float a, float b, float max);
|
||||
float rotlerp(float a, float b, float max);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,34 +2,30 @@
|
|||
#include "../../Headers/net.minecraft.world.entity.h"
|
||||
#include "Sensing.h"
|
||||
|
||||
Sensing::Sensing(Mob *mob)
|
||||
{
|
||||
this->mob = mob;
|
||||
Sensing::Sensing(Mob* mob) { this->mob = mob; }
|
||||
|
||||
void Sensing::tick() {
|
||||
seen.clear();
|
||||
unseen.clear();
|
||||
}
|
||||
|
||||
void Sensing::tick()
|
||||
{
|
||||
seen.clear();
|
||||
unseen.clear();
|
||||
}
|
||||
bool Sensing::canSee(std::shared_ptr<Entity> target) {
|
||||
// if ( find(seen.begin(), seen.end(), target) != seen.end() ) return true;
|
||||
// if ( find(unseen.begin(), unseen.end(), target) != unseen.end()) return
|
||||
// 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)
|
||||
{
|
||||
//if ( find(seen.begin(), seen.end(), target) != seen.end() ) return true;
|
||||
//if ( find(unseen.begin(), unseen.end(), target) != unseen.end()) return 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;
|
||||
}
|
||||
|
||||
//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;
|
||||
// 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;
|
||||
}
|
||||
|
|
@ -1,15 +1,14 @@
|
|||
#pragma once
|
||||
|
||||
class Sensing
|
||||
{
|
||||
class Sensing {
|
||||
private:
|
||||
Mob *mob;
|
||||
std::vector<std::weak_ptr<Entity> > seen;
|
||||
std::vector<std::weak_ptr<Entity> > unseen;
|
||||
Mob* mob;
|
||||
std::vector<std::weak_ptr<Entity> > seen;
|
||||
std::vector<std::weak_ptr<Entity> > unseen;
|
||||
|
||||
public:
|
||||
Sensing(Mob *mob);
|
||||
Sensing(Mob* mob);
|
||||
|
||||
void tick();
|
||||
bool canSee(std::shared_ptr<Entity> target);
|
||||
void tick();
|
||||
bool canSee(std::shared_ptr<Entity> target);
|
||||
};
|
||||
|
|
@ -9,83 +9,82 @@
|
|||
#include "../../Util/SoundTypes.h"
|
||||
#include "ArrowAttackGoal.h"
|
||||
|
||||
ArrowAttackGoal::ArrowAttackGoal(Mob *mob, float speed, int projectileType, int attackInterval)
|
||||
{
|
||||
// 4J Init
|
||||
target = std::weak_ptr<Mob>();
|
||||
attackTime = 0;
|
||||
seeTime = 0;
|
||||
ArrowAttackGoal::ArrowAttackGoal(Mob* mob, float speed, int projectileType,
|
||||
int attackInterval) {
|
||||
// 4J Init
|
||||
target = std::weak_ptr<Mob>();
|
||||
attackTime = 0;
|
||||
seeTime = 0;
|
||||
|
||||
this->mob = mob;
|
||||
this->level = mob->level;
|
||||
this->speed = speed;
|
||||
this->projectileType = projectileType;
|
||||
this->attackInterval = attackInterval;
|
||||
setRequiredControlFlags(Control::MoveControlFlag | Control::LookControlFlag);
|
||||
this->mob = mob;
|
||||
this->level = mob->level;
|
||||
this->speed = speed;
|
||||
this->projectileType = projectileType;
|
||||
this->attackInterval = attackInterval;
|
||||
setRequiredControlFlags(Control::MoveControlFlag |
|
||||
Control::LookControlFlag);
|
||||
}
|
||||
|
||||
bool ArrowAttackGoal::canUse()
|
||||
{
|
||||
std::shared_ptr<Mob> bestTarget = mob->getTarget();
|
||||
if (bestTarget == NULL) return false;
|
||||
target = std::weak_ptr<Mob>(bestTarget);
|
||||
return true;
|
||||
bool ArrowAttackGoal::canUse() {
|
||||
std::shared_ptr<Mob> bestTarget = mob->getTarget();
|
||||
if (bestTarget == NULL) return false;
|
||||
target = std::weak_ptr<Mob>(bestTarget);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ArrowAttackGoal::canContinueToUse()
|
||||
{
|
||||
return target.lock() != NULL && (canUse() || !mob->getNavigation()->isDone());
|
||||
bool ArrowAttackGoal::canContinueToUse() {
|
||||
return target.lock() != NULL &&
|
||||
(canUse() || !mob->getNavigation()->isDone());
|
||||
}
|
||||
|
||||
void ArrowAttackGoal::stop()
|
||||
{
|
||||
target = std::weak_ptr<Mob>();
|
||||
void ArrowAttackGoal::stop() { 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()
|
||||
{
|
||||
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);
|
||||
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);
|
||||
|
||||
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::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);
|
||||
}
|
||||
level->playSound(mob->shared_from_this(), eSoundType_RANDOM_BOW, 1.0f,
|
||||
1 / (mob->getRandom()->nextFloat() * 0.4f + 0.8f));
|
||||
level->addEntity(snowball);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,32 +2,33 @@
|
|||
|
||||
#include "Goal.h"
|
||||
|
||||
class ArrowAttackGoal : public Goal
|
||||
{
|
||||
class ArrowAttackGoal : public Goal {
|
||||
public:
|
||||
static const int ArrowType = 1;
|
||||
static const int SnowballType = 2;
|
||||
static const int ArrowType = 1;
|
||||
static const int SnowballType = 2;
|
||||
|
||||
Level *level;
|
||||
Mob *mob; // Owner of this goal
|
||||
std::weak_ptr<Mob> target;
|
||||
int attackTime;
|
||||
float speed;
|
||||
int seeTime;
|
||||
int projectileType;
|
||||
int attackInterval;
|
||||
Level* level;
|
||||
Mob* mob; // Owner of this goal
|
||||
std::weak_ptr<Mob> target;
|
||||
int attackTime;
|
||||
float speed;
|
||||
int seeTime;
|
||||
int projectileType;
|
||||
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 canContinueToUse();
|
||||
virtual void stop();
|
||||
virtual void tick();
|
||||
virtual bool canUse();
|
||||
virtual bool canContinueToUse();
|
||||
virtual void stop();
|
||||
virtual void tick();
|
||||
|
||||
private:
|
||||
void fireAtTarget();
|
||||
void fireAtTarget();
|
||||
|
||||
public:
|
||||
// 4J Added override to update ai elements when loading entity from schematics
|
||||
virtual void setLevel(Level *level) { this->level = level; }
|
||||
// 4J Added override to update ai elements when loading entity from
|
||||
// schematics
|
||||
virtual void setLevel(Level* level) { this->level = level; }
|
||||
};
|
||||
|
|
@ -10,76 +10,77 @@
|
|||
#include "../../Headers/net.minecraft.world.phys.h"
|
||||
#include "AvoidPlayerGoal.h"
|
||||
|
||||
AvoidPlayerGoal::AvoidPlayerGoal(PathfinderMob *mob, const std::type_info& avoidType, float maxDist, float walkSpeed, float sprintSpeed) : avoidType(avoidType)
|
||||
{
|
||||
this->mob = mob;
|
||||
//this->avoidType = avoidType;
|
||||
this->maxDist = maxDist;
|
||||
this->walkSpeed = walkSpeed;
|
||||
this->sprintSpeed = sprintSpeed;
|
||||
this->pathNav = mob->getNavigation();
|
||||
setRequiredControlFlags(Control::MoveControlFlag);
|
||||
AvoidPlayerGoal::AvoidPlayerGoal(PathfinderMob* mob,
|
||||
const std::type_info& avoidType, float maxDist,
|
||||
float walkSpeed, float sprintSpeed)
|
||||
: avoidType(avoidType) {
|
||||
this->mob = mob;
|
||||
// this->avoidType = avoidType;
|
||||
this->maxDist = maxDist;
|
||||
this->walkSpeed = walkSpeed;
|
||||
this->sprintSpeed = sprintSpeed;
|
||||
this->pathNav = mob->getNavigation();
|
||||
setRequiredControlFlags(Control::MoveControlFlag);
|
||||
|
||||
toAvoid = std::weak_ptr<Entity>();
|
||||
path = NULL;
|
||||
toAvoid = std::weak_ptr<Entity>();
|
||||
path = NULL;
|
||||
}
|
||||
|
||||
AvoidPlayerGoal::~AvoidPlayerGoal()
|
||||
{
|
||||
if(path != NULL) delete path;
|
||||
AvoidPlayerGoal::~AvoidPlayerGoal() {
|
||||
if (path != NULL) delete path;
|
||||
}
|
||||
|
||||
bool AvoidPlayerGoal::canUse()
|
||||
{
|
||||
if (avoidType == typeid(Player))
|
||||
{
|
||||
std::shared_ptr<TamableAnimal> tamableAnimal = std::dynamic_pointer_cast<TamableAnimal>(mob->shared_from_this());
|
||||
if (tamableAnimal != NULL && tamableAnimal->isTame()) return false;
|
||||
toAvoid = std::weak_ptr<Entity>(mob->level->getNearestPlayer(mob->shared_from_this(), maxDist));
|
||||
if (toAvoid.lock() == NULL) return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<std::shared_ptr<Entity> > *entities = mob->level->getEntitiesOfClass(avoidType, mob->bb->grow(maxDist, 3, maxDist));
|
||||
if (entities->empty())
|
||||
{
|
||||
delete entities;
|
||||
return false;
|
||||
}
|
||||
toAvoid = std::weak_ptr<Entity>(entities->at(0));
|
||||
delete entities;
|
||||
}
|
||||
bool AvoidPlayerGoal::canUse() {
|
||||
if (avoidType == typeid(Player)) {
|
||||
std::shared_ptr<TamableAnimal> tamableAnimal =
|
||||
std::dynamic_pointer_cast<TamableAnimal>(mob->shared_from_this());
|
||||
if (tamableAnimal != NULL && tamableAnimal->isTame()) return false;
|
||||
toAvoid = std::weak_ptr<Entity>(
|
||||
mob->level->getNearestPlayer(mob->shared_from_this(), maxDist));
|
||||
if (toAvoid.lock() == NULL) return false;
|
||||
} else {
|
||||
std::vector<std::shared_ptr<Entity> >* entities =
|
||||
mob->level->getEntitiesOfClass(avoidType,
|
||||
mob->bb->grow(maxDist, 3, maxDist));
|
||||
if (entities->empty()) {
|
||||
delete entities;
|
||||
return false;
|
||||
}
|
||||
toAvoid = std::weak_ptr<Entity>(entities->at(0));
|
||||
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));
|
||||
if (pos == NULL) return false;
|
||||
if (toAvoid.lock()->distanceToSqr(pos->x, pos->y, pos->z) < toAvoid.lock()->distanceToSqr(mob->shared_from_this())) 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;
|
||||
Vec3* pos = RandomPos::getPosAvoid(
|
||||
std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()), 16,
|
||||
7,
|
||||
Vec3::newTemp(toAvoid.lock()->x, toAvoid.lock()->y, toAvoid.lock()->z));
|
||||
if (pos == NULL) return false;
|
||||
if (toAvoid.lock()->distanceToSqr(pos->x, pos->y, pos->z) <
|
||||
toAvoid.lock()->distanceToSqr(mob->shared_from_this()))
|
||||
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()
|
||||
{
|
||||
return toAvoid.lock() != NULL && !pathNav->isDone();
|
||||
bool AvoidPlayerGoal::canContinueToUse() {
|
||||
return toAvoid.lock() != NULL && !pathNav->isDone();
|
||||
}
|
||||
|
||||
void AvoidPlayerGoal::start()
|
||||
{
|
||||
pathNav->moveTo(path, walkSpeed);
|
||||
path = NULL;
|
||||
void AvoidPlayerGoal::start() {
|
||||
pathNav->moveTo(path, walkSpeed);
|
||||
path = NULL;
|
||||
}
|
||||
|
||||
void AvoidPlayerGoal::stop()
|
||||
{
|
||||
toAvoid = std::weak_ptr<Entity>();
|
||||
}
|
||||
void AvoidPlayerGoal::stop() { toAvoid = std::weak_ptr<Entity>(); }
|
||||
|
||||
void AvoidPlayerGoal::tick()
|
||||
{
|
||||
if (mob->distanceToSqr(toAvoid.lock()) < 7 * 7) mob->getNavigation()->setSpeed(sprintSpeed);
|
||||
else mob->getNavigation()->setSpeed(walkSpeed);
|
||||
void AvoidPlayerGoal::tick() {
|
||||
if (mob->distanceToSqr(toAvoid.lock()) < 7 * 7)
|
||||
mob->getNavigation()->setSpeed(sprintSpeed);
|
||||
else
|
||||
mob->getNavigation()->setSpeed(walkSpeed);
|
||||
}
|
||||
|
|
@ -6,24 +6,24 @@ class PathNavigation;
|
|||
class PathfinderMob;
|
||||
class Path;
|
||||
|
||||
class AvoidPlayerGoal : public Goal
|
||||
{
|
||||
class AvoidPlayerGoal : public Goal {
|
||||
private:
|
||||
PathfinderMob *mob; // Owner of this goal
|
||||
float walkSpeed, sprintSpeed;
|
||||
std::weak_ptr<Entity> toAvoid;
|
||||
float maxDist;
|
||||
Path *path;
|
||||
PathNavigation *pathNav;
|
||||
const std::type_info& avoidType;
|
||||
PathfinderMob* mob; // Owner of this goal
|
||||
float walkSpeed, sprintSpeed;
|
||||
std::weak_ptr<Entity> toAvoid;
|
||||
float maxDist;
|
||||
Path* path;
|
||||
PathNavigation* pathNav;
|
||||
const std::type_info& avoidType;
|
||||
|
||||
public:
|
||||
AvoidPlayerGoal(PathfinderMob *mob, const std::type_info& avoidType, float maxDist, float walkSpeed, float sprintSpeed);
|
||||
~AvoidPlayerGoal();
|
||||
AvoidPlayerGoal(PathfinderMob* mob, const std::type_info& avoidType,
|
||||
float maxDist, float walkSpeed, float sprintSpeed);
|
||||
~AvoidPlayerGoal();
|
||||
|
||||
virtual bool canUse();
|
||||
virtual bool canContinueToUse();
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual void tick();
|
||||
virtual bool canUse();
|
||||
virtual bool canContinueToUse();
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual void tick();
|
||||
};
|
||||
|
|
@ -6,55 +6,52 @@
|
|||
#include "../../Headers/net.minecraft.world.item.h"
|
||||
#include "BegGoal.h"
|
||||
|
||||
BegGoal::BegGoal(Wolf *wolf, float lookDistance)
|
||||
{
|
||||
player = std::weak_ptr<Player>();
|
||||
lookTime = 0;
|
||||
BegGoal::BegGoal(Wolf* wolf, float lookDistance) {
|
||||
player = std::weak_ptr<Player>();
|
||||
lookTime = 0;
|
||||
|
||||
this->wolf = wolf;
|
||||
this->level = wolf->level;
|
||||
this->lookDistance = lookDistance;
|
||||
setRequiredControlFlags(Control::LookControlFlag);
|
||||
this->wolf = wolf;
|
||||
this->level = wolf->level;
|
||||
this->lookDistance = lookDistance;
|
||||
setRequiredControlFlags(Control::LookControlFlag);
|
||||
}
|
||||
|
||||
bool BegGoal::canUse()
|
||||
{
|
||||
player = std::weak_ptr<Player>(level->getNearestPlayer(wolf->shared_from_this(), lookDistance));
|
||||
if (player.lock() == NULL) return false;
|
||||
wolf->setDespawnProtected();
|
||||
return playerHoldingInteresting(player.lock());
|
||||
bool BegGoal::canUse() {
|
||||
player = std::weak_ptr<Player>(
|
||||
level->getNearestPlayer(wolf->shared_from_this(), lookDistance));
|
||||
if (player.lock() == NULL) return false;
|
||||
wolf->setDespawnProtected();
|
||||
return playerHoldingInteresting(player.lock());
|
||||
}
|
||||
|
||||
bool BegGoal::canContinueToUse()
|
||||
{
|
||||
if (player.lock() == NULL || !player.lock()->isAlive()) return false;
|
||||
if (wolf->distanceToSqr(player.lock()) > lookDistance * lookDistance) return false;
|
||||
wolf->setDespawnProtected();
|
||||
return lookTime > 0 && playerHoldingInteresting(player.lock());
|
||||
bool BegGoal::canContinueToUse() {
|
||||
if (player.lock() == NULL || !player.lock()->isAlive()) return false;
|
||||
if (wolf->distanceToSqr(player.lock()) > lookDistance * lookDistance)
|
||||
return false;
|
||||
wolf->setDespawnProtected();
|
||||
return lookTime > 0 && playerHoldingInteresting(player.lock());
|
||||
}
|
||||
|
||||
void BegGoal::start()
|
||||
{
|
||||
wolf->setIsInterested(true);
|
||||
lookTime = 40 + wolf->getRandom()->nextInt(40);
|
||||
void BegGoal::start() {
|
||||
wolf->setIsInterested(true);
|
||||
lookTime = 40 + wolf->getRandom()->nextInt(40);
|
||||
}
|
||||
|
||||
void BegGoal::stop()
|
||||
{
|
||||
wolf->setIsInterested(false);
|
||||
player = std::weak_ptr<Player>();
|
||||
void BegGoal::stop() {
|
||||
wolf->setIsInterested(false);
|
||||
player = std::weak_ptr<Player>();
|
||||
}
|
||||
|
||||
void BegGoal::tick()
|
||||
{
|
||||
wolf->getLookControl()->setLookAt(player.lock()->x, player.lock()->y + player.lock()->getHeadHeight(), player.lock()->z, 10, wolf->getMaxHeadXRot());
|
||||
--lookTime;
|
||||
void BegGoal::tick() {
|
||||
wolf->getLookControl()->setLookAt(
|
||||
player.lock()->x, player.lock()->y + player.lock()->getHeadHeight(),
|
||||
player.lock()->z, 10, wolf->getMaxHeadXRot());
|
||||
--lookTime;
|
||||
}
|
||||
|
||||
bool BegGoal::playerHoldingInteresting(std::shared_ptr<Player> player)
|
||||
{
|
||||
std::shared_ptr<ItemInstance> item = player->inventory->getSelected();
|
||||
if (item == NULL) return false;
|
||||
if (!wolf->isTame() && item->id == Item::bone_Id) return true;
|
||||
return wolf->isFood(item);
|
||||
bool BegGoal::playerHoldingInteresting(std::shared_ptr<Player> player) {
|
||||
std::shared_ptr<ItemInstance> item = player->inventory->getSelected();
|
||||
if (item == NULL) return false;
|
||||
if (!wolf->isTame() && item->id == Item::bone_Id) return true;
|
||||
return wolf->isFood(item);
|
||||
}
|
||||
|
|
@ -4,28 +4,28 @@
|
|||
|
||||
class Wolf;
|
||||
|
||||
class BegGoal : public Goal
|
||||
{
|
||||
class BegGoal : public Goal {
|
||||
private:
|
||||
Wolf *wolf; // Owner of this goal
|
||||
std::weak_ptr<Player> player;
|
||||
Level *level;
|
||||
float lookDistance;
|
||||
int lookTime;
|
||||
Wolf* wolf; // Owner of this goal
|
||||
std::weak_ptr<Player> player;
|
||||
Level* level;
|
||||
float lookDistance;
|
||||
int lookTime;
|
||||
|
||||
public:
|
||||
BegGoal(Wolf *wolf, float lookDistance);
|
||||
BegGoal(Wolf* wolf, float lookDistance);
|
||||
|
||||
virtual bool canUse();
|
||||
virtual bool canContinueToUse();
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual void tick();
|
||||
virtual bool canUse();
|
||||
virtual bool canContinueToUse();
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual void tick();
|
||||
|
||||
private:
|
||||
bool playerHoldingInteresting(std::shared_ptr<Player> player);
|
||||
bool playerHoldingInteresting(std::shared_ptr<Player> player);
|
||||
|
||||
public:
|
||||
// 4J Added override to update ai elements when loading entity from schematics
|
||||
virtual void setLevel(Level *level) { this->level = level; }
|
||||
// 4J Added override to update ai elements when loading entity from
|
||||
// schematics
|
||||
virtual void setLevel(Level* level) { this->level = level; }
|
||||
};
|
||||
|
|
@ -6,60 +6,55 @@
|
|||
#include "../../Util/SharedConstants.h"
|
||||
#include "BreakDoorGoal.h"
|
||||
|
||||
BreakDoorGoal::BreakDoorGoal(Mob *mob) : DoorInteractGoal(mob)
|
||||
{
|
||||
breakTime = 0;
|
||||
lastBreakProgress = -1;
|
||||
BreakDoorGoal::BreakDoorGoal(Mob* mob) : DoorInteractGoal(mob) {
|
||||
breakTime = 0;
|
||||
lastBreakProgress = -1;
|
||||
}
|
||||
|
||||
bool BreakDoorGoal::canUse()
|
||||
{
|
||||
if (!DoorInteractGoal::canUse()) return false;
|
||||
return !doorTile->isOpen(mob->level, doorX, doorY, doorZ);
|
||||
bool BreakDoorGoal::canUse() {
|
||||
if (!DoorInteractGoal::canUse()) return false;
|
||||
return !doorTile->isOpen(mob->level, doorX, doorY, doorZ);
|
||||
}
|
||||
|
||||
void BreakDoorGoal::start()
|
||||
{
|
||||
DoorInteractGoal::start();
|
||||
breakTime = 0;
|
||||
void BreakDoorGoal::start() {
|
||||
DoorInteractGoal::start();
|
||||
breakTime = 0;
|
||||
}
|
||||
|
||||
bool BreakDoorGoal::canContinueToUse()
|
||||
{
|
||||
double d = mob->distanceToSqr(doorX, doorY, doorZ);
|
||||
return breakTime <= DOOR_BREAK_TIME && !doorTile->isOpen(mob->level, doorX, doorY, doorZ) && d < 2 * 2;
|
||||
bool BreakDoorGoal::canContinueToUse() {
|
||||
double d = mob->distanceToSqr(doorX, doorY, doorZ);
|
||||
return breakTime <= DOOR_BREAK_TIME &&
|
||||
!doorTile->isOpen(mob->level, doorX, doorY, doorZ) && d < 2 * 2;
|
||||
}
|
||||
|
||||
void BreakDoorGoal::stop()
|
||||
{
|
||||
DoorInteractGoal::stop();
|
||||
mob->level->destroyTileProgress(mob->entityId, doorX, doorY, doorZ, -1);
|
||||
void BreakDoorGoal::stop() {
|
||||
DoorInteractGoal::stop();
|
||||
mob->level->destroyTileProgress(mob->entityId, doorX, doorY, doorZ, -1);
|
||||
}
|
||||
|
||||
void BreakDoorGoal::tick()
|
||||
{
|
||||
DoorInteractGoal::tick();
|
||||
if (mob->getRandom()->nextInt(20) == 0)
|
||||
{
|
||||
mob->level->levelEvent(LevelEvent::SOUND_ZOMBIE_WOODEN_DOOR, doorX, doorY, doorZ, 0);
|
||||
}
|
||||
void BreakDoorGoal::tick() {
|
||||
DoorInteractGoal::tick();
|
||||
if (mob->getRandom()->nextInt(20) == 0) {
|
||||
mob->level->levelEvent(LevelEvent::SOUND_ZOMBIE_WOODEN_DOOR, doorX,
|
||||
doorY, doorZ, 0);
|
||||
}
|
||||
|
||||
breakTime++;
|
||||
breakTime++;
|
||||
|
||||
int progress = (int) (breakTime / (float) DOOR_BREAK_TIME * 10);
|
||||
if (progress != lastBreakProgress)
|
||||
{
|
||||
mob->level->destroyTileProgress(mob->entityId, doorX, doorY, doorZ, progress);
|
||||
lastBreakProgress = progress;
|
||||
}
|
||||
int progress = (int)(breakTime / (float)DOOR_BREAK_TIME * 10);
|
||||
if (progress != lastBreakProgress) {
|
||||
mob->level->destroyTileProgress(mob->entityId, doorX, doorY, doorZ,
|
||||
progress);
|
||||
lastBreakProgress = progress;
|
||||
}
|
||||
|
||||
if (breakTime == DOOR_BREAK_TIME)
|
||||
{
|
||||
if (mob->level->difficulty == Difficulty::HARD)
|
||||
{
|
||||
mob->level->setTile(doorX, doorY, doorZ, 0);
|
||||
mob->level->levelEvent(LevelEvent::SOUND_ZOMBIE_DOOR_CRASH, doorX, doorY, doorZ, 0);
|
||||
mob->level->levelEvent(LevelEvent::PARTICLES_DESTROY_BLOCK, doorX, doorY, doorZ, doorTile->id);
|
||||
}
|
||||
}
|
||||
if (breakTime == DOOR_BREAK_TIME) {
|
||||
if (mob->level->difficulty == Difficulty::HARD) {
|
||||
mob->level->setTile(doorX, doorY, doorZ, 0);
|
||||
mob->level->levelEvent(LevelEvent::SOUND_ZOMBIE_DOOR_CRASH, doorX,
|
||||
doorY, doorZ, 0);
|
||||
mob->level->levelEvent(LevelEvent::PARTICLES_DESTROY_BLOCK, doorX,
|
||||
doorY, doorZ, doorTile->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,20 +3,19 @@
|
|||
#include "DoorInteractGoal.h"
|
||||
#include "../../Util/SharedConstants.h"
|
||||
|
||||
class BreakDoorGoal : public DoorInteractGoal
|
||||
{
|
||||
class BreakDoorGoal : public DoorInteractGoal {
|
||||
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 lastBreakProgress;
|
||||
int breakTime;
|
||||
int lastBreakProgress;
|
||||
|
||||
public:
|
||||
BreakDoorGoal(Mob *mob);
|
||||
BreakDoorGoal(Mob* mob);
|
||||
|
||||
virtual bool canUse();
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual bool canContinueToUse();
|
||||
virtual void tick();
|
||||
virtual bool canUse();
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual bool canContinueToUse();
|
||||
virtual void tick();
|
||||
};
|
||||
|
|
@ -9,108 +9,111 @@
|
|||
|
||||
#include "../../Stats/GenericStats.h"
|
||||
|
||||
BreedGoal::BreedGoal(Animal *animal, float speed)
|
||||
{
|
||||
partner = std::weak_ptr<Animal>();
|
||||
loveTime = 0;
|
||||
BreedGoal::BreedGoal(Animal* animal, float speed) {
|
||||
partner = std::weak_ptr<Animal>();
|
||||
loveTime = 0;
|
||||
|
||||
this->animal = animal;
|
||||
this->level = animal->level;
|
||||
this->speed = speed;
|
||||
setRequiredControlFlags(Control::MoveControlFlag | Control::LookControlFlag);
|
||||
this->animal = animal;
|
||||
this->level = animal->level;
|
||||
this->speed = speed;
|
||||
setRequiredControlFlags(Control::MoveControlFlag |
|
||||
Control::LookControlFlag);
|
||||
}
|
||||
|
||||
bool BreedGoal::canUse()
|
||||
{
|
||||
if (!animal->isInLove()) return false;
|
||||
partner = std::weak_ptr<Animal>(getFreePartner());
|
||||
return partner.lock() != NULL;
|
||||
bool BreedGoal::canUse() {
|
||||
if (!animal->isInLove()) return false;
|
||||
partner = std::weak_ptr<Animal>(getFreePartner());
|
||||
return partner.lock() != NULL;
|
||||
}
|
||||
|
||||
bool BreedGoal::canContinueToUse()
|
||||
{
|
||||
return partner.lock() != NULL && partner.lock()->isAlive() && partner.lock()->isInLove() && loveTime < 20 * 3;
|
||||
bool BreedGoal::canContinueToUse() {
|
||||
return partner.lock() != NULL && partner.lock()->isAlive() &&
|
||||
partner.lock()->isInLove() && loveTime < 20 * 3;
|
||||
}
|
||||
|
||||
void BreedGoal::stop()
|
||||
{
|
||||
partner = std::weak_ptr<Animal>();
|
||||
loveTime = 0;
|
||||
void BreedGoal::stop() {
|
||||
partner = std::weak_ptr<Animal>();
|
||||
loveTime = 0;
|
||||
}
|
||||
|
||||
void BreedGoal::tick()
|
||||
{
|
||||
animal->getLookControl()->setLookAt(partner.lock(), 10, animal->getMaxHeadXRot());
|
||||
animal->getNavigation()->moveTo(partner.lock(), speed);
|
||||
++loveTime;
|
||||
if (loveTime == 20 * 3) breed();
|
||||
void BreedGoal::tick() {
|
||||
animal->getLookControl()->setLookAt(partner.lock(), 10,
|
||||
animal->getMaxHeadXRot());
|
||||
animal->getNavigation()->moveTo(partner.lock(), speed);
|
||||
++loveTime;
|
||||
if (loveTime == 20 * 3) breed();
|
||||
}
|
||||
|
||||
std::shared_ptr<Animal> BreedGoal::getFreePartner()
|
||||
{
|
||||
float r = 8;
|
||||
std::vector<std::shared_ptr<Entity> > *others = level->getEntitiesOfClass(typeid(*animal), animal->bb->grow(r, r, r));
|
||||
for(AUTO_VAR(it, others->begin()); it != others->end(); ++it)
|
||||
{
|
||||
std::shared_ptr<Animal> p = std::dynamic_pointer_cast<Animal>(*it);
|
||||
if (animal->canMate(p))
|
||||
{
|
||||
delete others;
|
||||
return p;
|
||||
}
|
||||
}
|
||||
delete others;
|
||||
return nullptr;
|
||||
std::shared_ptr<Animal> BreedGoal::getFreePartner() {
|
||||
float r = 8;
|
||||
std::vector<std::shared_ptr<Entity> >* others =
|
||||
level->getEntitiesOfClass(typeid(*animal), animal->bb->grow(r, r, r));
|
||||
for (AUTO_VAR(it, others->begin()); it != others->end(); ++it) {
|
||||
std::shared_ptr<Animal> p = std::dynamic_pointer_cast<Animal>(*it);
|
||||
if (animal->canMate(p)) {
|
||||
delete others;
|
||||
return p;
|
||||
}
|
||||
}
|
||||
delete others;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void BreedGoal::breed()
|
||||
{
|
||||
std::shared_ptr<AgableMob> offspring = animal->getBreedOffspring(partner.lock());
|
||||
animal->setDespawnProtected();
|
||||
partner.lock()->setDespawnProtected();
|
||||
if (offspring == NULL)
|
||||
{
|
||||
// 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
|
||||
animal->resetLove();
|
||||
partner.lock()->resetLove();
|
||||
return;
|
||||
}
|
||||
void BreedGoal::breed() {
|
||||
std::shared_ptr<AgableMob> offspring =
|
||||
animal->getBreedOffspring(partner.lock());
|
||||
animal->setDespawnProtected();
|
||||
partner.lock()->setDespawnProtected();
|
||||
if (offspring == NULL) {
|
||||
// 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
|
||||
animal->resetLove();
|
||||
partner.lock()->resetLove();
|
||||
return;
|
||||
}
|
||||
|
||||
std::shared_ptr<Player> loveCause = animal->getLoveCause();
|
||||
if (loveCause == NULL && partner.lock()->getLoveCause() != NULL)
|
||||
{
|
||||
loveCause = partner.lock()->getLoveCause();
|
||||
}
|
||||
std::shared_ptr<Player> loveCause = animal->getLoveCause();
|
||||
if (loveCause == NULL && partner.lock()->getLoveCause() != NULL) {
|
||||
loveCause = partner.lock()->getLoveCause();
|
||||
}
|
||||
|
||||
if (loveCause != NULL)
|
||||
{
|
||||
// Record mob bred stat.
|
||||
loveCause->awardStat(GenericStats::breedEntity(offspring->GetType()),GenericStats::param_breedEntity(offspring->GetType()));
|
||||
if (loveCause != NULL) {
|
||||
// Record mob bred stat.
|
||||
loveCause->awardStat(
|
||||
GenericStats::breedEntity(offspring->GetType()),
|
||||
GenericStats::param_breedEntity(offspring->GetType()));
|
||||
|
||||
if (animal->GetType() == eTYPE_COW)
|
||||
{
|
||||
//loveCause->awardStat(Achievements.breedCow);
|
||||
}
|
||||
}
|
||||
if (animal->GetType() == eTYPE_COW) {
|
||||
// loveCause->awardStat(Achievements.breedCow);
|
||||
}
|
||||
}
|
||||
|
||||
animal->setAge(5 * 60 * 20);
|
||||
partner.lock()->setAge(5 * 60 * 20);
|
||||
animal->resetLove();
|
||||
partner.lock()->resetLove();
|
||||
offspring->setAge(-20 * 60 * 20);
|
||||
offspring->moveTo(animal->x, animal->y, animal->z, 0, 0);
|
||||
offspring->setDespawnProtected();
|
||||
level->addEntity(offspring);
|
||||
animal->setAge(5 * 60 * 20);
|
||||
partner.lock()->setAge(5 * 60 * 20);
|
||||
animal->resetLove();
|
||||
partner.lock()->resetLove();
|
||||
offspring->setAge(-20 * 60 * 20);
|
||||
offspring->moveTo(animal->x, animal->y, animal->z, 0, 0);
|
||||
offspring->setDespawnProtected();
|
||||
level->addEntity(offspring);
|
||||
|
||||
Random *random = animal->getRandom();
|
||||
for (int i = 0; i < 7; i++)
|
||||
{
|
||||
double xa = random->nextGaussian() * 0.02;
|
||||
double ya = random->nextGaussian() * 0.02;
|
||||
double za = random->nextGaussian() * 0.02;
|
||||
level->addParticle(eParticleType_heart, animal->x + random->nextFloat() * animal->bbWidth * 2 - animal->bbWidth, animal->y + .5f + random->nextFloat() * animal->bbHeight, animal->z + random->nextFloat()
|
||||
* 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) ) );
|
||||
Random* random = animal->getRandom();
|
||||
for (int i = 0; i < 7; i++) {
|
||||
double xa = random->nextGaussian() * 0.02;
|
||||
double ya = random->nextGaussian() * 0.02;
|
||||
double za = random->nextGaussian() * 0.02;
|
||||
level->addParticle(
|
||||
eParticleType_heart,
|
||||
animal->x + random->nextFloat() * animal->bbWidth * 2 -
|
||||
animal->bbWidth,
|
||||
animal->y + .5f + random->nextFloat() * animal->bbHeight,
|
||||
animal->z + random->nextFloat() * 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)));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,28 +5,28 @@
|
|||
class Animal;
|
||||
class Level;
|
||||
|
||||
class BreedGoal : public Goal
|
||||
{
|
||||
class BreedGoal : public Goal {
|
||||
private:
|
||||
Animal *animal; // Owner of this goal
|
||||
Level *level;
|
||||
std::weak_ptr<Animal> partner;
|
||||
int loveTime;
|
||||
float speed;
|
||||
Animal* animal; // Owner of this goal
|
||||
Level* level;
|
||||
std::weak_ptr<Animal> partner;
|
||||
int loveTime;
|
||||
float speed;
|
||||
|
||||
public:
|
||||
BreedGoal(Animal *animal, float speed);
|
||||
BreedGoal(Animal* animal, float speed);
|
||||
|
||||
virtual bool canUse();
|
||||
virtual bool canContinueToUse();
|
||||
virtual void stop();
|
||||
virtual void tick();
|
||||
virtual bool canUse();
|
||||
virtual bool canContinueToUse();
|
||||
virtual void stop();
|
||||
virtual void tick();
|
||||
|
||||
private:
|
||||
std::shared_ptr<Animal> getFreePartner();
|
||||
void breed();
|
||||
std::shared_ptr<Animal> getFreePartner();
|
||||
void breed();
|
||||
|
||||
public:
|
||||
// 4J Added override to update ai elements when loading entity from schematics
|
||||
virtual void setLevel(Level *level) { this->level = level; }
|
||||
// 4J Added override to update ai elements when loading entity from
|
||||
// schematics
|
||||
virtual void setLevel(Level* level) { this->level = level; }
|
||||
};
|
||||
|
|
@ -8,145 +8,143 @@
|
|||
#include "../../Headers/net.minecraft.world.level.pathfinder.h"
|
||||
#include "ControlledByPlayerGoal.h"
|
||||
|
||||
ControlledByPlayerGoal::ControlledByPlayerGoal(Mob *mob, float maxSpeed, float walkSpeed)
|
||||
{
|
||||
this->mob = mob;
|
||||
this->maxSpeed = maxSpeed;
|
||||
this->walkSpeed = walkSpeed;
|
||||
speed = 0;
|
||||
boosting = false;
|
||||
boostTime = 0;
|
||||
boostTimeTotal = 0;
|
||||
setRequiredControlFlags(Control::MoveControlFlag | Control::JumpControlFlag | Control::LookControlFlag);
|
||||
ControlledByPlayerGoal::ControlledByPlayerGoal(Mob* mob, float maxSpeed,
|
||||
float walkSpeed) {
|
||||
this->mob = mob;
|
||||
this->maxSpeed = maxSpeed;
|
||||
this->walkSpeed = walkSpeed;
|
||||
speed = 0;
|
||||
boosting = false;
|
||||
boostTime = 0;
|
||||
boostTimeTotal = 0;
|
||||
setRequiredControlFlags(Control::MoveControlFlag |
|
||||
Control::JumpControlFlag |
|
||||
Control::LookControlFlag);
|
||||
}
|
||||
|
||||
void ControlledByPlayerGoal::start()
|
||||
{
|
||||
speed = 0;
|
||||
void ControlledByPlayerGoal::start() {
|
||||
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
|
||||
if(mob->getSpeed() < walkSpeed) mob->setSpeed(walkSpeed);
|
||||
// 4J Stu - Need to initialise this otherwise the pig will never move if you
|
||||
// jump on before another goal has made it move and set the speed
|
||||
if (mob->getSpeed() < walkSpeed) mob->setSpeed(walkSpeed);
|
||||
}
|
||||
|
||||
void ControlledByPlayerGoal::stop()
|
||||
{
|
||||
boosting = false;
|
||||
speed = 0;
|
||||
void ControlledByPlayerGoal::stop() {
|
||||
boosting = false;
|
||||
speed = 0;
|
||||
}
|
||||
|
||||
bool ControlledByPlayerGoal::canUse()
|
||||
{
|
||||
std::shared_ptr<Player> player = std::dynamic_pointer_cast<Player>( mob->rider.lock() );
|
||||
return mob->isAlive() && player && (boosting || mob->canBeControlledByRider());
|
||||
bool ControlledByPlayerGoal::canUse() {
|
||||
std::shared_ptr<Player> player =
|
||||
std::dynamic_pointer_cast<Player>(mob->rider.lock());
|
||||
return mob->isAlive() && player &&
|
||||
(boosting || mob->canBeControlledByRider());
|
||||
}
|
||||
|
||||
void ControlledByPlayerGoal::tick()
|
||||
{
|
||||
std::shared_ptr<Player> player = std::dynamic_pointer_cast<Player>(mob->rider.lock());
|
||||
PathfinderMob *pig = (PathfinderMob *)mob;
|
||||
void ControlledByPlayerGoal::tick() {
|
||||
std::shared_ptr<Player> player =
|
||||
std::dynamic_pointer_cast<Player>(mob->rider.lock());
|
||||
PathfinderMob* pig = (PathfinderMob*)mob;
|
||||
|
||||
float yrd = Mth::wrapDegrees(player->yRot - mob->yRot) * 0.5f;
|
||||
if (yrd > 5) yrd = 5;
|
||||
if (yrd < -5) yrd = -5;
|
||||
float yrd = Mth::wrapDegrees(player->yRot - mob->yRot) * 0.5f;
|
||||
if (yrd > 5) yrd = 5;
|
||||
if (yrd < -5) yrd = -5;
|
||||
|
||||
mob->yRot = Mth::wrapDegrees(mob->yRot + yrd);
|
||||
if (speed < maxSpeed) speed += (maxSpeed - speed) * 0.01f;
|
||||
if (speed > maxSpeed) speed = maxSpeed;
|
||||
mob->yRot = Mth::wrapDegrees(mob->yRot + yrd);
|
||||
if (speed < maxSpeed) speed += (maxSpeed - speed) * 0.01f;
|
||||
if (speed > maxSpeed) speed = maxSpeed;
|
||||
|
||||
int x = Mth::floor(mob->x);
|
||||
int y = Mth::floor(mob->y);
|
||||
int z = Mth::floor(mob->z);
|
||||
float moveSpeed = speed;
|
||||
if (boosting)
|
||||
{
|
||||
if (boostTime++ > boostTimeTotal)
|
||||
{
|
||||
boosting = false;
|
||||
}
|
||||
moveSpeed += moveSpeed * 1.15f * Mth::sin((float) boostTime / boostTimeTotal * PI);
|
||||
}
|
||||
int x = Mth::floor(mob->x);
|
||||
int y = Mth::floor(mob->y);
|
||||
int z = Mth::floor(mob->z);
|
||||
float moveSpeed = speed;
|
||||
if (boosting) {
|
||||
if (boostTime++ > boostTimeTotal) {
|
||||
boosting = false;
|
||||
}
|
||||
moveSpeed += moveSpeed * 1.15f *
|
||||
Mth::sin((float)boostTime / boostTimeTotal * PI);
|
||||
}
|
||||
|
||||
float friction = 0.91f;
|
||||
if (mob->onGround)
|
||||
{
|
||||
friction = 0.6f * 0.91f;
|
||||
int t = mob->level->getTile(x,y,z);
|
||||
if (t > 0)
|
||||
{
|
||||
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 sin = Mth::sin(pig->yRot * PI / 180);
|
||||
float cos = Mth::cos(pig->yRot * PI / 180);
|
||||
float aproxSpeed = pig->getSpeed() * friction2;
|
||||
float dist = std::max((int)moveSpeed, 1);
|
||||
dist = aproxSpeed / dist;
|
||||
float normMoveSpeed = moveSpeed * dist;
|
||||
float xa = -(normMoveSpeed * sin);
|
||||
float za = normMoveSpeed * cos;
|
||||
float friction = 0.91f;
|
||||
if (mob->onGround) {
|
||||
friction = 0.6f * 0.91f;
|
||||
int t = mob->level->getTile(x, y, z);
|
||||
if (t > 0) {
|
||||
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 sin = Mth::sin(pig->yRot * PI / 180);
|
||||
float cos = Mth::cos(pig->yRot * PI / 180);
|
||||
float aproxSpeed = pig->getSpeed() * friction2;
|
||||
float dist = std::max((int)moveSpeed, 1);
|
||||
dist = aproxSpeed / dist;
|
||||
float normMoveSpeed = moveSpeed * dist;
|
||||
float xa = -(normMoveSpeed * sin);
|
||||
float za = normMoveSpeed * cos;
|
||||
|
||||
if (Mth::abs(xa) > Mth::abs(za))
|
||||
{
|
||||
if (xa < 0) xa -= mob->bbWidth / 2.0f;
|
||||
if (xa > 0) xa += mob->bbWidth / 2.0f;
|
||||
za = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
xa = 0;
|
||||
if (za < 0) za -= mob->bbWidth / 2.0f;
|
||||
if (za > 0) za += mob->bbWidth / 2.0f;
|
||||
}
|
||||
if (Mth::abs(xa) > Mth::abs(za)) {
|
||||
if (xa < 0) xa -= mob->bbWidth / 2.0f;
|
||||
if (xa > 0) xa += mob->bbWidth / 2.0f;
|
||||
za = 0;
|
||||
} else {
|
||||
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 zt = Mth::floor(mob->z + za);
|
||||
int xt = Mth::floor(mob->x + xa);
|
||||
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 (PathFinder::isFree(mob, xt, y, zt, size, false, false, true) == PathFinder::TYPE_BLOCKED
|
||||
&& PathFinder::isFree(mob, x, y + 1, z, size, false, false, true) == PathFinder::TYPE_OPEN
|
||||
&& PathFinder::isFree(mob, xt, y + 1, zt, size, false, false, true) == PathFinder::TYPE_OPEN)
|
||||
{
|
||||
pig->getJumpControl()->jump();
|
||||
}
|
||||
}
|
||||
if (x != xt || z != zt) {
|
||||
if (PathFinder::isFree(mob, xt, y, zt, size, false, false, true) ==
|
||||
PathFinder::TYPE_BLOCKED &&
|
||||
PathFinder::isFree(mob, x, y + 1, z, size, false, false, true) ==
|
||||
PathFinder::TYPE_OPEN &&
|
||||
PathFinder::isFree(mob, xt, y + 1, zt, size, false, false, true) ==
|
||||
PathFinder::TYPE_OPEN) {
|
||||
pig->getJumpControl()->jump();
|
||||
}
|
||||
}
|
||||
|
||||
if (!player->abilities.instabuild && speed >= maxSpeed * 0.5f && mob->getRandom()->nextFloat() < 0.006f && !boosting)
|
||||
{
|
||||
std::shared_ptr<ItemInstance> carriedItem = player->getCarriedItem();
|
||||
if (!player->abilities.instabuild && speed >= maxSpeed * 0.5f &&
|
||||
mob->getRandom()->nextFloat() < 0.006f && !boosting) {
|
||||
std::shared_ptr<ItemInstance> carriedItem = player->getCarriedItem();
|
||||
|
||||
if (carriedItem != NULL && carriedItem->id == Item::carrotOnAStick_Id)
|
||||
{
|
||||
carriedItem->hurt(1, player);
|
||||
if (carriedItem != NULL && carriedItem->id == Item::carrotOnAStick_Id) {
|
||||
carriedItem->hurt(1, player);
|
||||
|
||||
if (carriedItem->count == 0)
|
||||
{
|
||||
std::shared_ptr<ItemInstance> replacement = std::shared_ptr<ItemInstance>(new ItemInstance(Item::fishingRod));
|
||||
replacement->setTag(carriedItem->tag);
|
||||
player->inventory->items[player->inventory->selected] = replacement;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (carriedItem->count == 0) {
|
||||
std::shared_ptr<ItemInstance> replacement =
|
||||
std::shared_ptr<ItemInstance>(
|
||||
new ItemInstance(Item::fishingRod));
|
||||
replacement->setTag(carriedItem->tag);
|
||||
player->inventory->items[player->inventory->selected] =
|
||||
replacement;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mob->travel(0, moveSpeed);
|
||||
mob->travel(0, moveSpeed);
|
||||
}
|
||||
|
||||
bool ControlledByPlayerGoal::isBoosting()
|
||||
{
|
||||
return boosting;
|
||||
bool ControlledByPlayerGoal::isBoosting() { 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()
|
||||
{
|
||||
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;
|
||||
bool ControlledByPlayerGoal::canBoost() {
|
||||
return !isBoosting() && speed > maxSpeed * 0.3f;
|
||||
}
|
||||
|
|
@ -5,28 +5,28 @@
|
|||
|
||||
class Mob;
|
||||
|
||||
class ControlledByPlayerGoal : public Goal
|
||||
{
|
||||
class ControlledByPlayerGoal : public Goal {
|
||||
private:
|
||||
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 MIN_BOOST_TIME = SharedConstants::TICKS_PER_SECOND * 7;
|
||||
static const int MAX_BOOST_TIME = SharedConstants::TICKS_PER_SECOND * 35;
|
||||
|
||||
Mob *mob; // Owner of this goal
|
||||
float maxSpeed;
|
||||
float walkSpeed;
|
||||
float speed;
|
||||
bool boosting;
|
||||
int boostTime;
|
||||
int boostTimeTotal;
|
||||
Mob* mob; // Owner of this goal
|
||||
float maxSpeed;
|
||||
float walkSpeed;
|
||||
float speed;
|
||||
bool boosting;
|
||||
int boostTime;
|
||||
int boostTimeTotal;
|
||||
|
||||
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 stop();
|
||||
bool canUse();
|
||||
void tick();
|
||||
bool isBoosting();
|
||||
void boost();
|
||||
bool canBoost();
|
||||
void start();
|
||||
void stop();
|
||||
bool canUse();
|
||||
void tick();
|
||||
bool isBoosting();
|
||||
void boost();
|
||||
bool canBoost();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3,22 +3,21 @@
|
|||
#include "../../Headers/net.minecraft.world.entity.animal.h"
|
||||
#include "DefendVillageTargetGoal.h"
|
||||
|
||||
DefendVillageTargetGoal::DefendVillageTargetGoal(VillagerGolem *golem) : TargetGoal(golem, 16, false, true)
|
||||
{
|
||||
this->golem = golem;
|
||||
setRequiredControlFlags(TargetGoal::TargetFlag);
|
||||
DefendVillageTargetGoal::DefendVillageTargetGoal(VillagerGolem* golem)
|
||||
: TargetGoal(golem, 16, false, true) {
|
||||
this->golem = golem;
|
||||
setRequiredControlFlags(TargetGoal::TargetFlag);
|
||||
}
|
||||
|
||||
bool DefendVillageTargetGoal::canUse()
|
||||
{
|
||||
std::shared_ptr<Village> village = golem->getVillage();
|
||||
if (village == NULL) return false;
|
||||
potentialTarget = std::weak_ptr<Mob>(village->getClosestAggressor(std::dynamic_pointer_cast<Mob>(golem->shared_from_this())));
|
||||
return canAttack(potentialTarget.lock(), false);
|
||||
bool DefendVillageTargetGoal::canUse() {
|
||||
std::shared_ptr<Village> village = golem->getVillage();
|
||||
if (village == NULL) return false;
|
||||
potentialTarget = std::weak_ptr<Mob>(village->getClosestAggressor(
|
||||
std::dynamic_pointer_cast<Mob>(golem->shared_from_this())));
|
||||
return canAttack(potentialTarget.lock(), false);
|
||||
}
|
||||
|
||||
void DefendVillageTargetGoal::start()
|
||||
{
|
||||
golem->setTarget(potentialTarget.lock());
|
||||
TargetGoal::start();
|
||||
void DefendVillageTargetGoal::start() {
|
||||
golem->setTarget(potentialTarget.lock());
|
||||
TargetGoal::start();
|
||||
}
|
||||
|
|
@ -4,15 +4,14 @@
|
|||
|
||||
class VillagerGolem;
|
||||
|
||||
class DefendVillageTargetGoal : public TargetGoal
|
||||
{
|
||||
class DefendVillageTargetGoal : public TargetGoal {
|
||||
private:
|
||||
VillagerGolem *golem; // Owner of this goal
|
||||
std::weak_ptr<Mob> potentialTarget;
|
||||
VillagerGolem* golem; // Owner of this goal
|
||||
std::weak_ptr<Mob> potentialTarget;
|
||||
|
||||
public:
|
||||
DefendVillageTargetGoal(VillagerGolem *golem);
|
||||
DefendVillageTargetGoal(VillagerGolem* golem);
|
||||
|
||||
bool canUse();
|
||||
void start();
|
||||
bool canUse();
|
||||
void start();
|
||||
};
|
||||
|
|
@ -6,68 +6,59 @@
|
|||
#include "../../Headers/net.minecraft.world.level.tile.h"
|
||||
#include "DoorInteractGoal.h"
|
||||
|
||||
DoorInteractGoal::DoorInteractGoal(Mob *mob)
|
||||
{
|
||||
doorX = doorY = doorZ = 0;
|
||||
doorTile = NULL;
|
||||
passed = false;
|
||||
doorOpenDirX = doorOpenDirZ = 0.0f;
|
||||
DoorInteractGoal::DoorInteractGoal(Mob* mob) {
|
||||
doorX = doorY = doorZ = 0;
|
||||
doorTile = NULL;
|
||||
passed = false;
|
||||
doorOpenDirX = doorOpenDirZ = 0.0f;
|
||||
|
||||
this->mob = mob;
|
||||
this->mob = mob;
|
||||
}
|
||||
|
||||
bool DoorInteractGoal::canUse()
|
||||
{
|
||||
if (!mob->horizontalCollision) return false;
|
||||
PathNavigation *pathNav = mob->getNavigation();
|
||||
Path *path = pathNav->getPath();
|
||||
if (path == NULL || path->isDone() || !pathNav->canOpenDoors()) return false;
|
||||
bool DoorInteractGoal::canUse() {
|
||||
if (!mob->horizontalCollision) return false;
|
||||
PathNavigation* pathNav = mob->getNavigation();
|
||||
Path* path = pathNav->getPath();
|
||||
if (path == NULL || path->isDone() || !pathNav->canOpenDoors())
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < std::min(path->getIndex() + 2, path->getSize()); ++i)
|
||||
{
|
||||
Node *n = path->get(i);
|
||||
doorX = n->x;
|
||||
doorY = n->y + 1;
|
||||
doorZ = n->z;
|
||||
if (mob->distanceToSqr(doorX, mob->y, doorZ) > 1.5 * 1.5) continue;
|
||||
doorTile = getDoorTile(doorX, doorY, doorZ);
|
||||
if (doorTile == NULL) continue;
|
||||
return true;
|
||||
}
|
||||
for (int i = 0; i < std::min(path->getIndex() + 2, path->getSize()); ++i) {
|
||||
Node* n = path->get(i);
|
||||
doorX = n->x;
|
||||
doorY = n->y + 1;
|
||||
doorZ = n->z;
|
||||
if (mob->distanceToSqr(doorX, mob->y, doorZ) > 1.5 * 1.5) continue;
|
||||
doorTile = getDoorTile(doorX, doorY, doorZ);
|
||||
if (doorTile == NULL) continue;
|
||||
return true;
|
||||
}
|
||||
|
||||
doorX = Mth::floor(mob->x);
|
||||
doorY = Mth::floor(mob->y + 1);
|
||||
doorZ = Mth::floor(mob->z);
|
||||
doorTile = getDoorTile(doorX, doorY, doorZ);
|
||||
return doorTile != NULL;
|
||||
doorX = Mth::floor(mob->x);
|
||||
doorY = Mth::floor(mob->y + 1);
|
||||
doorZ = Mth::floor(mob->z);
|
||||
doorTile = getDoorTile(doorX, doorY, doorZ);
|
||||
return doorTile != NULL;
|
||||
}
|
||||
|
||||
bool DoorInteractGoal::canContinueToUse()
|
||||
{
|
||||
return !passed;
|
||||
bool DoorInteractGoal::canContinueToUse() { return !passed; }
|
||||
|
||||
void DoorInteractGoal::start() {
|
||||
passed = false;
|
||||
doorOpenDirX = (float)(doorX + 0.5f - mob->x);
|
||||
doorOpenDirZ = (float)(doorZ + 0.5f - mob->z);
|
||||
}
|
||||
|
||||
void DoorInteractGoal::start()
|
||||
{
|
||||
passed = false;
|
||||
doorOpenDirX = (float) (doorX + 0.5f - mob->x);
|
||||
doorOpenDirZ = (float) (doorZ + 0.5f - mob->z);
|
||||
void DoorInteractGoal::tick() {
|
||||
float newDoorDirX = (float)(doorX + 0.5f - mob->x);
|
||||
float newDoorDirZ = (float)(doorZ + 0.5f - mob->z);
|
||||
float dot = doorOpenDirX * newDoorDirX + doorOpenDirZ * newDoorDirZ;
|
||||
if (dot < 0) {
|
||||
passed = true;
|
||||
}
|
||||
}
|
||||
|
||||
void DoorInteractGoal::tick()
|
||||
{
|
||||
float newDoorDirX = (float) (doorX + 0.5f - mob->x);
|
||||
float newDoorDirZ = (float) (doorZ + 0.5f - mob->z);
|
||||
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];
|
||||
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];
|
||||
}
|
||||
|
|
@ -4,26 +4,25 @@
|
|||
|
||||
class DoorTile;
|
||||
|
||||
class DoorInteractGoal : public Goal
|
||||
{
|
||||
class DoorInteractGoal : public Goal {
|
||||
protected:
|
||||
Mob *mob; // Owner of this goal
|
||||
int doorX, doorY, doorZ;
|
||||
DoorTile *doorTile;
|
||||
Mob* mob; // Owner of this goal
|
||||
int doorX, doorY, doorZ;
|
||||
DoorTile* doorTile;
|
||||
|
||||
private:
|
||||
bool passed;
|
||||
float doorOpenDirX, doorOpenDirZ;
|
||||
bool passed;
|
||||
float doorOpenDirX, doorOpenDirZ;
|
||||
|
||||
public:
|
||||
DoorInteractGoal(Mob *mob);
|
||||
virtual ~DoorInteractGoal() {}
|
||||
DoorInteractGoal(Mob* mob);
|
||||
virtual ~DoorInteractGoal() {}
|
||||
|
||||
virtual bool canUse();
|
||||
virtual bool canContinueToUse();
|
||||
virtual void start();
|
||||
virtual void tick();
|
||||
virtual bool canUse();
|
||||
virtual bool canContinueToUse();
|
||||
virtual void start();
|
||||
virtual void tick();
|
||||
|
||||
private:
|
||||
DoorTile *getDoorTile(int x, int y, int z);
|
||||
DoorTile* getDoorTile(int x, int y, int z);
|
||||
};
|
||||
|
|
@ -6,68 +6,60 @@
|
|||
#include "../../Headers/net.minecraft.world.level.tile.h"
|
||||
#include "EatTileGoal.h"
|
||||
|
||||
EatTileGoal::EatTileGoal(Mob *mob)
|
||||
{
|
||||
eatAnimationTick = 0;
|
||||
EatTileGoal::EatTileGoal(Mob* mob) {
|
||||
eatAnimationTick = 0;
|
||||
|
||||
this->mob = mob;
|
||||
this->level = mob->level;
|
||||
setRequiredControlFlags(Control::MoveControlFlag | Control::LookControlFlag | Control::JumpControlFlag);
|
||||
this->mob = mob;
|
||||
this->level = mob->level;
|
||||
setRequiredControlFlags(Control::MoveControlFlag |
|
||||
Control::LookControlFlag |
|
||||
Control::JumpControlFlag);
|
||||
}
|
||||
|
||||
bool EatTileGoal::canUse()
|
||||
{
|
||||
if (mob->getRandom()->nextInt(mob->isBaby() ? 50 : 1000) != 0) return false;
|
||||
bool EatTileGoal::canUse() {
|
||||
if (mob->getRandom()->nextInt(mob->isBaby() ? 50 : 1000) != 0) return false;
|
||||
|
||||
int xx = Mth::floor(mob->x);
|
||||
int yy = Mth::floor(mob->y);
|
||||
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 - 1, zz) == Tile::grass_Id) return true;
|
||||
return false;
|
||||
int xx = Mth::floor(mob->x);
|
||||
int yy = Mth::floor(mob->y);
|
||||
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 - 1, zz) == Tile::grass_Id) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void EatTileGoal::start()
|
||||
{
|
||||
eatAnimationTick = EAT_ANIMATION_TICKS;
|
||||
level->broadcastEntityEvent(mob->shared_from_this(), EntityEvent::EAT_GRASS);
|
||||
mob->getNavigation()->stop();
|
||||
void EatTileGoal::start() {
|
||||
eatAnimationTick = EAT_ANIMATION_TICKS;
|
||||
level->broadcastEntityEvent(mob->shared_from_this(),
|
||||
EntityEvent::EAT_GRASS);
|
||||
mob->getNavigation()->stop();
|
||||
}
|
||||
|
||||
void EatTileGoal::stop()
|
||||
{
|
||||
eatAnimationTick = 0;
|
||||
}
|
||||
void EatTileGoal::stop() { eatAnimationTick = 0; }
|
||||
|
||||
bool EatTileGoal::canContinueToUse()
|
||||
{
|
||||
return eatAnimationTick > 0;
|
||||
}
|
||||
bool EatTileGoal::canContinueToUse() { return eatAnimationTick > 0; }
|
||||
|
||||
int EatTileGoal::getEatAnimationTick()
|
||||
{
|
||||
return eatAnimationTick;
|
||||
}
|
||||
int EatTileGoal::getEatAnimationTick() { return eatAnimationTick; }
|
||||
|
||||
void EatTileGoal::tick()
|
||||
{
|
||||
eatAnimationTick = std::max(0, eatAnimationTick - 1);
|
||||
if (eatAnimationTick != 4) return;
|
||||
void EatTileGoal::tick() {
|
||||
eatAnimationTick = std::max(0, eatAnimationTick - 1);
|
||||
if (eatAnimationTick != 4) return;
|
||||
|
||||
int xx = Mth::floor(mob->x);
|
||||
int yy = Mth::floor(mob->y);
|
||||
int zz = Mth::floor(mob->z);
|
||||
int xx = Mth::floor(mob->x);
|
||||
int yy = Mth::floor(mob->y);
|
||||
int zz = Mth::floor(mob->z);
|
||||
|
||||
if (level->getTile(xx, yy, zz) == Tile::tallgrass_Id)
|
||||
{
|
||||
level->levelEvent(LevelEvent::PARTICLES_DESTROY_BLOCK, xx, yy, zz, Tile::tallgrass_Id + (TallGrass::TALL_GRASS << Tile::TILE_NUM_SHIFT));
|
||||
level->setTile(xx, yy, zz, 0);
|
||||
mob->ate();
|
||||
}
|
||||
else if (level->getTile(xx, yy - 1, zz) == Tile::grass_Id)
|
||||
{
|
||||
level->levelEvent(LevelEvent::PARTICLES_DESTROY_BLOCK, xx, yy - 1, zz, Tile::grass_Id);
|
||||
level->setTile(xx, yy - 1, zz, Tile::dirt_Id);
|
||||
mob->ate();
|
||||
}
|
||||
if (level->getTile(xx, yy, zz) == Tile::tallgrass_Id) {
|
||||
level->levelEvent(LevelEvent::PARTICLES_DESTROY_BLOCK, xx, yy, zz,
|
||||
Tile::tallgrass_Id +
|
||||
(TallGrass::TALL_GRASS << Tile::TILE_NUM_SHIFT));
|
||||
level->setTile(xx, yy, zz, 0);
|
||||
mob->ate();
|
||||
} else if (level->getTile(xx, yy - 1, zz) == Tile::grass_Id) {
|
||||
level->levelEvent(LevelEvent::PARTICLES_DESTROY_BLOCK, xx, yy - 1, zz,
|
||||
Tile::grass_Id);
|
||||
level->setTile(xx, yy - 1, zz, Tile::dirt_Id);
|
||||
mob->ate();
|
||||
}
|
||||
}
|
||||
|
|
@ -3,26 +3,28 @@
|
|||
#include "Goal.h"
|
||||
#include "../../Util/SharedConstants.h"
|
||||
|
||||
// note: Mob should implement handleEntityEvent for client state, also ate to take action upon eating
|
||||
class EatTileGoal : public Goal
|
||||
{
|
||||
// note: Mob should implement handleEntityEvent for client state, also ate to
|
||||
// take action upon eating
|
||||
class EatTileGoal : public Goal {
|
||||
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
|
||||
Level *level;
|
||||
int eatAnimationTick;
|
||||
Mob* mob; // Owner of this goal
|
||||
Level* level;
|
||||
int eatAnimationTick;
|
||||
|
||||
public:
|
||||
EatTileGoal(Mob *mob);
|
||||
EatTileGoal(Mob* mob);
|
||||
|
||||
virtual bool canUse();
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual bool canContinueToUse();
|
||||
virtual int getEatAnimationTick();
|
||||
virtual void tick();
|
||||
|
||||
// 4J Added override to update ai elements when loading entity from schematics
|
||||
virtual void setLevel(Level *level) { this->level = level; }
|
||||
virtual bool canUse();
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual bool canContinueToUse();
|
||||
virtual int getEatAnimationTick();
|
||||
virtual void tick();
|
||||
|
||||
// 4J Added override to update ai elements when loading entity from
|
||||
// schematics
|
||||
virtual void setLevel(Level* level) { this->level = level; }
|
||||
};
|
||||
|
|
@ -6,47 +6,43 @@
|
|||
#include "../../Headers/net.minecraft.world.phys.h"
|
||||
#include "FleeSunGoal.h"
|
||||
|
||||
FleeSunGoal::FleeSunGoal(PathfinderMob *mob, float speed)
|
||||
{
|
||||
this->mob = mob;
|
||||
this->speed = speed;
|
||||
this->level = mob->level;
|
||||
setRequiredControlFlags(Control::MoveControlFlag);
|
||||
FleeSunGoal::FleeSunGoal(PathfinderMob* mob, float speed) {
|
||||
this->mob = mob;
|
||||
this->speed = speed;
|
||||
this->level = mob->level;
|
||||
setRequiredControlFlags(Control::MoveControlFlag);
|
||||
}
|
||||
|
||||
bool FleeSunGoal::canUse()
|
||||
{
|
||||
if (!level->isDay()) return false;
|
||||
if (!mob->isOnFire()) return false;
|
||||
if (!level->canSeeSky(Mth::floor(mob->x), (int) mob->bb->y0, Mth::floor(mob->z))) return false;
|
||||
bool FleeSunGoal::canUse() {
|
||||
if (!level->isDay()) return false;
|
||||
if (!mob->isOnFire()) return false;
|
||||
if (!level->canSeeSky(Mth::floor(mob->x), (int)mob->bb->y0,
|
||||
Mth::floor(mob->z)))
|
||||
return false;
|
||||
|
||||
Vec3 *pos = getHidePos();
|
||||
if (pos == NULL) return false;
|
||||
wantedX = pos->x;
|
||||
wantedY = pos->y;
|
||||
wantedZ = pos->z;
|
||||
return true;
|
||||
Vec3* pos = getHidePos();
|
||||
if (pos == NULL) return false;
|
||||
wantedX = pos->x;
|
||||
wantedY = pos->y;
|
||||
wantedZ = pos->z;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FleeSunGoal::canContinueToUse()
|
||||
{
|
||||
return !mob->getNavigation()->isDone();
|
||||
bool FleeSunGoal::canContinueToUse() { return !mob->getNavigation()->isDone(); }
|
||||
|
||||
void FleeSunGoal::start() {
|
||||
mob->getNavigation()->moveTo(wantedX, wantedY, wantedZ, speed);
|
||||
}
|
||||
|
||||
void FleeSunGoal::start()
|
||||
{
|
||||
mob->getNavigation()->moveTo(wantedX, wantedY, wantedZ, speed);
|
||||
}
|
||||
|
||||
Vec3 *FleeSunGoal::getHidePos()
|
||||
{
|
||||
Random *random = mob->getRandom();
|
||||
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);
|
||||
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;
|
||||
Vec3* FleeSunGoal::getHidePos() {
|
||||
Random* random = mob->getRandom();
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
|
@ -2,25 +2,25 @@
|
|||
|
||||
#include "Goal.h"
|
||||
|
||||
class FleeSunGoal : public Goal
|
||||
{
|
||||
class FleeSunGoal : public Goal {
|
||||
private:
|
||||
PathfinderMob *mob; // Owner of this goal
|
||||
double wantedX, wantedY, wantedZ;
|
||||
float speed;
|
||||
Level *level;
|
||||
PathfinderMob* mob; // Owner of this goal
|
||||
double wantedX, wantedY, wantedZ;
|
||||
float speed;
|
||||
Level* level;
|
||||
|
||||
public:
|
||||
FleeSunGoal(PathfinderMob *mob, float speed);
|
||||
FleeSunGoal(PathfinderMob* mob, float speed);
|
||||
|
||||
virtual bool canUse();
|
||||
virtual bool canContinueToUse();
|
||||
virtual void start();
|
||||
virtual bool canUse();
|
||||
virtual bool canContinueToUse();
|
||||
virtual void start();
|
||||
|
||||
private:
|
||||
Vec3 *getHidePos();
|
||||
Vec3* getHidePos();
|
||||
|
||||
public:
|
||||
// 4J Added override to update ai elements when loading entity from schematics
|
||||
virtual void setLevel(Level *level) { this->level = level; }
|
||||
// 4J Added override to update ai elements when loading entity from
|
||||
// schematics
|
||||
virtual void setLevel(Level* level) { this->level = level; }
|
||||
};
|
||||
|
|
@ -4,19 +4,14 @@
|
|||
#include "../../Headers/net.minecraft.world.entity.ai.navigation.h"
|
||||
#include "FloatGoal.h"
|
||||
|
||||
FloatGoal::FloatGoal(Mob *mob)
|
||||
{
|
||||
this->mob = mob;
|
||||
setRequiredControlFlags(Control::JumpControlFlag);
|
||||
mob->getNavigation()->setCanFloat(true);
|
||||
FloatGoal::FloatGoal(Mob* mob) {
|
||||
this->mob = mob;
|
||||
setRequiredControlFlags(Control::JumpControlFlag);
|
||||
mob->getNavigation()->setCanFloat(true);
|
||||
}
|
||||
|
||||
bool FloatGoal::canUse()
|
||||
{
|
||||
return (mob->isInWater() || mob->isInLava());
|
||||
}
|
||||
bool FloatGoal::canUse() { return (mob->isInWater() || mob->isInLava()); }
|
||||
|
||||
void FloatGoal::tick()
|
||||
{
|
||||
if (mob->getRandom()->nextFloat() < 0.8f) mob->getJumpControl()->jump();
|
||||
void FloatGoal::tick() {
|
||||
if (mob->getRandom()->nextFloat() < 0.8f) mob->getJumpControl()->jump();
|
||||
}
|
||||
|
|
@ -4,14 +4,13 @@
|
|||
|
||||
class Mob;
|
||||
|
||||
class FloatGoal : public Goal
|
||||
{
|
||||
class FloatGoal : public Goal {
|
||||
private:
|
||||
Mob *mob;
|
||||
Mob* mob;
|
||||
|
||||
public:
|
||||
FloatGoal(Mob *mob);
|
||||
FloatGoal(Mob* mob);
|
||||
|
||||
virtual bool canUse();
|
||||
virtual void tick();
|
||||
virtual bool canUse();
|
||||
virtual void tick();
|
||||
};
|
||||
|
|
@ -7,79 +7,80 @@
|
|||
#include "../../Headers/net.minecraft.world.phys.h"
|
||||
#include "FollowOwnerGoal.h"
|
||||
|
||||
FollowOwnerGoal::FollowOwnerGoal(TamableAnimal *tamable, float speed, float startDistance, float stopDistance)
|
||||
{
|
||||
owner = std::weak_ptr<Mob>();
|
||||
timeToRecalcPath = 0;
|
||||
oldAvoidWater = false;
|
||||
FollowOwnerGoal::FollowOwnerGoal(TamableAnimal* tamable, float speed,
|
||||
float startDistance, float stopDistance) {
|
||||
owner = std::weak_ptr<Mob>();
|
||||
timeToRecalcPath = 0;
|
||||
oldAvoidWater = false;
|
||||
|
||||
this->tamable = tamable;
|
||||
this->level = tamable->level;
|
||||
this->speed = speed;
|
||||
this->navigation = tamable->getNavigation();
|
||||
this->startDistance = startDistance;
|
||||
this->stopDistance = stopDistance;
|
||||
setRequiredControlFlags(Control::MoveControlFlag | Control::LookControlFlag);
|
||||
this->tamable = tamable;
|
||||
this->level = tamable->level;
|
||||
this->speed = speed;
|
||||
this->navigation = tamable->getNavigation();
|
||||
this->startDistance = startDistance;
|
||||
this->stopDistance = stopDistance;
|
||||
setRequiredControlFlags(Control::MoveControlFlag |
|
||||
Control::LookControlFlag);
|
||||
}
|
||||
|
||||
bool FollowOwnerGoal::canUse()
|
||||
{
|
||||
std::shared_ptr<Mob> owner = tamable->getOwner();
|
||||
if (owner == NULL) return false;
|
||||
if (tamable->isSitting()) return false;
|
||||
if (tamable->distanceToSqr(owner) < startDistance * startDistance) return false;
|
||||
this->owner = std::weak_ptr<Mob>(owner);
|
||||
return true;
|
||||
bool FollowOwnerGoal::canUse() {
|
||||
std::shared_ptr<Mob> owner = tamable->getOwner();
|
||||
if (owner == NULL) return false;
|
||||
if (tamable->isSitting()) return false;
|
||||
if (tamable->distanceToSqr(owner) < startDistance * startDistance)
|
||||
return false;
|
||||
this->owner = std::weak_ptr<Mob>(owner);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FollowOwnerGoal::canContinueToUse()
|
||||
{
|
||||
return owner.lock() != NULL && !navigation->isDone() && tamable->distanceToSqr(owner.lock()) > stopDistance * stopDistance && !tamable->isSitting();
|
||||
bool FollowOwnerGoal::canContinueToUse() {
|
||||
return owner.lock() != NULL && !navigation->isDone() &&
|
||||
tamable->distanceToSqr(owner.lock()) > stopDistance * stopDistance &&
|
||||
!tamable->isSitting();
|
||||
}
|
||||
|
||||
void FollowOwnerGoal::start()
|
||||
{
|
||||
timeToRecalcPath = 0;
|
||||
oldAvoidWater = tamable->getNavigation()->getAvoidWater();
|
||||
tamable->getNavigation()->setAvoidWater(false);
|
||||
void FollowOwnerGoal::start() {
|
||||
timeToRecalcPath = 0;
|
||||
oldAvoidWater = tamable->getNavigation()->getAvoidWater();
|
||||
tamable->getNavigation()->setAvoidWater(false);
|
||||
}
|
||||
|
||||
void FollowOwnerGoal::stop()
|
||||
{
|
||||
owner = std::weak_ptr<Mob>();
|
||||
navigation->stop();
|
||||
tamable->getNavigation()->setAvoidWater(oldAvoidWater);
|
||||
void FollowOwnerGoal::stop() {
|
||||
owner = std::weak_ptr<Mob>();
|
||||
navigation->stop();
|
||||
tamable->getNavigation()->setAvoidWater(oldAvoidWater);
|
||||
}
|
||||
|
||||
void FollowOwnerGoal::tick()
|
||||
{
|
||||
tamable->getLookControl()->setLookAt(owner.lock(), 10, tamable->getMaxHeadXRot());
|
||||
if (tamable->isSitting()) return;
|
||||
void FollowOwnerGoal::tick() {
|
||||
tamable->getLookControl()->setLookAt(owner.lock(), 10,
|
||||
tamable->getMaxHeadXRot());
|
||||
if (tamable->isSitting()) return;
|
||||
|
||||
if (--timeToRecalcPath > 0) return;
|
||||
timeToRecalcPath = 10;
|
||||
if (--timeToRecalcPath > 0) return;
|
||||
timeToRecalcPath = 10;
|
||||
|
||||
if (navigation->moveTo(owner.lock(), speed)) return;
|
||||
if (tamable->distanceToSqr(owner.lock()) < TeleportDistance * TeleportDistance) return;
|
||||
if (navigation->moveTo(owner.lock(), speed)) return;
|
||||
if (tamable->distanceToSqr(owner.lock()) <
|
||||
TeleportDistance * TeleportDistance)
|
||||
return;
|
||||
|
||||
// find a good spawn position nearby the owner
|
||||
int sx = Mth::floor(owner.lock()->x) - 2;
|
||||
int sz = Mth::floor(owner.lock()->z) - 2;
|
||||
int y = Mth::floor(owner.lock()->bb->y0);
|
||||
for (int x = 0; x <= 4; x++)
|
||||
{
|
||||
for (int z = 0; z <= 4; z++)
|
||||
{
|
||||
if (x >= 1 && z >= 1 && x <= 3 && z <= 3)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (level->isTopSolidBlocking(sx + x, y - 1, sz + z) && !level->isSolidBlockingTile(sx + x, y, sz + z) && !level->isSolidBlockingTile(sx + x, y + 1, sz + z))
|
||||
{
|
||||
tamable->moveTo(sx + x + .5f, y, sz + z + .5f, tamable->yRot, tamable->xRot);
|
||||
navigation->stop();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
// find a good spawn position nearby the owner
|
||||
int sx = Mth::floor(owner.lock()->x) - 2;
|
||||
int sz = Mth::floor(owner.lock()->z) - 2;
|
||||
int y = Mth::floor(owner.lock()->bb->y0);
|
||||
for (int x = 0; x <= 4; x++) {
|
||||
for (int z = 0; z <= 4; z++) {
|
||||
if (x >= 1 && z >= 1 && x <= 3 && z <= 3) {
|
||||
continue;
|
||||
}
|
||||
if (level->isTopSolidBlocking(sx + x, y - 1, sz + z) &&
|
||||
!level->isSolidBlockingTile(sx + x, y, sz + z) &&
|
||||
!level->isSolidBlockingTile(sx + x, y + 1, sz + z)) {
|
||||
tamable->moveTo(sx + x + .5f, y, sz + z + .5f, tamable->yRot,
|
||||
tamable->xRot);
|
||||
navigation->stop();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,30 +5,31 @@
|
|||
class PathNavigation;
|
||||
class TamableAnimal;
|
||||
|
||||
class FollowOwnerGoal : public Goal
|
||||
{
|
||||
class FollowOwnerGoal : public Goal {
|
||||
public:
|
||||
static const int TeleportDistance = 12;
|
||||
static const int TeleportDistance = 12;
|
||||
|
||||
private:
|
||||
TamableAnimal *tamable; // Owner of this goal
|
||||
std::weak_ptr<Mob> owner;
|
||||
Level *level;
|
||||
float speed;
|
||||
PathNavigation *navigation;
|
||||
int timeToRecalcPath;
|
||||
float stopDistance, startDistance;
|
||||
bool oldAvoidWater;
|
||||
TamableAnimal* tamable; // Owner of this goal
|
||||
std::weak_ptr<Mob> owner;
|
||||
Level* level;
|
||||
float speed;
|
||||
PathNavigation* navigation;
|
||||
int timeToRecalcPath;
|
||||
float stopDistance, startDistance;
|
||||
bool oldAvoidWater;
|
||||
|
||||
public:
|
||||
FollowOwnerGoal(TamableAnimal *tamable, float speed, float startDistance, float stopDistance);
|
||||
FollowOwnerGoal(TamableAnimal* tamable, float speed, float startDistance,
|
||||
float stopDistance);
|
||||
|
||||
virtual bool canUse();
|
||||
virtual bool canContinueToUse();
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual void tick();
|
||||
|
||||
// 4J Added override to update ai elements when loading entity from schematics
|
||||
virtual void setLevel(Level *level) { this->level = level; }
|
||||
virtual bool canUse();
|
||||
virtual bool canContinueToUse();
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual void tick();
|
||||
|
||||
// 4J Added override to update ai elements when loading entity from
|
||||
// schematics
|
||||
virtual void setLevel(Level* level) { this->level = level; }
|
||||
};
|
||||
|
|
@ -6,60 +6,51 @@
|
|||
#include "../../Util/BasicTypeContainers.h"
|
||||
#include "FollowParentGoal.h"
|
||||
|
||||
FollowParentGoal::FollowParentGoal(Animal *animal, float speed)
|
||||
{
|
||||
timeToRecalcPath = 0;
|
||||
FollowParentGoal::FollowParentGoal(Animal* animal, float speed) {
|
||||
timeToRecalcPath = 0;
|
||||
|
||||
this->animal = animal;
|
||||
this->speed = speed;
|
||||
this->animal = animal;
|
||||
this->speed = speed;
|
||||
}
|
||||
|
||||
bool FollowParentGoal::canUse()
|
||||
{
|
||||
if (animal->getAge() >= 0) return false;
|
||||
bool FollowParentGoal::canUse() {
|
||||
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;
|
||||
double closestDistSqr = Double::MAX_VALUE;
|
||||
for(AUTO_VAR(it, parents->begin()); it != parents->end(); ++it)
|
||||
{
|
||||
std::shared_ptr<Animal> parent = std::dynamic_pointer_cast<Animal>(*it);
|
||||
if (parent->getAge() < 0) continue;
|
||||
double distSqr = animal->distanceToSqr(parent);
|
||||
if (distSqr > closestDistSqr) continue;
|
||||
closestDistSqr = distSqr;
|
||||
closest = parent;
|
||||
}
|
||||
delete parents;
|
||||
std::shared_ptr<Animal> closest = nullptr;
|
||||
double closestDistSqr = Double::MAX_VALUE;
|
||||
for (AUTO_VAR(it, parents->begin()); it != parents->end(); ++it) {
|
||||
std::shared_ptr<Animal> parent = std::dynamic_pointer_cast<Animal>(*it);
|
||||
if (parent->getAge() < 0) continue;
|
||||
double distSqr = animal->distanceToSqr(parent);
|
||||
if (distSqr > closestDistSqr) continue;
|
||||
closestDistSqr = distSqr;
|
||||
closest = parent;
|
||||
}
|
||||
delete parents;
|
||||
|
||||
if (closest == NULL) return false;
|
||||
if (closestDistSqr < 3 * 3) return false;
|
||||
parent = std::weak_ptr<Animal>(closest);
|
||||
return true;
|
||||
if (closest == NULL) return false;
|
||||
if (closestDistSqr < 3 * 3) return false;
|
||||
parent = std::weak_ptr<Animal>(closest);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FollowParentGoal::canContinueToUse()
|
||||
{
|
||||
if (parent.lock() == NULL || !parent.lock()->isAlive()) return false;
|
||||
double distSqr = animal->distanceToSqr(parent.lock());
|
||||
if (distSqr < 3 * 3 || distSqr > 16 * 16) return false;
|
||||
return true;
|
||||
bool FollowParentGoal::canContinueToUse() {
|
||||
if (parent.lock() == NULL || !parent.lock()->isAlive()) return false;
|
||||
double distSqr = animal->distanceToSqr(parent.lock());
|
||||
if (distSqr < 3 * 3 || distSqr > 16 * 16) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void FollowParentGoal::start()
|
||||
{
|
||||
timeToRecalcPath = 0;
|
||||
}
|
||||
void FollowParentGoal::start() { timeToRecalcPath = 0; }
|
||||
|
||||
void FollowParentGoal::stop()
|
||||
{
|
||||
parent = std::weak_ptr<Animal>();
|
||||
}
|
||||
void FollowParentGoal::stop() { parent = std::weak_ptr<Animal>(); }
|
||||
|
||||
void FollowParentGoal::tick()
|
||||
{
|
||||
if (--timeToRecalcPath > 0) return;
|
||||
timeToRecalcPath = 10;
|
||||
animal->getNavigation()->moveTo(parent.lock(), speed);
|
||||
void FollowParentGoal::tick() {
|
||||
if (--timeToRecalcPath > 0) return;
|
||||
timeToRecalcPath = 10;
|
||||
animal->getNavigation()->moveTo(parent.lock(), speed);
|
||||
}
|
||||
|
|
@ -4,20 +4,19 @@
|
|||
|
||||
class Animal;
|
||||
|
||||
class FollowParentGoal : public Goal
|
||||
{
|
||||
class FollowParentGoal : public Goal {
|
||||
private:
|
||||
Animal *animal; // Owner of this goal
|
||||
std::weak_ptr<Animal> parent;
|
||||
float speed;
|
||||
int timeToRecalcPath;
|
||||
Animal* animal; // Owner of this goal
|
||||
std::weak_ptr<Animal> parent;
|
||||
float speed;
|
||||
int timeToRecalcPath;
|
||||
|
||||
public:
|
||||
FollowParentGoal(Animal *animal, float speed);
|
||||
FollowParentGoal(Animal* animal, float speed);
|
||||
|
||||
virtual bool canUse();
|
||||
virtual bool canContinueToUse();
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual void tick();
|
||||
virtual bool canUse();
|
||||
virtual bool canContinueToUse();
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual void tick();
|
||||
};
|
||||
|
|
@ -1,39 +1,20 @@
|
|||
#include "../../Platform/stdafx.h"
|
||||
#include "Goal.h"
|
||||
|
||||
Goal::Goal()
|
||||
{
|
||||
_requiredControlFlags = 0;
|
||||
Goal::Goal() { _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()
|
||||
{
|
||||
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;
|
||||
}
|
||||
int Goal::getRequiredControlFlags() { return _requiredControlFlags; }
|
||||
|
|
@ -1,23 +1,24 @@
|
|||
#pragma once
|
||||
|
||||
class Goal
|
||||
{
|
||||
class Goal {
|
||||
private:
|
||||
int _requiredControlFlags;
|
||||
int _requiredControlFlags;
|
||||
|
||||
protected:
|
||||
Goal();
|
||||
Goal();
|
||||
|
||||
public:
|
||||
virtual ~Goal() {}
|
||||
virtual bool canUse() = 0;
|
||||
virtual bool canContinueToUse();
|
||||
virtual bool canInterrupt();
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual void tick();
|
||||
virtual void setRequiredControlFlags(int requiredControlFlags);
|
||||
virtual int getRequiredControlFlags();
|
||||
|
||||
// 4J Added override to update ai elements when loading entity from schematics
|
||||
virtual void setLevel(Level *level) {};
|
||||
virtual ~Goal() {}
|
||||
virtual bool canUse() = 0;
|
||||
virtual bool canContinueToUse();
|
||||
virtual bool canInterrupt();
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual void tick();
|
||||
virtual void setRequiredControlFlags(int requiredControlFlags);
|
||||
virtual int getRequiredControlFlags();
|
||||
|
||||
// 4J Added override to update ai elements when loading entity from
|
||||
// schematics
|
||||
virtual void setLevel(Level* level) {};
|
||||
};
|
||||
|
|
@ -2,146 +2,124 @@
|
|||
#include "Goal.h"
|
||||
#include "GoalSelector.h"
|
||||
|
||||
|
||||
GoalSelector::InternalGoal::InternalGoal(int prio, Goal *goal, bool canDeletePointer)
|
||||
{
|
||||
this->prio = prio;
|
||||
this->goal = goal;
|
||||
this->canDeletePointer = canDeletePointer;
|
||||
GoalSelector::InternalGoal::InternalGoal(int prio, Goal* goal,
|
||||
bool canDeletePointer) {
|
||||
this->prio = prio;
|
||||
this->goal = goal;
|
||||
this->canDeletePointer = canDeletePointer;
|
||||
}
|
||||
|
||||
GoalSelector::GoalSelector()
|
||||
{
|
||||
tickCount = 0;
|
||||
newGoalRate = 3;
|
||||
GoalSelector::GoalSelector() {
|
||||
tickCount = 0;
|
||||
newGoalRate = 3;
|
||||
}
|
||||
|
||||
GoalSelector::~GoalSelector()
|
||||
{
|
||||
for(AUTO_VAR(it, goals.begin()); it != goals.end(); ++it)
|
||||
{
|
||||
if((*it)->canDeletePointer) delete (*it)->goal;
|
||||
delete (*it);
|
||||
}
|
||||
GoalSelector::~GoalSelector() {
|
||||
for (AUTO_VAR(it, goals.begin()); it != goals.end(); ++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()
|
||||
{
|
||||
std::vector<InternalGoal *> toStart;
|
||||
void GoalSelector::tick() {
|
||||
std::vector<InternalGoal*> toStart;
|
||||
|
||||
if(tickCount++ % newGoalRate == 0)
|
||||
{
|
||||
//for (InternalGoal ig : goals)
|
||||
for(AUTO_VAR(it, goals.begin()); it != goals.end(); ++it)
|
||||
{
|
||||
InternalGoal *ig = *it;
|
||||
//bool isUsing = usingGoals.contains(ig);
|
||||
AUTO_VAR(usingIt, find(usingGoals.begin(), usingGoals.end(), ig));
|
||||
if (tickCount++ % newGoalRate == 0) {
|
||||
// for (InternalGoal ig : goals)
|
||||
for (AUTO_VAR(it, goals.begin()); it != goals.end(); ++it) {
|
||||
InternalGoal* ig = *it;
|
||||
// bool isUsing = usingGoals.contains(ig);
|
||||
AUTO_VAR(usingIt, find(usingGoals.begin(), usingGoals.end(), ig));
|
||||
|
||||
//if (isUsing)
|
||||
if(usingIt != usingGoals.end())
|
||||
{
|
||||
if (!canUseInSystem(ig) || !canContinueToUse(ig))
|
||||
{
|
||||
ig->goal->stop();
|
||||
//usingGoals.remove(ig);
|
||||
usingGoals.erase(usingIt);
|
||||
}
|
||||
else continue;
|
||||
}
|
||||
// if (isUsing)
|
||||
if (usingIt != usingGoals.end()) {
|
||||
if (!canUseInSystem(ig) || !canContinueToUse(ig)) {
|
||||
ig->goal->stop();
|
||||
// usingGoals.remove(ig);
|
||||
usingGoals.erase(usingIt);
|
||||
} else
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!canUseInSystem(ig) || !ig->goal->canUse()) continue;
|
||||
if (!canUseInSystem(ig) || !ig->goal->canUse()) continue;
|
||||
|
||||
toStart.push_back(ig);
|
||||
usingGoals.push_back(ig);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(AUTO_VAR(it, usingGoals.begin() ); it != usingGoals.end(); )
|
||||
{
|
||||
InternalGoal *ig = *it;
|
||||
if (!ig->goal->canContinueToUse())
|
||||
{
|
||||
ig->goal->stop();
|
||||
it = usingGoals.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
toStart.push_back(ig);
|
||||
usingGoals.push_back(ig);
|
||||
}
|
||||
} else {
|
||||
for (AUTO_VAR(it, usingGoals.begin()); it != usingGoals.end();) {
|
||||
InternalGoal* ig = *it;
|
||||
if (!ig->goal->canContinueToUse()) {
|
||||
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 && 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();
|
||||
}
|
||||
|
||||
//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();
|
||||
}
|
||||
// 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()
|
||||
{
|
||||
return &usingGoals;
|
||||
std::vector<GoalSelector::InternalGoal*>* GoalSelector::getRunningGoals() {
|
||||
return &usingGoals;
|
||||
}
|
||||
|
||||
bool GoalSelector::canContinueToUse(InternalGoal *ig)
|
||||
{
|
||||
return ig->goal->canContinueToUse();
|
||||
bool GoalSelector::canContinueToUse(InternalGoal* ig) {
|
||||
return ig->goal->canContinueToUse();
|
||||
}
|
||||
|
||||
bool GoalSelector::canUseInSystem(GoalSelector::InternalGoal *goal)
|
||||
{
|
||||
//for (InternalGoal ig : goals)
|
||||
for(AUTO_VAR(it, goals.begin()); it != goals.end(); ++it)
|
||||
{
|
||||
InternalGoal *ig = *it;
|
||||
if (ig == goal) continue;
|
||||
bool GoalSelector::canUseInSystem(GoalSelector::InternalGoal* goal) {
|
||||
// for (InternalGoal ig : goals)
|
||||
for (AUTO_VAR(it, goals.begin()); it != goals.end(); ++it) {
|
||||
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 (usingIt != usingGoals.end() && !canCoExist(goal, ig)) return false;
|
||||
}
|
||||
else if (usingIt != usingGoals.end() && !ig->goal->canInterrupt()) return false;
|
||||
}
|
||||
if (goal->prio >= ig->prio) {
|
||||
if (usingIt != usingGoals.end() && !canCoExist(goal, ig))
|
||||
return false;
|
||||
} else if (usingIt != usingGoals.end() && !ig->goal->canInterrupt())
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GoalSelector::canCoExist(GoalSelector::InternalGoal *goalA, GoalSelector::InternalGoal *goalB)
|
||||
{
|
||||
return (goalA->goal->getRequiredControlFlags() & goalB->goal->getRequiredControlFlags()) == 0;
|
||||
bool GoalSelector::canCoExist(GoalSelector::InternalGoal* goalA,
|
||||
GoalSelector::InternalGoal* goalB) {
|
||||
return (goalA->goal->getRequiredControlFlags() &
|
||||
goalB->goal->getRequiredControlFlags()) == 0;
|
||||
}
|
||||
|
||||
void GoalSelector::setNewGoalRate(int newGoalRate)
|
||||
{
|
||||
this->newGoalRate = newGoalRate;
|
||||
void GoalSelector::setNewGoalRate(int newGoalRate) {
|
||||
this->newGoalRate = newGoalRate;
|
||||
}
|
||||
|
||||
void GoalSelector::setLevel(Level *level)
|
||||
{
|
||||
for(AUTO_VAR(it, goals.begin()); it != goals.end(); ++it)
|
||||
{
|
||||
InternalGoal *ig = *it;
|
||||
ig->goal->setLevel(level);
|
||||
}
|
||||
void GoalSelector::setLevel(Level* level) {
|
||||
for (AUTO_VAR(it, goals.begin()); it != goals.end(); ++it) {
|
||||
InternalGoal* ig = *it;
|
||||
ig->goal->setLevel(level);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,45 +1,43 @@
|
|||
#pragma once
|
||||
|
||||
|
||||
class Goal;
|
||||
|
||||
class GoalSelector
|
||||
{
|
||||
class GoalSelector {
|
||||
private:
|
||||
class InternalGoal
|
||||
{
|
||||
public:
|
||||
// 4J Added canDelete param
|
||||
InternalGoal(int prio, Goal *goal, bool canDeletePointer);
|
||||
class InternalGoal {
|
||||
public:
|
||||
// 4J Added canDelete param
|
||||
InternalGoal(int prio, Goal* goal, bool canDeletePointer);
|
||||
|
||||
Goal *goal;
|
||||
int prio;
|
||||
bool canDeletePointer;
|
||||
};
|
||||
Goal* goal;
|
||||
int prio;
|
||||
bool canDeletePointer;
|
||||
};
|
||||
|
||||
private:
|
||||
std::vector<InternalGoal *> goals;
|
||||
std::vector<InternalGoal *> usingGoals;
|
||||
int tickCount;
|
||||
int newGoalRate;
|
||||
std::vector<InternalGoal*> goals;
|
||||
std::vector<InternalGoal*> usingGoals;
|
||||
int tickCount;
|
||||
int newGoalRate;
|
||||
|
||||
public:
|
||||
GoalSelector();
|
||||
~GoalSelector();
|
||||
GoalSelector();
|
||||
~GoalSelector();
|
||||
|
||||
// 4J Added canDelete param
|
||||
void addGoal(int prio, Goal *goal, bool canDeletePointer = true);
|
||||
void tick();
|
||||
std::vector<InternalGoal *> *getRunningGoals();
|
||||
// 4J Added canDelete param
|
||||
void addGoal(int prio, Goal* goal, bool canDeletePointer = true);
|
||||
void tick();
|
||||
std::vector<InternalGoal*>* getRunningGoals();
|
||||
|
||||
private:
|
||||
bool canContinueToUse(InternalGoal *ig);
|
||||
bool canUseInSystem(InternalGoal *goal);
|
||||
bool canCoExist(InternalGoal *goalA, InternalGoal *goalB);
|
||||
bool canContinueToUse(InternalGoal* ig);
|
||||
bool canUseInSystem(InternalGoal* goal);
|
||||
bool canCoExist(InternalGoal* goalA, InternalGoal* goalB);
|
||||
|
||||
public:
|
||||
void setNewGoalRate(int newGoalRate);
|
||||
void setNewGoalRate(int newGoalRate);
|
||||
|
||||
// 4J Added override to update ai elements when loading entity from schematics
|
||||
void setLevel(Level *level);
|
||||
// 4J Added override to update ai elements when loading entity from
|
||||
// schematics
|
||||
void setLevel(Level* level);
|
||||
};
|
||||
|
|
@ -4,42 +4,41 @@
|
|||
#include "../../Headers/net.minecraft.world.level.h"
|
||||
#include "HurtByTargetGoal.h"
|
||||
|
||||
HurtByTargetGoal::HurtByTargetGoal(Mob *mob, bool alertSameType) : TargetGoal(mob, 16, false)
|
||||
{
|
||||
this->alertSameType = alertSameType;
|
||||
setRequiredControlFlags(TargetGoal::TargetFlag);
|
||||
HurtByTargetGoal::HurtByTargetGoal(Mob* mob, bool alertSameType)
|
||||
: TargetGoal(mob, 16, false) {
|
||||
this->alertSameType = alertSameType;
|
||||
setRequiredControlFlags(TargetGoal::TargetFlag);
|
||||
}
|
||||
|
||||
bool HurtByTargetGoal::canUse()
|
||||
{
|
||||
return canAttack(mob->getLastHurtByMob(), false);
|
||||
bool HurtByTargetGoal::canUse() {
|
||||
return canAttack(mob->getLastHurtByMob(), false);
|
||||
}
|
||||
|
||||
void HurtByTargetGoal::start()
|
||||
{
|
||||
mob->setTarget(mob->getLastHurtByMob());
|
||||
oldHurtByMob = mob->getLastHurtByMob();
|
||||
void HurtByTargetGoal::start() {
|
||||
mob->setTarget(mob->getLastHurtByMob());
|
||||
oldHurtByMob = mob->getLastHurtByMob();
|
||||
|
||||
if (alertSameType)
|
||||
{
|
||||
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));
|
||||
for(AUTO_VAR(it, nearby->begin()); it != nearby->end(); ++it)
|
||||
{
|
||||
std::shared_ptr<Mob> other = std::dynamic_pointer_cast<Mob>(*it);
|
||||
if (this->mob->shared_from_this() == other) continue;
|
||||
if (other->getTarget() != NULL) continue;
|
||||
other->setTarget(mob->getLastHurtByMob());
|
||||
}
|
||||
delete nearby;
|
||||
}
|
||||
if (alertSameType) {
|
||||
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));
|
||||
for (AUTO_VAR(it, nearby->begin()); it != nearby->end(); ++it) {
|
||||
std::shared_ptr<Mob> other = std::dynamic_pointer_cast<Mob>(*it);
|
||||
if (this->mob->shared_from_this() == other) continue;
|
||||
if (other->getTarget() != NULL) continue;
|
||||
other->setTarget(mob->getLastHurtByMob());
|
||||
}
|
||||
delete nearby;
|
||||
}
|
||||
|
||||
TargetGoal::start();
|
||||
TargetGoal::start();
|
||||
}
|
||||
|
||||
void HurtByTargetGoal::tick()
|
||||
{
|
||||
if (mob->getLastHurtByMob() != NULL && mob->getLastHurtByMob() != oldHurtByMob)
|
||||
{
|
||||
this->start();
|
||||
}
|
||||
void HurtByTargetGoal::tick() {
|
||||
if (mob->getLastHurtByMob() != NULL &&
|
||||
mob->getLastHurtByMob() != oldHurtByMob) {
|
||||
this->start();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,16 +2,15 @@
|
|||
|
||||
#include "TargetGoal.h"
|
||||
|
||||
class HurtByTargetGoal : public TargetGoal
|
||||
{
|
||||
class HurtByTargetGoal : public TargetGoal {
|
||||
private:
|
||||
bool alertSameType;
|
||||
std::shared_ptr<Mob> oldHurtByMob;
|
||||
bool alertSameType;
|
||||
std::shared_ptr<Mob> oldHurtByMob;
|
||||
|
||||
public:
|
||||
HurtByTargetGoal(Mob *mob, bool alertSameType);
|
||||
HurtByTargetGoal(Mob* mob, bool alertSameType);
|
||||
|
||||
bool canUse();
|
||||
void start();
|
||||
void tick();
|
||||
bool canUse();
|
||||
void start();
|
||||
void tick();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,12 +2,16 @@
|
|||
#include "../../Headers/net.minecraft.world.entity.ai.control.h"
|
||||
#include "InteractGoal.h"
|
||||
|
||||
InteractGoal::InteractGoal(Mob *mob, const std::type_info& lookAtType, float lookDistance) : LookAtPlayerGoal(mob, lookAtType, lookDistance)
|
||||
{
|
||||
setRequiredControlFlags(Control::LookControlFlag | Control::MoveControlFlag);
|
||||
InteractGoal::InteractGoal(Mob* mob, const std::type_info& lookAtType,
|
||||
float lookDistance)
|
||||
: 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)
|
||||
{
|
||||
setRequiredControlFlags(Control::LookControlFlag | Control::MoveControlFlag);
|
||||
InteractGoal::InteractGoal(Mob* mob, const std::type_info& lookAtType,
|
||||
float lookDistance, float probability)
|
||||
: LookAtPlayerGoal(mob, lookAtType, lookDistance, probability) {
|
||||
setRequiredControlFlags(Control::LookControlFlag |
|
||||
Control::MoveControlFlag);
|
||||
}
|
||||
|
|
@ -2,9 +2,10 @@
|
|||
|
||||
#include "LookAtPlayerGoal.h"
|
||||
|
||||
class InteractGoal : public LookAtPlayerGoal
|
||||
{
|
||||
class InteractGoal : public LookAtPlayerGoal {
|
||||
public:
|
||||
InteractGoal(Mob *mob, const std::type_info& lookAtType, float lookDistance);
|
||||
InteractGoal(Mob *mob, const std::type_info& lookAtType, float lookDistance, float probability);
|
||||
InteractGoal(Mob* mob, const std::type_info& lookAtType,
|
||||
float lookDistance);
|
||||
InteractGoal(Mob* mob, const std::type_info& lookAtType, float lookDistance,
|
||||
float probability);
|
||||
};
|
||||
|
|
@ -3,38 +3,35 @@
|
|||
#include "../../Headers/net.minecraft.world.entity.h"
|
||||
#include "LeapAtTargetGoal.h"
|
||||
|
||||
LeapAtTargetGoal::LeapAtTargetGoal(Mob *mob, float yd)
|
||||
{
|
||||
target = std::weak_ptr<Mob>();
|
||||
LeapAtTargetGoal::LeapAtTargetGoal(Mob* mob, float yd) {
|
||||
target = std::weak_ptr<Mob>();
|
||||
|
||||
this->mob = mob;
|
||||
this->yd = yd;
|
||||
setRequiredControlFlags(Control::JumpControlFlag | Control::MoveControlFlag);
|
||||
this->mob = mob;
|
||||
this->yd = yd;
|
||||
setRequiredControlFlags(Control::JumpControlFlag |
|
||||
Control::MoveControlFlag);
|
||||
}
|
||||
|
||||
bool LeapAtTargetGoal::canUse()
|
||||
{
|
||||
target = std::weak_ptr<Mob>(mob->getTarget());
|
||||
if (target.lock() == NULL) return false;
|
||||
double d = mob->distanceToSqr(target.lock());
|
||||
if (d < 2 * 2 || d > 4 * 4) return false;
|
||||
if (!mob->onGround) return false;
|
||||
if (mob->getRandom()->nextInt(5) != 0) return false;
|
||||
return true;
|
||||
bool LeapAtTargetGoal::canUse() {
|
||||
target = std::weak_ptr<Mob>(mob->getTarget());
|
||||
if (target.lock() == NULL) return false;
|
||||
double d = mob->distanceToSqr(target.lock());
|
||||
if (d < 2 * 2 || d > 4 * 4) return false;
|
||||
if (!mob->onGround) return false;
|
||||
if (mob->getRandom()->nextInt(5) != 0) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LeapAtTargetGoal::canContinueToUse()
|
||||
{
|
||||
return target.lock() != NULL && !mob->onGround;
|
||||
bool LeapAtTargetGoal::canContinueToUse() {
|
||||
return target.lock() != NULL && !mob->onGround;
|
||||
}
|
||||
|
||||
void LeapAtTargetGoal::start()
|
||||
{
|
||||
// TODO: move to control?
|
||||
double xdd = target.lock()->x - mob->x;
|
||||
double zdd = target.lock()->z - mob->z;
|
||||
float dd = sqrt(xdd * xdd + zdd * zdd);
|
||||
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->yd = yd;
|
||||
void LeapAtTargetGoal::start() {
|
||||
// TODO: move to control?
|
||||
double xdd = target.lock()->x - mob->x;
|
||||
double zdd = target.lock()->z - mob->z;
|
||||
float dd = sqrt(xdd * xdd + zdd * zdd);
|
||||
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->yd = yd;
|
||||
}
|
||||
|
|
@ -2,15 +2,14 @@
|
|||
|
||||
#include "Goal.h"
|
||||
|
||||
class LeapAtTargetGoal : public Goal
|
||||
{
|
||||
class LeapAtTargetGoal : public Goal {
|
||||
private:
|
||||
Mob *mob; // Owner of this goal
|
||||
Mob* mob; // Owner of this goal
|
||||
std::weak_ptr<Mob> target;
|
||||
float yd;
|
||||
|
||||
public:
|
||||
LeapAtTargetGoal(Mob *mob, float yd);
|
||||
LeapAtTargetGoal(Mob* mob, float yd);
|
||||
|
||||
virtual bool canUse();
|
||||
virtual bool canContinueToUse();
|
||||
|
|
|
|||
|
|
@ -5,53 +5,56 @@
|
|||
#include "../../Headers/net.minecraft.world.phys.h"
|
||||
#include "LookAtPlayerGoal.h"
|
||||
|
||||
LookAtPlayerGoal::LookAtPlayerGoal(Mob *mob, const std::type_info& lookAtType, float lookDistance) : lookAtType(lookAtType)
|
||||
{
|
||||
this->mob = mob;
|
||||
this->lookDistance = lookDistance;
|
||||
this->probability = 0.02f;
|
||||
setRequiredControlFlags(Control::LookControlFlag);
|
||||
LookAtPlayerGoal::LookAtPlayerGoal(Mob* mob, const std::type_info& lookAtType,
|
||||
float lookDistance)
|
||||
: lookAtType(lookAtType) {
|
||||
this->mob = mob;
|
||||
this->lookDistance = lookDistance;
|
||||
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)
|
||||
{
|
||||
this->mob = mob;
|
||||
this->lookDistance = lookDistance;
|
||||
this->probability = probability;
|
||||
setRequiredControlFlags(Control::LookControlFlag);
|
||||
LookAtPlayerGoal::LookAtPlayerGoal(Mob* mob, const std::type_info& lookAtType,
|
||||
float lookDistance, float probability)
|
||||
: lookAtType(lookAtType) {
|
||||
this->mob = mob;
|
||||
this->lookDistance = lookDistance;
|
||||
this->probability = probability;
|
||||
setRequiredControlFlags(Control::LookControlFlag);
|
||||
|
||||
lookTime = 0;
|
||||
lookTime = 0;
|
||||
}
|
||||
|
||||
bool LookAtPlayerGoal::canUse()
|
||||
{
|
||||
if (mob->getRandom()->nextFloat() >= probability) return false;
|
||||
if (lookAtType == typeid(Player)) lookAt = mob->level->getNearestPlayer(mob->shared_from_this(), lookDistance);
|
||||
else lookAt = std::weak_ptr<Entity>(mob->level->getClosestEntityOfClass(lookAtType, mob->bb->grow(lookDistance, 3, lookDistance), mob->shared_from_this()));
|
||||
return lookAt.lock() != NULL;
|
||||
bool LookAtPlayerGoal::canUse() {
|
||||
if (mob->getRandom()->nextFloat() >= probability) return false;
|
||||
if (lookAtType == typeid(Player))
|
||||
lookAt =
|
||||
mob->level->getNearestPlayer(mob->shared_from_this(), lookDistance);
|
||||
else
|
||||
lookAt = std::weak_ptr<Entity>(mob->level->getClosestEntityOfClass(
|
||||
lookAtType, mob->bb->grow(lookDistance, 3, lookDistance),
|
||||
mob->shared_from_this()));
|
||||
return lookAt.lock() != NULL;
|
||||
}
|
||||
|
||||
bool LookAtPlayerGoal::canContinueToUse()
|
||||
{
|
||||
if (lookAt.lock() == NULL || !lookAt.lock()->isAlive()) return false;
|
||||
if (mob->distanceToSqr(lookAt.lock()) > lookDistance * lookDistance) return false;
|
||||
return lookTime > 0;
|
||||
bool LookAtPlayerGoal::canContinueToUse() {
|
||||
if (lookAt.lock() == NULL || !lookAt.lock()->isAlive()) return false;
|
||||
if (mob->distanceToSqr(lookAt.lock()) > lookDistance * lookDistance)
|
||||
return false;
|
||||
return lookTime > 0;
|
||||
}
|
||||
|
||||
void LookAtPlayerGoal::start()
|
||||
{
|
||||
lookTime = 40 + mob->getRandom()->nextInt(40);
|
||||
void LookAtPlayerGoal::start() {
|
||||
lookTime = 40 + mob->getRandom()->nextInt(40);
|
||||
}
|
||||
|
||||
void LookAtPlayerGoal::stop()
|
||||
{
|
||||
lookAt = std::weak_ptr<Entity>();
|
||||
}
|
||||
void LookAtPlayerGoal::stop() { lookAt = std::weak_ptr<Entity>(); }
|
||||
|
||||
void LookAtPlayerGoal::tick()
|
||||
{
|
||||
mob->getLookControl()->setLookAt(lookAt.lock()->x, lookAt.lock()->y + lookAt.lock()->getHeadHeight(), lookAt.lock()->z, 10, mob->getMaxHeadXRot());
|
||||
--lookTime;
|
||||
void LookAtPlayerGoal::tick() {
|
||||
mob->getLookControl()->setLookAt(
|
||||
lookAt.lock()->x, lookAt.lock()->y + lookAt.lock()->getHeadHeight(),
|
||||
lookAt.lock()->z, 10, mob->getMaxHeadXRot());
|
||||
--lookTime;
|
||||
}
|
||||
|
|
@ -5,28 +5,29 @@
|
|||
class Mob;
|
||||
class Level;
|
||||
|
||||
class LookAtPlayerGoal : public Goal
|
||||
{
|
||||
class LookAtPlayerGoal : public Goal {
|
||||
private:
|
||||
Mob *mob; // Owner of this goal
|
||||
Mob* mob; // Owner of this goal
|
||||
|
||||
protected:
|
||||
std::weak_ptr<Entity> lookAt;
|
||||
std::weak_ptr<Entity> lookAt;
|
||||
|
||||
private:
|
||||
float lookDistance;
|
||||
int lookTime;
|
||||
float probability;
|
||||
const std::type_info& lookAtType;
|
||||
float lookDistance;
|
||||
int lookTime;
|
||||
float probability;
|
||||
const std::type_info& lookAtType;
|
||||
|
||||
public:
|
||||
LookAtPlayerGoal(Mob *mob, const std::type_info& lookAtType, float lookDistance);
|
||||
LookAtPlayerGoal(Mob *mob, const std::type_info& lookAtType, float lookDistance, float probability);
|
||||
virtual ~LookAtPlayerGoal() {}
|
||||
LookAtPlayerGoal(Mob* mob, const std::type_info& lookAtType,
|
||||
float lookDistance);
|
||||
LookAtPlayerGoal(Mob* mob, const std::type_info& lookAtType,
|
||||
float lookDistance, float probability);
|
||||
virtual ~LookAtPlayerGoal() {}
|
||||
|
||||
virtual bool canUse();
|
||||
virtual bool canContinueToUse();
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual void tick();
|
||||
virtual bool canUse();
|
||||
virtual bool canContinueToUse();
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual void tick();
|
||||
};
|
||||
|
|
@ -3,17 +3,16 @@
|
|||
#include "../../Headers/net.minecraft.world.entity.npc.h"
|
||||
#include "LookAtTradingPlayerGoal.h"
|
||||
|
||||
LookAtTradingPlayerGoal::LookAtTradingPlayerGoal(Villager *villager) : LookAtPlayerGoal((Mob *)villager, typeid(Player), 8)
|
||||
{
|
||||
this->villager = villager;
|
||||
LookAtTradingPlayerGoal::LookAtTradingPlayerGoal(Villager* villager)
|
||||
: LookAtPlayerGoal((Mob*)villager, typeid(Player), 8) {
|
||||
this->villager = villager;
|
||||
}
|
||||
|
||||
bool LookAtTradingPlayerGoal::canUse()
|
||||
{
|
||||
if (villager->isTrading())
|
||||
{
|
||||
lookAt = std::weak_ptr<Entity>(std::dynamic_pointer_cast<Entity>(villager->getTradingPlayer()));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
bool LookAtTradingPlayerGoal::canUse() {
|
||||
if (villager->isTrading()) {
|
||||
lookAt = std::weak_ptr<Entity>(
|
||||
std::dynamic_pointer_cast<Entity>(villager->getTradingPlayer()));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -4,13 +4,12 @@
|
|||
|
||||
class Villager;
|
||||
|
||||
class LookAtTradingPlayerGoal : public LookAtPlayerGoal
|
||||
{
|
||||
class LookAtTradingPlayerGoal : public LookAtPlayerGoal {
|
||||
private:
|
||||
Villager *villager; // This is the owner of this goal
|
||||
Villager* villager; // This is the owner of this goal
|
||||
|
||||
public:
|
||||
LookAtTradingPlayerGoal(Villager *villager);
|
||||
LookAtTradingPlayerGoal(Villager* villager);
|
||||
|
||||
virtual bool canUse();
|
||||
virtual bool canUse();
|
||||
};
|
||||
|
|
@ -8,96 +8,95 @@
|
|||
#include "../../Headers/net.minecraft.world.phys.h"
|
||||
#include "MakeLoveGoal.h"
|
||||
|
||||
MakeLoveGoal::MakeLoveGoal(Villager *villager)
|
||||
{
|
||||
village = std::weak_ptr<Village>();
|
||||
partner = std::weak_ptr<Villager>();
|
||||
loveMakingTime = 0;
|
||||
MakeLoveGoal::MakeLoveGoal(Villager* villager) {
|
||||
village = std::weak_ptr<Village>();
|
||||
partner = std::weak_ptr<Villager>();
|
||||
loveMakingTime = 0;
|
||||
|
||||
this->villager = villager;
|
||||
level = villager->level;
|
||||
setRequiredControlFlags(Control::MoveControlFlag | Control::LookControlFlag);
|
||||
this->villager = villager;
|
||||
level = villager->level;
|
||||
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;
|
||||
if (villager->getRandom()->nextInt(500) != 0) return false;
|
||||
village = level->villages->getClosestVillage(Mth::floor(villager->x),
|
||||
Mth::floor(villager->y),
|
||||
Mth::floor(villager->z), 0);
|
||||
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);
|
||||
if (village.lock() == NULL) return false;
|
||||
if (!villageNeedsMoreVillagers()) return false;
|
||||
std::shared_ptr<Entity> mate = level->getClosestEntityOfClass(
|
||||
typeid(Villager), villager->bb->grow(8, 3, 8),
|
||||
villager->shared_from_this());
|
||||
if (mate == NULL) return false;
|
||||
|
||||
std::shared_ptr<Entity> mate = level->getClosestEntityOfClass(typeid(Villager), villager->bb->grow(8, 3, 8), villager->shared_from_this());
|
||||
if (mate == NULL) return false;
|
||||
partner =
|
||||
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));
|
||||
if (partner.lock()->getAge() != 0) return false;
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void MakeLoveGoal::start()
|
||||
{
|
||||
loveMakingTime = 300;
|
||||
villager->setInLove(true);
|
||||
void MakeLoveGoal::start() {
|
||||
loveMakingTime = 300;
|
||||
villager->setInLove(true);
|
||||
}
|
||||
|
||||
void MakeLoveGoal::stop()
|
||||
{
|
||||
village = std::weak_ptr<Village>();
|
||||
partner = std::weak_ptr<Villager>();
|
||||
villager->setInLove(false);
|
||||
void MakeLoveGoal::stop() {
|
||||
village = std::weak_ptr<Village>();
|
||||
partner = std::weak_ptr<Villager>();
|
||||
villager->setInLove(false);
|
||||
}
|
||||
|
||||
bool MakeLoveGoal::canContinueToUse()
|
||||
{
|
||||
return partner.lock() != NULL && loveMakingTime >= 0 && villageNeedsMoreVillagers() && villager->getAge() == 0;
|
||||
bool MakeLoveGoal::canContinueToUse() {
|
||||
return partner.lock() != NULL && loveMakingTime >= 0 &&
|
||||
villageNeedsMoreVillagers() && villager->getAge() == 0;
|
||||
}
|
||||
|
||||
void MakeLoveGoal::tick()
|
||||
{
|
||||
--loveMakingTime;
|
||||
villager->getLookControl()->setLookAt(partner.lock(), 10, 30);
|
||||
void MakeLoveGoal::tick() {
|
||||
--loveMakingTime;
|
||||
villager->getLookControl()->setLookAt(partner.lock(), 10, 30);
|
||||
|
||||
if (villager->distanceToSqr(partner.lock()) > 1.5 * 1.5)
|
||||
{
|
||||
villager->getNavigation()->moveTo(partner.lock(), 0.25f);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (loveMakingTime == 0 && partner.lock()->isInLove()) breed();
|
||||
}
|
||||
if (villager->distanceToSqr(partner.lock()) > 1.5 * 1.5) {
|
||||
villager->getNavigation()->moveTo(partner.lock(), 0.25f);
|
||||
} 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()
|
||||
{
|
||||
std::shared_ptr<Village> _village = village.lock();
|
||||
if( _village == NULL ) return false;
|
||||
bool MakeLoveGoal::villageNeedsMoreVillagers() {
|
||||
std::shared_ptr<Village> _village = village.lock();
|
||||
if (_village == NULL) return false;
|
||||
|
||||
int idealSize = (int) ((float) _village->getDoorCount() * 0.35);
|
||||
// System.out.println("idealSize: " + idealSize + " pop: " +
|
||||
// village.getPopulationSize());
|
||||
return _village->getPopulationSize() < idealSize;
|
||||
int idealSize = (int)((float)_village->getDoorCount() * 0.35);
|
||||
// System.out.println("idealSize: " + idealSize + " pop: " +
|
||||
// village.getPopulationSize());
|
||||
return _village->getPopulationSize() < idealSize;
|
||||
}
|
||||
|
||||
void MakeLoveGoal::breed()
|
||||
{
|
||||
// 4J Stu - This sets a timer that stops these villagers from trying to breed again
|
||||
// We should do this even if breeding fails due to vilalger count to stop them continually trying to breed
|
||||
partner.lock()->setAge(5 * 60 * 20);
|
||||
villager->setAge(5 * 60 * 20);
|
||||
// 4J - added limit to number of animals that can be bred
|
||||
if(level->canCreateMore( eTYPE_VILLAGER, Level::eSpawnType_Breed) )
|
||||
{
|
||||
std::shared_ptr<Villager> child = std::shared_ptr<Villager>( new Villager(level) );
|
||||
child->setAge(-20 * 60 * 20);
|
||||
child->setProfession(villager->getRandom()->nextInt(Villager::PROFESSION_MAX));
|
||||
child->moveTo(villager->x, villager->y, villager->z, 0, 0);
|
||||
level->addEntity(child);
|
||||
level->broadcastEntityEvent(child, EntityEvent::LOVE_HEARTS);
|
||||
}
|
||||
void MakeLoveGoal::breed() {
|
||||
// 4J Stu - This sets a timer that stops these villagers from trying to
|
||||
// breed again We should do this even if breeding fails due to vilalger
|
||||
// count to stop them continually trying to breed
|
||||
partner.lock()->setAge(5 * 60 * 20);
|
||||
villager->setAge(5 * 60 * 20);
|
||||
// 4J - added limit to number of animals that can be bred
|
||||
if (level->canCreateMore(eTYPE_VILLAGER, Level::eSpawnType_Breed)) {
|
||||
std::shared_ptr<Villager> child =
|
||||
std::shared_ptr<Villager>(new Villager(level));
|
||||
child->setAge(-20 * 60 * 20);
|
||||
child->setProfession(
|
||||
villager->getRandom()->nextInt(Villager::PROFESSION_MAX));
|
||||
child->moveTo(villager->x, villager->y, villager->z, 0, 0);
|
||||
level->addEntity(child);
|
||||
level->broadcastEntityEvent(child, EntityEvent::LOVE_HEARTS);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,29 +5,29 @@
|
|||
class Villager;
|
||||
class Village;
|
||||
|
||||
class MakeLoveGoal : public Goal
|
||||
{
|
||||
class MakeLoveGoal : public Goal {
|
||||
private:
|
||||
Villager *villager; // Owner of this goal
|
||||
std::weak_ptr<Villager> partner;
|
||||
Level *level;
|
||||
int loveMakingTime;
|
||||
std::weak_ptr<Village> village;
|
||||
Villager* villager; // Owner of this goal
|
||||
std::weak_ptr<Villager> partner;
|
||||
Level* level;
|
||||
int loveMakingTime;
|
||||
std::weak_ptr<Village> village;
|
||||
|
||||
public:
|
||||
MakeLoveGoal(Villager *villager);
|
||||
MakeLoveGoal(Villager* villager);
|
||||
|
||||
bool canUse();
|
||||
void start();
|
||||
void stop();
|
||||
bool canContinueToUse();
|
||||
void tick();
|
||||
bool canUse();
|
||||
void start();
|
||||
void stop();
|
||||
bool canContinueToUse();
|
||||
void tick();
|
||||
|
||||
private:
|
||||
bool villageNeedsMoreVillagers();
|
||||
void breed();
|
||||
bool villageNeedsMoreVillagers();
|
||||
void breed();
|
||||
|
||||
public:
|
||||
// 4J Added override to update ai elements when loading entity from schematics
|
||||
virtual void setLevel(Level *level) { this->level = level; }
|
||||
public:
|
||||
// 4J Added override to update ai elements when loading entity from
|
||||
// schematics
|
||||
virtual void setLevel(Level* level) { this->level = level; }
|
||||
};
|
||||
|
|
@ -9,89 +9,86 @@
|
|||
#include "MeleeAttackGoal.h"
|
||||
#include "../Navigation/Path.h"
|
||||
|
||||
void MeleeAttackGoal::_init(Mob *mob, float speed, bool trackTarget)
|
||||
{
|
||||
this->attackType = eTYPE_NOTSET;
|
||||
this->mob = mob;
|
||||
this->level = mob->level;
|
||||
this->speed = speed;
|
||||
this->trackTarget = trackTarget;
|
||||
setRequiredControlFlags(Control::MoveControlFlag | Control::LookControlFlag);
|
||||
void MeleeAttackGoal::_init(Mob* mob, float speed, bool trackTarget) {
|
||||
this->attackType = eTYPE_NOTSET;
|
||||
this->mob = mob;
|
||||
this->level = mob->level;
|
||||
this->speed = speed;
|
||||
this->trackTarget = trackTarget;
|
||||
setRequiredControlFlags(Control::MoveControlFlag |
|
||||
Control::LookControlFlag);
|
||||
|
||||
|
||||
attackTime = 0;
|
||||
path = NULL;
|
||||
timeToRecalcPath = 0;
|
||||
attackTime = 0;
|
||||
path = NULL;
|
||||
timeToRecalcPath = 0;
|
||||
}
|
||||
|
||||
MeleeAttackGoal::MeleeAttackGoal(Mob *mob, eINSTANCEOF attackType, float speed, bool trackTarget)
|
||||
{
|
||||
_init(mob, speed, trackTarget);
|
||||
this->attackType = attackType;
|
||||
MeleeAttackGoal::MeleeAttackGoal(Mob* mob, eINSTANCEOF attackType, float speed,
|
||||
bool trackTarget) {
|
||||
_init(mob, speed, trackTarget);
|
||||
this->attackType = attackType;
|
||||
}
|
||||
|
||||
MeleeAttackGoal::MeleeAttackGoal(Mob *mob, float speed, bool trackTarget)
|
||||
{
|
||||
_init(mob,speed,trackTarget);
|
||||
MeleeAttackGoal::MeleeAttackGoal(Mob* mob, float speed, bool trackTarget) {
|
||||
_init(mob, speed, trackTarget);
|
||||
}
|
||||
|
||||
MeleeAttackGoal::~MeleeAttackGoal()
|
||||
{
|
||||
if(path != NULL) delete path;
|
||||
MeleeAttackGoal::~MeleeAttackGoal() {
|
||||
if (path != NULL) delete path;
|
||||
}
|
||||
|
||||
bool MeleeAttackGoal::canUse()
|
||||
{
|
||||
std::shared_ptr<Mob> bestTarget = mob->getTarget();
|
||||
if (bestTarget == NULL) return false;
|
||||
if(!bestTarget->isAlive()) return false;
|
||||
if (attackType != eTYPE_NOTSET && (attackType & bestTarget->GetType()) != attackType) return false;
|
||||
target = std::weak_ptr<Mob>(bestTarget);
|
||||
delete path;
|
||||
path = mob->getNavigation()->createPath(target.lock());
|
||||
return path != NULL;
|
||||
bool MeleeAttackGoal::canUse() {
|
||||
std::shared_ptr<Mob> bestTarget = mob->getTarget();
|
||||
if (bestTarget == NULL) return false;
|
||||
if (!bestTarget->isAlive()) return false;
|
||||
if (attackType != eTYPE_NOTSET &&
|
||||
(attackType & bestTarget->GetType()) != attackType)
|
||||
return false;
|
||||
target = std::weak_ptr<Mob>(bestTarget);
|
||||
delete path;
|
||||
path = mob->getNavigation()->createPath(target.lock());
|
||||
return path != NULL;
|
||||
}
|
||||
|
||||
bool MeleeAttackGoal::canContinueToUse()
|
||||
{
|
||||
std::shared_ptr<Mob> bestTarget = mob->getTarget();
|
||||
if (bestTarget == NULL) return false;
|
||||
if (target.lock() == NULL || !target.lock()->isAlive()) return false;
|
||||
if (!trackTarget) return !mob->getNavigation()->isDone();
|
||||
if (!mob->isWithinRestriction(Mth::floor(target.lock()->x), Mth::floor(target.lock()->y), Mth::floor(target.lock()->z))) return false;
|
||||
return true;
|
||||
bool MeleeAttackGoal::canContinueToUse() {
|
||||
std::shared_ptr<Mob> bestTarget = mob->getTarget();
|
||||
if (bestTarget == NULL) return false;
|
||||
if (target.lock() == NULL || !target.lock()->isAlive()) return false;
|
||||
if (!trackTarget) return !mob->getNavigation()->isDone();
|
||||
if (!mob->isWithinRestriction(Mth::floor(target.lock()->x),
|
||||
Mth::floor(target.lock()->y),
|
||||
Mth::floor(target.lock()->z)))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void MeleeAttackGoal::start()
|
||||
{
|
||||
mob->getNavigation()->moveTo(path, speed);
|
||||
path = NULL;
|
||||
timeToRecalcPath = 0;
|
||||
void MeleeAttackGoal::start() {
|
||||
mob->getNavigation()->moveTo(path, speed);
|
||||
path = NULL;
|
||||
timeToRecalcPath = 0;
|
||||
}
|
||||
|
||||
void MeleeAttackGoal::stop()
|
||||
{
|
||||
target = std::weak_ptr<Mob>();
|
||||
mob->getNavigation()->stop();
|
||||
void MeleeAttackGoal::stop() {
|
||||
target = std::weak_ptr<Mob>();
|
||||
mob->getNavigation()->stop();
|
||||
}
|
||||
|
||||
void MeleeAttackGoal::tick()
|
||||
{
|
||||
mob->getLookControl()->setLookAt(target.lock(), 30, 30);
|
||||
if (trackTarget || mob->getSensing()->canSee(target.lock()))
|
||||
{
|
||||
if (--timeToRecalcPath <= 0)
|
||||
{
|
||||
timeToRecalcPath = 4 + mob->getRandom()->nextInt(7);
|
||||
mob->getNavigation()->moveTo(target.lock(), speed);
|
||||
}
|
||||
}
|
||||
void MeleeAttackGoal::tick() {
|
||||
mob->getLookControl()->setLookAt(target.lock(), 30, 30);
|
||||
if (trackTarget || mob->getSensing()->canSee(target.lock())) {
|
||||
if (--timeToRecalcPath <= 0) {
|
||||
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);
|
||||
if (mob->distanceToSqr(target.lock()->x, target.lock()->bb->y0, target.lock()->z) > meleeRadiusSqr) return;
|
||||
if (attackTime > 0) return;
|
||||
attackTime = 20;
|
||||
mob->doHurtTarget(target.lock());
|
||||
double meleeRadiusSqr = (mob->bbWidth * 2) * (mob->bbWidth * 2);
|
||||
if (mob->distanceToSqr(target.lock()->x, target.lock()->bb->y0,
|
||||
target.lock()->z) > meleeRadiusSqr)
|
||||
return;
|
||||
if (attackTime > 0) return;
|
||||
attackTime = 20;
|
||||
mob->doHurtTarget(target.lock());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,33 +6,34 @@ class Level;
|
|||
class Mob;
|
||||
class Path;
|
||||
|
||||
class MeleeAttackGoal : public Goal
|
||||
{
|
||||
class MeleeAttackGoal : public Goal {
|
||||
private:
|
||||
Level *level;
|
||||
Mob *mob; // Owner of this goal
|
||||
std::weak_ptr<Mob> target;
|
||||
Level* level;
|
||||
Mob* mob; // Owner of this goal
|
||||
std::weak_ptr<Mob> target;
|
||||
|
||||
int attackTime;
|
||||
float speed;
|
||||
bool trackTarget;
|
||||
Path *path;
|
||||
eINSTANCEOF attackType;
|
||||
int timeToRecalcPath;
|
||||
int attackTime;
|
||||
float speed;
|
||||
bool trackTarget;
|
||||
Path* path;
|
||||
eINSTANCEOF attackType;
|
||||
int timeToRecalcPath;
|
||||
|
||||
void _init(Mob *mob, float speed, bool trackTarget);
|
||||
void _init(Mob* mob, float speed, bool trackTarget);
|
||||
|
||||
public:
|
||||
MeleeAttackGoal(Mob *mob, eINSTANCEOF attackType, float speed, bool trackTarget);
|
||||
MeleeAttackGoal(Mob *mob, float speed, bool trackTarget);
|
||||
~MeleeAttackGoal();
|
||||
MeleeAttackGoal(Mob* mob, eINSTANCEOF attackType, float speed,
|
||||
bool trackTarget);
|
||||
MeleeAttackGoal(Mob* mob, float speed, bool trackTarget);
|
||||
~MeleeAttackGoal();
|
||||
|
||||
virtual bool canUse();
|
||||
virtual bool canContinueToUse();
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual void tick();
|
||||
|
||||
// 4J Added override to update ai elements when loading entity from schematics
|
||||
virtual void setLevel(Level *level) { this->level = level; }
|
||||
virtual bool canUse();
|
||||
virtual bool canContinueToUse();
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual void tick();
|
||||
|
||||
// 4J Added override to update ai elements when loading entity from
|
||||
// schematics
|
||||
virtual void setLevel(Level* level) { this->level = level; }
|
||||
};
|
||||
|
|
@ -8,58 +8,64 @@
|
|||
#include "../../Headers/net.minecraft.world.level.dimension.h"
|
||||
#include "MoveIndoorsGoal.h"
|
||||
|
||||
MoveIndoorsGoal::MoveIndoorsGoal(PathfinderMob *mob)
|
||||
{
|
||||
insideX = insideZ = -1;
|
||||
MoveIndoorsGoal::MoveIndoorsGoal(PathfinderMob* mob) {
|
||||
insideX = insideZ = -1;
|
||||
|
||||
this->mob = mob;
|
||||
setRequiredControlFlags(Control::MoveControlFlag);
|
||||
this->mob = mob;
|
||||
setRequiredControlFlags(Control::MoveControlFlag);
|
||||
}
|
||||
|
||||
bool MoveIndoorsGoal::canUse()
|
||||
{
|
||||
if ((mob->level->isDay() && !mob->level->isRaining()) || mob->level->dimension->hasCeiling) return false;
|
||||
if (mob->getRandom()->nextInt(50) != 0) return false;
|
||||
if (insideX != -1 && mob->distanceToSqr(insideX, mob->y, insideZ) < 2 * 2) return false;
|
||||
std::shared_ptr<Village> village = mob->level->villages->getClosestVillage(Mth::floor(mob->x), Mth::floor(mob->y), Mth::floor(mob->z), 14);
|
||||
if (village == NULL) return false;
|
||||
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::canUse() {
|
||||
if ((mob->level->isDay() && !mob->level->isRaining()) ||
|
||||
mob->level->dimension->hasCeiling)
|
||||
return false;
|
||||
if (mob->getRandom()->nextInt(50) != 0) return false;
|
||||
if (insideX != -1 && mob->distanceToSqr(insideX, mob->y, insideZ) < 2 * 2)
|
||||
return false;
|
||||
std::shared_ptr<Village> village = mob->level->villages->getClosestVillage(
|
||||
Mth::floor(mob->x), Mth::floor(mob->y), Mth::floor(mob->z), 14);
|
||||
if (village == NULL) return false;
|
||||
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()
|
||||
{
|
||||
return !mob->getNavigation()->isDone();
|
||||
bool MoveIndoorsGoal::canContinueToUse() {
|
||||
return !mob->getNavigation()->isDone();
|
||||
}
|
||||
|
||||
void MoveIndoorsGoal::start()
|
||||
{
|
||||
insideX = -1;
|
||||
std::shared_ptr<DoorInfo> _doorInfo = doorInfo.lock();
|
||||
if( _doorInfo == NULL )
|
||||
{
|
||||
doorInfo = std::weak_ptr<DoorInfo>();
|
||||
return;
|
||||
}
|
||||
if (mob->distanceToSqr(_doorInfo->getIndoorX(), _doorInfo->y, _doorInfo->getIndoorZ()) > 16 * 16)
|
||||
{
|
||||
Vec3 *pos = RandomPos::getPosTowards(std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()), 14, 3, Vec3::newTemp(_doorInfo->getIndoorX() + 0.5, _doorInfo->getIndoorY(), _doorInfo->getIndoorZ() + 0.5));
|
||||
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::start() {
|
||||
insideX = -1;
|
||||
std::shared_ptr<DoorInfo> _doorInfo = doorInfo.lock();
|
||||
if (_doorInfo == NULL) {
|
||||
doorInfo = std::weak_ptr<DoorInfo>();
|
||||
return;
|
||||
}
|
||||
if (mob->distanceToSqr(_doorInfo->getIndoorX(), _doorInfo->y,
|
||||
_doorInfo->getIndoorZ()) > 16 * 16) {
|
||||
Vec3* pos = RandomPos::getPosTowards(
|
||||
std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()),
|
||||
14, 3,
|
||||
Vec3::newTemp(_doorInfo->getIndoorX() + 0.5,
|
||||
_doorInfo->getIndoorY(),
|
||||
_doorInfo->getIndoorZ() + 0.5));
|
||||
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()
|
||||
{
|
||||
std::shared_ptr<DoorInfo> _doorInfo = doorInfo.lock();
|
||||
if( _doorInfo == NULL )
|
||||
{
|
||||
doorInfo = std::weak_ptr<DoorInfo>();
|
||||
return;
|
||||
}
|
||||
void MoveIndoorsGoal::stop() {
|
||||
std::shared_ptr<DoorInfo> _doorInfo = doorInfo.lock();
|
||||
if (_doorInfo == NULL) {
|
||||
doorInfo = std::weak_ptr<DoorInfo>();
|
||||
return;
|
||||
}
|
||||
|
||||
insideX = _doorInfo->getIndoorX();
|
||||
insideZ = _doorInfo->getIndoorZ();
|
||||
doorInfo = std::weak_ptr<DoorInfo>();
|
||||
insideX = _doorInfo->getIndoorX();
|
||||
insideZ = _doorInfo->getIndoorZ();
|
||||
doorInfo = std::weak_ptr<DoorInfo>();
|
||||
}
|
||||
|
|
@ -5,18 +5,17 @@
|
|||
class PathfinderMob;
|
||||
class DoorInfo;
|
||||
|
||||
class MoveIndoorsGoal : public Goal
|
||||
{
|
||||
class MoveIndoorsGoal : public Goal {
|
||||
private:
|
||||
PathfinderMob *mob;
|
||||
std::weak_ptr<DoorInfo> doorInfo;
|
||||
int insideX, insideZ;
|
||||
PathfinderMob* mob;
|
||||
std::weak_ptr<DoorInfo> doorInfo;
|
||||
int insideX, insideZ;
|
||||
|
||||
public:
|
||||
MoveIndoorsGoal(PathfinderMob *mob);
|
||||
MoveIndoorsGoal(PathfinderMob* mob);
|
||||
|
||||
bool canUse();
|
||||
bool canContinueToUse();
|
||||
void start();
|
||||
void stop();
|
||||
bool canUse();
|
||||
bool canContinueToUse();
|
||||
void start();
|
||||
void stop();
|
||||
};
|
||||
|
|
@ -9,119 +9,114 @@
|
|||
#include "MoveThroughVillageGoal.h"
|
||||
#include "../Navigation/Path.h"
|
||||
|
||||
MoveThroughVillageGoal::MoveThroughVillageGoal(PathfinderMob *mob, float speed, bool onlyAtNight)
|
||||
{
|
||||
path = NULL;
|
||||
doorInfo = std::weak_ptr<DoorInfo>();
|
||||
MoveThroughVillageGoal::MoveThroughVillageGoal(PathfinderMob* mob, float speed,
|
||||
bool onlyAtNight) {
|
||||
path = NULL;
|
||||
doorInfo = std::weak_ptr<DoorInfo>();
|
||||
|
||||
this->mob = mob;
|
||||
this->speed = speed;
|
||||
this->onlyAtNight = onlyAtNight;
|
||||
setRequiredControlFlags(Control::MoveControlFlag);
|
||||
this->mob = mob;
|
||||
this->speed = speed;
|
||||
this->onlyAtNight = onlyAtNight;
|
||||
setRequiredControlFlags(Control::MoveControlFlag);
|
||||
}
|
||||
|
||||
MoveThroughVillageGoal::~MoveThroughVillageGoal()
|
||||
{
|
||||
if(path != NULL) delete path;
|
||||
MoveThroughVillageGoal::~MoveThroughVillageGoal() {
|
||||
if (path != NULL) delete path;
|
||||
}
|
||||
|
||||
bool MoveThroughVillageGoal::canUse()
|
||||
{
|
||||
updateVisited();
|
||||
bool MoveThroughVillageGoal::canUse() {
|
||||
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);
|
||||
if (village == NULL) return false;
|
||||
std::shared_ptr<Village> village = mob->level->villages->getClosestVillage(
|
||||
Mth::floor(mob->x), Mth::floor(mob->y), Mth::floor(mob->z), 0);
|
||||
if (village == NULL) return false;
|
||||
|
||||
std::shared_ptr<DoorInfo> _doorInfo = getNextDoorInfo(village);
|
||||
if (_doorInfo == NULL) return false;
|
||||
doorInfo = _doorInfo;
|
||||
std::shared_ptr<DoorInfo> _doorInfo = getNextDoorInfo(village);
|
||||
if (_doorInfo == NULL) return false;
|
||||
doorInfo = _doorInfo;
|
||||
|
||||
bool oldCanOpenDoors = mob->getNavigation()->canOpenDoors();
|
||||
mob->getNavigation()->setCanOpenDoors(false);
|
||||
delete path;
|
||||
bool oldCanOpenDoors = mob->getNavigation()->canOpenDoors();
|
||||
mob->getNavigation()->setCanOpenDoors(false);
|
||||
delete path;
|
||||
|
||||
path = mob->getNavigation()->createPath(_doorInfo->x, _doorInfo->y, _doorInfo->z);
|
||||
mob->getNavigation()->setCanOpenDoors(oldCanOpenDoors);
|
||||
if (path != NULL) return true;
|
||||
path = mob->getNavigation()->createPath(_doorInfo->x, _doorInfo->y,
|
||||
_doorInfo->z);
|
||||
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));
|
||||
if (pos == NULL) return false;
|
||||
mob->getNavigation()->setCanOpenDoors(false);
|
||||
delete path;
|
||||
path = mob->getNavigation()->createPath(pos->x, pos->y, pos->z);
|
||||
mob->getNavigation()->setCanOpenDoors(oldCanOpenDoors);
|
||||
return path != NULL;
|
||||
Vec3* pos = RandomPos::getPosTowards(
|
||||
std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()), 10,
|
||||
7, Vec3::newTemp(_doorInfo->x, _doorInfo->y, _doorInfo->z));
|
||||
if (pos == NULL) return false;
|
||||
mob->getNavigation()->setCanOpenDoors(false);
|
||||
delete path;
|
||||
path = mob->getNavigation()->createPath(pos->x, pos->y, pos->z);
|
||||
mob->getNavigation()->setCanOpenDoors(oldCanOpenDoors);
|
||||
return path != NULL;
|
||||
}
|
||||
|
||||
bool MoveThroughVillageGoal::canContinueToUse()
|
||||
{
|
||||
if (mob->getNavigation()->isDone()) return false;
|
||||
float dist = mob->bbWidth + 4.f;
|
||||
std::shared_ptr<DoorInfo> _doorInfo = doorInfo.lock();
|
||||
if( _doorInfo == NULL ) return false;
|
||||
bool MoveThroughVillageGoal::canContinueToUse() {
|
||||
if (mob->getNavigation()->isDone()) return false;
|
||||
float dist = mob->bbWidth + 4.f;
|
||||
std::shared_ptr<DoorInfo> _doorInfo = doorInfo.lock();
|
||||
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()
|
||||
{
|
||||
mob->getNavigation()->moveTo(path, speed);
|
||||
path = NULL;
|
||||
void MoveThroughVillageGoal::start() {
|
||||
mob->getNavigation()->moveTo(path, speed);
|
||||
path = NULL;
|
||||
}
|
||||
|
||||
void MoveThroughVillageGoal::stop()
|
||||
{
|
||||
std::shared_ptr<DoorInfo> _doorInfo = doorInfo.lock();
|
||||
if( _doorInfo == NULL ) return;
|
||||
void MoveThroughVillageGoal::stop() {
|
||||
std::shared_ptr<DoorInfo> _doorInfo = doorInfo.lock();
|
||||
if (_doorInfo == NULL) return;
|
||||
|
||||
if (mob->getNavigation()->isDone() || mob->distanceToSqr(_doorInfo->x, _doorInfo->y, _doorInfo->z) < 4 * 4)
|
||||
{
|
||||
visited.push_back(doorInfo);
|
||||
}
|
||||
if (mob->getNavigation()->isDone() ||
|
||||
mob->distanceToSqr(_doorInfo->x, _doorInfo->y, _doorInfo->z) < 4 * 4) {
|
||||
visited.push_back(doorInfo);
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<DoorInfo> MoveThroughVillageGoal::getNextDoorInfo(std::shared_ptr<Village> village)
|
||||
{
|
||||
std::shared_ptr<DoorInfo> closest = nullptr;
|
||||
int closestDistSqr = Integer::MAX_VALUE;
|
||||
std::vector<std::shared_ptr<DoorInfo> > *doorInfos = village->getDoorInfos();
|
||||
//for (DoorInfo di : doorInfos)
|
||||
for(AUTO_VAR(it, doorInfos->begin()); it != doorInfos->end(); ++it)
|
||||
{
|
||||
std::shared_ptr<DoorInfo> di = *it;
|
||||
int distSqr = di->distanceToSqr(Mth::floor(mob->x), Mth::floor(mob->y), Mth::floor(mob->z));
|
||||
if (distSqr < closestDistSqr)
|
||||
{
|
||||
if (hasVisited(di)) continue;
|
||||
closest = di;
|
||||
closestDistSqr = distSqr;
|
||||
}
|
||||
}
|
||||
return closest;
|
||||
std::shared_ptr<DoorInfo> MoveThroughVillageGoal::getNextDoorInfo(
|
||||
std::shared_ptr<Village> village) {
|
||||
std::shared_ptr<DoorInfo> closest = nullptr;
|
||||
int closestDistSqr = Integer::MAX_VALUE;
|
||||
std::vector<std::shared_ptr<DoorInfo> >* doorInfos =
|
||||
village->getDoorInfos();
|
||||
// for (DoorInfo di : doorInfos)
|
||||
for (AUTO_VAR(it, doorInfos->begin()); it != doorInfos->end(); ++it) {
|
||||
std::shared_ptr<DoorInfo> di = *it;
|
||||
int distSqr = di->distanceToSqr(Mth::floor(mob->x), Mth::floor(mob->y),
|
||||
Mth::floor(mob->z));
|
||||
if (distSqr < closestDistSqr) {
|
||||
if (hasVisited(di)) continue;
|
||||
closest = di;
|
||||
closestDistSqr = distSqr;
|
||||
}
|
||||
}
|
||||
return closest;
|
||||
}
|
||||
|
||||
bool MoveThroughVillageGoal::hasVisited(std::shared_ptr<DoorInfo>di)
|
||||
{
|
||||
//for (DoorInfo di2 : visited)
|
||||
for(AUTO_VAR(it, visited.begin()); it != visited.end(); )
|
||||
{
|
||||
std::shared_ptr<DoorInfo> di2 = (*it).lock();
|
||||
if( di2 == NULL )
|
||||
{
|
||||
it = visited.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (di->x == di2->x && di->y == di2->y && di->z == di2->z) return true;
|
||||
++it;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
bool MoveThroughVillageGoal::hasVisited(std::shared_ptr<DoorInfo> di) {
|
||||
// for (DoorInfo di2 : visited)
|
||||
for (AUTO_VAR(it, visited.begin()); it != visited.end();) {
|
||||
std::shared_ptr<DoorInfo> di2 = (*it).lock();
|
||||
if (di2 == NULL) {
|
||||
it = visited.erase(it);
|
||||
} else {
|
||||
if (di->x == di2->x && di->y == di2->y && di->z == di2->z)
|
||||
return true;
|
||||
++it;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void MoveThroughVillageGoal::updateVisited()
|
||||
{
|
||||
if (visited.size() > 15) visited.erase(visited.begin());
|
||||
void MoveThroughVillageGoal::updateVisited() {
|
||||
if (visited.size() > 15) visited.erase(visited.begin());
|
||||
}
|
||||
|
|
@ -6,27 +6,26 @@ class PathfinderMob;
|
|||
class Path;
|
||||
class DoorInfo;
|
||||
|
||||
class MoveThroughVillageGoal : public Goal
|
||||
{
|
||||
class MoveThroughVillageGoal : public Goal {
|
||||
private:
|
||||
PathfinderMob *mob;
|
||||
float speed;
|
||||
Path *path;
|
||||
std::weak_ptr<DoorInfo> doorInfo;
|
||||
bool onlyAtNight;
|
||||
std::vector< std::weak_ptr<DoorInfo> > visited;
|
||||
PathfinderMob* mob;
|
||||
float speed;
|
||||
Path* path;
|
||||
std::weak_ptr<DoorInfo> doorInfo;
|
||||
bool onlyAtNight;
|
||||
std::vector<std::weak_ptr<DoorInfo> > visited;
|
||||
|
||||
public:
|
||||
MoveThroughVillageGoal(PathfinderMob *mob, float speed, bool onlyAtNight);
|
||||
~MoveThroughVillageGoal();
|
||||
MoveThroughVillageGoal(PathfinderMob* mob, float speed, bool onlyAtNight);
|
||||
~MoveThroughVillageGoal();
|
||||
|
||||
virtual bool canUse();
|
||||
virtual bool canContinueToUse();
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual bool canUse();
|
||||
virtual bool canContinueToUse();
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
|
||||
private:
|
||||
std::shared_ptr<DoorInfo> getNextDoorInfo(std::shared_ptr<Village> village);
|
||||
bool hasVisited(std::shared_ptr<DoorInfo> di);
|
||||
void updateVisited();
|
||||
std::shared_ptr<DoorInfo> getNextDoorInfo(std::shared_ptr<Village> village);
|
||||
bool hasVisited(std::shared_ptr<DoorInfo> di);
|
||||
void updateVisited();
|
||||
};
|
||||
|
|
@ -6,33 +6,32 @@
|
|||
#include "../../Headers/net.minecraft.world.level.h"
|
||||
#include "MoveTowardsRestrictionGoal.h"
|
||||
|
||||
MoveTowardsRestrictionGoal::MoveTowardsRestrictionGoal(PathfinderMob *mob, float speed)
|
||||
{
|
||||
wantedX = wantedY = wantedZ = 0.0;
|
||||
MoveTowardsRestrictionGoal::MoveTowardsRestrictionGoal(PathfinderMob* mob,
|
||||
float speed) {
|
||||
wantedX = wantedY = wantedZ = 0.0;
|
||||
|
||||
this->mob = mob;
|
||||
this->speed = speed;
|
||||
setRequiredControlFlags(Control::MoveControlFlag);
|
||||
this->mob = mob;
|
||||
this->speed = speed;
|
||||
setRequiredControlFlags(Control::MoveControlFlag);
|
||||
}
|
||||
|
||||
bool MoveTowardsRestrictionGoal::canUse()
|
||||
{
|
||||
if (mob->isWithinRestriction()) return false;
|
||||
Pos *towards = mob->getRestrictCenter();
|
||||
Vec3 *pos = RandomPos::getPosTowards(std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()), 16, 7, Vec3::newTemp(towards->x, towards->y, towards->z));
|
||||
if (pos == NULL) return false;
|
||||
wantedX = pos->x;
|
||||
wantedY = pos->y;
|
||||
wantedZ = pos->z;
|
||||
return true;
|
||||
bool MoveTowardsRestrictionGoal::canUse() {
|
||||
if (mob->isWithinRestriction()) return false;
|
||||
Pos* towards = mob->getRestrictCenter();
|
||||
Vec3* pos = RandomPos::getPosTowards(
|
||||
std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()), 16,
|
||||
7, Vec3::newTemp(towards->x, towards->y, towards->z));
|
||||
if (pos == NULL) return false;
|
||||
wantedX = pos->x;
|
||||
wantedY = pos->y;
|
||||
wantedZ = pos->z;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MoveTowardsRestrictionGoal::canContinueToUse()
|
||||
{
|
||||
return !mob->getNavigation()->isDone();
|
||||
bool MoveTowardsRestrictionGoal::canContinueToUse() {
|
||||
return !mob->getNavigation()->isDone();
|
||||
}
|
||||
|
||||
void MoveTowardsRestrictionGoal::start()
|
||||
{
|
||||
mob->getNavigation()->moveTo(wantedX, wantedY, wantedZ, speed);
|
||||
void MoveTowardsRestrictionGoal::start() {
|
||||
mob->getNavigation()->moveTo(wantedX, wantedY, wantedZ, speed);
|
||||
}
|
||||
|
|
@ -2,17 +2,16 @@
|
|||
|
||||
#include "Goal.h"
|
||||
|
||||
class MoveTowardsRestrictionGoal : public Goal
|
||||
{
|
||||
class MoveTowardsRestrictionGoal : public Goal {
|
||||
private:
|
||||
PathfinderMob *mob;
|
||||
double wantedX, wantedY, wantedZ;
|
||||
float speed;
|
||||
PathfinderMob* mob;
|
||||
double wantedX, wantedY, wantedZ;
|
||||
float speed;
|
||||
|
||||
public:
|
||||
MoveTowardsRestrictionGoal(PathfinderMob *mob, float speed);
|
||||
MoveTowardsRestrictionGoal(PathfinderMob* mob, float speed);
|
||||
|
||||
bool canUse();
|
||||
bool canContinueToUse();
|
||||
void start();
|
||||
bool canUse();
|
||||
bool canContinueToUse();
|
||||
void start();
|
||||
};
|
||||
|
|
@ -6,38 +6,38 @@
|
|||
#include "../../Headers/net.minecraft.world.phys.h"
|
||||
#include "MoveTowardsTargetGoal.h"
|
||||
|
||||
MoveTowardsTargetGoal::MoveTowardsTargetGoal(PathfinderMob *mob, float speed, float within)
|
||||
{
|
||||
this->mob = mob;
|
||||
this->speed = speed;
|
||||
this->within = within;
|
||||
setRequiredControlFlags(Control::MoveControlFlag);
|
||||
MoveTowardsTargetGoal::MoveTowardsTargetGoal(PathfinderMob* mob, float speed,
|
||||
float within) {
|
||||
this->mob = mob;
|
||||
this->speed = speed;
|
||||
this->within = within;
|
||||
setRequiredControlFlags(Control::MoveControlFlag);
|
||||
}
|
||||
|
||||
bool MoveTowardsTargetGoal::canUse()
|
||||
{
|
||||
target = std::weak_ptr<Mob>(mob->getTarget());
|
||||
if (target.lock() == NULL) return false;
|
||||
if (target.lock()->distanceToSqr(mob->shared_from_this()) > within * within) return false;
|
||||
Vec3 *pos = RandomPos::getPosTowards(std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()), 16, 7, Vec3::newTemp(target.lock()->x, target.lock()->y, target.lock()->z));
|
||||
if (pos == NULL) return false;
|
||||
wantedX = pos->x;
|
||||
wantedY = pos->y;
|
||||
wantedZ = pos->z;
|
||||
return true;
|
||||
bool MoveTowardsTargetGoal::canUse() {
|
||||
target = std::weak_ptr<Mob>(mob->getTarget());
|
||||
if (target.lock() == NULL) return false;
|
||||
if (target.lock()->distanceToSqr(mob->shared_from_this()) > within * within)
|
||||
return false;
|
||||
Vec3* pos = RandomPos::getPosTowards(
|
||||
std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()), 16,
|
||||
7, Vec3::newTemp(target.lock()->x, target.lock()->y, target.lock()->z));
|
||||
if (pos == NULL) return false;
|
||||
wantedX = pos->x;
|
||||
wantedY = pos->y;
|
||||
wantedZ = pos->z;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MoveTowardsTargetGoal::canContinueToUse()
|
||||
{
|
||||
return target.lock() != NULL && !mob->getNavigation()->isDone() && target.lock()->isAlive() && target.lock()->distanceToSqr(mob->shared_from_this()) < within * within;
|
||||
bool MoveTowardsTargetGoal::canContinueToUse() {
|
||||
return target.lock() != NULL && !mob->getNavigation()->isDone() &&
|
||||
target.lock()->isAlive() &&
|
||||
target.lock()->distanceToSqr(mob->shared_from_this()) <
|
||||
within * within;
|
||||
}
|
||||
|
||||
void MoveTowardsTargetGoal::stop()
|
||||
{
|
||||
target = std::weak_ptr<Mob>();
|
||||
}
|
||||
void MoveTowardsTargetGoal::stop() { target = std::weak_ptr<Mob>(); }
|
||||
|
||||
void MoveTowardsTargetGoal::start()
|
||||
{
|
||||
mob->getNavigation()->moveTo(wantedX, wantedY, wantedZ, speed);
|
||||
void MoveTowardsTargetGoal::start() {
|
||||
mob->getNavigation()->moveTo(wantedX, wantedY, wantedZ, speed);
|
||||
}
|
||||
|
|
@ -2,19 +2,18 @@
|
|||
|
||||
#include "Goal.h"
|
||||
|
||||
class MoveTowardsTargetGoal : public Goal
|
||||
{
|
||||
class MoveTowardsTargetGoal : public Goal {
|
||||
private:
|
||||
PathfinderMob *mob;
|
||||
std::weak_ptr<Mob> target;
|
||||
double wantedX, wantedY, wantedZ;
|
||||
float speed, within;
|
||||
PathfinderMob* mob;
|
||||
std::weak_ptr<Mob> target;
|
||||
double wantedX, wantedY, wantedZ;
|
||||
float speed, within;
|
||||
|
||||
public:
|
||||
MoveTowardsTargetGoal(PathfinderMob *mob, float speed, float within);
|
||||
MoveTowardsTargetGoal(PathfinderMob* mob, float speed, float within);
|
||||
|
||||
bool canUse();
|
||||
bool canContinueToUse();
|
||||
void stop();
|
||||
void start();
|
||||
bool canUse();
|
||||
bool canContinueToUse();
|
||||
void stop();
|
||||
void start();
|
||||
};
|
||||
|
|
@ -4,68 +4,64 @@
|
|||
#include "../../Headers/net.minecraft.world.phys.h"
|
||||
#include "NearestAttackableTargetGoal.h"
|
||||
|
||||
NearestAttackableTargetGoal::DistComp::DistComp(Entity *source)
|
||||
{
|
||||
this->source = source;
|
||||
NearestAttackableTargetGoal::DistComp::DistComp(Entity* source) {
|
||||
this->source = source;
|
||||
}
|
||||
|
||||
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
|
||||
double distSqr1 = source->distanceToSqr(e1);
|
||||
double distSqr2 = source->distanceToSqr(e2);
|
||||
if (distSqr1 < distSqr2) return true;
|
||||
if (distSqr1 > distSqr2) return false;
|
||||
return true;
|
||||
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
|
||||
double distSqr1 = source->distanceToSqr(e1);
|
||||
double distSqr2 = source->distanceToSqr(e2);
|
||||
if (distSqr1 < distSqr2) return true;
|
||||
if (distSqr1 > distSqr2) return false;
|
||||
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)
|
||||
{
|
||||
//this->targetType = targetType;
|
||||
this->within = within;
|
||||
this->randomInterval = randomInterval;
|
||||
this->distComp = new DistComp(mob);
|
||||
setRequiredControlFlags(TargetGoal::TargetFlag);
|
||||
NearestAttackableTargetGoal::NearestAttackableTargetGoal(
|
||||
Mob* mob, const std::type_info& targetType, float within,
|
||||
int randomInterval, bool mustSee, bool mustReach /*= false*/)
|
||||
: TargetGoal(mob, within, mustSee, mustReach), targetType(targetType) {
|
||||
// this->targetType = targetType;
|
||||
this->within = within;
|
||||
this->randomInterval = randomInterval;
|
||||
this->distComp = new DistComp(mob);
|
||||
setRequiredControlFlags(TargetGoal::TargetFlag);
|
||||
}
|
||||
|
||||
NearestAttackableTargetGoal::~NearestAttackableTargetGoal()
|
||||
{
|
||||
delete distComp;
|
||||
NearestAttackableTargetGoal::~NearestAttackableTargetGoal() { 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()
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
void NearestAttackableTargetGoal::start()
|
||||
{
|
||||
mob->setTarget(target.lock());
|
||||
TargetGoal::start();
|
||||
void NearestAttackableTargetGoal::start() {
|
||||
mob->setTarget(target.lock());
|
||||
TargetGoal::start();
|
||||
}
|
||||
|
|
@ -2,35 +2,36 @@
|
|||
|
||||
#include "TargetGoal.h"
|
||||
|
||||
class NearestAttackableTargetGoal : public TargetGoal
|
||||
{
|
||||
class NearestAttackableTargetGoal : public TargetGoal {
|
||||
public:
|
||||
class DistComp
|
||||
{
|
||||
private:
|
||||
Entity *source;
|
||||
class DistComp {
|
||||
private:
|
||||
Entity* source;
|
||||
|
||||
public:
|
||||
DistComp(Entity *source);
|
||||
public:
|
||||
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:
|
||||
std::weak_ptr<Mob> target;
|
||||
const std::type_info& targetType;
|
||||
int randomInterval;
|
||||
DistComp *distComp;
|
||||
std::weak_ptr<Mob> target;
|
||||
const std::type_info& targetType;
|
||||
int randomInterval;
|
||||
DistComp* distComp;
|
||||
|
||||
public:
|
||||
//public NearestAttackableTargetGoal(Mob mob, const std::type_info& targetType, float within, int randomInterval, bool mustSee)
|
||||
//{
|
||||
// this(mob, targetType, within, randomInterval, mustSee, false);
|
||||
//}
|
||||
// public NearestAttackableTargetGoal(Mob mob, const std::type_info&
|
||||
// targetType, float within, int randomInterval, bool mustSee)
|
||||
//{
|
||||
// this(mob, targetType, within, randomInterval, mustSee, false);
|
||||
// }
|
||||
|
||||
NearestAttackableTargetGoal(Mob *mob, const std::type_info& targetType, float within, int randomInterval, bool mustSee, bool mustReach = false);
|
||||
virtual ~NearestAttackableTargetGoal();
|
||||
NearestAttackableTargetGoal(Mob* mob, const std::type_info& targetType,
|
||||
float within, int randomInterval, bool mustSee,
|
||||
bool mustReach = false);
|
||||
virtual ~NearestAttackableTargetGoal();
|
||||
|
||||
virtual bool canUse();
|
||||
void start();
|
||||
virtual bool canUse();
|
||||
void start();
|
||||
};
|
||||
|
|
@ -2,13 +2,15 @@
|
|||
#include "../../Headers/net.minecraft.world.entity.animal.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)
|
||||
{
|
||||
this->tamableMob = mob;
|
||||
NonTameRandomTargetGoal::NonTameRandomTargetGoal(
|
||||
TamableAnimal* mob, const std::type_info& targetType, float within,
|
||||
int randomInterval, bool mustSee)
|
||||
: NearestAttackableTargetGoal(mob, targetType, within, randomInterval,
|
||||
mustSee) {
|
||||
this->tamableMob = mob;
|
||||
}
|
||||
|
||||
bool NonTameRandomTargetGoal::canUse()
|
||||
{
|
||||
if (tamableMob->isTame()) return false;
|
||||
return NearestAttackableTargetGoal::canUse();
|
||||
bool NonTameRandomTargetGoal::canUse() {
|
||||
if (tamableMob->isTame()) return false;
|
||||
return NearestAttackableTargetGoal::canUse();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,13 +4,14 @@
|
|||
|
||||
class TamableAnimal;
|
||||
|
||||
class NonTameRandomTargetGoal : public NearestAttackableTargetGoal
|
||||
{
|
||||
class NonTameRandomTargetGoal : public NearestAttackableTargetGoal {
|
||||
private:
|
||||
TamableAnimal *tamableMob; // Owner of this goal
|
||||
TamableAnimal* tamableMob; // Owner of this goal
|
||||
|
||||
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();
|
||||
};
|
||||
|
|
@ -6,56 +6,55 @@
|
|||
#include "../../Headers/net.minecraft.world.phys.h"
|
||||
#include "OcelotAttackGoal.h"
|
||||
|
||||
OzelotAttackGoal::OzelotAttackGoal(Mob *mob)
|
||||
{
|
||||
target = std::weak_ptr<Mob>();
|
||||
attackTime = 0;
|
||||
speed = 0;
|
||||
trackTarget = false;
|
||||
OzelotAttackGoal::OzelotAttackGoal(Mob* mob) {
|
||||
target = std::weak_ptr<Mob>();
|
||||
attackTime = 0;
|
||||
speed = 0;
|
||||
trackTarget = false;
|
||||
|
||||
this->mob = mob;
|
||||
this->level = mob->level;
|
||||
setRequiredControlFlags(Control::MoveControlFlag | Control::LookControlFlag);
|
||||
this->mob = mob;
|
||||
this->level = mob->level;
|
||||
setRequiredControlFlags(Control::MoveControlFlag |
|
||||
Control::LookControlFlag);
|
||||
}
|
||||
|
||||
bool OzelotAttackGoal::canUse()
|
||||
{
|
||||
std::shared_ptr<Mob> bestTarget = mob->getTarget();
|
||||
if (bestTarget == NULL) return false;
|
||||
target = std::weak_ptr<Mob>(bestTarget);
|
||||
return true;
|
||||
bool OzelotAttackGoal::canUse() {
|
||||
std::shared_ptr<Mob> bestTarget = mob->getTarget();
|
||||
if (bestTarget == NULL) return false;
|
||||
target = std::weak_ptr<Mob>(bestTarget);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OzelotAttackGoal::canContinueToUse()
|
||||
{
|
||||
if (target.lock() == NULL || !target.lock()->isAlive()) return false;
|
||||
if (mob->distanceToSqr(target.lock()) > 15 * 15) return false;
|
||||
return !mob->getNavigation()->isDone() || canUse();
|
||||
bool OzelotAttackGoal::canContinueToUse() {
|
||||
if (target.lock() == NULL || !target.lock()->isAlive()) return false;
|
||||
if (mob->distanceToSqr(target.lock()) > 15 * 15) return false;
|
||||
return !mob->getNavigation()->isDone() || canUse();
|
||||
}
|
||||
|
||||
void OzelotAttackGoal::stop()
|
||||
{
|
||||
target = std::weak_ptr<Mob>();
|
||||
mob->getNavigation()->stop();
|
||||
void OzelotAttackGoal::stop() {
|
||||
target = std::weak_ptr<Mob>();
|
||||
mob->getNavigation()->stop();
|
||||
}
|
||||
|
||||
void OzelotAttackGoal::tick()
|
||||
{
|
||||
mob->getLookControl()->setLookAt(target.lock(), 30, 30);
|
||||
void OzelotAttackGoal::tick() {
|
||||
mob->getLookControl()->setLookAt(target.lock(), 30, 30);
|
||||
|
||||
double meleeRadiusSqr = (mob->bbWidth * 2) * (mob->bbWidth * 2);
|
||||
double distSqr = mob->distanceToSqr(target.lock()->x, target.lock()->bb->y0, target.lock()->z);
|
||||
double meleeRadiusSqr = (mob->bbWidth * 2) * (mob->bbWidth * 2);
|
||||
double distSqr = mob->distanceToSqr(target.lock()->x, target.lock()->bb->y0,
|
||||
target.lock()->z);
|
||||
|
||||
float speed = Ozelot::WALK_SPEED;
|
||||
if (distSqr > meleeRadiusSqr && distSqr < 4 * 4) speed = Ozelot::SPRINT_SPEED;
|
||||
else if (distSqr < 15 * 15) speed = Ozelot::SNEAK_SPEED;
|
||||
float speed = Ozelot::WALK_SPEED;
|
||||
if (distSqr > meleeRadiusSqr && distSqr < 4 * 4)
|
||||
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 (attackTime > 0) return;
|
||||
attackTime = 20;
|
||||
mob->doHurtTarget(target.lock());
|
||||
if (distSqr > meleeRadiusSqr) return;
|
||||
if (attackTime > 0) return;
|
||||
attackTime = 20;
|
||||
mob->doHurtTarget(target.lock());
|
||||
}
|
||||
|
|
@ -2,24 +2,24 @@
|
|||
|
||||
#include "Goal.h"
|
||||
|
||||
class OzelotAttackGoal : public Goal
|
||||
{
|
||||
class OzelotAttackGoal : public Goal {
|
||||
private:
|
||||
Level *level;
|
||||
Mob *mob;
|
||||
std::weak_ptr<Mob> target;
|
||||
int attackTime;
|
||||
float speed;
|
||||
bool trackTarget;
|
||||
Level* level;
|
||||
Mob* mob;
|
||||
std::weak_ptr<Mob> target;
|
||||
int attackTime;
|
||||
float speed;
|
||||
bool trackTarget;
|
||||
|
||||
public:
|
||||
OzelotAttackGoal(Mob *mob);
|
||||
OzelotAttackGoal(Mob* mob);
|
||||
|
||||
virtual bool canUse();
|
||||
virtual bool canContinueToUse();
|
||||
virtual void stop();
|
||||
virtual void tick();
|
||||
|
||||
// 4J Added override to update ai elements when loading entity from schematics
|
||||
virtual void setLevel(Level *level) { this->level = level; }
|
||||
virtual bool canUse();
|
||||
virtual bool canContinueToUse();
|
||||
virtual void stop();
|
||||
virtual void tick();
|
||||
|
||||
// 4J Added override to update ai elements when loading entity from
|
||||
// schematics
|
||||
virtual void setLevel(Level* level) { this->level = level; }
|
||||
};
|
||||
|
|
@ -10,118 +10,107 @@
|
|||
#include "../../Util/Arrays.h"
|
||||
#include "OcelotSitOnTileGoal.h"
|
||||
|
||||
const int OcelotSitOnTileGoal::GIVE_UP_TICKS = 3 * SharedConstants::TICKS_PER_SECOND;
|
||||
const int OcelotSitOnTileGoal::SIT_TICKS = 60 * SharedConstants::TICKS_PER_SECOND;
|
||||
const int OcelotSitOnTileGoal::GIVE_UP_TICKS =
|
||||
3 * SharedConstants::TICKS_PER_SECOND;
|
||||
const int OcelotSitOnTileGoal::SIT_TICKS =
|
||||
60 * SharedConstants::TICKS_PER_SECOND;
|
||||
const int OcelotSitOnTileGoal::SEARCH_RANGE = 8;
|
||||
const double OcelotSitOnTileGoal::SIT_CHANCE = 0.0065f;
|
||||
|
||||
OcelotSitOnTileGoal::OcelotSitOnTileGoal(Ozelot *ocelot, float speed)
|
||||
{
|
||||
_tick = 0;
|
||||
tryTicks = 0;
|
||||
maxTicks = 0;
|
||||
tileX = 0;
|
||||
tileY = 0;
|
||||
tileZ = 0;
|
||||
OcelotSitOnTileGoal::OcelotSitOnTileGoal(Ozelot* ocelot, float speed) {
|
||||
_tick = 0;
|
||||
tryTicks = 0;
|
||||
maxTicks = 0;
|
||||
tileX = 0;
|
||||
tileY = 0;
|
||||
tileZ = 0;
|
||||
|
||||
this->ocelot = ocelot;
|
||||
this->speed = speed;
|
||||
setRequiredControlFlags(Control::MoveControlFlag | Control::JumpControlFlag);
|
||||
this->ocelot = ocelot;
|
||||
this->speed = speed;
|
||||
setRequiredControlFlags(Control::MoveControlFlag |
|
||||
Control::JumpControlFlag);
|
||||
}
|
||||
|
||||
bool OcelotSitOnTileGoal::canUse()
|
||||
{
|
||||
return ocelot->isTame() && !ocelot->isSitting() && ocelot->getRandom()->nextDouble() <= SIT_CHANCE && findNearestTile();
|
||||
bool OcelotSitOnTileGoal::canUse() {
|
||||
return ocelot->isTame() && !ocelot->isSitting() &&
|
||||
ocelot->getRandom()->nextDouble() <= SIT_CHANCE && findNearestTile();
|
||||
}
|
||||
|
||||
bool OcelotSitOnTileGoal::canContinueToUse()
|
||||
{
|
||||
return _tick <= maxTicks && tryTicks <= GIVE_UP_TICKS && isValidTarget(ocelot->level, tileX, tileY, tileZ);
|
||||
bool OcelotSitOnTileGoal::canContinueToUse() {
|
||||
return _tick <= maxTicks && tryTicks <= GIVE_UP_TICKS &&
|
||||
isValidTarget(ocelot->level, tileX, tileY, tileZ);
|
||||
}
|
||||
|
||||
void OcelotSitOnTileGoal::start()
|
||||
{
|
||||
ocelot->getNavigation()->moveTo((float) tileX + 0.5, tileY + 1, (float) tileZ + 0.5, speed);
|
||||
_tick = 0;
|
||||
tryTicks = 0;
|
||||
maxTicks = ocelot->getRandom()->nextInt(ocelot->getRandom()->nextInt(SIT_TICKS) + SIT_TICKS) + SIT_TICKS;
|
||||
ocelot->getSitGoal()->wantToSit(false);
|
||||
void OcelotSitOnTileGoal::start() {
|
||||
ocelot->getNavigation()->moveTo((float)tileX + 0.5, tileY + 1,
|
||||
(float)tileZ + 0.5, speed);
|
||||
_tick = 0;
|
||||
tryTicks = 0;
|
||||
maxTicks = ocelot->getRandom()->nextInt(
|
||||
ocelot->getRandom()->nextInt(SIT_TICKS) + SIT_TICKS) +
|
||||
SIT_TICKS;
|
||||
ocelot->getSitGoal()->wantToSit(false);
|
||||
}
|
||||
|
||||
void OcelotSitOnTileGoal::stop()
|
||||
{
|
||||
ocelot->setSitting(false);
|
||||
void OcelotSitOnTileGoal::stop() { 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()
|
||||
{
|
||||
_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--;
|
||||
}
|
||||
bool OcelotSitOnTileGoal::findNearestTile() {
|
||||
int y = (int)ocelot->y;
|
||||
double distSqr = Integer::MAX_VALUE;
|
||||
|
||||
for (int x = (int)ocelot->x - SEARCH_RANGE; x < ocelot->x + SEARCH_RANGE;
|
||||
x++) {
|
||||
for (int z = (int)ocelot->z - SEARCH_RANGE;
|
||||
z < ocelot->z + SEARCH_RANGE; z++) {
|
||||
if (isValidTarget(ocelot->level, x, y, z) &&
|
||||
ocelot->level->isEmptyTile(x, y + 1, z)) {
|
||||
double dist = ocelot->distanceToSqr(x, y, z);
|
||||
|
||||
if (dist < distSqr) {
|
||||
this->tileX = x;
|
||||
this->tileY = y;
|
||||
this->tileZ = z;
|
||||
distSqr = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return distSqr < Integer::MAX_VALUE;
|
||||
}
|
||||
|
||||
bool OcelotSitOnTileGoal::findNearestTile()
|
||||
{
|
||||
int y = (int) ocelot->y;
|
||||
double distSqr = Integer::MAX_VALUE;
|
||||
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);
|
||||
|
||||
for (int x = (int) ocelot->x - SEARCH_RANGE; x < ocelot->x + SEARCH_RANGE; x++)
|
||||
{
|
||||
for (int z = (int) ocelot->z - SEARCH_RANGE; z < ocelot->z + SEARCH_RANGE; z++)
|
||||
{
|
||||
if (isValidTarget(ocelot->level, x, y, z) && ocelot->level->isEmptyTile(x, y + 1, z))
|
||||
{
|
||||
double dist = ocelot->distanceToSqr(x, y, z);
|
||||
if (tile == Tile::chest_Id) {
|
||||
std::shared_ptr<ChestTileEntity> chest =
|
||||
std::dynamic_pointer_cast<ChestTileEntity>(
|
||||
level->getTileEntity(x, y, z));
|
||||
|
||||
if (dist < distSqr)
|
||||
{
|
||||
this->tileX = x;
|
||||
this->tileY = y;
|
||||
this->tileZ = z;
|
||||
distSqr = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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 distSqr < Integer::MAX_VALUE;
|
||||
}
|
||||
|
||||
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;
|
||||
return false;
|
||||
}
|
||||
|
|
@ -4,34 +4,33 @@
|
|||
|
||||
class Ozelot;
|
||||
|
||||
class OcelotSitOnTileGoal : public Goal
|
||||
{
|
||||
class OcelotSitOnTileGoal : public Goal {
|
||||
private:
|
||||
static const int GIVE_UP_TICKS;
|
||||
static const int SIT_TICKS;
|
||||
static const int SEARCH_RANGE;
|
||||
static const double SIT_CHANCE;
|
||||
static const int GIVE_UP_TICKS;
|
||||
static const int SIT_TICKS;
|
||||
static const int SEARCH_RANGE;
|
||||
static const double SIT_CHANCE;
|
||||
|
||||
private:
|
||||
Ozelot *ocelot; // Owner of this goal
|
||||
float speed;
|
||||
int _tick;
|
||||
int tryTicks;
|
||||
int maxTicks;
|
||||
int tileX;
|
||||
int tileY;
|
||||
int tileZ;
|
||||
Ozelot* ocelot; // Owner of this goal
|
||||
float speed;
|
||||
int _tick;
|
||||
int tryTicks;
|
||||
int maxTicks;
|
||||
int tileX;
|
||||
int tileY;
|
||||
int tileZ;
|
||||
|
||||
public:
|
||||
OcelotSitOnTileGoal(Ozelot *ocelot, float speed);
|
||||
OcelotSitOnTileGoal(Ozelot* ocelot, float speed);
|
||||
|
||||
bool canUse();
|
||||
bool canContinueToUse();
|
||||
void start();
|
||||
void stop();
|
||||
void tick();
|
||||
bool canUse();
|
||||
bool canContinueToUse();
|
||||
void start();
|
||||
void stop();
|
||||
void tick();
|
||||
|
||||
private:
|
||||
bool findNearestTile();
|
||||
bool isValidTarget(Level *level, int x, int y, int z);
|
||||
bool findNearestTile();
|
||||
bool isValidTarget(Level* level, int x, int y, int z);
|
||||
};
|
||||
|
|
@ -6,39 +6,37 @@
|
|||
#include "../../Headers/net.minecraft.world.phys.h"
|
||||
#include "OfferFlowerGoal.h"
|
||||
|
||||
OfferFlowerGoal::OfferFlowerGoal(VillagerGolem *golem)
|
||||
{
|
||||
this->golem = golem;
|
||||
setRequiredControlFlags(Control::MoveControlFlag | Control::LookControlFlag);
|
||||
OfferFlowerGoal::OfferFlowerGoal(VillagerGolem* golem) {
|
||||
this->golem = golem;
|
||||
setRequiredControlFlags(Control::MoveControlFlag |
|
||||
Control::LookControlFlag);
|
||||
}
|
||||
|
||||
bool OfferFlowerGoal::canUse()
|
||||
{
|
||||
if (!golem->level->isDay()) return false;
|
||||
if (golem->getRandom()->nextInt(8000) != 0) return false;
|
||||
villager = std::weak_ptr<Villager>(std::dynamic_pointer_cast<Villager>( golem->level->getClosestEntityOfClass(typeid(Villager), golem->bb->grow(6, 2, 6), golem->shared_from_this()) ));
|
||||
return villager.lock() != NULL;
|
||||
bool OfferFlowerGoal::canUse() {
|
||||
if (!golem->level->isDay()) return false;
|
||||
if (golem->getRandom()->nextInt(8000) != 0) return false;
|
||||
villager = std::weak_ptr<Villager>(std::dynamic_pointer_cast<Villager>(
|
||||
golem->level->getClosestEntityOfClass(typeid(Villager),
|
||||
golem->bb->grow(6, 2, 6),
|
||||
golem->shared_from_this())));
|
||||
return villager.lock() != NULL;
|
||||
}
|
||||
|
||||
bool OfferFlowerGoal::canContinueToUse()
|
||||
{
|
||||
return _tick > 0 && villager.lock() != NULL;
|
||||
bool OfferFlowerGoal::canContinueToUse() {
|
||||
return _tick > 0 && villager.lock() != NULL;
|
||||
}
|
||||
|
||||
void OfferFlowerGoal::start()
|
||||
{
|
||||
_tick = OFFER_TICKS;
|
||||
golem->offerFlower(true);
|
||||
void OfferFlowerGoal::start() {
|
||||
_tick = OFFER_TICKS;
|
||||
golem->offerFlower(true);
|
||||
}
|
||||
|
||||
void OfferFlowerGoal::stop()
|
||||
{
|
||||
golem->offerFlower(false);
|
||||
villager = std::weak_ptr<Villager>();
|
||||
void OfferFlowerGoal::stop() {
|
||||
golem->offerFlower(false);
|
||||
villager = std::weak_ptr<Villager>();
|
||||
}
|
||||
|
||||
void OfferFlowerGoal::tick()
|
||||
{
|
||||
golem->getLookControl()->setLookAt(villager.lock(), 30, 30);
|
||||
--_tick;
|
||||
void OfferFlowerGoal::tick() {
|
||||
golem->getLookControl()->setLookAt(villager.lock(), 30, 30);
|
||||
--_tick;
|
||||
}
|
||||
|
|
@ -4,22 +4,21 @@
|
|||
|
||||
class VillagerGolem;
|
||||
|
||||
class OfferFlowerGoal : public Goal
|
||||
{
|
||||
class OfferFlowerGoal : public Goal {
|
||||
public:
|
||||
static const int OFFER_TICKS = 400;
|
||||
static const int OFFER_TICKS = 400;
|
||||
|
||||
private:
|
||||
VillagerGolem *golem;
|
||||
std::weak_ptr<Villager> villager;
|
||||
int _tick;
|
||||
VillagerGolem* golem;
|
||||
std::weak_ptr<Villager> villager;
|
||||
int _tick;
|
||||
|
||||
public:
|
||||
OfferFlowerGoal(VillagerGolem *golem);
|
||||
OfferFlowerGoal(VillagerGolem* golem);
|
||||
|
||||
virtual bool canUse();
|
||||
virtual bool canContinueToUse();
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual void tick();
|
||||
virtual bool canUse();
|
||||
virtual bool canContinueToUse();
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual void tick();
|
||||
};
|
||||
|
|
@ -3,33 +3,28 @@
|
|||
#include "../../Headers/net.minecraft.world.level.tile.h"
|
||||
#include "OpenDoorGoal.h"
|
||||
|
||||
OpenDoorGoal::OpenDoorGoal(Mob *mob, bool closeDoorAfter) : DoorInteractGoal(mob)
|
||||
{
|
||||
this->mob = mob;
|
||||
this->closeDoor = closeDoorAfter;
|
||||
OpenDoorGoal::OpenDoorGoal(Mob* mob, bool closeDoorAfter)
|
||||
: DoorInteractGoal(mob) {
|
||||
this->mob = mob;
|
||||
this->closeDoor = closeDoorAfter;
|
||||
}
|
||||
|
||||
bool OpenDoorGoal::canContinueToUse()
|
||||
{
|
||||
return closeDoor && forgetTime > 0 && DoorInteractGoal::canContinueToUse();
|
||||
bool OpenDoorGoal::canContinueToUse() {
|
||||
return closeDoor && forgetTime > 0 && DoorInteractGoal::canContinueToUse();
|
||||
}
|
||||
|
||||
void OpenDoorGoal::start()
|
||||
{
|
||||
forgetTime = 20;
|
||||
doorTile->setOpen(mob->level, doorX, doorY, doorZ, true);
|
||||
void OpenDoorGoal::start() {
|
||||
forgetTime = 20;
|
||||
doorTile->setOpen(mob->level, doorX, doorY, doorZ, true);
|
||||
}
|
||||
|
||||
void OpenDoorGoal::stop()
|
||||
{
|
||||
if (closeDoor)
|
||||
{
|
||||
doorTile->setOpen(mob->level, doorX, doorY, doorZ, false);
|
||||
}
|
||||
void OpenDoorGoal::stop() {
|
||||
if (closeDoor) {
|
||||
doorTile->setOpen(mob->level, doorX, doorY, doorZ, false);
|
||||
}
|
||||
}
|
||||
|
||||
void OpenDoorGoal::tick()
|
||||
{
|
||||
--forgetTime;
|
||||
DoorInteractGoal::tick();
|
||||
void OpenDoorGoal::tick() {
|
||||
--forgetTime;
|
||||
DoorInteractGoal::tick();
|
||||
}
|
||||
|
|
@ -2,17 +2,16 @@
|
|||
|
||||
#include "DoorInteractGoal.h"
|
||||
|
||||
class OpenDoorGoal : public DoorInteractGoal
|
||||
{
|
||||
class OpenDoorGoal : public DoorInteractGoal {
|
||||
private:
|
||||
bool closeDoor;
|
||||
int forgetTime;
|
||||
bool closeDoor;
|
||||
int forgetTime;
|
||||
|
||||
public:
|
||||
OpenDoorGoal(Mob *mob, bool closeDoorAfter);
|
||||
OpenDoorGoal(Mob* mob, bool closeDoorAfter);
|
||||
|
||||
virtual bool canContinueToUse();
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual void tick();
|
||||
virtual bool canContinueToUse();
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual void tick();
|
||||
};
|
||||
|
|
@ -3,23 +3,21 @@
|
|||
#include "../../Headers/net.minecraft.world.entity.animal.h"
|
||||
#include "OwnerHurtByTargetGoal.h"
|
||||
|
||||
OwnerHurtByTargetGoal::OwnerHurtByTargetGoal(TamableAnimal *tameAnimal) : TargetGoal(tameAnimal, 32, false)
|
||||
{
|
||||
this->tameAnimal = tameAnimal;
|
||||
setRequiredControlFlags(TargetGoal::TargetFlag);
|
||||
OwnerHurtByTargetGoal::OwnerHurtByTargetGoal(TamableAnimal* tameAnimal)
|
||||
: TargetGoal(tameAnimal, 32, false) {
|
||||
this->tameAnimal = tameAnimal;
|
||||
setRequiredControlFlags(TargetGoal::TargetFlag);
|
||||
}
|
||||
|
||||
bool OwnerHurtByTargetGoal::canUse()
|
||||
{
|
||||
if (!tameAnimal->isTame()) return false;
|
||||
std::shared_ptr<Mob> owner = tameAnimal->getOwner();
|
||||
if (owner == NULL) return false;
|
||||
ownerLastHurtBy = std::weak_ptr<Mob>(owner->getLastHurtByMob());
|
||||
return canAttack(ownerLastHurtBy.lock(), false);
|
||||
bool OwnerHurtByTargetGoal::canUse() {
|
||||
if (!tameAnimal->isTame()) return false;
|
||||
std::shared_ptr<Mob> owner = tameAnimal->getOwner();
|
||||
if (owner == NULL) return false;
|
||||
ownerLastHurtBy = std::weak_ptr<Mob>(owner->getLastHurtByMob());
|
||||
return canAttack(ownerLastHurtBy.lock(), false);
|
||||
}
|
||||
|
||||
void OwnerHurtByTargetGoal::start()
|
||||
{
|
||||
mob->setTarget(ownerLastHurtBy.lock());
|
||||
TargetGoal::start();
|
||||
void OwnerHurtByTargetGoal::start() {
|
||||
mob->setTarget(ownerLastHurtBy.lock());
|
||||
TargetGoal::start();
|
||||
}
|
||||
|
|
@ -4,15 +4,14 @@
|
|||
|
||||
class TamableAnimal;
|
||||
|
||||
class OwnerHurtByTargetGoal : public TargetGoal
|
||||
{
|
||||
class OwnerHurtByTargetGoal : public TargetGoal {
|
||||
private:
|
||||
TamableAnimal *tameAnimal; // Owner of this goal
|
||||
std::weak_ptr<Mob> ownerLastHurtBy;
|
||||
TamableAnimal* tameAnimal; // Owner of this goal
|
||||
std::weak_ptr<Mob> ownerLastHurtBy;
|
||||
|
||||
public:
|
||||
OwnerHurtByTargetGoal(TamableAnimal *tameAnimal);
|
||||
OwnerHurtByTargetGoal(TamableAnimal* tameAnimal);
|
||||
|
||||
bool canUse();
|
||||
void start();
|
||||
bool canUse();
|
||||
void start();
|
||||
};
|
||||
|
|
@ -3,23 +3,21 @@
|
|||
#include "../../Headers/net.minecraft.world.entity.animal.h"
|
||||
#include "OwnerHurtTargetGoal.h"
|
||||
|
||||
OwnerHurtTargetGoal::OwnerHurtTargetGoal(TamableAnimal *tameAnimal) : TargetGoal(tameAnimal, 32, false)
|
||||
{
|
||||
this->tameAnimal = tameAnimal;
|
||||
setRequiredControlFlags(TargetGoal::TargetFlag);
|
||||
OwnerHurtTargetGoal::OwnerHurtTargetGoal(TamableAnimal* tameAnimal)
|
||||
: TargetGoal(tameAnimal, 32, false) {
|
||||
this->tameAnimal = tameAnimal;
|
||||
setRequiredControlFlags(TargetGoal::TargetFlag);
|
||||
}
|
||||
|
||||
bool OwnerHurtTargetGoal::canUse()
|
||||
{
|
||||
if (!tameAnimal->isTame()) return false;
|
||||
std::shared_ptr<Mob> owner = tameAnimal->getOwner();
|
||||
if (owner == NULL) return false;
|
||||
ownerLastHurt = std::weak_ptr<Mob>(owner->getLastHurtMob());
|
||||
return canAttack(ownerLastHurt.lock(), false);
|
||||
bool OwnerHurtTargetGoal::canUse() {
|
||||
if (!tameAnimal->isTame()) return false;
|
||||
std::shared_ptr<Mob> owner = tameAnimal->getOwner();
|
||||
if (owner == NULL) return false;
|
||||
ownerLastHurt = std::weak_ptr<Mob>(owner->getLastHurtMob());
|
||||
return canAttack(ownerLastHurt.lock(), false);
|
||||
}
|
||||
|
||||
void OwnerHurtTargetGoal::start()
|
||||
{
|
||||
mob->setTarget(ownerLastHurt.lock());
|
||||
TargetGoal::start();
|
||||
void OwnerHurtTargetGoal::start() {
|
||||
mob->setTarget(ownerLastHurt.lock());
|
||||
TargetGoal::start();
|
||||
}
|
||||
|
|
@ -4,15 +4,14 @@
|
|||
|
||||
class TamableAnimal;
|
||||
|
||||
class OwnerHurtTargetGoal : public TargetGoal
|
||||
{
|
||||
class OwnerHurtTargetGoal : public TargetGoal {
|
||||
private:
|
||||
TamableAnimal *tameAnimal; // Owner of this goal
|
||||
std::weak_ptr<Mob> ownerLastHurt;
|
||||
TamableAnimal* tameAnimal; // Owner of this goal
|
||||
std::weak_ptr<Mob> ownerLastHurt;
|
||||
|
||||
public:
|
||||
OwnerHurtTargetGoal(TamableAnimal *tameAnimal);
|
||||
OwnerHurtTargetGoal(TamableAnimal* tameAnimal);
|
||||
|
||||
bool canUse();
|
||||
void start();
|
||||
bool canUse();
|
||||
void start();
|
||||
};
|
||||
|
|
@ -6,30 +6,26 @@
|
|||
#include "../../Headers/net.minecraft.world.phys.h"
|
||||
#include "PanicGoal.h"
|
||||
|
||||
PanicGoal::PanicGoal(PathfinderMob *mob, float speed)
|
||||
{
|
||||
this->mob = mob;
|
||||
this->speed = speed;
|
||||
setRequiredControlFlags(Control::MoveControlFlag);
|
||||
PanicGoal::PanicGoal(PathfinderMob* mob, float speed) {
|
||||
this->mob = mob;
|
||||
this->speed = speed;
|
||||
setRequiredControlFlags(Control::MoveControlFlag);
|
||||
}
|
||||
|
||||
bool PanicGoal::canUse()
|
||||
{
|
||||
if (mob->getLastHurtByMob() == NULL) return false;
|
||||
Vec3 *pos = RandomPos::getPos(std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()), 5, 4);
|
||||
if (pos == NULL) return false;
|
||||
posX = pos->x;
|
||||
posY = pos->y;
|
||||
posZ = pos->z;
|
||||
return true;
|
||||
bool PanicGoal::canUse() {
|
||||
if (mob->getLastHurtByMob() == NULL) return false;
|
||||
Vec3* pos = RandomPos::getPos(
|
||||
std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()), 5,
|
||||
4);
|
||||
if (pos == NULL) return false;
|
||||
posX = pos->x;
|
||||
posY = pos->y;
|
||||
posZ = pos->z;
|
||||
return true;
|
||||
}
|
||||
|
||||
void PanicGoal::start()
|
||||
{
|
||||
mob->getNavigation()->moveTo(posX, posY, posZ, speed);
|
||||
void PanicGoal::start() {
|
||||
mob->getNavigation()->moveTo(posX, posY, posZ, speed);
|
||||
}
|
||||
|
||||
bool PanicGoal::canContinueToUse()
|
||||
{
|
||||
return !mob->getNavigation()->isDone();
|
||||
}
|
||||
bool PanicGoal::canContinueToUse() { return !mob->getNavigation()->isDone(); }
|
||||
|
|
@ -4,17 +4,16 @@
|
|||
|
||||
class PathfinderMob;
|
||||
|
||||
class PanicGoal : public Goal
|
||||
{
|
||||
class PanicGoal : public Goal {
|
||||
private:
|
||||
PathfinderMob *mob;
|
||||
float speed;
|
||||
double posX, posY, posZ;
|
||||
PathfinderMob* mob;
|
||||
float speed;
|
||||
double posX, posY, posZ;
|
||||
|
||||
public:
|
||||
PanicGoal(PathfinderMob *mob, float speed);
|
||||
PanicGoal(PathfinderMob* mob, float speed);
|
||||
|
||||
virtual bool canUse();
|
||||
virtual void start();
|
||||
virtual bool canContinueToUse();
|
||||
virtual bool canUse();
|
||||
virtual void start();
|
||||
virtual bool canContinueToUse();
|
||||
};
|
||||
|
|
@ -9,78 +9,75 @@
|
|||
#include "../../Util/BasicTypeContainers.h"
|
||||
#include "PlayGoal.h"
|
||||
|
||||
PlayGoal::PlayGoal(Villager *mob, float speed)
|
||||
{
|
||||
followFriend = std::weak_ptr<Mob>();
|
||||
wantedX = wantedY = wantedZ = 0.0;
|
||||
playTime = 0;
|
||||
PlayGoal::PlayGoal(Villager* mob, float speed) {
|
||||
followFriend = std::weak_ptr<Mob>();
|
||||
wantedX = wantedY = wantedZ = 0.0;
|
||||
playTime = 0;
|
||||
|
||||
this->mob = mob;
|
||||
this->speed = speed;
|
||||
setRequiredControlFlags(Control::MoveControlFlag);
|
||||
this->mob = mob;
|
||||
this->speed = speed;
|
||||
setRequiredControlFlags(Control::MoveControlFlag);
|
||||
}
|
||||
|
||||
bool PlayGoal::canUse()
|
||||
{
|
||||
if (mob->getAge() >= 0) return false;
|
||||
if (mob->getRandom()->nextInt(400) != 0) return false;
|
||||
bool PlayGoal::canUse() {
|
||||
if (mob->getAge() >= 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));
|
||||
double closestDistSqr = Double::MAX_VALUE;
|
||||
//for (Entity c : children)
|
||||
for(AUTO_VAR(it, children->begin()); it != children->end(); ++it)
|
||||
{
|
||||
std::shared_ptr<Entity> c = *it;
|
||||
if (c.get() == mob) continue;
|
||||
std::shared_ptr<Villager> friendV = std::dynamic_pointer_cast<Villager>(c);
|
||||
if (friendV->isChasing()) continue;
|
||||
if (friendV->getAge() >= 0) continue;
|
||||
double distSqr = friendV->distanceToSqr(mob->shared_from_this());
|
||||
if (distSqr > closestDistSqr) continue;
|
||||
closestDistSqr = distSqr;
|
||||
followFriend = std::weak_ptr<Mob>(friendV);
|
||||
}
|
||||
delete children;
|
||||
std::vector<std::shared_ptr<Entity> >* children =
|
||||
mob->level->getEntitiesOfClass(typeid(Villager),
|
||||
mob->bb->grow(6, 3, 6));
|
||||
double closestDistSqr = Double::MAX_VALUE;
|
||||
// for (Entity c : children)
|
||||
for (AUTO_VAR(it, children->begin()); it != children->end(); ++it) {
|
||||
std::shared_ptr<Entity> c = *it;
|
||||
if (c.get() == mob) continue;
|
||||
std::shared_ptr<Villager> friendV =
|
||||
std::dynamic_pointer_cast<Villager>(c);
|
||||
if (friendV->isChasing()) continue;
|
||||
if (friendV->getAge() >= 0) continue;
|
||||
double distSqr = friendV->distanceToSqr(mob->shared_from_this());
|
||||
if (distSqr > closestDistSqr) continue;
|
||||
closestDistSqr = distSqr;
|
||||
followFriend = std::weak_ptr<Mob>(friendV);
|
||||
}
|
||||
delete children;
|
||||
|
||||
if (followFriend.lock() == NULL)
|
||||
{
|
||||
Vec3 *pos = RandomPos::getPos(std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()), 16, 3);
|
||||
if (pos == NULL) return false;
|
||||
}
|
||||
return true;
|
||||
if (followFriend.lock() == NULL) {
|
||||
Vec3* pos = RandomPos::getPos(
|
||||
std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()),
|
||||
16, 3);
|
||||
if (pos == NULL) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PlayGoal::canContinueToUse()
|
||||
{
|
||||
return playTime > 0 && followFriend.lock() != NULL;
|
||||
bool PlayGoal::canContinueToUse() {
|
||||
return playTime > 0 && followFriend.lock() != NULL;
|
||||
}
|
||||
|
||||
void PlayGoal::start()
|
||||
{
|
||||
if (followFriend.lock() != NULL) mob->setChasing(true);
|
||||
playTime = 1000;
|
||||
void PlayGoal::start() {
|
||||
if (followFriend.lock() != NULL) mob->setChasing(true);
|
||||
playTime = 1000;
|
||||
}
|
||||
|
||||
void PlayGoal::stop()
|
||||
{
|
||||
mob->setChasing(false);
|
||||
followFriend = std::weak_ptr<Mob>();
|
||||
void PlayGoal::stop() {
|
||||
mob->setChasing(false);
|
||||
followFriend = std::weak_ptr<Mob>();
|
||||
}
|
||||
|
||||
void PlayGoal::tick()
|
||||
{
|
||||
--playTime;
|
||||
if (followFriend.lock() != NULL)
|
||||
{
|
||||
if (mob->distanceToSqr(followFriend.lock()) > 2 * 2) mob->getNavigation()->moveTo(followFriend.lock(), speed);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mob->getNavigation()->isDone())
|
||||
{
|
||||
Vec3 *pos = RandomPos::getPos(std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()), 16, 3);
|
||||
if (pos == NULL) return;
|
||||
mob->getNavigation()->moveTo(pos->x, pos->y, pos->z, speed);
|
||||
}
|
||||
}
|
||||
void PlayGoal::tick() {
|
||||
--playTime;
|
||||
if (followFriend.lock() != NULL) {
|
||||
if (mob->distanceToSqr(followFriend.lock()) > 2 * 2)
|
||||
mob->getNavigation()->moveTo(followFriend.lock(), speed);
|
||||
} else {
|
||||
if (mob->getNavigation()->isDone()) {
|
||||
Vec3* pos =
|
||||
RandomPos::getPos(std::dynamic_pointer_cast<PathfinderMob>(
|
||||
mob->shared_from_this()),
|
||||
16, 3);
|
||||
if (pos == NULL) return;
|
||||
mob->getNavigation()->moveTo(pos->x, pos->y, pos->z, speed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,21 +2,20 @@
|
|||
|
||||
#include "Goal.h"
|
||||
|
||||
class PlayGoal : public Goal
|
||||
{
|
||||
class PlayGoal : public Goal {
|
||||
private:
|
||||
Villager *mob;
|
||||
std::weak_ptr<Mob> followFriend;
|
||||
float speed;
|
||||
double wantedX, wantedY, wantedZ;
|
||||
int playTime;
|
||||
Villager* mob;
|
||||
std::weak_ptr<Mob> followFriend;
|
||||
float speed;
|
||||
double wantedX, wantedY, wantedZ;
|
||||
int playTime;
|
||||
|
||||
public:
|
||||
PlayGoal(Villager *mob, float speed);
|
||||
PlayGoal(Villager* mob, float speed);
|
||||
|
||||
virtual bool canUse();
|
||||
virtual bool canContinueToUse();
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual void tick();
|
||||
virtual bool canUse();
|
||||
virtual bool canContinueToUse();
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual void tick();
|
||||
};
|
||||
|
|
@ -3,35 +3,31 @@
|
|||
#include "../../Headers/net.minecraft.world.entity.ai.control.h"
|
||||
#include "RandomLookAroundGoal.h"
|
||||
|
||||
RandomLookAroundGoal::RandomLookAroundGoal(Mob *mob)
|
||||
{
|
||||
relX = relZ = 0.0;
|
||||
lookTime = 0;
|
||||
RandomLookAroundGoal::RandomLookAroundGoal(Mob* mob) {
|
||||
relX = relZ = 0.0;
|
||||
lookTime = 0;
|
||||
|
||||
this->mob = mob;
|
||||
setRequiredControlFlags(Control::MoveControlFlag | Control::LookControlFlag);
|
||||
this->mob = mob;
|
||||
setRequiredControlFlags(Control::MoveControlFlag |
|
||||
Control::LookControlFlag);
|
||||
}
|
||||
|
||||
bool RandomLookAroundGoal::canUse()
|
||||
{
|
||||
return mob->getRandom()->nextFloat() < 0.02f;
|
||||
bool RandomLookAroundGoal::canUse() {
|
||||
return mob->getRandom()->nextFloat() < 0.02f;
|
||||
}
|
||||
|
||||
bool RandomLookAroundGoal::canContinueToUse()
|
||||
{
|
||||
return lookTime >= 0;
|
||||
bool RandomLookAroundGoal::canContinueToUse() { 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()
|
||||
{
|
||||
double rnd = 2 * PI * mob->getRandom()->nextDouble();
|
||||
relX = cos(rnd);
|
||||
relZ = sin(rnd);
|
||||
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());
|
||||
void RandomLookAroundGoal::tick() {
|
||||
--lookTime;
|
||||
mob->getLookControl()->setLookAt(mob->x + relX,
|
||||
mob->y + mob->getHeadHeight(),
|
||||
mob->z + relZ, 10, mob->getMaxHeadXRot());
|
||||
}
|
||||
|
|
@ -2,18 +2,17 @@
|
|||
|
||||
#include "Goal.h"
|
||||
|
||||
class RandomLookAroundGoal : public Goal
|
||||
{
|
||||
class RandomLookAroundGoal : public Goal {
|
||||
private:
|
||||
Mob *mob;
|
||||
double relX, relZ;
|
||||
int lookTime;
|
||||
Mob* mob;
|
||||
double relX, relZ;
|
||||
int lookTime;
|
||||
|
||||
public:
|
||||
RandomLookAroundGoal(Mob *mob);
|
||||
RandomLookAroundGoal(Mob* mob);
|
||||
|
||||
virtual bool canUse();
|
||||
virtual bool canContinueToUse();
|
||||
virtual void start();
|
||||
virtual void tick();
|
||||
virtual bool canUse();
|
||||
virtual bool canContinueToUse();
|
||||
virtual void start();
|
||||
virtual void tick();
|
||||
};
|
||||
|
|
@ -7,54 +7,55 @@
|
|||
#include "../../Util/SharedConstants.h"
|
||||
#include "RandomStrollGoal.h"
|
||||
|
||||
RandomStrollGoal::RandomStrollGoal(PathfinderMob *mob, float speed)
|
||||
{
|
||||
this->mob = mob;
|
||||
this->speed = speed;
|
||||
setRequiredControlFlags(Control::MoveControlFlag | Control::LookControlFlag);
|
||||
RandomStrollGoal::RandomStrollGoal(PathfinderMob* mob, float speed) {
|
||||
this->mob = mob;
|
||||
this->speed = speed;
|
||||
setRequiredControlFlags(Control::MoveControlFlag |
|
||||
Control::LookControlFlag);
|
||||
}
|
||||
|
||||
bool RandomStrollGoal::canUse()
|
||||
{
|
||||
// 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
|
||||
if (mob->getNoActionTime() < SharedConstants::TICKS_PER_SECOND * 5)
|
||||
{
|
||||
if (mob->getRandom()->nextInt(120) == 0)
|
||||
{
|
||||
Vec3 *pos = RandomPos::getPos(std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()), 10, 7);
|
||||
if (pos == NULL) return false;
|
||||
wantedX = pos->x;
|
||||
wantedY = pos->y;
|
||||
wantedZ = pos->z;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// This entity wouldn't normally be randomly strolling. However, if our management system says that it should do, then do. Don't
|
||||
// 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
|
||||
// stroll out of a given area and so waiting around is just wasting time
|
||||
bool RandomStrollGoal::canUse() {
|
||||
// 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
|
||||
if (mob->getNoActionTime() < SharedConstants::TICKS_PER_SECOND * 5) {
|
||||
if (mob->getRandom()->nextInt(120) == 0) {
|
||||
Vec3* pos =
|
||||
RandomPos::getPos(std::dynamic_pointer_cast<PathfinderMob>(
|
||||
mob->shared_from_this()),
|
||||
10, 7);
|
||||
if (pos == NULL) return false;
|
||||
wantedX = pos->x;
|
||||
wantedY = pos->y;
|
||||
wantedZ = pos->z;
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
// This entity wouldn't normally be randomly strolling. However, if our
|
||||
// management system says that it should do, then do. Don't 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 stroll out of
|
||||
// a given area and so waiting around is just wasting time
|
||||
|
||||
if( mob->isExtraWanderingEnabled() )
|
||||
{
|
||||
Vec3 *pos = RandomPos::getPos(std::dynamic_pointer_cast<PathfinderMob>(mob->shared_from_this()), 10, 7,mob->getWanderingQuadrant());
|
||||
if (pos == NULL) return false;
|
||||
wantedX = pos->x;
|
||||
wantedY = pos->y;
|
||||
wantedZ = pos->z;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
if (mob->isExtraWanderingEnabled()) {
|
||||
Vec3* pos =
|
||||
RandomPos::getPos(std::dynamic_pointer_cast<PathfinderMob>(
|
||||
mob->shared_from_this()),
|
||||
10, 7, mob->getWanderingQuadrant());
|
||||
if (pos == NULL) return false;
|
||||
wantedX = pos->x;
|
||||
wantedY = pos->y;
|
||||
wantedZ = pos->z;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RandomStrollGoal::canContinueToUse()
|
||||
{
|
||||
return !mob->getNavigation()->isDone();
|
||||
bool RandomStrollGoal::canContinueToUse() {
|
||||
return !mob->getNavigation()->isDone();
|
||||
}
|
||||
|
||||
void RandomStrollGoal::start()
|
||||
{
|
||||
mob->getNavigation()->moveTo(wantedX, wantedY, wantedZ, speed);
|
||||
void RandomStrollGoal::start() {
|
||||
mob->getNavigation()->moveTo(wantedX, wantedY, wantedZ, speed);
|
||||
}
|
||||
|
|
@ -4,17 +4,16 @@
|
|||
|
||||
class PathfinderMob;
|
||||
|
||||
class RandomStrollGoal : public Goal
|
||||
{
|
||||
class RandomStrollGoal : public Goal {
|
||||
private:
|
||||
PathfinderMob *mob;
|
||||
double wantedX, wantedY, wantedZ;
|
||||
float speed;
|
||||
PathfinderMob* mob;
|
||||
double wantedX, wantedY, wantedZ;
|
||||
float speed;
|
||||
|
||||
public:
|
||||
RandomStrollGoal(PathfinderMob *mob, float speed);
|
||||
RandomStrollGoal(PathfinderMob* mob, float speed);
|
||||
|
||||
virtual bool canUse();
|
||||
virtual bool canContinueToUse();
|
||||
virtual void start();
|
||||
virtual bool canUse();
|
||||
virtual bool canContinueToUse();
|
||||
virtual void start();
|
||||
};
|
||||
|
|
@ -5,45 +5,44 @@
|
|||
#include "../../Headers/net.minecraft.world.level.h"
|
||||
#include "RestrictOpenDoorGoal.h"
|
||||
|
||||
RestrictOpenDoorGoal::RestrictOpenDoorGoal(PathfinderMob *mob)
|
||||
{
|
||||
this->mob = mob;
|
||||
RestrictOpenDoorGoal::RestrictOpenDoorGoal(PathfinderMob* mob) {
|
||||
this->mob = mob;
|
||||
}
|
||||
|
||||
bool RestrictOpenDoorGoal::canUse()
|
||||
{
|
||||
if (mob->level->isDay()) return false;
|
||||
std::shared_ptr<Village> village = mob->level->villages->getClosestVillage(Mth::floor(mob->x), Mth::floor(mob->y), Mth::floor(mob->z), 16);
|
||||
if (village == NULL) return false;
|
||||
std::shared_ptr<DoorInfo> _doorInfo = village->getClosestDoorInfo(Mth::floor(mob->x), Mth::floor(mob->y), Mth::floor(mob->z));
|
||||
if (_doorInfo == NULL) return false;
|
||||
doorInfo = _doorInfo;
|
||||
return _doorInfo->distanceToInsideSqr(Mth::floor(mob->x), Mth::floor(mob->y), Mth::floor(mob->z)) < 1.5 * 1.5;
|
||||
bool RestrictOpenDoorGoal::canUse() {
|
||||
if (mob->level->isDay()) return false;
|
||||
std::shared_ptr<Village> village = mob->level->villages->getClosestVillage(
|
||||
Mth::floor(mob->x), Mth::floor(mob->y), Mth::floor(mob->z), 16);
|
||||
if (village == NULL) return false;
|
||||
std::shared_ptr<DoorInfo> _doorInfo = village->getClosestDoorInfo(
|
||||
Mth::floor(mob->x), Mth::floor(mob->y), Mth::floor(mob->z));
|
||||
if (_doorInfo == NULL) return false;
|
||||
doorInfo = _doorInfo;
|
||||
return _doorInfo->distanceToInsideSqr(Mth::floor(mob->x),
|
||||
Mth::floor(mob->y),
|
||||
Mth::floor(mob->z)) < 1.5 * 1.5;
|
||||
}
|
||||
|
||||
bool RestrictOpenDoorGoal::canContinueToUse()
|
||||
{
|
||||
if (mob->level->isDay()) return false;
|
||||
std::shared_ptr<DoorInfo> _doorInfo = doorInfo.lock();
|
||||
if ( _doorInfo == NULL ) return false;
|
||||
return !_doorInfo->removed && _doorInfo->isInsideSide(Mth::floor(mob->x), Mth::floor(mob->z));
|
||||
bool RestrictOpenDoorGoal::canContinueToUse() {
|
||||
if (mob->level->isDay()) return false;
|
||||
std::shared_ptr<DoorInfo> _doorInfo = doorInfo.lock();
|
||||
if (_doorInfo == NULL) return false;
|
||||
return !_doorInfo->removed &&
|
||||
_doorInfo->isInsideSide(Mth::floor(mob->x), Mth::floor(mob->z));
|
||||
}
|
||||
|
||||
void RestrictOpenDoorGoal::start()
|
||||
{
|
||||
mob->getNavigation()->setCanOpenDoors(false);
|
||||
mob->getNavigation()->setCanPassDoors(false);
|
||||
void RestrictOpenDoorGoal::start() {
|
||||
mob->getNavigation()->setCanOpenDoors(false);
|
||||
mob->getNavigation()->setCanPassDoors(false);
|
||||
}
|
||||
|
||||
void RestrictOpenDoorGoal::stop()
|
||||
{
|
||||
mob->getNavigation()->setCanOpenDoors(true);
|
||||
mob->getNavigation()->setCanPassDoors(true);
|
||||
doorInfo = std::weak_ptr<DoorInfo>();
|
||||
void RestrictOpenDoorGoal::stop() {
|
||||
mob->getNavigation()->setCanOpenDoors(true);
|
||||
mob->getNavigation()->setCanPassDoors(true);
|
||||
doorInfo = std::weak_ptr<DoorInfo>();
|
||||
}
|
||||
|
||||
void RestrictOpenDoorGoal::tick()
|
||||
{
|
||||
std::shared_ptr<DoorInfo> _doorInfo = doorInfo.lock();
|
||||
if ( _doorInfo ) _doorInfo->incBookingCount();
|
||||
void RestrictOpenDoorGoal::tick() {
|
||||
std::shared_ptr<DoorInfo> _doorInfo = doorInfo.lock();
|
||||
if (_doorInfo) _doorInfo->incBookingCount();
|
||||
}
|
||||
|
|
@ -5,18 +5,17 @@
|
|||
class PathfinderMob;
|
||||
class DoorInfo;
|
||||
|
||||
class RestrictOpenDoorGoal : public Goal
|
||||
{
|
||||
class RestrictOpenDoorGoal : public Goal {
|
||||
private:
|
||||
PathfinderMob *mob;
|
||||
std::weak_ptr<DoorInfo> doorInfo;
|
||||
PathfinderMob* mob;
|
||||
std::weak_ptr<DoorInfo> doorInfo;
|
||||
|
||||
public:
|
||||
RestrictOpenDoorGoal(PathfinderMob *mob);
|
||||
RestrictOpenDoorGoal(PathfinderMob* mob);
|
||||
|
||||
virtual bool canUse();
|
||||
virtual bool canContinueToUse();
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual void tick();
|
||||
virtual bool canUse();
|
||||
virtual bool canContinueToUse();
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual void tick();
|
||||
};
|
||||
|
|
@ -4,22 +4,10 @@
|
|||
#include "../../Headers/net.minecraft.world.level.h"
|
||||
#include "RestrictSunGoal.h"
|
||||
|
||||
RestrictSunGoal::RestrictSunGoal(PathfinderMob *mob)
|
||||
{
|
||||
this->mob = mob;
|
||||
}
|
||||
RestrictSunGoal::RestrictSunGoal(PathfinderMob* mob) { this->mob = mob; }
|
||||
|
||||
bool RestrictSunGoal::canUse()
|
||||
{
|
||||
return mob->level->isDay();
|
||||
}
|
||||
bool RestrictSunGoal::canUse() { return mob->level->isDay(); }
|
||||
|
||||
void RestrictSunGoal::start()
|
||||
{
|
||||
mob->getNavigation()->setAvoidSun(true);
|
||||
}
|
||||
void RestrictSunGoal::start() { mob->getNavigation()->setAvoidSun(true); }
|
||||
|
||||
void RestrictSunGoal::stop()
|
||||
{
|
||||
mob->getNavigation()->setAvoidSun(false);
|
||||
}
|
||||
void RestrictSunGoal::stop() { mob->getNavigation()->setAvoidSun(false); }
|
||||
|
|
@ -2,15 +2,14 @@
|
|||
|
||||
#include "Goal.h"
|
||||
|
||||
class RestrictSunGoal : public Goal
|
||||
{
|
||||
class RestrictSunGoal : public Goal {
|
||||
private:
|
||||
PathfinderMob *mob;
|
||||
PathfinderMob* mob;
|
||||
|
||||
public:
|
||||
RestrictSunGoal(PathfinderMob *mob);
|
||||
RestrictSunGoal(PathfinderMob* mob);
|
||||
|
||||
bool canUse();
|
||||
void start();
|
||||
void stop();
|
||||
bool canUse();
|
||||
void start();
|
||||
void stop();
|
||||
};
|
||||
|
|
@ -6,40 +6,35 @@
|
|||
#include "../../Headers/net.minecraft.world.entity.animal.h"
|
||||
#include "SitGoal.h"
|
||||
|
||||
SitGoal::SitGoal(TamableAnimal *mob)
|
||||
{
|
||||
_wantToSit = false;
|
||||
SitGoal::SitGoal(TamableAnimal* mob) {
|
||||
_wantToSit = false;
|
||||
|
||||
this->mob = mob;
|
||||
setRequiredControlFlags(Control::JumpControlFlag | Control::MoveControlFlag);
|
||||
this->mob = mob;
|
||||
setRequiredControlFlags(Control::JumpControlFlag |
|
||||
Control::MoveControlFlag);
|
||||
}
|
||||
|
||||
bool SitGoal::canUse()
|
||||
{
|
||||
if (!mob->isTame()) return false;
|
||||
if (mob->isInWater()) return false;
|
||||
if (!mob->onGround) return false;
|
||||
bool SitGoal::canUse() {
|
||||
if (!mob->isTame()) return false;
|
||||
if (mob->isInWater()) return false;
|
||||
if (!mob->onGround) return false;
|
||||
|
||||
std::shared_ptr<Mob> owner = mob->getOwner();
|
||||
if (owner == NULL) return true; // owner not on level
|
||||
std::shared_ptr<Mob> owner = mob->getOwner();
|
||||
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()
|
||||
{
|
||||
mob->getNavigation()->stop();
|
||||
mob->setSitting(true);
|
||||
void SitGoal::start() {
|
||||
mob->getNavigation()->stop();
|
||||
mob->setSitting(true);
|
||||
}
|
||||
|
||||
void SitGoal::stop()
|
||||
{
|
||||
mob->setSitting(false);
|
||||
}
|
||||
void SitGoal::stop() { mob->setSitting(false); }
|
||||
|
||||
void SitGoal::wantToSit(bool _wantToSit)
|
||||
{
|
||||
this->_wantToSit = _wantToSit;
|
||||
}
|
||||
void SitGoal::wantToSit(bool _wantToSit) { this->_wantToSit = _wantToSit; }
|
||||
|
|
@ -2,17 +2,16 @@
|
|||
|
||||
#include "Goal.h"
|
||||
|
||||
class SitGoal : public Goal
|
||||
{
|
||||
class SitGoal : public Goal {
|
||||
private:
|
||||
TamableAnimal *mob;
|
||||
bool _wantToSit;
|
||||
TamableAnimal* mob;
|
||||
bool _wantToSit;
|
||||
|
||||
public:
|
||||
SitGoal(TamableAnimal *mob);
|
||||
SitGoal(TamableAnimal* mob);
|
||||
|
||||
bool canUse();
|
||||
void start();
|
||||
void stop();
|
||||
void wantToSit(bool _wantToSit);
|
||||
bool canUse();
|
||||
void start();
|
||||
void stop();
|
||||
void wantToSit(bool _wantToSit);
|
||||
};
|
||||
|
|
@ -5,50 +5,41 @@
|
|||
#include "../../Headers/net.minecraft.world.entity.monster.h"
|
||||
#include "SwellGoal.h"
|
||||
|
||||
SwellGoal::SwellGoal(Creeper *creeper)
|
||||
{
|
||||
target = std::weak_ptr<Mob>();
|
||||
SwellGoal::SwellGoal(Creeper* creeper) {
|
||||
target = std::weak_ptr<Mob>();
|
||||
|
||||
this->creeper = creeper;
|
||||
setRequiredControlFlags(Control::MoveControlFlag);
|
||||
this->creeper = creeper;
|
||||
setRequiredControlFlags(Control::MoveControlFlag);
|
||||
}
|
||||
|
||||
bool SwellGoal::canUse()
|
||||
{
|
||||
std::shared_ptr<Mob> target = creeper->getTarget();
|
||||
return creeper->getSwellDir() > 0 || (target != NULL && (creeper->distanceToSqr(target) < 3 * 3));
|
||||
bool SwellGoal::canUse() {
|
||||
std::shared_ptr<Mob> target = creeper->getTarget();
|
||||
return creeper->getSwellDir() > 0 ||
|
||||
(target != NULL && (creeper->distanceToSqr(target) < 3 * 3));
|
||||
}
|
||||
|
||||
void SwellGoal::start()
|
||||
{
|
||||
creeper->getNavigation()->stop();
|
||||
target = std::weak_ptr<Mob>(creeper->getTarget());
|
||||
void SwellGoal::start() {
|
||||
creeper->getNavigation()->stop();
|
||||
target = std::weak_ptr<Mob>(creeper->getTarget());
|
||||
}
|
||||
|
||||
void SwellGoal::stop()
|
||||
{
|
||||
target = std::weak_ptr<Mob>();
|
||||
}
|
||||
|
||||
void SwellGoal::tick()
|
||||
{
|
||||
if (target.lock() == NULL)
|
||||
{
|
||||
creeper->setSwellDir(-1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (creeper->distanceToSqr(target.lock()) > 7 * 7)
|
||||
{
|
||||
creeper->setSwellDir(-1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!creeper->getSensing()->canSee(target.lock()))
|
||||
{
|
||||
creeper->setSwellDir(-1);
|
||||
return;
|
||||
}
|
||||
|
||||
creeper->setSwellDir(1);
|
||||
void SwellGoal::stop() { target = std::weak_ptr<Mob>(); }
|
||||
|
||||
void SwellGoal::tick() {
|
||||
if (target.lock() == NULL) {
|
||||
creeper->setSwellDir(-1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (creeper->distanceToSqr(target.lock()) > 7 * 7) {
|
||||
creeper->setSwellDir(-1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!creeper->getSensing()->canSee(target.lock())) {
|
||||
creeper->setSwellDir(-1);
|
||||
return;
|
||||
}
|
||||
|
||||
creeper->setSwellDir(1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,17 +4,16 @@
|
|||
|
||||
class Creeper;
|
||||
|
||||
class SwellGoal : public Goal
|
||||
{
|
||||
class SwellGoal : public Goal {
|
||||
private:
|
||||
Creeper *creeper;
|
||||
std::weak_ptr<Mob> target;
|
||||
Creeper* creeper;
|
||||
std::weak_ptr<Mob> target;
|
||||
|
||||
public:
|
||||
SwellGoal(Creeper *creeper);
|
||||
SwellGoal(Creeper* creeper);
|
||||
|
||||
bool canUse();
|
||||
void start();
|
||||
void stop();
|
||||
void tick();
|
||||
bool canUse();
|
||||
void start();
|
||||
void stop();
|
||||
void tick();
|
||||
};
|
||||
|
|
@ -8,75 +8,68 @@
|
|||
#include "../../Headers/net.minecraft.world.phys.h"
|
||||
#include "TakeFlowerGoal.h"
|
||||
|
||||
TakeFlowerGoal::TakeFlowerGoal(Villager *villager)
|
||||
{
|
||||
takeFlower = false;
|
||||
pickupTick = 0;
|
||||
golem = std::weak_ptr<VillagerGolem>();
|
||||
TakeFlowerGoal::TakeFlowerGoal(Villager* villager) {
|
||||
takeFlower = false;
|
||||
pickupTick = 0;
|
||||
golem = std::weak_ptr<VillagerGolem>();
|
||||
|
||||
this->villager = villager;
|
||||
setRequiredControlFlags(Control::MoveControlFlag | Control::LookControlFlag);
|
||||
this->villager = villager;
|
||||
setRequiredControlFlags(Control::MoveControlFlag |
|
||||
Control::LookControlFlag);
|
||||
}
|
||||
|
||||
bool TakeFlowerGoal::canUse()
|
||||
{
|
||||
if (villager->getAge() >= 0) return false;
|
||||
if (!villager->level->isDay()) return false;
|
||||
bool TakeFlowerGoal::canUse() {
|
||||
if (villager->getAge() >= 0) 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));
|
||||
if (golems->size() == 0)
|
||||
{
|
||||
delete golems;
|
||||
return false;
|
||||
}
|
||||
std::vector<std::shared_ptr<Entity> >* golems =
|
||||
villager->level->getEntitiesOfClass(typeid(VillagerGolem),
|
||||
villager->bb->grow(6, 2, 6));
|
||||
if (golems->size() == 0) {
|
||||
delete golems;
|
||||
return false;
|
||||
}
|
||||
|
||||
//for (Entity e : golems)
|
||||
for(AUTO_VAR(it,golems->begin()); it != golems->end(); ++it)
|
||||
{
|
||||
std::shared_ptr<VillagerGolem> vg = std::dynamic_pointer_cast<VillagerGolem>(*it);
|
||||
if (vg->getOfferFlowerTick() > 0)
|
||||
{
|
||||
golem = std::weak_ptr<VillagerGolem>(vg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
delete golems;
|
||||
return golem.lock() != NULL;
|
||||
// for (Entity e : golems)
|
||||
for (AUTO_VAR(it, golems->begin()); it != golems->end(); ++it) {
|
||||
std::shared_ptr<VillagerGolem> vg =
|
||||
std::dynamic_pointer_cast<VillagerGolem>(*it);
|
||||
if (vg->getOfferFlowerTick() > 0) {
|
||||
golem = std::weak_ptr<VillagerGolem>(vg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
delete golems;
|
||||
return golem.lock() != NULL;
|
||||
}
|
||||
|
||||
bool TakeFlowerGoal::canContinueToUse()
|
||||
{
|
||||
return golem.lock() != NULL && golem.lock()->getOfferFlowerTick() > 0;
|
||||
bool TakeFlowerGoal::canContinueToUse() {
|
||||
return golem.lock() != NULL && golem.lock()->getOfferFlowerTick() > 0;
|
||||
}
|
||||
|
||||
void TakeFlowerGoal::start()
|
||||
{
|
||||
pickupTick = villager->getRandom()->nextInt((int) (OfferFlowerGoal::OFFER_TICKS * 0.8));
|
||||
takeFlower = false;
|
||||
golem.lock()->getNavigation()->stop();
|
||||
void TakeFlowerGoal::start() {
|
||||
pickupTick = villager->getRandom()->nextInt(
|
||||
(int)(OfferFlowerGoal::OFFER_TICKS * 0.8));
|
||||
takeFlower = false;
|
||||
golem.lock()->getNavigation()->stop();
|
||||
}
|
||||
|
||||
void TakeFlowerGoal::stop()
|
||||
{
|
||||
golem = std::weak_ptr<VillagerGolem>();
|
||||
villager->getNavigation()->stop();
|
||||
void TakeFlowerGoal::stop() {
|
||||
golem = std::weak_ptr<VillagerGolem>();
|
||||
villager->getNavigation()->stop();
|
||||
}
|
||||
|
||||
void TakeFlowerGoal::tick()
|
||||
{
|
||||
villager->getLookControl()->setLookAt(golem.lock(), 30, 30);
|
||||
if (golem.lock()->getOfferFlowerTick() == pickupTick)
|
||||
{
|
||||
villager->getNavigation()->moveTo(golem.lock(), 0.15f);
|
||||
takeFlower = true;
|
||||
}
|
||||
void TakeFlowerGoal::tick() {
|
||||
villager->getLookControl()->setLookAt(golem.lock(), 30, 30);
|
||||
if (golem.lock()->getOfferFlowerTick() == pickupTick) {
|
||||
villager->getNavigation()->moveTo(golem.lock(), 0.15f);
|
||||
takeFlower = true;
|
||||
}
|
||||
|
||||
if (takeFlower)
|
||||
{
|
||||
if (villager->distanceToSqr(golem.lock()) < 2 * 2)
|
||||
{
|
||||
golem.lock()->offerFlower(false);
|
||||
villager->getNavigation()->stop();
|
||||
}
|
||||
}
|
||||
if (takeFlower) {
|
||||
if (villager->distanceToSqr(golem.lock()) < 2 * 2) {
|
||||
golem.lock()->offerFlower(false);
|
||||
villager->getNavigation()->stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,20 +2,19 @@
|
|||
|
||||
#include "Goal.h"
|
||||
|
||||
class TakeFlowerGoal : public Goal
|
||||
{
|
||||
class TakeFlowerGoal : public Goal {
|
||||
private:
|
||||
Villager *villager;
|
||||
std::weak_ptr<VillagerGolem> golem;
|
||||
int pickupTick;
|
||||
bool takeFlower;
|
||||
Villager* villager;
|
||||
std::weak_ptr<VillagerGolem> golem;
|
||||
int pickupTick;
|
||||
bool takeFlower;
|
||||
|
||||
public:
|
||||
TakeFlowerGoal(Villager *villager);
|
||||
TakeFlowerGoal(Villager* villager);
|
||||
|
||||
bool canUse();
|
||||
bool canContinueToUse();
|
||||
void start();
|
||||
void stop();
|
||||
void tick();
|
||||
bool canUse();
|
||||
bool canContinueToUse();
|
||||
void start();
|
||||
void stop();
|
||||
void tick();
|
||||
};
|
||||
|
|
@ -8,106 +8,95 @@
|
|||
#include "../../Headers/net.minecraft.world.phys.h"
|
||||
#include "TargetGoal.h"
|
||||
|
||||
void TargetGoal::_init(Mob *mob, float within, bool mustSee, bool mustReach)
|
||||
{
|
||||
reachCache = EmptyReachCache;
|
||||
reachCacheTime = 0;
|
||||
unseenTicks = 0;
|
||||
void TargetGoal::_init(Mob* mob, float within, bool mustSee, bool mustReach) {
|
||||
reachCache = EmptyReachCache;
|
||||
reachCacheTime = 0;
|
||||
unseenTicks = 0;
|
||||
|
||||
this->mob = mob;
|
||||
this->within = within;
|
||||
this->mustSee = mustSee;
|
||||
this->mustReach = mustReach;
|
||||
this->mob = mob;
|
||||
this->within = within;
|
||||
this->mustSee = mustSee;
|
||||
this->mustReach = mustReach;
|
||||
}
|
||||
|
||||
TargetGoal::TargetGoal(Mob *mob, float within, bool mustSee)
|
||||
{
|
||||
_init(mob, within, mustSee, false);
|
||||
TargetGoal::TargetGoal(Mob* mob, float within, bool mustSee) {
|
||||
_init(mob, within, mustSee, false);
|
||||
}
|
||||
|
||||
TargetGoal::TargetGoal(Mob *mob, float within, bool mustSee, bool mustReach)
|
||||
{
|
||||
_init(mob,within,mustSee,mustReach);
|
||||
TargetGoal::TargetGoal(Mob* mob, float within, bool mustSee, bool mustReach) {
|
||||
_init(mob, within, mustSee, mustReach);
|
||||
}
|
||||
|
||||
bool TargetGoal::canContinueToUse()
|
||||
{
|
||||
std::shared_ptr<Mob> target = mob->getTarget();
|
||||
if (target == NULL) return false;
|
||||
if (!target->isAlive()) return false;
|
||||
if (mob->distanceToSqr(target) > within * within) return false;
|
||||
if (mustSee)
|
||||
{
|
||||
if (mob->getSensing()->canSee(target))
|
||||
{
|
||||
unseenTicks = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (++unseenTicks > UnseenMemoryTicks) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
bool TargetGoal::canContinueToUse() {
|
||||
std::shared_ptr<Mob> target = mob->getTarget();
|
||||
if (target == NULL) return false;
|
||||
if (!target->isAlive()) return false;
|
||||
if (mob->distanceToSqr(target) > within * within) return false;
|
||||
if (mustSee) {
|
||||
if (mob->getSensing()->canSee(target)) {
|
||||
unseenTicks = 0;
|
||||
} else {
|
||||
if (++unseenTicks > UnseenMemoryTicks) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void TargetGoal::start()
|
||||
{
|
||||
reachCache = EmptyReachCache;
|
||||
reachCacheTime = 0;
|
||||
unseenTicks = 0;
|
||||
void TargetGoal::start() {
|
||||
reachCache = EmptyReachCache;
|
||||
reachCacheTime = 0;
|
||||
unseenTicks = 0;
|
||||
}
|
||||
|
||||
void TargetGoal::stop()
|
||||
{
|
||||
mob->setTarget(nullptr);
|
||||
void TargetGoal::stop() { 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)
|
||||
{
|
||||
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::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;
|
||||
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;
|
||||
}
|
||||
|
|
@ -2,43 +2,41 @@
|
|||
|
||||
#include "Goal.h"
|
||||
|
||||
class TargetGoal : public Goal
|
||||
{
|
||||
|
||||
class TargetGoal : public Goal {
|
||||
public:
|
||||
static const int TargetFlag = 1;
|
||||
static const int TargetFlag = 1;
|
||||
|
||||
private:
|
||||
static const int EmptyReachCache = 0;
|
||||
static const int CanReachCache = 1;
|
||||
static const int CantReachCache = 2;
|
||||
static const int UnseenMemoryTicks = 60;
|
||||
static const int EmptyReachCache = 0;
|
||||
static const int CanReachCache = 1;
|
||||
static const int CantReachCache = 2;
|
||||
static const int UnseenMemoryTicks = 60;
|
||||
|
||||
protected:
|
||||
Mob *mob; // Owner of this goal
|
||||
float within;
|
||||
bool mustSee;
|
||||
Mob* mob; // Owner of this goal
|
||||
float within;
|
||||
bool mustSee;
|
||||
|
||||
private:
|
||||
bool mustReach;
|
||||
int reachCache;
|
||||
int reachCacheTime;
|
||||
int unseenTicks;
|
||||
bool mustReach;
|
||||
int reachCache;
|
||||
int reachCacheTime;
|
||||
int unseenTicks;
|
||||
|
||||
void _init(Mob *mob, float within, bool mustSee, bool mustReach);
|
||||
void _init(Mob* mob, float within, bool mustSee, bool mustReach);
|
||||
|
||||
public:
|
||||
TargetGoal(Mob *mob, float within, bool mustSee);
|
||||
TargetGoal(Mob *mob, float within, bool mustSee, bool mustReach);
|
||||
virtual ~TargetGoal() {}
|
||||
TargetGoal(Mob* mob, float within, bool mustSee);
|
||||
TargetGoal(Mob* mob, float within, bool mustSee, bool mustReach);
|
||||
virtual ~TargetGoal() {}
|
||||
|
||||
virtual bool canContinueToUse();
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual bool canContinueToUse();
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
|
||||
protected:
|
||||
virtual bool canAttack(std::shared_ptr<Mob> target, bool allowInvulnerable);
|
||||
virtual bool canAttack(std::shared_ptr<Mob> target, bool allowInvulnerable);
|
||||
|
||||
private:
|
||||
bool canReach(std::shared_ptr<Mob> target);
|
||||
bool canReach(std::shared_ptr<Mob> target);
|
||||
};
|
||||
|
|
@ -6,86 +6,82 @@
|
|||
#include "../../Headers/net.minecraft.world.level.h"
|
||||
#include "TemptGoal.h"
|
||||
|
||||
TemptGoal::TemptGoal(PathfinderMob *mob, float speed, int itemId, bool canScare)
|
||||
{
|
||||
px = py = pz = pRotX = pRotY = 0.0;
|
||||
player = std::weak_ptr<Player>();
|
||||
calmDown = 0;
|
||||
_isRunning = false;
|
||||
oldAvoidWater = false;
|
||||
TemptGoal::TemptGoal(PathfinderMob* mob, float speed, int itemId,
|
||||
bool canScare) {
|
||||
px = py = pz = pRotX = pRotY = 0.0;
|
||||
player = std::weak_ptr<Player>();
|
||||
calmDown = 0;
|
||||
_isRunning = false;
|
||||
oldAvoidWater = false;
|
||||
|
||||
this->mob = mob;
|
||||
this->speed = speed;
|
||||
this->itemId = itemId;
|
||||
this->canScare = canScare;
|
||||
setRequiredControlFlags(Control::MoveControlFlag | Control::LookControlFlag);
|
||||
this->mob = mob;
|
||||
this->speed = speed;
|
||||
this->itemId = itemId;
|
||||
this->canScare = canScare;
|
||||
setRequiredControlFlags(Control::MoveControlFlag |
|
||||
Control::LookControlFlag);
|
||||
}
|
||||
|
||||
bool TemptGoal::canUse()
|
||||
{
|
||||
if (calmDown > 0)
|
||||
{
|
||||
--calmDown;
|
||||
return false;
|
||||
}
|
||||
player = std::weak_ptr<Player>(mob->level->getNearestPlayer(mob->shared_from_this(), 10));
|
||||
if (player.lock() == NULL) return false;
|
||||
mob->setDespawnProtected(); // If we've got a nearby player, then consider this mob as something we'd miss if it despawned
|
||||
std::shared_ptr<ItemInstance> item = player.lock()->getSelectedItem();
|
||||
if (item == NULL) return false;
|
||||
if (item->id != itemId) return false;
|
||||
return true;
|
||||
bool TemptGoal::canUse() {
|
||||
if (calmDown > 0) {
|
||||
--calmDown;
|
||||
return false;
|
||||
}
|
||||
player = std::weak_ptr<Player>(
|
||||
mob->level->getNearestPlayer(mob->shared_from_this(), 10));
|
||||
if (player.lock() == NULL) return false;
|
||||
mob->setDespawnProtected(); // If we've got a nearby player, then consider
|
||||
// this mob as something we'd miss if it
|
||||
// despawned
|
||||
std::shared_ptr<ItemInstance> item = player.lock()->getSelectedItem();
|
||||
if (item == NULL) return false;
|
||||
if (item->id != itemId) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TemptGoal::canContinueToUse()
|
||||
{
|
||||
if (canScare)
|
||||
{
|
||||
if(player.lock() == NULL) return false;
|
||||
if (mob->distanceToSqr(player.lock()) < 6 * 6)
|
||||
{
|
||||
if (player.lock()->distanceToSqr(px, py, pz) > 0.1 * 0.1) return false;
|
||||
if (abs(player.lock()->xRot - pRotX) > 5 || abs(player.lock()->yRot - pRotY) > 5) return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
px = player.lock()->x;
|
||||
py = player.lock()->y;
|
||||
pz = player.lock()->z;
|
||||
}
|
||||
pRotX = player.lock()->xRot;
|
||||
pRotY = player.lock()->yRot;
|
||||
}
|
||||
return canUse();
|
||||
bool TemptGoal::canContinueToUse() {
|
||||
if (canScare) {
|
||||
if (player.lock() == NULL) return false;
|
||||
if (mob->distanceToSqr(player.lock()) < 6 * 6) {
|
||||
if (player.lock()->distanceToSqr(px, py, pz) > 0.1 * 0.1)
|
||||
return false;
|
||||
if (abs(player.lock()->xRot - pRotX) > 5 ||
|
||||
abs(player.lock()->yRot - pRotY) > 5)
|
||||
return false;
|
||||
} else {
|
||||
px = player.lock()->x;
|
||||
py = player.lock()->y;
|
||||
pz = player.lock()->z;
|
||||
}
|
||||
pRotX = player.lock()->xRot;
|
||||
pRotY = player.lock()->yRot;
|
||||
}
|
||||
return canUse();
|
||||
}
|
||||
|
||||
void TemptGoal::start()
|
||||
{
|
||||
px = player.lock()->x;
|
||||
py = player.lock()->y;
|
||||
pz = player.lock()->z;
|
||||
_isRunning = true;
|
||||
oldAvoidWater = mob->getNavigation()->getAvoidWater();
|
||||
mob->getNavigation()->setAvoidWater(false);
|
||||
void TemptGoal::start() {
|
||||
px = player.lock()->x;
|
||||
py = player.lock()->y;
|
||||
pz = player.lock()->z;
|
||||
_isRunning = true;
|
||||
oldAvoidWater = mob->getNavigation()->getAvoidWater();
|
||||
mob->getNavigation()->setAvoidWater(false);
|
||||
}
|
||||
|
||||
void TemptGoal::stop()
|
||||
{
|
||||
player = std::weak_ptr<Player>();
|
||||
mob->getNavigation()->stop();
|
||||
calmDown = 100;
|
||||
_isRunning = false;
|
||||
mob->getNavigation()->setAvoidWater(oldAvoidWater);
|
||||
void TemptGoal::stop() {
|
||||
player = std::weak_ptr<Player>();
|
||||
mob->getNavigation()->stop();
|
||||
calmDown = 100;
|
||||
_isRunning = false;
|
||||
mob->getNavigation()->setAvoidWater(oldAvoidWater);
|
||||
}
|
||||
|
||||
void TemptGoal::tick()
|
||||
{
|
||||
mob->getLookControl()->setLookAt(player.lock(), 30, mob->getMaxHeadXRot());
|
||||
if (mob->distanceToSqr(player.lock()) < 2.5 * 2.5) mob->getNavigation()->stop();
|
||||
else mob->getNavigation()->moveTo(player.lock(), speed);
|
||||
void TemptGoal::tick() {
|
||||
mob->getLookControl()->setLookAt(player.lock(), 30, mob->getMaxHeadXRot());
|
||||
if (mob->distanceToSqr(player.lock()) < 2.5 * 2.5)
|
||||
mob->getNavigation()->stop();
|
||||
else
|
||||
mob->getNavigation()->moveTo(player.lock(), speed);
|
||||
}
|
||||
|
||||
bool TemptGoal::isRunning()
|
||||
{
|
||||
return _isRunning;
|
||||
}
|
||||
bool TemptGoal::isRunning() { return _isRunning; }
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue