From b691c43c44ff180d10e7d4a9afc83b98551ff586 Mon Sep 17 00:00:00 2001 From: daoge_cmd <3523206925@qq.com> Date: Sun, 1 Mar 2026 12:16:08 +0800 Subject: Initial commit --- Minecraft.World/HangingEntity.cpp | 292 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 292 insertions(+) create mode 100644 Minecraft.World/HangingEntity.cpp (limited to 'Minecraft.World/HangingEntity.cpp') 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 > *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 e = (*it); + if(dynamic_pointer_cast(e) != NULL) + { + return false; + } + } + } + } + } + return true; +} + +bool HangingEntity::isPickable() +{ + return true; +} + +bool HangingEntity::skipAttackInteraction(shared_ptr source) +{ + if(source->GetType()==eTYPE_PLAYER) + { + return hurt(DamageSource::playerAttack(dynamic_pointer_cast( source)), 0); + } + return false; +} + +bool HangingEntity::hurt(DamageSource *source, int damage) +{ + if (!removed && !level->isClientSide) + { + if (dynamic_cast(source) != NULL) + { + shared_ptr sourceEntity = source->getDirectEntity(); + + if (dynamic_pointer_cast(sourceEntity) != NULL && !dynamic_pointer_cast(sourceEntity)->isAllowedToHurtEntity(shared_from_this()) ) + { + return false; + } + } + + remove(); + markHurt(); + + shared_ptr player = nullptr; + shared_ptr e = source->getEntity(); + if (e!=NULL && ((e->GetType() & eTYPE_PLAYER)!=0) ) // check if it's serverplayer or player + { + player = dynamic_pointer_cast( 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); +} + + -- cgit v1.2.3