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/TripWireTile.cpp | 221 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 221 insertions(+) create mode 100644 Minecraft.World/TripWireTile.cpp (limited to 'Minecraft.World/TripWireTile.cpp') diff --git a/Minecraft.World/TripWireTile.cpp b/Minecraft.World/TripWireTile.cpp new file mode 100644 index 00000000..40ad93f8 --- /dev/null +++ b/Minecraft.World/TripWireTile.cpp @@ -0,0 +1,221 @@ +#include "stdafx.h" +#include "net.minecraft.world.item.h" +#include "net.minecraft.world.level.h" +#include "net.minecraft.world.level.tile.h" +#include "net.minecraft.world.phys.h" +#include "TripWireTile.h" + +TripWireTile::TripWireTile(int id) : Tile(id, Material::decoration, isSolidRender()) +{ + setShape(0, 0, 0, 1, 2.5f / 16.0f, 1); + this->setTicking(true); +} + +int TripWireTile::getTickDelay(Level *level) +{ + // 4J: Increased (x2); quick update caused problems with shared + // data between client and server. + return 20; // 10; +} + +AABB *TripWireTile::getAABB(Level *level, int x, int y, int z) +{ + return NULL; +} + +bool TripWireTile::blocksLight() +{ + return false; +} + +bool TripWireTile::isSolidRender(bool isServerLevel) +{ + return false; +} + +bool TripWireTile::isCubeShaped() +{ + return false; +} + +int TripWireTile::getRenderLayer() +{ + return 1; +} + +int TripWireTile::getRenderShape() +{ + return Tile::SHAPE_TRIPWIRE; +} + +int TripWireTile::getResource(int data, Random *random, int playerBonusLevel) +{ + return Item::string_Id; +} + +int TripWireTile::cloneTileId(Level *level, int x, int y, int z) +{ + return Item::string_Id; +} + +void TripWireTile::neighborChanged(Level *level, int x, int y, int z, int type) +{ + int data = level->getData(x, y, z); + bool wasSuspended = (data & MASK_SUSPENDED) == MASK_SUSPENDED; + bool isSuspended = !level->isTopSolidBlocking(x, y - 1, z); + if (wasSuspended != isSuspended) + { + spawnResources(level, x, y, z, data, 0); + level->setTile(x, y, z, 0); + } +} + +void TripWireTile::updateShape(LevelSource *level, int x, int y, int z, int forceData, shared_ptr forceEntity) +{ + int data = level->getData(x, y, z); + bool attached = (data & MASK_ATTACHED) == MASK_ATTACHED; + bool suspended = (data & MASK_SUSPENDED) == MASK_SUSPENDED; + + if (!suspended) + { + setShape(0, 0, 0, 1, 1.5f / 16.0f, 1); + } + else if (!attached) + { + setShape(0, 0, 0, 1, 8.0f / 16.0f, 1); + } + else + { + setShape(0, 1.0f / 16.0f, 0, 1, 2.5f / 16.0f, 1); + } +} + +void TripWireTile::onPlace(Level *level, int x, int y, int z) +{ + int data = level->isTopSolidBlocking(x, y - 1, z) ? 0 : MASK_SUSPENDED; + level->setData(x, y, z, data); + updateSource(level, x, y, z, data); +} + +void TripWireTile::onRemove(Level *level, int x, int y, int z, int id, int data) +{ + updateSource(level, x, y, z, data | MASK_POWERED); +} + +void TripWireTile::playerWillDestroy(Level *level, int x, int y, int z, int data, shared_ptr player) +{ + if (level->isClientSide) return; + + if (player->getSelectedItem() != NULL && player->getSelectedItem()->id == Item::shears_Id) + { + level->setData(x, y, z, data | MASK_DISARMED); + } +} + +void TripWireTile::updateSource(Level *level, int x, int y, int z, int data) +{ + for (int dir = 0; dir < 2; dir++) + { + for (int i = 1; i < TripWireSourceTile::WIRE_DIST_MAX; i++) + { + int xx = x + Direction::STEP_X[dir] * i; + int zz = z + Direction::STEP_Z[dir] * i; + int tile = level->getTile(xx, y, zz); + + if (tile == Tile::tripWireSource_Id) + { + int sourceDir = level->getData(xx, y, zz) & TripWireSourceTile::MASK_DIR; + + if (sourceDir == Direction::DIRECTION_OPPOSITE[dir]) + { + Tile::tripWireSource->calculateState(level, xx, y, zz, tile, level->getData(xx, y, zz), true, i, data); + } + + break; + } + else if (tile != Tile::tripWire_Id) + { + break; + } + } + } +} + +void TripWireTile::entityInside(Level *level, int x, int y, int z, shared_ptr entity) +{ + if (level->isClientSide) return; + + if ((level->getData(x, y, z) & MASK_POWERED) == MASK_POWERED) return; + + checkPressed(level, x, y, z); +} + +void TripWireTile::tick(Level *level, int x, int y, int z, Random *random) +{ + if (level->isClientSide) return; + + if ((level->getData(x, y, z) & MASK_POWERED) != MASK_POWERED) return; + + checkPressed(level, x, y, z); +} + +void TripWireTile::checkPressed(Level *level, int x, int y, int z) +{ + int data = level->getData(x, y, z); + bool wasPressed = (data & MASK_POWERED) == MASK_POWERED; + bool shouldBePressed = false; + + ThreadStorage *tls = (ThreadStorage *)TlsGetValue(Tile::tlsIdxShape); + vector > *entities = level->getEntities(nullptr, AABB::newTemp(x + tls->xx0, y + tls->yy0, z + tls->zz0, x + tls->xx1, y + tls->yy1, z + tls->zz1)); + if (!entities->empty()) + { + shouldBePressed = true; + } + + if (shouldBePressed && !wasPressed) + { + data |= MASK_POWERED; + } + + if (!shouldBePressed && wasPressed) + { + data &= ~MASK_POWERED; + } + + if (shouldBePressed != wasPressed) + { + level->setData(x, y, z, data); + updateSource(level, x, y, z, data); + } + + if (shouldBePressed) + { + level->addToTickNextTick(x, y, z, id, getTickDelay(level)); + } +} + +bool TripWireTile::shouldConnectTo(LevelSource *level, int x, int y, int z, int data, int dir) +{ + int tx = x + Direction::STEP_X[dir]; + int ty = y; + int tz = z + Direction::STEP_Z[dir]; + int t = level->getTile(tx, ty, tz); + bool suspended = (data & MASK_SUSPENDED) == MASK_SUSPENDED; + + if (t == Tile::tripWireSource_Id) + { + int otherData = level->getData(tx, ty, tz); + int facing = otherData & TripWireSourceTile::MASK_DIR; + + return facing == Direction::DIRECTION_OPPOSITE[dir]; + } + + if (t == Tile::tripWire_Id) + { + int otherData = level->getData(tx, ty, tz); + bool otherSuspended = (otherData & MASK_SUSPENDED) == MASK_SUSPENDED; + return suspended == otherSuspended; + } + + return false; +} -- cgit v1.2.3