aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.World/HangingEntity.cpp
diff options
context:
space:
mode:
authordaoge_cmd <3523206925@qq.com>2026-03-01 12:16:08 +0800
committerdaoge_cmd <3523206925@qq.com>2026-03-01 12:16:08 +0800
commitb691c43c44ff180d10e7d4a9afc83b98551ff586 (patch)
tree3e9849222cbc6ba49f2f1fc6e5fe7179632c7390 /Minecraft.World/HangingEntity.cpp
parentdef8cb415354ac390b7e89052a50605285f1aca9 (diff)
Initial commit
Diffstat (limited to 'Minecraft.World/HangingEntity.cpp')
-rw-r--r--Minecraft.World/HangingEntity.cpp292
1 files changed, 292 insertions, 0 deletions
diff --git a/Minecraft.World/HangingEntity.cpp b/Minecraft.World/HangingEntity.cpp
new file mode 100644
index 00000000..6256a381
--- /dev/null
+++ b/Minecraft.World/HangingEntity.cpp
@@ -0,0 +1,292 @@
+#include "stdafx.h"
+#include "net.minecraft.world.phys.h"
+#include "net.minecraft.world.entity.h"
+#include "net.minecraft.world.level.tile.h"
+#include "net.minecraft.world.level.h"
+#include "net.minecraft.world.damagesource.h"
+#include "com.mojang.nbt.h"
+#include "HangingEntity.h"
+
+
+
+void HangingEntity::_init(Level *level)
+{
+ checkInterval = 0;
+ dir = 0;
+ xTile = yTile = zTile = 0;
+}
+
+HangingEntity::HangingEntity(Level *level) : Entity( level )
+{
+ _init(level);
+
+ this->heightOffset = 0;
+ this->setSize(0.5f, 0.5f);
+}
+
+HangingEntity::HangingEntity(Level *level, int xTile, int yTile, int zTile, int dir) : Entity( level )
+{
+ _init(level);
+ //motive = NULL;
+ this->heightOffset = 0;
+ this->setSize(0.5f, 0.5f);
+ this->xTile = xTile;
+ this->yTile = yTile;
+ this->zTile = zTile;
+}
+
+void HangingEntity::setDir(int dir)
+{
+ this->dir = dir;
+ this->yRotO = this->yRot = (float)(dir * 90);
+
+ float w = (float)getWidth();
+ float h = (float)getHeight();
+ float d = (float)getWidth();
+
+ if (dir == Direction::NORTH || dir == Direction::SOUTH)
+ {
+ d = 0.5f;
+ yRot = yRotO = (float)(Direction::DIRECTION_OPPOSITE[dir] * 90);
+ }
+ else
+ {
+ w = 0.5f;
+ }
+
+ w /= 32.0f;
+ h /= 32.0f;
+ d /= 32.0f;
+
+ float x = xTile + 0.5f;
+ float y = yTile + 0.5f;
+ float z = zTile + 0.5f;
+
+ float fOffs = 0.5f + 1.0f / 16.0f;
+
+ if (dir == Direction::NORTH) z -= fOffs;
+ if (dir == Direction::WEST) x -= fOffs;
+ if (dir == Direction::SOUTH) z += fOffs;
+ if (dir == Direction::EAST) x += fOffs;
+
+ if (dir == Direction::NORTH) x -= offs(getWidth());
+ if (dir == Direction::WEST) z += offs(getWidth());
+ if (dir == Direction::SOUTH) x += offs(getWidth());
+ if (dir == Direction::EAST) z -= offs(getWidth());
+ y += offs(getHeight());
+
+ this->setPos(x, y, z);
+
+ float ss = -(0.5f / 16.0f);
+
+ // 4J Stu - Due to rotations the bb couold be set with a lower bound x/z being higher than the higher bound
+ float x0 = x - w - ss;
+ float x1 = x + w + ss;
+ float y0 = y - h - ss;
+ float y1 = y + h + ss;
+ float z0 = z - d - ss;
+ float z1 = z + d + ss;
+ bb->set(min(x0,x1), min(y0,y1), min(z0,z1), max(x0,x1), max(y0,y1), max(z0,z1));
+}
+
+float HangingEntity::offs(int w)
+{
+ if (w == 32) return 0.5f;
+ if (w == 64) return 0.5f;
+ return 0.0f;
+}
+
+void HangingEntity::tick()
+{
+ if (checkInterval++ == 20 * 5 && !level->isClientSide)//isClientSide)
+ {
+ checkInterval = 0;
+ if (!removed && !survives())
+ {
+ remove();
+ dropItem();
+ }
+ }
+}
+
+bool HangingEntity::survives()
+{
+ if (level->getCubes(shared_from_this(), bb)->size()!=0)//isEmpty())
+ {
+ return false;
+ }
+ else
+ {
+ int ws = max(1, getWidth() / 16);
+ int hs = max(1, getHeight() / 16);
+
+ int xt = xTile;
+ int yt = yTile;
+ int zt = zTile;
+ if (dir == Direction::NORTH) xt = Mth::floor(x - getWidth() / 32.0f);
+ if (dir == Direction::WEST) zt = Mth::floor(z - getWidth() / 32.0f);
+ if (dir == Direction::SOUTH) xt = Mth::floor(x - getWidth() / 32.0f);
+ if (dir == Direction::EAST) zt = Mth::floor(z - getWidth() / 32.0f);
+ yt = Mth::floor(y - getHeight() / 32.0f);
+
+ for (int ss = 0; ss < ws; ss++)
+ {
+ for (int yy = 0; yy < hs; yy++)
+ {
+ Material *m;
+ if (dir == Direction::NORTH || dir == Direction::SOUTH)
+ {
+ m = level->getMaterial(xt + ss, yt + yy, zTile);
+ }
+ else
+ {
+ m = level->getMaterial(xTile, yt + yy, zt + ss);
+ }
+ if (!m->isSolid())
+ {
+ return false;
+ }
+ }
+
+ vector<shared_ptr<Entity> > *entities = level->getEntities(shared_from_this(), bb);
+
+ if (entities != NULL && entities->size() > 0)
+ {
+ AUTO_VAR(itEnd, entities->end());
+ for (AUTO_VAR(it, entities->begin()); it != itEnd; it++)
+ {
+ shared_ptr<Entity> e = (*it);
+ if(dynamic_pointer_cast<HangingEntity>(e) != NULL)
+ {
+ return false;
+ }
+ }
+ }
+ }
+ }
+ return true;
+}
+
+bool HangingEntity::isPickable()
+{
+ return true;
+}
+
+bool HangingEntity::skipAttackInteraction(shared_ptr<Entity> source)
+{
+ if(source->GetType()==eTYPE_PLAYER)
+ {
+ return hurt(DamageSource::playerAttack(dynamic_pointer_cast<Player>( source)), 0);
+ }
+ return false;
+}
+
+bool HangingEntity::hurt(DamageSource *source, int damage)
+{
+ if (!removed && !level->isClientSide)
+ {
+ if (dynamic_cast<EntityDamageSource *>(source) != NULL)
+ {
+ shared_ptr<Entity> sourceEntity = source->getDirectEntity();
+
+ if (dynamic_pointer_cast<Player>(sourceEntity) != NULL && !dynamic_pointer_cast<Player>(sourceEntity)->isAllowedToHurtEntity(shared_from_this()) )
+ {
+ return false;
+ }
+ }
+
+ remove();
+ markHurt();
+
+ shared_ptr<Player> player = nullptr;
+ shared_ptr<Entity> e = source->getEntity();
+ if (e!=NULL && ((e->GetType() & eTYPE_PLAYER)!=0) ) // check if it's serverplayer or player
+ {
+ player = dynamic_pointer_cast<Player>( e );
+ }
+
+ if (player != NULL && player->abilities.instabuild)
+ {
+ return true;
+ }
+
+ dropItem();
+ }
+ return true;
+}
+
+// 4J - added noEntityCubes parameter
+void HangingEntity::move(double xa, double ya, double za, bool noEntityCubes)
+{
+ if (!level->isClientSide && !removed && (xa * xa + ya * ya + za * za) > 0)
+ {
+ remove();
+ dropItem();
+ }
+}
+
+void HangingEntity::push(double xa, double ya, double za)
+{
+ if (!level->isClientSide && !removed && (xa * xa + ya * ya + za * za) > 0)
+ {
+ remove();
+ dropItem();
+ }
+}
+
+void HangingEntity::addAdditonalSaveData(CompoundTag *tag)
+{
+ tag->putByte(L"Direction", (byte) dir);
+ tag->putInt(L"TileX", xTile);
+ tag->putInt(L"TileY", yTile);
+ tag->putInt(L"TileZ", zTile);
+
+ // Back compat
+ switch (dir)
+ {
+ case Direction::NORTH:
+ tag->putByte(L"Dir", (byte) 0);
+ break;
+ case Direction::WEST:
+ tag->putByte(L"Dir", (byte) 1);
+ break;
+ case Direction::SOUTH:
+ tag->putByte(L"Dir", (byte) 2);
+ break;
+ case Direction::EAST:
+ tag->putByte(L"Dir", (byte) 3);
+ break;
+ }
+}
+
+void HangingEntity::readAdditionalSaveData(CompoundTag *tag)
+{
+ if (tag->contains(L"Direction"))
+ {
+ dir = tag->getByte(L"Direction");
+ }
+ else
+ {
+ switch (tag->getByte(L"Dir"))
+ {
+ case 0:
+ dir = Direction::NORTH;
+ break;
+ case 1:
+ dir = Direction::WEST;
+ break;
+ case 2:
+ dir = Direction::SOUTH;
+ break;
+ case 3:
+ dir = Direction::EAST;
+ break;
+ }
+ }
+ xTile = tag->getInt(L"TileX");
+ yTile = tag->getInt(L"TileY");
+ zTile = tag->getInt(L"TileZ");
+ setDir(dir);
+}
+
+