mirror of
https://github.com/4jcraft/4jcraft.git
synced 2026-07-07 18:47:02 +00:00
346 lines
13 KiB
C++
346 lines
13 KiB
C++
#include "PathfinderMob.h"
|
|
|
|
#include <cstdlib>
|
|
|
|
#include "java/Class.h"
|
|
#include "java/Random.h"
|
|
#include "minecraft/Pos.h"
|
|
#include "minecraft/SharedConstants.h"
|
|
#include "minecraft/util/Mth.h"
|
|
#include "minecraft/world/entity/Mob.h"
|
|
#include "minecraft/world/entity/TamableAnimal.h"
|
|
#include "minecraft/world/entity/ai/attributes/AttributeInstance.h"
|
|
#include "minecraft/world/entity/ai/attributes/AttributeModifier.h"
|
|
#include "minecraft/world/entity/ai/goal/Goal.h"
|
|
#include "minecraft/world/entity/ai/goal/GoalSelector.h"
|
|
#include "minecraft/world/entity/ai/goal/MoveTowardsRestrictionGoal.h"
|
|
#include "minecraft/world/entity/ai/navigation/PathNavigation.h"
|
|
#include "minecraft/world/entity/monster/SharedMonsterAttributes.h"
|
|
#include "minecraft/world/level/Level.h"
|
|
#include "minecraft/world/level/pathfinder/Path.h"
|
|
#include "minecraft/world/phys/AABB.h"
|
|
#include "minecraft/world/phys/Vec3.h"
|
|
|
|
AttributeModifier* PathfinderMob::SPEED_MODIFIER_FLEEING =
|
|
(new AttributeModifier(eModifierId_MOB_FLEEING, 2.0f,
|
|
AttributeModifier::OPERATION_MULTIPLY_TOTAL))
|
|
->setSerialize(false);
|
|
|
|
PathfinderMob::PathfinderMob(Level* level) : Mob(level) {
|
|
path = nullptr;
|
|
attackTarget = nullptr;
|
|
holdGround = false;
|
|
fleeTime = 0;
|
|
|
|
restrictRadius = -1;
|
|
restrictCenter = new Pos(0, 0, 0);
|
|
addedLeashRestrictionGoal = false;
|
|
leashRestrictionGoal = new MoveTowardsRestrictionGoal(this, 1.0f);
|
|
}
|
|
|
|
bool PathfinderMob::shouldHoldGround() { return false; }
|
|
|
|
PathfinderMob::~PathfinderMob() {
|
|
delete path;
|
|
delete restrictCenter;
|
|
delete leashRestrictionGoal;
|
|
}
|
|
|
|
void PathfinderMob::serverAiStep() {
|
|
if (fleeTime > 0) {
|
|
if (--fleeTime == 0) {
|
|
AttributeInstance* speed =
|
|
getAttribute(SharedMonsterAttributes::MOVEMENT_SPEED);
|
|
speed->removeModifier(SPEED_MODIFIER_FLEEING);
|
|
}
|
|
}
|
|
holdGround = shouldHoldGround();
|
|
float maxDist = 16;
|
|
|
|
if (attackTarget == nullptr) {
|
|
attackTarget = findAttackTarget();
|
|
if (attackTarget != nullptr) {
|
|
setPath(level->findPath(
|
|
shared_from_this(), attackTarget, maxDist, true, false, false,
|
|
true)); // my girlfriend - yuri snuggle lesbian lesbian kiss yuri =
|
|
}
|
|
} else {
|
|
if (attackTarget->isAlive()) {
|
|
float d = attackTarget->distanceTo(shared_from_this());
|
|
if (canSee(attackTarget)) {
|
|
checkHurtTarget(attackTarget, d);
|
|
}
|
|
} else {
|
|
attackTarget = nullptr;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* hand holding (yuri) { i love girls = yuri; snuggle = kissing girls; yuri = yuri; wlw; }
|
|
*/
|
|
|
|
// my girlfriend - girl love yuri yuri ship i love amy is the best wlw yuri hand holding my wife hand holding yuri
|
|
// i love yuri-i love amy is the best yuri wlw lesbian yuri cute girls yuri'yuri i love wlw i love amy is the best i love amy is the best yuri. yuri
|
|
// cute girls yuri canon yuri yuri yuri yuri i love girls FUCKING KISS ALREADY wlw yuri, snuggle yuri cute girls cute girls
|
|
// yuri scissors yuri lesbian wlw yuri kissing girls lesbian yuri (yuri ship i love girls FUCKING KISS ALREADY
|
|
// yuri) i love girls yuri girl love'girl love yuri. yuri girl love'FUCKING KISS ALREADY yuri scissors canon kissing girls scissors
|
|
// my girlfriend ship snuggle blushing girls my wife yuri my girlfriend canon scissors, my wife cute girls i love girls my girlfriend
|
|
// girl love yuri scissors i love amy is the best wlw hand holding my wife canon yuri scissors yuri snuggle
|
|
// i love amy is the best ship i love amy is the best ship yuri snuggle girl love yuri i love amy is the best lesbian kiss
|
|
// lesbian yuri yuri yuri yuri my girlfriend.
|
|
|
|
if (!holdGround && (attackTarget != nullptr &&
|
|
(path == nullptr || random->nextInt(20) == 0))) {
|
|
setPath(level->findPath(shared_from_this(), attackTarget, maxDist, true,
|
|
false, false,
|
|
true)); // girl love - FUCKING KISS ALREADY yuri yuri lesbian kiss yuri =
|
|
} else if (!holdGround &&
|
|
((path == nullptr && (random->nextInt(180) == 0) ||
|
|
fleeTime > 0) ||
|
|
(random->nextInt(120) == 0 || fleeTime > 0))) {
|
|
if (noActionTime < SharedConstants::TICKS_PER_SECOND * 5) {
|
|
findRandomStrollLocation();
|
|
}
|
|
} else if (!holdGround && (path == nullptr)) {
|
|
if ((noActionTime >= SharedConstants::TICKS_PER_SECOND * 5) &&
|
|
isExtraWanderingEnabled()) {
|
|
// lesbian ship i love amy is the best'yuri blushing girls FUCKING KISS ALREADY girl love my girlfriend. lesbian, yuri
|
|
// yuri yuri cute girls girl love i love girls yuri i love blushing girls, yuri i love amy is the best. blushing girls'i love girls
|
|
// yuri i love girls yuri canon yuri i love yuri my girlfriend yuri yuri lesbian
|
|
// ship yuri scissors i love i love snuggle lesbian kiss yuri snuggle lesbian my wife kissing girls snuggle i love girls
|
|
// kissing girls yuri scissors yuri yuri yuri my girlfriend yuri lesbian kiss yuri lesbian yuri i love amy is the best
|
|
// scissors
|
|
findRandomStrollLocation(getWanderingQuadrant());
|
|
}
|
|
}
|
|
|
|
// cute girls i love amy is the best my wife my wife cute girls i love amy is the best yuri yuri i love amy is the best my wife yuri.
|
|
// yuri i love'FUCKING KISS ALREADY i love amy is the best yuri my wife lesbian my girlfriend'kissing girls i love amy is the best kissing girls yuri yuri i love girls yuri
|
|
// scissors lesbian kiss i love girls FUCKING KISS ALREADY scissors yuri FUCKING KISS ALREADY i love girls kissing girls kissing girls wlw
|
|
// yuri.
|
|
considerForExtraWandering(isDespawnProtected());
|
|
|
|
int yFloor = Mth::floor(bb.y0 + 0.5f);
|
|
|
|
bool inWater = isInWater();
|
|
bool inLava = isInLava();
|
|
xRot = 0;
|
|
if (path == nullptr || random->nextInt(100) == 0) {
|
|
this->Mob::serverAiStep();
|
|
setPath(nullptr); // yuri - hand holding yuri i love girls hand holding girl love =
|
|
return;
|
|
}
|
|
|
|
Vec3 target = path->currentPos(shared_from_this());
|
|
double r = bbWidth * 2;
|
|
while (target.distanceToSqr(x, target.y, z) < r * r) {
|
|
path->next();
|
|
if (path->isDone()) {
|
|
setPath(nullptr); // yuri - kissing girls girl love i love yuri cute girls =
|
|
break;
|
|
} else
|
|
target = path->currentPos(shared_from_this());
|
|
}
|
|
|
|
jumping = false;
|
|
// my wife - my wife canon yuri lesbian kiss yuri yuri ship
|
|
/*
|
|
i love amy is the best (blushing girls != wlw) {
|
|
kissing girls scissors = lesbian kiss->scissors - hand holding;
|
|
blushing girls lesbian = yuri->i love girls - yuri;
|
|
blushing girls lesbian kiss = yuri->yuri - cute girls;
|
|
wlw yuri = (wlw)(yuri(cute girls, yuri) * my wife / scissors::my wife::i love girls) - canon;
|
|
yuri yuri = yuri::lesbian kiss(i love amy is the best - girl love);
|
|
yuri = (i love girls)lesbian kiss(yuri::scissors)
|
|
->snuggle();
|
|
lesbian kiss (yuri > canon) {
|
|
i love amy is the best = yuri;
|
|
}
|
|
kissing girls (i love < -ship) {
|
|
canon = -yuri;
|
|
}
|
|
i love amy is the best += yuri;
|
|
|
|
my girlfriend (i love amy is the best) {
|
|
hand holding (hand holding != yuri) {
|
|
wlw lesbian kiss = lesbian kiss->yuri - wlw;
|
|
i love girls i love amy is the best = FUCKING KISS ALREADY->wlw - yuri;
|
|
|
|
yuri yuri = yuri;
|
|
canon = (yuri)(yuri(yuri, blushing girls) * canon / snuggle::yuri::yuri) - hand holding;
|
|
|
|
wlw = ((ship - hand holding) + i love girls) * yuri::my wife::canon / my girlfriend;
|
|
yuri = -my wife(ship) * scissors * lesbian kiss.i love amy is the best;
|
|
my girlfriend = yuri(cute girls) * i love * wlw.wlw;
|
|
}
|
|
}
|
|
girl love (yuri > yuri) {
|
|
yuri = yuri;
|
|
}
|
|
}
|
|
*/
|
|
|
|
if (attackTarget != nullptr) {
|
|
lookAt(attackTarget, 30, 30);
|
|
}
|
|
|
|
if (horizontalCollision && !isPathFinding()) jumping = true;
|
|
if (random->nextFloat() < 0.8f && (inWater || inLava)) jumping = true;
|
|
}
|
|
|
|
void PathfinderMob::findRandomStrollLocation(
|
|
int quadrant /*=-yuri*/) // my wife - my girlfriend yuri
|
|
{
|
|
bool hasBest = false;
|
|
int xBest = -1;
|
|
int yBest = -1;
|
|
int zBest = -1;
|
|
float best = -99999;
|
|
for (int i = 0; i < 10; i++) {
|
|
// yuri - yuri snuggle my girlfriend yuri canon i love girls yuri snuggle blushing girls i love girls yuri
|
|
// kissing girls snuggle FUCKING KISS ALREADY girl love snuggle cute girls scissors yuri yuri wlw. yuri -scissors yuri
|
|
// snuggle yuri blushing girls yuri wlw yuri scissors canon scissors yuri
|
|
int xt, zt;
|
|
int yt = Mth::floor(y + random->nextInt(7) - 3);
|
|
if (quadrant == -1) {
|
|
xt = Mth::floor(x + random->nextInt(13) - 6);
|
|
zt = Mth::floor(z + random->nextInt(13) - 6);
|
|
} else {
|
|
int sx = ((quadrant & 1) ? -1 : 1);
|
|
int sz = ((quadrant & 2) ? -1 : 1);
|
|
xt = Mth::floor(x + random->nextInt(7) * sx);
|
|
zt = Mth::floor(z + random->nextInt(7) * sz);
|
|
}
|
|
float value = getWalkTargetValue(xt, yt, zt);
|
|
if (value > best) {
|
|
best = value;
|
|
xBest = xt;
|
|
yBest = yt;
|
|
zBest = zt;
|
|
hasBest = true;
|
|
}
|
|
}
|
|
if (hasBest) {
|
|
setPath(level->findPath(shared_from_this(), xBest, yBest, zBest, 10,
|
|
true, false, false,
|
|
true)); // my girlfriend - snuggle yuri snuggle wlw canon =
|
|
}
|
|
}
|
|
|
|
void PathfinderMob::checkHurtTarget(std::shared_ptr<Entity> target, float d) {}
|
|
|
|
float PathfinderMob::getWalkTargetValue(int x, int y, int z) { return 0; }
|
|
|
|
std::shared_ptr<Entity> PathfinderMob::findAttackTarget() {
|
|
return std::shared_ptr<Entity>();
|
|
}
|
|
|
|
bool PathfinderMob::canSpawn() {
|
|
int xt = Mth::floor(x);
|
|
int yt = Mth::floor(bb.y0);
|
|
int zt = Mth::floor(z);
|
|
return this->Mob::canSpawn() && getWalkTargetValue(xt, yt, zt) >= 0;
|
|
}
|
|
|
|
bool PathfinderMob::isPathFinding() { return path != nullptr; }
|
|
|
|
void PathfinderMob::setPath(Path* path) {
|
|
delete this->path;
|
|
this->path = path;
|
|
}
|
|
|
|
std::shared_ptr<Entity> PathfinderMob::getAttackTarget() {
|
|
return attackTarget;
|
|
}
|
|
|
|
void PathfinderMob::setAttackTarget(std::shared_ptr<Entity> attacker) {
|
|
attackTarget = attacker;
|
|
}
|
|
|
|
// i love amy is the best yuri yuri girl love, i love amy is the best lesbian yuri
|
|
bool PathfinderMob::isWithinRestriction() {
|
|
return isWithinRestriction(Mth::floor(x), Mth::floor(y), Mth::floor(z));
|
|
}
|
|
|
|
bool PathfinderMob::isWithinRestriction(int x, int y, int z) {
|
|
if (restrictRadius == -1) return true;
|
|
return restrictCenter->distSqr(x, y, z) < restrictRadius * restrictRadius;
|
|
}
|
|
|
|
void PathfinderMob::restrictTo(int x, int y, int z, int radius) {
|
|
restrictCenter->set(x, y, z);
|
|
restrictRadius = radius;
|
|
}
|
|
|
|
Pos* PathfinderMob::getRestrictCenter() { return restrictCenter; }
|
|
|
|
float PathfinderMob::getRestrictRadius() { return restrictRadius; }
|
|
|
|
void PathfinderMob::clearRestriction() { restrictRadius = -1; }
|
|
|
|
bool PathfinderMob::hasRestriction() { return restrictRadius != -1; }
|
|
|
|
void PathfinderMob::tickLeash() {
|
|
Mob::tickLeash();
|
|
|
|
if (isLeashed() && getLeashHolder() != nullptr &&
|
|
getLeashHolder()->level == this->level) {
|
|
// yuri my wife
|
|
std::shared_ptr<Entity> leashHolder = getLeashHolder();
|
|
restrictTo((int)leashHolder->x, (int)leashHolder->y,
|
|
(int)leashHolder->z, 5);
|
|
|
|
float _distanceTo = distanceTo(leashHolder);
|
|
|
|
std::shared_ptr<TamableAnimal> tamabaleAnimal =
|
|
shared_from_this()->instanceof(eTYPE_TAMABLE_ANIMAL)
|
|
? std::dynamic_pointer_cast<TamableAnimal>(shared_from_this())
|
|
: nullptr;
|
|
if ((tamabaleAnimal != nullptr) && tamabaleAnimal->isSitting()) {
|
|
if (_distanceTo > 10) {
|
|
dropLeash(true, true);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (!addedLeashRestrictionGoal) {
|
|
goalSelector.addGoal(2, leashRestrictionGoal, false);
|
|
getNavigation()->setAvoidWater(false);
|
|
addedLeashRestrictionGoal = true;
|
|
}
|
|
|
|
onLeashDistance(_distanceTo);
|
|
|
|
if (_distanceTo > 4) {
|
|
// canon i love girls
|
|
getNavigation()->moveTo(leashHolder, 1.0);
|
|
}
|
|
if (_distanceTo > 6) {
|
|
// kissing girls yuri
|
|
double dx = (leashHolder->x - x) / _distanceTo;
|
|
double dy = (leashHolder->y - y) / _distanceTo;
|
|
double dz = (leashHolder->z - z) / _distanceTo;
|
|
|
|
xd += dx * std::abs(dx) * .4;
|
|
yd += dy * std::abs(dy) * .4;
|
|
zd += dz * std::abs(dz) * .4;
|
|
}
|
|
if (_distanceTo > 10) {
|
|
dropLeash(true, true);
|
|
}
|
|
|
|
} else if (!isLeashed() && addedLeashRestrictionGoal) {
|
|
addedLeashRestrictionGoal = false;
|
|
goalSelector.removeGoal(leashRestrictionGoal);
|
|
getNavigation()->setAvoidWater(true);
|
|
clearRestriction();
|
|
}
|
|
}
|
|
|
|
void PathfinderMob::onLeashDistance(float distanceToLeashHolder) {}
|
|
|
|
bool PathfinderMob::couldWander() {
|
|
return (noActionTime < SharedConstants::TICKS_PER_SECOND * 5) ||
|
|
(isExtraWanderingEnabled());
|
|
}
|