Fixed door destroy logic

This commit is contained in:
mschiller890
2026-03-12 19:17:32 +01:00
parent f17a11c670
commit b4f54083dc
2 changed files with 22 additions and 7 deletions

View File

@@ -165,7 +165,8 @@ void DoorTile::neighborChanged(Level* level, int x, int y, int z, int type) {
}
if (spawn) {
if (!level->isClientSide) {
spawnResources(level, x, y, z, data, 0);
// use default chance (1.0) so the drop always occurs
spawnResources(level, x, y, z, data);
}
} else {
bool signal = level->hasNeighborSignal(x, y, z) || level->hasNeighborSignal(x, y + 1, z);
@@ -174,13 +175,12 @@ void DoorTile::neighborChanged(Level* level, int x, int y, int z, int type) {
}
}
} else {
// upper half: removal should not drop a second door. the
// lower half neighbour handler takes care of spawning the item
// whenever the door is broken from either end.
if (level->getTile(x, y - 1, z) != id) {
level->setTile(x, y, z, 0);
if(material == Material::metal) {
popResource(level, x, y, z, ItemInstance(Item::door_iron));
} else {
popResource(level, x, y, z, ItemInstance(Item::door_wood));
}
// no resource spawn here
}
if (type > 0 && type != id) {
neighborChanged(level, x, y - 1, z, type);
@@ -189,7 +189,11 @@ void DoorTile::neighborChanged(Level* level, int x, int y, int z, int type) {
}
int DoorTile::getResource(int data, Random* random) {
if ((data & 8) != 0) return 0;
// only the lower half should return a resource ID; the upper half
// itself never drops anything and playerDestroy suppresses spawning
// from the top. This prevents duplicate drops if the bottom half is
// mined.
if ((data & UPPER_BIT) != 0) return 0;
if (material == Material::metal) return Item::door_iron->id;
return Item::door_wood->id;
}
@@ -199,6 +203,14 @@ HitResult DoorTile::clip(Level* level, int xt, int yt, int zt, const Vec3& a, co
return super::clip(level, xt, yt, zt, a, b);
}
// override to prevent double-dropping when top half is directly mined
void DoorTile::playerDestroy(Level* level, Player* player, int x, int y, int z, int data) {
if ((data & UPPER_BIT) == 0) {
// only let the lower half handle the actual spawning
super::playerDestroy(level, player, x, y, z, data);
}
}
int DoorTile::getDir(LevelSource* level, int x, int y, int z) {
return getCompositeData(level, x, y, z) & C_DIR_MASK;
}

View File

@@ -49,6 +49,9 @@ public:
int getResource(int data, Random* random);
// override to avoid duplicate drops when upper half is mined directly
void playerDestroy(Level* level, Player* player, int x, int y, int z, int data) override;
HitResult clip(Level* level, int xt, int yt, int zt, const Vec3& a, const Vec3& b);
int getDir(LevelSource* level, int x, int y, int z);