internal void CheckBlock(ushort x, ushort y, ushort z) { byte bHead = level.GetTile(x, y, z); byte bFeet = level.GetTile(x, (ushort)(y - 1), z); HandleWalkthrough handler = BlockBehaviour.walkthroughHandlers[bHead]; if (handler != null && handler(this, bHead, x, y, z)) { lastWalkthrough = level.PosToInt(x, y, z); return; } handler = BlockBehaviour.walkthroughHandlers[bFeet]; if (handler != null && handler(this, bFeet, x, (ushort)(y - 1), z)) { lastWalkthrough = level.PosToInt(x, (ushort)(y - 1), z); return; } lastWalkthrough = level.PosToInt(x, y, z); if ((bHead == Block.tntexplosion || bFeet == Block.tntexplosion) && PlayingTntWars) { return; } if (Block.Props[bHead].KillerBlock) { HandleDeath(bHead, 0); } else if (Block.Props[bFeet].KillerBlock) { HandleDeath(bFeet, 0); } }
internal static void Walkthrough(Player p, AABB bb) { Vec3S32 min = bb.BlockMin, max = bb.BlockMax; bool hitWalkthrough = false; for (int y = min.Y; y <= max.Y; y++) { for (int z = min.Z; z <= max.Z; z++) { for (int x = min.X; x <= max.X; x++) { ushort xP = (ushort)x, yP = (ushort)y, zP = (ushort)z; ExtBlock block = p.level.GetBlock(xP, yP, zP); if (block.BlockID == Block.Invalid) { continue; } AABB blockBB = p.level.blockAABBs[block.Index].Offset(x * 32, y * 32, z * 32); if (!AABB.Intersects(ref bb, ref blockBB)) { continue; } // We can activate only one walkthrough block per movement if (!hitWalkthrough) { HandleWalkthrough handler = p.level.walkthroughHandlers[block.Index]; if (handler != null && handler(p, block, xP, yP, zP)) { p.lastWalkthrough = p.level.PosToInt(xP, yP, zP); hitWalkthrough = true; } } // Some blocks will cause death of players if (!p.level.Props[block.Index].KillerBlock) { continue; } if (block.BlockID == Block.TNT_Explosion && p.PlayingTntWars) { continue; // TODO: hardcoded behaviour is icky } if (block.BlockID == Block.Train && p.trainInvincible) { continue; } p.HandleDeath(block); } } } if (!hitWalkthrough) { p.lastWalkthrough = -1; } }