fix: entity push collision (#395)

This commit is contained in:
Aydin Y.
2026-04-04 14:04:09 -05:00
committed by GitHub
parent b143b0e0c5
commit da89ab8c5a
2 changed files with 19 additions and 26 deletions
+16 -23
View File
@@ -14,11 +14,10 @@
#include "EntityIO.h" #include "EntityIO.h"
#include "EntityPos.h" #include "EntityPos.h"
#include "SyncedEntityData.h"
#include "app/common/App_enums.h" #include "app/common/App_enums.h"
#include "app/linux/LinuxGame.h" #include "app/linux/LinuxGame.h"
#include "app/linux/Stubs/winapi_stubs.h" #include "app/linux/Stubs/winapi_stubs.h"
#include "SyncedEntityData.h"
#include "util/StringHelpers.h"
#include "java/Class.h" #include "java/Class.h"
#include "java/Random.h" #include "java/Random.h"
#include "minecraft/Direction.h" #include "minecraft/Direction.h"
@@ -46,6 +45,7 @@
#include "nbt/DoubleTag.h" #include "nbt/DoubleTag.h"
#include "nbt/FloatTag.h" #include "nbt/FloatTag.h"
#include "nbt/ListTag.h" #include "nbt/ListTag.h"
#include "util/StringHelpers.h"
thread_local bool Entity::m_tlsUseSmallIds = false; thread_local bool Entity::m_tlsUseSmallIds = false;
@@ -1167,36 +1167,29 @@ void Entity::playerTouch(std::shared_ptr<Player> player) {}
void Entity::push(std::shared_ptr<Entity> e) { void Entity::push(std::shared_ptr<Entity> e) {
if (e->rider.lock().get() == this || e->riding.get() == this) return; if (e->rider.lock().get() == this || e->riding.get() == this) return;
double xa = e->x - x; const double dx = e->x - x;
double za = e->z - z; const double dz = e->z - z;
double dd = std::max(fabs(xa), fabs(za)); constexpr double min_displacement = 0.1;
const double max_displacement = std::max(std::fabs(dx), std::fabs(dz));
if (dd >= 0.01f) { if (max_displacement >= min_displacement) {
dd = sqrt(dd); constexpr double dampening = 0.05;
xa /= dd; const double dist = std::sqrt(dx * dx + dz * dz);
za /= dd;
double pow = 1 / dd; const double nx = dx / dist;
if (pow > 1) pow = 1; const double nz = dz / dist;
xa *= pow;
za *= pow;
xa *= 0.05f; const double force =
za *= 0.05f; std::min(1.0 / dist, 1.0) * dampening * (1.0 - pushthrough);
xa *= 1 - pushthrough; push(-nx * force, 0.0, -nz * force);
za *= 1 - pushthrough; e->push(nx * force, 0, nz * force);
push(-xa, 0, -za);
e->push(xa, 0, za);
} }
} }
void Entity::push(double xa, double ya, double za) { void Entity::push(double xa, double ya, double za) {
xd += xa; move(xa, ya, za);
yd += ya;
zd += za;
hasImpulse = true; hasImpulse = true;
} }
@@ -1590,11 +1590,11 @@ void LivingEntity::aiStep() {
yya *= 0.98f; yya *= 0.98f;
yRotA *= 0.9f; yRotA *= 0.9f;
travel(xxa, yya);
if (!level->isClientSide) { if (!level->isClientSide) {
pushEntities(); pushEntities();
} }
travel(xxa, yya);
} }
void LivingEntity::newServerAiStep() {} void LivingEntity::newServerAiStep() {}
@@ -1607,7 +1607,7 @@ void LivingEntity::pushEntities() {
auto itEnd = entities->end(); auto itEnd = entities->end();
for (auto it = entities->begin(); it != itEnd; it++) { for (auto it = entities->begin(); it != itEnd; it++) {
std::shared_ptr<Entity> e = *it; // entities->at(i); std::shared_ptr<Entity> e = *it; // entities->at(i);
if (e->isPushable()) e->push(shared_from_this()); if (e and !e->removed and e->isPushable()) push(e);
} }
} }
} }