/// <summary> /// Tests if the player is overlapping a block /// </summary> /// <param name="p">The player</param> private bool Overlaps(WorldPlayer p) { if ((p.X < 0 || p.Y < 0) || ((p.X > World.Width * 16 - 16) || (p.Y > World.Height * 16 - 16))) { return(true); } if (p.IsGod()) { return(false); } var firstX = ((int)p.X >> 4); var firstY = ((int)p.Y >> 4); double lastX = (p.X + 16) / 16; double lastY = (p.Y + 16) / 16; bool skip = false; int x; int y = firstY; int a = firstY; int b; while (y < lastY) { x = firstX; b = firstX; for (; x < lastX; x++) { Block block = World[x, y, Layer.Foreground]; BlockID tileId = block.ID; if (IsSolid(tileId)) { if (CanJumpThrough(tileId)) { uint rot = 0; if (block is RotatableBlock) { RotatableBlock rotatableBlock = (RotatableBlock)block; rot = (uint)rotatableBlock.Rotation; } if (tileId == BlockID.OneWayCyan || tileId == BlockID.OneWayPink || tileId == BlockID.OneWayRed || tileId == BlockID.OneWayYellow) { if ((p.SpeedY < 0 || a <= p.m_overlapy) && rot == 1) { if (a != firstY || p.m_overlapy == -1) { p.m_overlapy = a; } skip = true; continue; } if ((p.SpeedX > 0 || b <= p.m_overlapy) && rot == 2) { if (b == firstX || p.m_overlapy == -1) { p.m_overlapy = b; } skip = true; continue; } if ((p.SpeedY > 0 || a <= p.m_overlapy) && rot == 3) { if (a == firstY || p.m_overlapy == -1) { p.m_overlapy = a; } skip = true; continue; } if ((p.SpeedX < 0 || b <= p.m_overlapy) && rot == 0) { if (b != firstX || p.m_overlapy == -1) { p.m_overlapy = b; } skip = true; continue; } } else { if (p.SpeedY < 0 || a <= p.m_overlapy) { if (a != y || p.m_overlapy == -1) { p.m_overlapy = a; } skip = true; continue; } } } switch (tileId) { case (BlockID)23: if (m_WorldConnection.Keys.IsKeyActive(Key.Red)) { continue; } break; case (BlockID)24: if (m_WorldConnection.Keys.IsKeyActive(Key.Green)) { continue; } break; case (BlockID)25: if (m_WorldConnection.Keys.IsKeyActive(Key.Blue)) { continue; } break; case (BlockID)26: if (m_WorldConnection.Keys.IsKeyHidden(Key.Red)) { continue; } break; case (BlockID)27: if (m_WorldConnection.Keys.IsKeyHidden(Key.Green)) { continue; } break; case (BlockID)28: if (m_WorldConnection.Keys.IsKeyHidden(Key.Blue)) { continue; } break; case (BlockID)156: if (m_WorldConnection.Keys.IsKeyHidden(Key.TimeDoor)) { continue; } break; case (BlockID)157: if (m_WorldConnection.Keys.IsKeyActive(Key.TimeDoor)) { continue; } break; case BlockID.CyanDoor: if (m_WorldConnection.Keys.IsKeyActive(Key.Cyan)) { continue; } break; case BlockID.MagentaDoor: if (m_WorldConnection.Keys.IsKeyActive(Key.Magenta)) { continue; } break; case BlockID.YellowDoor: if (m_WorldConnection.Keys.IsKeyActive(Key.Yellow)) { continue; } break; case BlockID.CyanGate: if (m_WorldConnection.Keys.IsKeyHidden(Key.Cyan)) { continue; } break; case BlockID.MagentaGate: if (m_WorldConnection.Keys.IsKeyHidden(Key.Magenta)) { continue; } break; case BlockID.YellowGate: if (m_WorldConnection.Keys.IsKeyHidden(Key.Yellow)) { continue; } break; case BlockID.PurpleSwitchDoor: { PurpleBlock purpleBlock = (PurpleBlock)World[x, y, Layer.Foreground]; if (p.m_switches[purpleBlock.SwitchID]) { continue; } } break; case BlockID.PurpleSwitchGate: { PurpleBlock purpleBlock = (PurpleBlock)World[x, y, Layer.Foreground]; if (!p.m_switches[purpleBlock.SwitchID]) { continue; } } break; case BlockID.DeathDoor: { DeathBlock deathBlock = (DeathBlock)World[x, y, Layer.Foreground]; if (p.m_deaths >= deathBlock.RequiredDeaths) { continue; } } break; case BlockID.DeathGate: { DeathBlock deathBlock = (DeathBlock)World[x, y, Layer.Foreground]; if (p.m_deaths < deathBlock.RequiredDeaths) { continue; } } break; case BlockID.DoorBuildersClub: if (p.HasBuildersClub) { continue; } break; case BlockID.GateBuildersClub: if (!p.HasBuildersClub) { continue; } break; case BlockID.CoinDoor: case BlockID.BlueCoinDoor: { CoinBlock coinBlock = (CoinBlock)World[x, y, Layer.Foreground]; if (coinBlock.Goal <= p.GoldCoins) { continue; } } break; case BlockID.CoinGate: case BlockID.BlueCoinGate: { CoinBlock coinBlock = (CoinBlock)World[x, y, Layer.Foreground]; if (coinBlock.Goal > p.BlueCoins) { continue; } } break; case BlockID.GateZombie: { if (p.HasPotionActive(Potion.Zombie)) { continue; } } break; case BlockID.DoorZombie: { if (!p.HasPotionActive(Potion.Zombie)) { continue; } } break; case (BlockID)61: case (BlockID)62: case (BlockID)63: case (BlockID)64: case (BlockID)89: case (BlockID)90: case (BlockID)91: case (BlockID)96: case (BlockID)97: case (BlockID)122: case (BlockID)123: case (BlockID)124: case (BlockID)125: case (BlockID)126: case (BlockID)127: case (BlockID)146: case (BlockID)154: case (BlockID)158: case (BlockID)194: case (BlockID)211: if (p.SpeedY < 0 || y <= p.m_overlapy) { if (y != firstY || p.m_overlapy == -1) { p.m_overlapy = y; } skip = true; continue; } break; case (BlockID)83: case (BlockID)77: continue; } return(true); } } y++; } if (!skip) { p.m_overlapy = -1; } return(false); }