Nowotwór jamy ustnej
Etiologia i przyczyny

Nowotwór jamy ustnej jest szóstym najczęściej występującym nowotworem złośliwym na świecie, z roczną liczbą diagnoz w USA wynoszącą około 53 000-59 000 przypadków. Choroba dotyka głównie mężczyzn po 40. roku życia, a ponad 90% przypadków stanowią raki płaskonabłonkowe, powstające z mutacji komórek nabłonka płaskiego w obrębie warg i jamy ustnej. Kluczowymi czynnikami ryzyka są używanie tytoniu (wszystkie formy, w tym tytoń bezdymny, który zwiększa ryzyko nawet 50-krotnie) oraz nadmierne spożycie alkoholu, które podnosi ryzyko 5-krotnie. Synergistyczne działanie tytoniu i alkoholu może zwiększyć ryzyko rozwoju nowotworu jamy ustnej nawet 30-50-krotnie, a u kobiet nawet 100-krotnie. Zmiany genetyczne w genach p53 i H-ras są powiązane z ekspozycją na kancerogeny zawarte w dymie tytoniowym.

Nowotwór jamy ustnej – etiologia

Nowotwór jamy ustnej stanowi poważny problem zdrowotny, będący szóstym najczęściej występującym nowotworem złośliwym na świecie1. W Stanach Zjednoczonych każdego roku diagnozuje się około 53 000-59 000 nowych przypadków nowotworów jamy ustnej i części ustnej gardła234. Nowotwór ten dotyka mężczyzn ponad dwukrotnie częściej niż kobiety i najczęściej diagnozowany jest u osób powyżej 40 roku życia56.

Patogeneza nowotworów jamy ustnej

Nowotwór jamy ustnej powstaje, gdy komórki na wargach lub wewnątrz jamy ustnej ulegają mutacji. Najczęściej proces ten rozpoczyna się w płaskich, cienkich komórkach nabłonkowych (nabłonek płaski) wyściełających wargi i wnętrze jamy ustnej, zwanych komórkami płaskonabłonkowymi7. Ponad 90% nowotworów jamy ustnej to właśnie raki płaskonabłonkowe89.

Proces nowotworowy zaczyna się, gdy w DNA komórek nabłonkowych zachodzą zmiany, które powodują nieprawidłowe instrukcje dla komórek. W zdrowych komórkach DNA zawiera informacje mówiące komórce, jak rosnąć i rozmnażać się w określonym tempie oraz kiedy umrzeć. W komórkach nowotworowych zmiany w DNA dają inne instrukcje – nakazują komórkom nowotworowym szybko rosnąć i mnożyć się, a także utrzymywać się przy życiu, gdy zdrowe komórki powinny obumrzeć10.

W rezultacie powstaje zbyt wiele komórek, które mogą tworzyć masę zwaną guzem. Guz może rosnąć, naciekać i niszczyć zdrowe tkanki. Z czasem komórki nowotworowe mogą oderwać się i rozprzestrzenić do innych części ciała, co określa się jako nowotwór przerzutowy1112.

Główne czynniki ryzyka

Tytoń jako podstawowy czynnik ryzyka

Używanie tytoniu jest najważniejszym czynnikiem ryzyka rozwoju nowotworów jamy ustnej, odpowiadającym za znaczącą większość przypadków13. Wszystkie formy tytoniu zwiększają ryzyko, w tym papierosy, cygara, fajki, tytoń do żucia oraz tabaka14. Dym tytoniowy zawiera liczne kancerogeny chemiczne, w tym węglowodory aromatyczne takie jak benzopiren i nitrozoaminy, które mogą powodować specyficzne zmiany genetyczne w genach p53 i H-ras15.

Badania pokazują, że około 75% osób, u których rozwija się nowotwór jamy ustnej, używa tytoniu16. Według Fundacji Nowotworów Jamy Ustnej, osoby używające tytoniu mają 6-krotnie wyższe ryzyko rozwoju nowotworów głowy i szyi, a 75% nowotworów jamy ustnej i gardła występuje u użytkowników tytoniu17. Palacze mają 20-krotnie wyższe ryzyko rozwoju nowotworów jamy ustnej niż osoby niepalące18.

Szczególnie niebezpieczny jest tytoń bezdymny (do żucia), który zwiększa ryzyko nowotworów policzka, dziąseł i warg nawet 50-krotnie w porównaniu do osób nieużywających1920. W Wielkiej Brytanii około 17% nowotworów jamy ustnej jest spowodowanych paleniem tytoniu21.

Alkohol jako istotny czynnik ryzyka

Nadmierne spożycie alkoholu jest drugim najważniejszym czynnikiem ryzyka nowotworów jamy ustnej22. Osoby nadużywające alkoholu mają 5-krotnie wyższe ryzyko rozwoju nowotworów jamy ustnej23. Według badań, około 70% osób z diagnozą nowotworu jamy ustnej to osoby intensywnie spożywające alkohol24.

W Wielkiej Brytanii alkohol jest przyczyną około 35% przypadków nowotworów jamy ustnej25, a w Australii odpowiada za około 31% przypadków26. Mechanizm kancerogenny alkoholu związany jest z jego działaniem drażniącym na komórki jamy ustnej oraz z osłabieniem układu odpornościowego, co utrudnia organizmowi walkę z nieprawidłowymi komórkami27.

Synergistyczne działanie tytoniu i alkoholu

Szczególnie niebezpieczne jest łączne używanie tytoniu i alkoholu, gdyż te czynniki działają synergistycznie, znacząco zwiększając ryzyko rozwoju nowotworu jamy ustnej2829. Osoby, które zarówno palą tytoń, jak i intensywnie spożywają alkohol, mają nawet 30-50-krotnie wyższe ryzyko rozwoju nowotworów jamy ustnej niż osoby, które nie stosują tych używek3031.

Alkohol może działać jako rozpuszczalnik ułatwiający przenikanie kancerogenów z tytoniu do tkanek jamy ustnej, a także wspiera działanie kancerogenne tytoniu poprzez wpływ na komórki i prowokowanie zmian nowotworowych32. Według badań, kombinacja intensywnego palenia i intensywnego picia alkoholu zwiększa ryzyko 100-krotnie u kobiet i 38-krotnie u mężczyzn33.

Zakażenia wirusowe jako czynnik etiologiczny

Wirus brodawczaka ludzkiego (HPV)

Zakażenie wirusem brodawczaka ludzkiego (HPV), szczególnie typem HPV-16, zostało zidentyfikowane jako istotny czynnik ryzyka nowotworów jamy ustnej i gardła3435. Związek między HPV a nowotworami części ustnej gardła (oropharynx) jest silniejszy niż w przypadku nowotworów jamy ustnej36.

HPV odpowiada za około 50% nowotworów części ustnej gardła w Wielkiej Brytanii37 i nawet 70% w Stanach Zjednoczonych38. Wirus HPV jest przenoszony głównie poprzez kontakt seksualny, w tym seks oralny39.

HPV może zmieniać normalne cechy komórkowe nabłonka jamy ustnej, co może prowadzić do rozwoju nowotworów40. W ostatnich latach wzrosła liczba przypadków nowotworów jamy ustnej związanych z HPV, szczególnie u młodszych osób, które nigdy nie paliły tytoniu4142.

Inne wirusy jako potencjalne czynniki ryzyka

Poza HPV, inne wirusy również mogą odgrywać rolę w rozwoju nowotworów jamy ustnej:

  • Wirus Epsteina-Barr (EBV) – został powiązany z nowotworami gardła nosowego i może zwiększać ryzyko nowotworów jamy ustnej4344
  • Wirusy z grupy Herpes – były impliko• Author — Allen Antony Ukani
    • Contact — auks256ATcs.washington.edu
    • Created Date — 08.2.2012
    • Last Modified Date — 10.10.2012
    • Last Modified By — Allen Antony Ukani
    */

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace LegendOfZelda
    {
    public static class GameContext
    {
    ///

    /// Store the current state of the game.
    ///

    public static class State
    {
    ///

    /// The screen displayed in-game
    ///

    public enum Screen
    {
    Title,
    FileSelect,
    Game,
    Inventory,
    GameOver,
    Win,
    Credits
    }

    ///

    /// The current screen displayed to the user.
    ///

    public static Screen CurrentScreen = Screen.Title;

    ///

    /// True if the game is paused, false otherwise.
    ///

    public static bool Paused = false;

    ///

    /// True if the Link is moving between screens, false otherwise
    ///

    public static bool TransitioningScreens = false;

    public enum MovementDirection
    {
    None, North, South, East, West
    }

    ///

    /// The direction that Link is moving towards while transitioning between screens
    ///

    public static MovementDirection TransitionDirection = MovementDirection.None;

    ///

    /// Flag to state if the door movement has started or not
    ///

    public static bool DoorTransitionStarted = false;

    ///

    /// True if Link is frozen in place (can’t move).
    ///

    public static bool LinkIsFrozen = false;

    ///

    /// Key Value pair to check whether transitions is happening in both directions or not by storing the entering room’s keys
    ///

    public static Dictionary<Tuple, IList<Tuple>> transitionCache = new Dictionary<Tuple, IList<Tuple>>();

    ///

    /// True if Link is dying
    ///

    public static bool IsDying = false;

    ///

    /// Transitioning from the Link Death screen to the Game Over screen
    ///

    public static bool LinkDeathToGameOver = false;
    }

    /* Tracking game world and level information */
    public static class World
    {
    ///

    /// Gets the room at the given row and column.
    ///

    /// The row of the room
    /// The column of the room
    /// The room at the given row and column
    public static Room GetRoom(int row, int col)
    {
    if (CurrentWorldRoom == null)
    {
    CurrentWorldRoom = RoomFactory.CreateRoom(row, col);
    CurrentRoomTileSet = new TileSet(CurrentWorldRoom.TileMap, row, col);
    }
    else if (CurrentWorldRoom.RoomRow != row || CurrentWorldRoom.RoomCol != col)
    {
    CurrentWorldRoom = RoomFactory.CreateRoom(row, col);
    CurrentRoomTileSet = new TileSet(CurrentWorldRoom.TileMap, row, col);
    }
    return CurrentWorldRoom;
    }

    ///

    /// The current room being explored (lazily-evaluated)
    ///

    private static Room currentWorldRoom = null;

    public static Room CurrentWorldRoom
    {
    get
    {
    if (currentWorldRoom == null)
    {
    currentWorldRoom = RoomFactory.CreateRoom(CurrentRoomRow, CurrentRoomCol);
    }
    return currentWorldRoom;
    }
    set
    {
    currentWorldRoom = value;
    }
    }

    ///

    /// Get the tileset for the current room
    ///

    private static TileSet currentRoomTileSet = null;
    public static TileSet CurrentRoomTileSet
    {
    get
    {
    if (currentRoomTileSet == null && CurrentWorldRoom != null)
    {
    currentRoomTileSet = new TileSet(CurrentWorldRoom.TileMap, CurrentRoomRow, CurrentRoomCol);
    }
    return currentRoomTileSet;
    }
    set
    {
    currentRoomTileSet = value;
    }
    }

    ///

    /// The row of the current room
    ///

    public static int CurrentRoomRow = 7;

    ///

    /// The column of the current room
    ///

    public static int CurrentRoomCol = 7;
    }

    ///

    /// Provide information about the game Window
    ///

    public static class Window
    {
    ///

    /// The horizontal size (in pixels) of the game window.
    ///

    public static int Width = 768; //512; //768; //512; //768

    ///

    /// The vertical size (in pixels) of the game window.
    ///

    public static int Height = 672; //448; //672; //448; //672

    ///

    /// Get the horizontal center of the game window.
    ///

    public static int CenterX
    {
    get
    {
    return Width / 2;
    }
    }

    ///

    /// Get the vertical center of the game window.
    ///

    public static int CenterY
    {
    get
    {
    return Height / 2;
    }
    }

    ///

    /// Get the width of the in-game room
    ///

    public static int RoomWidth
    {
    get
    {
    return 256 * Scale;
    }
    }

    ///

    /// Get the width of the in-game room * the sprite scale
    ///

    public static int ScaledRoomWidth
    {
    get
    {
    return 256 * Scale;
    }
    }

    ///

    /// Get the height of the in-game room
    ///

    public static int RoomHeight
    {
    get
    {
    return 176 * Scale;
    }
    }

    ///

    /// Get the height of the in-game room * the sprite scale
    ///

    public static int ScaledRoomHeight
    {
    get
    {
    return 176 * Scale;
    }
    }

    ///

    /// Get the X coordinate of the top-left corner of the in-game room
    ///

    public static int RoomX
    {
    get
    {
    return (Width – ScaledRoomWidth) / 2;
    }
    }

    ///

    /// Get the Y coordinate of the top-left corner of the in-game room
    ///

    public static int RoomY
    {
    get
    {
    return ((Height – ScaledRoomHeight) / 2) + 56;
    }
    }

    ///

    /// The scale at which sprites should be rendered in the window.
    ///

    public static int Scale = 3;
    }
    }
    }

    # auks256/cse3902
    /* Author — Allen Antony Ukani
    * Contact — auks256ATcs.washington.edu
    * Created Date — 10.15.2012
    * Last Modified Date — 10.17.2012
    * Last Modified By — Allen Antony Ukani
    */

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace LegendOfZelda
    {
    public class PlayerState : ICloneable
    {
    #region Constants
    // Default values taken from NES version of Zelda

    ///

    /// This is the cap on Link’s health. All values should match this.
    ///

    public static readonly int MAX_HEALTH = 16;

    ///

    /// Link’s maximum health with no Heart Containers
    ///

    public static readonly int MAX_HEALTH_BASE = 3;

    ///

    /// Link’s default health
    ///

    public static readonly int DEFAULT_HEALTH = 3;

    ///

    /// Number of Rupees that Link starts out with
    ///

    public static readonly int DEFAULT_RUPEE_COUNT = 0;

    ///

    /// Max number of Keys that Link can have
    ///

    public static readonly int MAX_KEY_COUNT = 9;

    ///

    /// Max number of Bombs that Link can have
    ///

    public static readonly int MAX_BOMB_COUNT = 9;

    ///

    /// Default number of arrows for Link to have
    ///

    public static readonly int DEFAULT_ARROW_COUNT = 0;

    ///

    /// The maximum number of arrows Link can carry
    ///

    public static readonly int MAX_ARROW_COUNT = 30;

    ///

    /// Which item slot the boomerang goes in (0-indexed)
    ///

    public static readonly int BOOMERANG_SLOT = 0;

    ///

    /// Which item slot the bomb goes in (0-indexed)
    ///

    public static readonly int BOMB_SLOT = 1;

    ///

    /// Which item slot the bow goes in (0-indexed)
    ///

    public static readonly int BOW_SLOT = 2;

    ///

    /// Which item slot the candle goes in (0-indexed)
    ///

    public static readonly int CANDLE_SLOT = 3;

    ///

    /// Which item slot the whistle goes in (0-indexed)
    ///

    public static readonly int WHISTLE_SLOT = 4;

    ///

    /// Which item slot the meat goes in (0-indexed)
    ///

    public static readonly int MEAT_SLOT = 5;

    ///

    /// Which item slot the potion goes in (0-indexed)
    ///

    public static readonly int POTION_SLOT = 6;

    ///

    /// Which item slot the wand goes in (0-indexed)
    ///

    public static readonly int WAND_SLOT = 7;

    ///

    /// The total number of equippable item slots available
    ///

    public static readonly int NUM_ITEM_SLOTS = 8;

    ///

    /// The max number of lives that Link can have
    ///

    public static readonly int MAX_LIFE_COUNT = 9;

    ///

    /// Max number of rupees that Link can hold
    ///

    public static readonly int MAX_RUPEE_COUNT = 255;

    ///

    /// The number of Triforce segments to collect
    ///

    public static readonly int MAX_TRIFORCE_COUNT = 8;

    #endregion

    public enum Weapon
    {
    None,
    Sword,
    WhiteSword,
    MagicalSword,
    Wand
    }

    // Life and equipment info
    private int health;

    ///

    /// Link’s current health
    ///

    public int Health
    {
    get { return health; }
    set
    {
    if (value > MaxHealth) health = MaxHealth;
    else health = value;
    }
    }

    private int maxHealth;

    ///

    /// Link’s current max health
    ///

    public int MaxHealth
    {
    get { return maxHealth; }
    set
    {
    if (value > MAX_HEALTH)
    maxHealth = MAX_HEALTH;
    else
    maxHealth = value;
    }
    }

    ///

    /// Number of life hearts Link has
    ///

    public int LifeCount { get; set; }

    ///

    /// Number of Rupees Link has
    ///

    public int RupeeCount { get; set; }

    ///

    /// Number of Keys Link has
    ///

    public int KeyCount { get; set; }

    ///

    /// Number of Bombs Link has
    ///

    public int BombCount { get; set; }

    ///

    /// Number of Arrows Link has
    ///

    public int ArrowCount { get; set; }

    ///

    /// Which weapon is Link using
    ///

    public Weapon CurrentWeapon { get; set; }

    // Item inventory info
    private bool[] hasItemInSlot;

    ///

    /// Access the inventory slot for a specific item, retrieved by index
    ///

    /// The index of the slot to check
    /// True if Link has the item in the given slot, false otherwise
    public bool HasItemInSlot(int slotIndex)
    {
    return hasItemInSlot[slotIndex];
    }

    ///

    /// Set whether Link has the item in a specific slot
    ///

    /// The index of the slot to set
    /// True if Link should have the item, false otherwise
    public void SetItemInSlot(int slotIndex, bool value)
    {
    hasItemInSlot[slotIndex] = value;
    }

    ///

    /// Clear Link’s inventory
    ///

    public void ClearInventory()
    {
    for (int i = 0; i < hasItemInSlot.Length; i++)
    {
    hasItemInSlot[i] = false;
    }
    }

    ///

    /// The currently selected item’s inventory slot
    ///

    public int CurrentItemSlot { get; set; }

    // Game world info
    protected bool[] hasDungeonMap;

    ///

    /// Get whether Link has the dungeon map for a specific dungeon ID
    ///

    /// Which dungeon’s map to check (0-indexed)
    /// True if Link has the map for the given dungeon, false otherwise
    public bool HasDungeonMap(int dungeonId)
    {
    return hasDungeonMap[dungeonId];
    }

    ///

    /// Set whether Link has the map for a specific dungeon
    ///

    /// Which dungeon’s map to set (0-indexed)
    /// True if Link should have the dungeon map, false otherwise
    public void SetDungeonMap(int dungeonId, bool value)
    {
    hasDungeonMap[dungeonId] = value;
    }

    ///

    /// Clear all dungeon maps from Link’s inventory.
    ///

    public void ClearDungeonMaps()
    {
    for (int i = 0; i < hasDungeonMap.Length; i++)
    {
    hasDungeonMap[i] = false;
    }
    }

    protected bool[] hasCompass;

    ///

    /// Get whether Link has the compass for a specific dungeon ID
    ///

    /// Which dungeon’s compass to check (0-indexed)
    /// True if Link has the compass for the given dungeon, false otherwise
    public bool HasCompass(int dungeonId)
    {
    return hasCompass[dungeonId];
    }

    ///

    /// Set whether Link has the compass for a specific dungeon
    ///

    /// Which dungeon’s compass to set (0-indexed)
    /// True if Link should have the dungeon’s compass, false otherwise
    public void SetCompass(int dungeonId, bool value)
    {
    hasCompass[dungeonId] = value;
    }

    ///

    /// Clear all compass items from Link’s inventory.
    ///

    public void ClearCompasses()
    {
    for (int i = 0; i < hasCompass.Length; i++)
    {
    hasCompass[i] = false;
    }
    }

    protected bool[] hasTriforcePiece;

    ///

    /// Get whether Link has a specific Triforce piece
    ///

    /// Which Triforce piece to check (0-indexed)
    /// True if Link has the specific Triforce piece, false otherwise
    public bool HasTriforcePiece(int pieceId)
    {
    return hasTriforcePiece[pieceId];
    }

    ///

    /// Set whether Link has a specific Triforce piece
    ///

    /// Which Triforce piece to set (0-indexed)
    /// True if Link should have the piece, false otherwise
    public void SetTriforcePiece(int pieceId, bool value)
    {
    hasTriforcePiece[pieceId] = value;
    }

    ///

    /// Count how many Triforce pieces Link has collected
    ///

    /// The number of Triforce pieces Link has
    public int GetTriforceCount()
    {
    int result = 0;
    for (int i = 0; i < hasTriforcePiece.Length; i++)
    {
    if (hasTriforcePiece[i]) result++;
    }
    return result;
    }

    ///

    /// Clear all Triforce pieces from Link’s inventory
    ///

    public void ClearTriforces()
    {
    for (int i = 0; i < hasTriforcePiece.Length; i++)
    {
    hasTriforcePiece[i] = false;
    }
    }

    ///

    /// Returns true if Link has the blue candle, false otherwise.
    ///

    public bool HasBlueCandle { get; set; }

    ///

    /// Returns true if Link has the red candle, false otherwise.
    ///

    public bool HasRedCandle { get; set; }

    ///

    /// Returns true if Link has the blue boomerang, false otherwise.
    ///

    public bool HasBlueBoomerang { get; set; }

    ///

    /// Returns true if Link has the blue boomerang, false otherwise.
    ///

    public bool HasMagicBoomerang { get; set; }

    ///

    /// Returns true if Link has the blue ring, false otherwise
    ///

    public bool HasBlueRing { get; set; }

    ///

    /// Returns true if Link has the red ring, false otherwise
    ///

    public bool HasRedRing { get; set; }

    ///

    /// Returns true if Link has the bow, false otherwise.
    ///

    public bool HasBow { get; set; }

    ///

    /// Returns true if Link has the raft.
    ///

    public bool HasRaft { get; set; }

    ///

    /// Returns true if Link has the ladder.
    ///

    public bool HasLadder { get; set; }

    ///

    /// Resets the player state to the starting state of the game.
    ///

    public void Reset()
    {
    // Set up vitals
    Health = DEFAULT_HEALTH;
    MaxHealth = MAX_HEALTH_BASE;
    LifeCount = 0;

    // Set up items
    RupeeCount = DEFAULT_RUPEE_COUNT;
    KeyCount = 0;
    BombCount = 0;
    ArrowCount = 0;

    // Set up item inventory
    for (int i = 0; i < hasItemInSlot.Length; i++)
    {
    hasItemInSlot[i] = false;
    }
    CurrentItemSlot = 0;

    // Set up weapon
    CurrentWeapon = Weapon.None;

    // Set up game world information
    for (int i = 0; i < hasDungeonMap.Length; i++)
    {
    hasDungeonMap[i] = false;
    }
    for (int i = 0; i < hasCompass.Length; i++)
    {
    hasCompass[i] = false;
    }
    for (int i = 0; i < hasTriforcePiece.Length; i++)
    {
    hasTriforcePiece[i] = false;
    }

    HasBlueCandle = false;
    HasRedCandle = false;
    HasBlueBoomerang = false;
    HasMagicBoomerang = false;
    HasBlueRing = false;
    HasRedRing = false;
    HasBow = false;
    HasRaft = false;
    HasLadder = false;
    }

    ///

    /// Set up a debug testing environment for Link
    ///

    public void SetupDebugState()
    {
    MaxHealth = MAX_HEALTH;
    Health = MAX_HEALTH;
    RupeeCount = 255;
    BombCount = 9;
    KeyCount = 9;
    ArrowCount = MAX_ARROW_COUNT;
    HasBow = true;
    HasItemInSlot(BOW_SLOT, true);
    CurrentWeapon = Weapon.Sword;
    HasLadder = true;
    HasBlueBoomerang = true;
    SetItemInSlot(BOOMERANG_SLOT, true);
    SetItemInSlot(BOMB_SLOT, true);
    SetItemInSlot(BOW_SLOT, true);
    }

    ///

    /// Initializes a player state object with the default values
    ///

    public PlayerState()
    {
    // Create arrays for equipment
    hasItemInSlot = new bool[NUM_ITEM_SLOTS];
    hasDungeonMap = new bool[MAX_TRIFORCE_COUNT];
    hasCompass = new bool[MAX_TRIFORCE_COUNT];
    hasTriforcePiece = new bool[MAX_TRIFORCE_COUNT];

    // Set the default state
    Reset();
    }

    ///

    /// Copy constructor
    ///

    /// PlayerState object to copy from
    public PlayerState(PlayerState copy)
    {
    // Create arrays for equipment
    hasItemInSlot = new bool[NUM_ITEM_SLOTS];
    hasDungeonMap = new bool[MAX_TRIFORCE_COUNT];
    hasCompass = new bool[MAX_TRIFORCE_COUNT];
    hasTriforcePiece = new bool[MAX_TRIFORCE_COUNT];

    // Copy over life info
    this.Health = copy.Health;
    this.MaxHealth = copy.MaxHealth;
    this.LifeCount = copy.LifeCount;

    // Copy over equipment
    this.RupeeCount = copy.RupeeCount;
    this.KeyCount = copy.KeyCount;
    this.BombCount = copy.BombCount;
    this.ArrowCount = copy.ArrowCount;

    // Copy over weapons
    this.CurrentWeapon = copy.CurrentWeapon;

    // Copy over item inventory
    for (int i = 0; i < copy.hasItemInSlot.Length; i++)
    {
    this.hasItemInSlot[i] = copy.hasItemInSlot[i];
    }
    this.CurrentItemSlot = copy.CurrentItemSlot;

    // Copy over game world info
    for (int i = 0; i < hasDungeonMap.Length; i++)
    {
    this.hasDungeonMap[i] = copy.hasDungeonMap[i];
    }
    for (int i = 0; i < hasCompass.Length; i++)
    {
    this.hasCompass[i] = copy.hasCompass[i];
    }
    for (int i = 0; i < hasTriforcePiece.Length; i++)
    {
    this.hasTriforcePiece[i] = copy.hasTriforcePiece[i];
    }

    // Copy over item state
    this.HasBlueCandle = copy.HasBlueCandle;
    this.HasRedCandle = copy.HasRedCandle;
    this.HasBlueBoomerang = copy.HasBlueBoomerang;
    this.HasMagicBoomerang = copy.HasMagicBoomerang;
    this.HasBlueRing = copy.HasBlueRing;
    this.HasRedRing = copy.HasRedRing;
    this.HasBow = copy.HasBow;
    this.HasRaft = copy.HasRaft;
    this.HasLadder = copy.HasLadder;
    }

    ///

    /// Clone the current player state
    ///

    /// A copy of the current PlayerState object
    public object Clone()
    {
    return new PlayerState(this);
    }
    }
    }

    /* Original Author — Allen Antony Ukani
    * Original Contact — auks256ATcs.washington.edu
    * Created Date — 10.9.2012
    * Last Modified Date — 10.17.2012
    * Last Modified By — Allen Antony Ukani
    */

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using LegendOfZelda.Items;
    using Microsoft.Xna.Framework;

    namespace LegendOfZelda
    {
    /**
    * Singleton class that manages global game state such as player information.
    *
    * Pattern: Singleton
    * Collaborators: ProjectileManager – manages in-game projectiles
    * CollisionDetector – controls collision detection
    * BlockManager – manages in-game blocks
    */
    public class GameManager
    {
    #region Singleton Instance
    /**
    * Creates a singleton instance of the GameManager. No parameters can be used during creation
    */
    private static GameManager instance;

    public static GameManager Instance
    {
    get
    {
    if (instance == null)
    {
    instance = new GameManager();
    }
    return instance;
    }
    }
    #endregion

    #region Delegates and Events

    // Event fired when Link collects a triforce piece
    public delegate void TriforceCollectedEventHandler(object source, EventArgs args);
    public event TriforceCollectedEventHandler TriforceCollected;
    protected virtual void OnTriforceCollected()
    {
    if (TriforceCollected != null)
    {
    TriforceCollected(this, EventArgs.Empty);
    }
    }

    #endregion

    #region Properties

    private ILink link;
    public ILink Link
    {
    get
    {
    return link;
    }
    set
    {
    link = value;
    }
    }

    ///

    /// Gets the player’s state
    ///

    private PlayerState player;
    public PlayerState Player
    {
    get { return player; }
    }

    ///

    /// The total number of lives Link has (GAME OVER if < 0)
    ///

    private SchedulableStopWatch activeStopWatch;

    public SchedulableStopWatch ActiveStopWatch
    {
    get { return activeStopWatch; }
    set { activeStopWatch = value; }
    }

    ///

    /// Gets the ProjectileManager for the application.
    ///

    private ProjectileManager projectileManager;
    public ProjectileManager ProjectileManager
    {
    get { return projectileManager; }
    }

    ///

    /// Gets the BlockManager for the application.
    ///

    private BlockManager blockManager;
    public BlockManager BlockManager
    {
    get { return blockManager; }
    }

    ///

    /// Gets the collision detector for the application
    ///

    private CollisionDetector collisionDetector;
    public CollisionDetector CollisionDetector
    {
    get { return collisionDetector; }
    }

    ///

    /// Gets the score keeper for the application.
    ///

    private ScoreKeeper scoreKeeper;
    public ScoreKeeper ScoreKeeper
    {
    get { return scoreKeeper; }
    }

    ///

    /// Gets the ParticleManager for the application.
    ///

    private ParticleManager particleManager;
    public ParticleManager ParticleManager
    {
    get { return particleManager; }
    }

    private Dictionary gameFiles = null;

    ///

    /// Gets/sets the dictionary of game files
    ///

    public Dictionary GameFiles
    {
    get
    {
    if (gameFiles == null) ResetGameFiles();
    return gameFiles;
    }
    set { gameFiles = value; }
    }

    #endregion

    #region Methods

    ///

    /// Reset all game files to a blank slate
    ///

    public void ResetGameFiles()
    {
    gameFiles = new Dictionary();
    gameFiles.Add(„file1”, new PlayerState());
    gameFiles.Add(„file2”, new PlayerState());
    gameFiles.Add(„file3”, new PlayerState());
    }

    ///

    /// Check whether the player can have the item based on an enum
    ///

    /// The item from the ItemSprite.ItemType being checked
    /// Returns true if the player can have the item (needs or doesn’t have), or false otherwise
    public bool CanHaveItem(ItemSprite.ItemType type)
    {
    // Check by item type
    switch (type)
    {
    case ItemSprite.ItemType.Bomb:
    return Player.BombCount < PlayerState.MAX_BOMB_COUNT;
    case ItemSprite.ItemType.BonusBombs:
    return Player.BombCount < PlayerState.MAX_BOMB_COUNT;
    case ItemSprite.ItemType.Rupee:
    case ItemSprite.ItemType.RedRupee:
    return Player.RupeeCount < PlayerState.MAX_RUPEE_COUNT;
    case ItemSprite.ItemType.Heart:
    return Player.Health < Player.MaxHealth;
    case ItemSprite.ItemType.Key:
    return Player.KeyCount < PlayerState.MAX_KEY_COUNT;
    case ItemSprite.ItemType.HeartContainer:
    return Player.MaxHealth < PlayerState.MAX_HEALTH;
    case ItemSprite.ItemType.Fairy:
    return Player.Health < Player.MaxHealth;
    case ItemSprite.ItemType.BlueBoomerang:
    return !Player.HasBlueBoomerang;
    case ItemSprite.ItemType.MagicBoomerang:
    return !Player.HasMagicBoomerang;
    case ItemSprite.ItemType.Candle:
    return !Player.HasBlueCandle && !Player.HasRedCandle;
    case ItemSprite.ItemType.Arrow:
    return Player.ArrowCount < PlayerState.MAX_ARROW_COUNT;
    case ItemSprite.ItemType.TriforcePiece:
    return !Player.HasTriforcePiece(0);
    case ItemSprite.ItemType.Bow:
    return !Player.HasBow;
    case ItemSprite.ItemType.BlueRing:
    return !Player.HasBlueRing;
    case ItemSprite.ItemType.Raft:
    return !Player.HasRaft;
    case ItemSprite.ItemType.Ladder:
    return !Player.HasLadder;
    default:
    return true;
    }
    }

    ///

    /// Give the player a specific item
    ///

    /// The Item to give to the player
    public void GivePlayerItem(ItemSprite.ItemType type)
    {
    // Check by item type
    switch (type)
    {
    case ItemSprite.ItemType.Bomb:
    Player.BombCount++;
    if (!Player.HasItemInSlot(PlayerState.BOMB_SLOT))
    {
    Player.SetItemInSlot(PlayerState.BOMB_SLOT, true);
    }
    SoundFactory.PlaySound(SoundFactory.SoundType.GetItem);
    break;
    case ItemSprite.ItemType.BonusBombs:
    if (Player.BombCount <= (PlayerState.MAX_BOMB_COUNT – 4))
    {
    Player.BombCount += 4;
    }
    else
    {
    Player.BombCount = PlayerState.MAX_BOMB_COUNT;
    }
    if (!Player.HasItemInSlot(PlayerState.BOMB_SLOT))
    {
    Player.SetItemInSlot(PlayerState.BOMB_SLOT, true);
    }
    SoundFactory.PlaySound(SoundFactory.SoundType.GetItem);
    break;
    case ItemSprite.ItemType.Bow:
    Player.HasBow = true;
    Player.SetItemInSlot(PlayerState.BOW_SLOT, true);
    SoundFactory.PlaySound(SoundFactory.SoundType.GetItem);
    break;
    case ItemSprite.ItemType.Rupee:
    if (Player.RupeeCount < PlayerState.MAX_RUPEE_COUNT)
    {
    Player.RupeeCount++;
    }
    SoundFactory.PlaySound(SoundFactory.SoundType.GetRupee);
    break;
    case ItemSprite.ItemType.RedRupee:
    if (Player.RupeeCount <= (PlayerState.MAX_RUPEE_COUNT – 5))
    {
    Player.RupeeCount += 5;
    }
    else
    {
    Player.RupeeCount = PlayerState.MAX_RUPEE_COUNT;
    }
    SoundFactory.PlaySound(SoundFactory.SoundType.GetRupee);
    break;
    case ItemSprite.ItemType.Heart:
    if (Player.Health < Player.MaxHealth)
    {
    Player.Health++;
    }
    SoundFactory.PlaySound(SoundFactory.SoundType.GetHeart);
    break;
    case ItemSprite.ItemType.Key:
    Player.KeyCount++;
    SoundFactory.PlaySound(SoundFactory.SoundType.GetKey);
    break;
    case ItemSprite.ItemType.HeartContainer:
    Player.MaxHealth++;
    Player.Health = Player.MaxHealth;
    SoundFactory.PlaySound(SoundFactory.SoundType.GetHeartContainer);
    break;
    case ItemSprite.ItemType.TriforcePiece:
    Player.SetTriforcePiece(0, true);
    SoundFactory.PlaySound(SoundFactory.SoundType.GetMapOrCompass);
    OnTriforceCollected();
    break;
    case ItemSprite.ItemType.Fairy:
    Player.Health = Player.MaxHealth;
    SoundFactory.PlaySound(SoundFactory.SoundType.GetHeart);
    break;
    case ItemSprite.ItemType.Ladder:
    Player.HasLadder = true;
    SoundFactory.PlaySound(SoundFactory.SoundType.GetHeart);
    break;
    case ItemSprite.ItemType.Clock:
    // Freeze all monsters
    SoundFactory.PlaySound(SoundFactory.SoundType.GetHeart);
    break;
    case ItemSprite.ItemType.Candle:
    Player.HasBlueCandle = true;
    Player.SetItemInSlot(PlayerState.CANDLE_SLOT, true);
    SoundFactory.PlaySound(SoundFactory.SoundType.GetItem);
    break;
    case ItemSprite.ItemType.BlueRing:
    Player.HasBlueRing = true;
    SoundFactory.PlaySound(SoundFactory.SoundType.GetItem);
    break;
    case ItemSprite.ItemType.Arrow:
    if (Player.ArrowCount <= (PlayerState.MAX_ARROW_COUNT – 5))
    {
    Player.ArrowCount += 5;
    }
    else
    {
    Player.ArrowCount = PlayerState.MAX_ARROW_COUNT;
    }
    SoundFactory.PlaySound(SoundFactory.SoundType.GetItem);
    break;
    case ItemSprite.ItemType.BlueBoomerang:
    Player.HasBlueBoomerang = true;
    Player.SetItemInSlot(PlayerState.BOOMERANG_SLOT, true);
    SoundFactory.PlaySound(SoundFactory.SoundType.GetItem);
    break;
    case ItemSprite.ItemType.MagicBoomerang:
    Player.HasMagicBoomerang = true;
    Player.HasBlueBoomerang = true;
    Player.SetItemInSlot(PlayerState.BOOMERANG_SLOT, true);
    SoundFactory.PlaySound(SoundFactory.SoundType.GetItem);
    break;
    case ItemSprite.ItemType.Sword:
    Player.CurrentWeapon = PlayerState.Weapon.Sword;
    SoundFactory.PlaySound(SoundFactory.SoundType.GetItem);
    break;
    case ItemSprite.ItemType.Raft:
    Player.HasRaft = true;
    SoundFactory.PlaySound(SoundFactory.SoundType.GetItem);
    break;
    default:
    break;
    }

    }

    ///

    /// Reset the state (create a new player data object, etc)
    ///

    public void ResetState()
    {
    player = new PlayerState();
    projectileManager = new ProjectileManager();
    blockManager = new BlockManager();
    collisionDetector = new CollisionDetector();
    scoreKeeper = new ScoreKeeper();
    particleManager = new ParticleManager();
    }

    ///

    /// Reset the player’s state
    ///

    /// Optional parameter to intialize the player data from another PlayerState
    public void ResetPlayer(PlayerState newPlayer = null)
    {
    if (newPlayer == null)
    {
    player = new PlayerState();
    }
    else
    {
    player = (PlayerState)newPlayer.Clone();
    }
    }

    ///

    /// Reset the player’s state and set up a testing environment
    ///

    public void ResetPlayerForTesting()
    {
    player = new PlayerState();
    player.SetupDebugState();
    }

    #endregion

    ///

    /// Private constructor to set up the initial game state
    ///

    private GameManager()
    {
    ResetState();
    }
    }
    }

    # auks256/cse3902
    /* Author — Scott-Michael Fried
    * Contact — fried.uw.edu
    * Created Date — 9.19.2012
    * Last Modified Date — 10.24.2012
    * Last Modified By — Scott-Michael Fried
    */

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Audio;
    using Microsoft.Xna.Framework.Content;
    using Microsoft.Xna.Framework.GamerServices;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Input;
    using Microsoft.Xna.Framework.Media;
    using LegendOfZelda.Collisions;

    namespace LegendOfZelda
    {
    ///

    /// This class represents Link carrying a treasure. It acts as a wrapper to store the treasure with Link
    ///

    /// The type of object that the treasure represents. Must be a sprite of some kind.
    class LinkTreasure : ILink where T : AnimatedSprite, ICollidable
    {
    private ILink Link;
    public T Treasure;

    ///

    /// Whether Link is holding treasure up or not.
    ///

    public bool HoldingTreasureUp { get; private set; }

    ///

    /// Create a new link treasure. Link will hold up the treasure until the animation is over.
    ///

    /// Link object to wrap.
    /// Treasure that Link will be carrying.
    public LinkTreasure(ILink link, T treasure)
    {
    HoldingTreasureUp = true;

    Link = link;
    Treasure = treasure;
    Treasure.Activate();
    Treasure.X = Link.X;
    Treasure.Y = Link.Y – 12;

    // Move Link back to facing up
    if (Link.FacingDirection != ILink.Direction.North)
    {
    Link.ChangeDirection(ILink.Direction.North);
    }

    // Freeze link in place when we get this treasure
    GameContext.State.LinkIsFrozen = true;
    }

    #region Link wrapper methods
    public void Attack()
    {
    Link.Attack();
    }

    public void ChangeDirection(ILink.Direction direction)
    {
    Link.ChangeDirection(direction);
    }

    public void Draw(SpriteBatch spriteBatch)
    {
    if (!IsDead)
    {
    Link.Draw(spriteBatch);

    if (HoldingTreasureUp)
    {
    Treasure.Draw(spriteBatch);
    }
    }
    }

    private bool firstUpdate = true;
    private int timer = 150;
    private bool linkDead = false;

    public void Update(GameTime gameTime)
    {
    if (firstUpdate)
    {
    linkDead = Link.IsDead;
    firstUpdate = false;
    }

    // Update wrapped Links
    Link.Update(gameTime);

    if (HoldingTreasureUp)
    {
    timer -= gameTime.ElapsedGameTime.Milliseconds;

    if (timer <= 0)
    {
    HoldingTreasureUp = false;
    GameContext.State.LinkIsFrozen = false;
    }

    if (Link is LinkItemPickup)
    {
    Treasure.X = Link.X – 3;
    Treasure.Y = Link.Y – 12;
    }
    else
    {
    Treasure.X = Link.X;
    Treasure.Y = Link.Y – 12;
    }

    Treasure.Update(gameTime);
    }
    }

    public void TakeDamage(int damage, ILink.Direction direction)
    {
    Link.TakeDamage(damage, direction);
    }

    public void UseItem()
    {
    Link.UseItem();
    }

    public int X
    {
    get { return Link.X; }
    set { Link.X = value; }
    }

    public int Y
    {
    get { return Link.Y; }
    set { Link.Y = value; }
    }

    public ILink.Direction FacingDirection
    {
    get { return Link.FacingDirection; }
    }

    public ILink.State LinkState
    {
    get { return Link.LinkState; }
    }

    public bool IsVisible
    {
    get { return Link.IsVisible; }
    set { Link.IsVisible = value; }
    }

    public bool IsDead
    {
    get { return linkDead; }
    }

    public bool IsBeingDamaged
    {
    get { return Link.IsBeingDamaged; }
    }

    ///

    /// Gets an integer representing the layer that this object should be drawn on, with higher values being drawn on top of lower values.
    /// Objects with equivalent z-indices have an undefined render order relative to each other.
    ///

    public int ZIndex
    {
    get { return Link.ZIndex; }
    }

    public Rectangle Bounds
    {
    get { return Link.Bounds; }
    }

    public CollisionGroup CollisionGroup
    {
    get { return Link.CollisionGroup; }
    }

    public Point Location
    {
    get { return Link.Location; }
    }

    public Point Size
    {
    get { return Link.Size; }
    }

    public int Width
    {
    get { return Link.Width; }
    }

    public int Height
    {
    get { return Link.Height; }
    }

    public void OnCollision(ICollidable obj)
    {
    if (HoldingTreasureUp) {
    // If we’re holding the treasure up, give the treasure the collision if possible
    Treasure.OnCollision(obj);
    }

    // Give the collision to the decorated link if the treasure didn’t handle it
    Link.OnCollision(obj);
    }

    public void ResetState()
    {
    Link.ResetState();
    }

    public void BecomeDamaged()
    {
    Link.BecomeDamaged();
    }

    ///

    /// Move Link to the given position on the screen.
    ///

    /// X-position to place Link at
    /// Y-position to place Link at
    public void MoveTo(int x, int y)
    {
    Link.MoveTo(x, y);
    }

    ///

    /// Switch which item Link has selected
    ///

    public void CycleSelectedItem()
    {
    Link.CycleSelectedItem();
    }

    ///

    /// Reset the item Link has selected
    ///

    public void ResetSelectedItem()
    {
    Link.ResetSelectedItem();
    }

    ///

    /// Reset Links position
    ///

    public void ResetPosition()
    {
    Link.ResetPosition();
    }

    ///

    /// Start animating Links death. Returns true if the Link is dead, false otherwise
    ///

    public bool Die()
    {
    return Link.Die();
    }

    ///

    /// Get the center of the link
    ///

    /// The Point where the Link’s center is.
    public Point Center
    {
    get
    {
    return Link.Center;
    }
    }

    #endregion
    }
    }

    /* Author — Scott-Michael Fried
    * Contact — fried.uw.edu
    * Created Date — 9.19.2012
    * Last Modified Date — 10.24.2012
    * Last Modified By — Scott-Michael Fried
    */

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Audio;
    using Microsoft.Xna.Framework.Content;
    using Microsoft.Xna.Framework.GamerServices;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Input;
    using Microsoft.Xna.Framework.Media;
    using LegendOfZelda.Collisions;

    namespace LegendOfZelda
    {
    ///

    /// A concrete Link decorator that represents how Link looks while picking up an item
    ///

    /// The type of object that is collected. Must be a sprite of some kind.
    class LinkItemPickup : ILink where T : AnimatedSprite, ICollidable
    {
    private ILink Link;
    private bool firstUpdate;
    private int pickupTimer;
    private readonly int pickupTime = 1000;

    ///

    /// Link is picking something up
    ///

    /// The ILink implementation for decoration
    public LinkItemPickup(ILink link)
    {
    Link = link;

    // Freeze link in place
    firstUpdate = true;
    pickupTimer = pickupTime;
    GameContext.State.LinkIsFrozen = true;
    }

    #region Link wrapper methods
    public void Attack()
    {
    Link.Attack();
    }

    public void ChangeDirection(ILink.Direction direction)
    {
    Link.ChangeDirection(direction);
    }

    public void Draw(SpriteBatch spriteBatch)
    {
    if (!IsDead)
    {
    Link.Draw(spriteBatch);
    }
    }

    public void Update(GameTime gameTime)
    {
    if (!IsDead)
    {
    Link.Update(gameTime);

    if (firstUpdate)
    {
    // If this is a new pickup, make sure Link is facing north
    if (Link.FacingDirection != ILink.Direction.North)
    {
    Link.ChangeDirection(ILink.Direction.North);
    }
    firstUpdate = false;
    }

    pickupTimer -= gameTime.ElapsedGameTime.Milliseconds;
    if (pickupTimer <= 0)
    {
    GameContext.State.LinkIsFrozen = false;
    }
    }
    }

    public void TakeDamage(int damage, ILink.Direction direction)
    {
    Link.TakeDamage(damage, direction);
    }

    public void UseItem()
    {
    Link.UseItem();
    }

    public int X
    {
    get { return Link.X; }
    set { Link.X = value; }
    }

    public int Y
    {
    get { return Link.Y; }
    set { Link.Y = value; }
    }

    public ILink.Direction FacingDirection
    {
    get { return Link.FacingDirection; }
    }

    public ILink.State LinkState
    {
    get { return Link.LinkState; }
    }

    public bool IsVisible
    {
    get { return Link.IsVisible; }
    set { Link.IsVisible = value; }
    }

    public bool IsDead
    {
    get { return Link.IsDead; }
    }

    public bool IsBeingDamaged
    {
    get { return Link.IsBeingDamaged; }
    }

    ///

    /// Gets an integer representing the layer that this object should be drawn on, with higher values being drawn on top of lower values.
    /// Objects with equivalent z-indices have an undefined render order relative to each other.
    ///

    public int ZIndex
    {
    get { return Link.ZIndex; }
    }

    public Rectangle Bounds
    {
    get { return Link.Bounds; }
    }

    public CollisionGroup CollisionGroup
    {
    get { return Link.CollisionGroup; }
    }

    public Point Location
    {
    get { return Link.Location; }
    }

    public Point Size
    {
    get { return Link.Size; }
    }

    public int Width
    {
    get { return Link.Width; }
    }

    public int Height
    {
    get { return Link.Height; }
    }

    public void OnCollision(ICollidable obj)
    {
    Link.OnCollision(obj);
    }

    public void ResetState()
    {
    Link.ResetState();
    }

    public void BecomeDamaged()
    {
    Link.BecomeDamaged();
    }

    ///

    /// Move Link to the given position on the screen.
    ///

    /// X-position to place Link at
    /// Y-position to place Link at
    public void MoveTo(int x, int y)
    {
    Link.MoveTo(x, y);
    }

    ///

    /// Switch which item Link has selected
    ///

    public void CycleSelectedItem()
    {
    Link.CycleSelectedItem();
    }

    ///

    /// Reset the item Link has selected
    ///

    public void ResetSelectedItem()
    {
    Link.ResetSelectedItem();
    }

    ///

    /// Reset Links position
    ///

    public void ResetPosition()
    {
    Link.ResetPosition();
    }

    ///

    /// Start animating Links death. Returns true if the Link is dead, false otherwise
    ///

    ///
    public bool Die()
    {
    return Link.Die();
    }

    ///

    /// Get the center of the link
    ///

    /// The Point where the Link’s center is.
    public Point Center
    {
    get
    {
    return Link.Center;
    }
    }

    #endregion
    }
    }

    # auks256/cse3902
    /* Author — Allen Antony Ukani
    * Contact — auks256ATcs.washington.edu
    * Created Date — 10.01.2012
    * Last Modified Date — 10.18.2012
    * Last Modified By — Allen Antony Ukani
    */

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Input;
    using LegendOfZelda.Collisions;
    using LegendOfZelda.Projectiles;
    using LegendOfZelda.Items;

    namespace LegendOfZelda
    {
    class BasicLink : AnimatedSprite, ILink
    {
    public enum Direction : int { North = 0, South = 4, East = 8, West = 12 }
    private ILink.Direction linkFacingDirection = ILink.Direction.South;

    public enum State : int { StillFacing = 0, Moving = 1, Sword = 2, ItemUse = 3 }
    private ILink.State linkState = ILink.State.StillFacing;

    // Map for basic north, south, west and east movement
    private static Dictionary directionToXYMap = new Dictionary()
    {
    {Direction.North, new Vector2(0,-1)},
    {Direction.South, new Vector2(0,1)},
    {Direction.East, new Vector2(1,0)},
    {Direction.West, new Vector2(-1,0)}
    };

    // Map for diagonal input movement – used if multiple directions are held
    private static Dictionary<Tuple, Vector2> diagonalMap = new Dictionary<Tuple, Vector2>()
    {
    {new Tuple(Direction.North, Direction.East), new Vector2(1,-1)},
    {new Tuple(Direction.North, Direction.West), new Vector2(-1,-1)},
    {new Tuple(Direction.South, Direction.East), new Vector2(1,1)},
    {new Tuple(Direction.South, Direction.West), new Vector2(-1,1)}
    };

    // Store the spritesheet file for the current Link
    private string spriteSheetName;

    // Rect for visualizing damage
    private Color damageColor = Color.Red * 0.5f;

    #region Animation Variables
    private Vector2 dir = Vector2.Zero;
    private int[] animArray = null;

    private Dictionary<Tuple, int[]> animTable = null;

    private const int ANIM_SPEED = 100;
    private const int MOVE_SPEED = 1;
    private const int DAMAGE_MOVE_SPEED = 2;

    private static Dictionary GetLinkAnimationTable()
    {
    Dictionary table = new Dictionary();

    // Still facing
    table.Add(LinkAnims.NStill, new Rectangle(1, 11, 16, 16));
    table.Add(LinkAnims.SStill, new Rectangle(1, 28, 16, 16));
    table.Add(LinkAnims.EStill, new Rectangle(1, 77, 16, 16));
    table.Add(LinkAnims.WStill, new Rectangle(1, 60, 16, 16));

    // Moving (two frames)
    table.Add(LinkAnims.NMove1, new Rectangle(1, 11, 16, 16));
    table.Add(LinkAnims.NMove2, new Rectangle(18, 11, 16, 16));
    table.Add(LinkAnims.SMove1, new Rectangle(1, 28, 16, 16));
    table.Add(LinkAnims.SMove2, new Rectangle(18, 28, 16, 16));
    table.Add(LinkAnims.EMove1, new Rectangle(1, 77, 16, 16));
    table.Add(LinkAnims.EMove2, new Rectangle(18, 77, 16, 16));
    table.Add(LinkAnims.WMove1, new Rectangle(1, 60, 16, 16));
    table.Add(LinkAnims.WMove2, new Rectangle(18, 60, 16, 16));

    // Sword (four frames)
    table.Add(LinkAnims.NSword1, new Rectangle(1, 97, 16, 27));
    table.Add(LinkAnims.NSword2, new Rectangle(18, 97, 16, 27));
    table.Add(LinkAnims.NSword3, new Rectangle(35, 97, 16, 27));
    table.Add(LinkAnims.NSword4, new Rectangle(52, 97, 16, 27));
    table.Add(LinkAnims.SSword1, new Rectangle(1, 124, 16, 27));
    table.Add(LinkAnims.SSword2, new Rectangle(18, 124, 16, 27));
    table.Add(LinkAnims.SSword3, new Rectangle(35, 124, 16, 27));
    table.Add(LinkAnims.SSword4, new Rectangle(52, 124, 16, 27));
    table.Add(LinkAnims.ESword1, new Rectangle(1, 147, 27, 16));
    table.Add(LinkAnims.ESword2, new Rectangle(35, 147, 27, 16));
    table.Add(LinkAnims.ESword3, new Rectangle(69, 147, 27, 16));
    table.Add(LinkAnims.ESword4, new Rectangle(103, 147, 27, 16));
    table.Add(LinkAnims.WSword1, new Rectangle(1, 173, 27, 16));
    table.Add(LinkAnims.WSword2, new Rectangle(35, 173, 27, 16));
    table.Add(LinkAnims.WSword3, new Rectangle(69, 173, 27, 16));
    table.Add(LinkAnims.WSword4, new Rectangle(103, 173, 27, 16));

    // Item Use (one frame)
    table.Add(LinkAnims.NItem, new Rectangle(1, 196, 16, 16));
    table.Add(LinkAnims.SItem, new Rectangle(18, 196, 16, 16));
    table.Add(LinkAnims.EItem, new Rectangle(1, 214, 16, 16));
    table.Add(LinkAnims.WItem, new Rectangle(18, 214, 16, 16));

    // Damage (one frame)
    table.Add(LinkAnims.NDamage, new Rectangle(52, 196, 16, 16));
    table.Add(LinkAnims.SDamage, new Rectangle(69, 196, 16, 16));
    table.Add(LinkAnims.EDamage, new Rectangle(52, 214, 16, 16));
    table.Add(LinkAnims.WDamage, new Rectangle(69, 214, 16, 16));

    return table;
    }

    ///

    /// Link animation table
    ///

    protected enum LinkAnims
    {
    NStill, SStill, EStill, WStill,
    NMove1, SMove1, EMove1, WMove1, NMove2, SMove2, EMove2, WMove2,
    NSword1, SSword1, ESword1, WSword1, NSword2, SSword2, ESword2, WSword2,
    NSword3, SSword3, ESword3, WSword3, NSword4, SSword4, ESword4, WSword4,
    NItem, SItem, EItem, WItem,
    NDamage, SDamage, EDamage, WDamage
    }
    #endregion

    // Position Management
    private int x, y;

    // Internal state management
    private bool isDying, isBeingDamaged;
    private Rectangle damageBounds;
    private int damageTimer, soundTimer;
    private int damageDuration = 750;
    private bool stillAttacking = false;
    private bool usingItem = false;
    private Direction damageDir;
    private int frameTimer;
    private const int swordDuration = 400; //200;
    private const int itemDuration = 250;

    // Items
    private int currentItemIndex = 0;

    // Cached PlayerState
    private PlayerState player;

    ///

    /// Construct a new basic Link sprite
    ///

    public BasicLink() : base(„Link”)
    {
    ChangeAnimationTable(GetLinkAnimationTable());

    // Create the animation table map
    animTable = new Dictionary<Tuple, int[]>();

    // Set up still animations
    animTable.Add(new Tuple(Direction.North, State.StillFacing), new int[] { (int)LinkAnims.NStill });
    animTable.Add(new Tuple(Direction.South, State.StillFacing), new int[] { (int)LinkAnims.SStill });
    animTable.Add(new Tuple(Direction.East, State.StillFacing), new int[] { (int)LinkAnims.EStill });
    animTable.Add(new Tuple(Direction.West, State.StillFacing), new int[] { (int)LinkAnims.WStill });

    // Set up moving animations
    animTable.Add(new Tuple(Direction.North, State.Moving), new int[] { (int)LinkAnims.NMove1, (int)LinkAnims.NMove2 });
    animTable.Add(new Tuple(Direction.South, State.Moving), new int[] { (int)LinkAnims.SMove1, (int)LinkAnims.SMove2 });
    animTable.Add(new Tuple(Direction.East, State.Moving), new int[] { (int)LinkAnims.EMove1, (int)LinkAnims.EMove2 });
    animTable.Add(new Tuple(Direction.West, State.Moving), new int[] { (int)LinkAnims.WMove1, (int)LinkAnims.WMove2 });

    // Set up sword animations
    animTable.Add(new Tuple(Direction.North, State.Sword), new int[] { (int)LinkAnims.NSword1, (int)LinkAnims.NSword2, (int)LinkAnims.NSword3, (int)LinkAnims.NSword4 });
    animTable.Add(new Tuple(Direction.South, State.Sword), new int[] { (int)LinkAnims.SSword1, (int)LinkAnims.SSword2, (int)LinkAnims.SSword3, (int)LinkAnims.SSword4 });
    animTable.Add(new Tuple(Direction.East, State.Sword), new int[] { (int)LinkAnims.ESword1, (int)LinkAnims.ESword2, (int)LinkAnims.ESword3, (int)LinkAnims.ESword4 });
    animTable.Add(new Tuple(Direction.West, State.Sword), new int[] { (int)LinkAnims.WSword1, (int)LinkAnims.WSword2, (int)LinkAnims.WSword3, (int)LinkAnims.WSword4 });

    // Set up item animations
    animTable.Add(new Tuple(Direction.North, State.ItemUse), new int[] { (int)LinkAnims.NItem });
    animTable.Add(new Tuple(Direction.South, State.ItemUse), new int[] { (int)LinkAnims.SItem });
    animTable.Add(new Tuple(Direction.East, State.ItemUse), new int[] { (int)LinkAnims.EItem });
    animTable.Add(new Tuple(Direction.West, State.ItemUse), new int[] { (int)LinkAnims.WItem });

    // Set up the first animation
    animArray = animTable[new Tuple(Direction.South, State.StillFacing)];

    // Choose which sprite to load
    DetermineSpriteType();

    // Cache player data
    player = GameManager.Instance.Player;

    // Put Link in the center of the room
    Reset();
    }

    ///

    /// Determine which sprite type to draw for Link
    ///

    private void DetermineSpriteType()
    {
    if (GameManager.Instance.Player.HasBlueRing)
    {
    spriteSheetName = „BlueLink”;
    }
    else if (GameManager.Instance.Player.HasRedRing)
    {
    spriteSheetName = „RedLink”;
    }
    else
    {
    spriteSheetName = „Link”;
    }
    }

    #region ILink Implementation
    ///

    /// Set the current facing direction of Link
    ///

    /// The direction Link should face
    public void ChangeDirection(ILink.Direction direction)
    {
    Direction newDirection = DirectionFromILinkDirection(direction);

    // Don’t allow any direction changes during attack
    if (stillAttacking || usingItem) return;

    if (linkFacingDirection != direction)
    {
    // Change direction
    linkFacingDirection = direction;

    // Update animations
    animArray = animTable[new Tuple((Direction)((int)newDirection), (State)((int)linkState))];
    AnimationIndex = 0;
    }
    }

    ///

    /// If Link is able to attack, perform an attack with his sword
    ///

    public void Attack()
    {
    if (stillAttacking || usingItem || isBeingDamaged || GameContext.State.LinkIsFrozen || isDying) return;

    // Check if Link has a sword
    var playerState = GameManager.Instance.Player;
    if (playerState.CurrentWeapon == PlayerState.Weapon.None) return;

    // Do the attack animation
    linkState = ILink.State.Sword;
    stillAttacking = true;
    frameTimer = swordDuration;
    AnimationIndex = 0;
    animArray = animTable[new Tuple((Direction)((int)DirectionFromILinkDirection(linkFacingDirection)), (State)((int)linkState))];

    SoundFactory.PlaySound(SoundFactory.SoundType.LinkSword);
    CreateSword();
    }

    ///

    /// Stop Link’s Sword animation
    ///

    private void StopSwordAnimation()
    {
    linkState = ILink.State.StillFacing;
    stillAttacking = false;
    AnimationIndex = 0;
    animArray = animTable[new Tuple((Direction)((int)DirectionFromILinkDirection(linkFacingDirection)), (State)((int)linkState))];
    }

    ///

    /// If Link can use an item, use his currently selected item
    ///

    public void UseItem()
    {
    if (stillAttacking || usingItem || isBeingDamaged || GameContext.State.LinkIsFrozen || isDying) return;

    // Check if Link has an item selected & if he can use it
    var playerState = GameManager.Instance.Player;

    // Don’t do anything if the player doesn’t have an item equipped
    if (!playerState.HasItemInSlot(playerState.CurrentItemSlot))
    {
    return;
    }

    // Handle specific item slots
    if (playerState.CurrentItemSlot == PlayerState.BOOMERANG_SLOT)
    {
    if (playerState.HasBlueBoomerang) UseBoomerang();
    }
    else if (playerState.CurrentItemSlot == PlayerState.BOMB_SLOT)
    {
    if (playerState.BombCount > 0) UseBomb();
    }
    else if (playerState.CurrentItemSlot == PlayerState.BOW_SLOT)
    {
    if (playerState.HasBow && playerState.ArrowCount > 0) UseArrow();
    }
    else if (playerState.CurrentItemSlot == PlayerState.CANDLE_SLOT)
    {
    if (playerState.HasBlueCandle || playerState.HasRedCandle) UseCandle();
    }
    else if (playerState.CurrentItemSlot == PlayerState.WHISTLE_SLOT)
    {
    if (playerState.HasItemInSlot(PlayerState.WHISTLE_SLOT)) UseWhistle();
    }
    else
    {
    // ItemUse is only triggered for specific cases
    return;
    }

    // Do the attack animation
    linkState = ILink.State.ItemUse;
    usingItem = true;
    frameTimer = itemDuration;
    AnimationIndex = 0;
    animArray = animTable[new Tuple((Direction)((int)DirectionFromILinkDirection(linkFacingDirection)), (State)((int)linkState))];
    }

    private void UseWhistle()
    {
    // Disrupt all enemies in the current room
    SoundFactory.PlaySound(SoundFactory.SoundType.WhistleSound);
    }

    private void UseCandle()
    {
    SoundFactory.PlaySound(SoundFactory.SoundType.CandleFire);
    CreateFireball();
    }

    private void UseArrow()
    {
    if (GameManager.Instance.Player.ArrowCount <= 0)
    {
    return;
    }

    GameManager.Instance.Player.ArrowCount–;

    SoundFactory.PlaySound(SoundFactory.SoundType.ArrowShoot);
    CreateArrow();
    }

    private void UseBomb()
    {
    if (GameManager.Instance.Player.BombCount <= 0)
    {
    return;
    }

    GameManager.Instance.Player.BombCount–;

    SoundFactory.PlaySound(SoundFactory.SoundType.BombPlace);
    CreateBomb();
    }

    private void UseBoomerang()
    {
    SoundFactory.PlaySound(SoundFactory.SoundType.Boomerang);
    CreateBoomerang();
    }

    ///

    /// Stop Link’s Item animation
    ///

    private void StopItemAnimation()
    {
    linkState = ILink.State.StillFacing;
    usingItem = false;
    AnimationIndex = 0;
    animArray = animTable[new Tuple((Direction)((int)DirectionFromILinkDirection(linkFacingDirection)), (State)((int)linkState))];
    }

    ///

    /// Draws Link on the screen
    ///

    /// SpriteBatch to be drawn with
    public override void Draw(SpriteBatch spriteBatch)
    {
    if (IsVisible)
    {
    // Check whether we need to update the sprite type
    DetermineSpriteType();

    // Determine location
    Rectangle currentFrame = AnimationTable[animArray[AnimationIndex]];
    int drawX = x;
    int drawY = y;

    // Adjust for sword animations
    if (stillAttacking)
    {
    if (linkFacingDirection == ILink.Direction.North)
    {
    // North sword animations place Link’s head at the same spot on the sheet
    drawY -= 12;
    }
    else if (linkFacingDirection == ILink.Direction.East)
    {
    // East sword animations need to adjust x position
    drawX -= 12;
    }
    }

    // Draw Link’s sprite
    if (!isBeingDamaged)
    {
    spriteBatch.Draw(ResourceManager.GetInstance().GetTexture2D(spriteSheetName),
    new Rectangle(drawX, drawY, currentFrame.Width * GameContext.Window.Scale, currentFrame.Height * GameContext.Window.Scale),
    currentFrame, Color.White);

    /*// Debug drawing
    Rectangle healthText = new Rectangle(drawX, drawY – 20, 12 * 3, 12);
    spriteBatch.DrawString(ResourceManager.GetInstance().GetFont(„DebugFont”),
    „HP: ” + GameManager.Instance.Player.Health,
    new Vector2(drawX, drawY – 20), Color.White);*/
    }
    else
    {
    // Flash red when damaged
    spriteBatch.Draw(ResourceManager.GetInstance().GetTexture2D(spriteSheetName),
    new Rectangle(drawX, drawY, currentFrame.Width * GameContext.Window.Scale, currentFrame.Height * GameContext.Window.Scale),
    currentFrame, damageColor);
    }

    // Debug drawing
    //spriteBatch.Draw(ResourceManager.GetInstance().GetTexture2D(„Pixel”), Bounds, Color.Green * 0.5f);
    }
    }

    ///

    /// Update’s Links state and animations
    ///

    /// GameTime structure provided by XNA framework
    public void Update(GameTime gameTime)
    {
    if (isDying)
    {
    // Check if Link has died
    if (GameManager.Instance.Player.Health <= 0)
    {
    SoundFactory.PlaySound(SoundFactory.SoundType.LinkDie);

    // Wait 2s, then go to Game Over screen
    GameContext.State.LinkIsFrozen = true;
    GameContext.State.IsDying = true;
    GameContext.State.LinkDeathToGameOver = true;

    isDying = false;
    return;
    }
    }

    // Don't change Link's movement if he's attacking or using an item
    if (!GameContext.State.LinkIsFrozen)
    {
    if (stillAttacking)
    {
    // Reduce the amount of time this animation is running
    frameTimer -= gameTime.ElapsedGameTime.Milliseconds;
    if (frameTimer <= 0) StopSwordAnimation();
    }
    else if (usingItem)
    {
    // Reduce the amount of time this animation is running
    frameTimer -= gameTime.ElapsedGameTime.Milliseconds;
    if (frameTimer <= 0) StopItemAnimation();
    }
    else if (!isBeingDamaged)
    {
    // Get the directions that the user is pressing
    Vector2 moveDir = GetMovementKeysDirectionVector();

    // Check if Link is moving, or switch his state
    if (moveDir != Vector2.Zero)
    {
    dir = moveDir; // Remember the direction Link was moving

    // Set Link's moving animation
    if (linkState != ILink.State.Moving)
    {
    linkState = ILink.State.Moving;
    animArray = animTable[new Tuple((Direction)((int)DirectionFromILinkDirection(linkFacingDirection)), (State)((int)linkState))];
    AnimationIndex = 0;
    }

    // Move Link by his speed * the time
    int linkMove = MOVE_SPEED;
    x += (int)(dir.X * MOVE_SPEED);
    y += (int)(dir.Y * MOVE_SPEED);
    }
    else if (linkState != ILink.State.StillFacing)
    {
    // Set Link’s still animation
    linkState = ILink.State.StillFacing;
    animArray = animTable[new Tuple((Direction)((int)DirectionFromILinkDirection(linkFacingDirection)), (State)((int)linkState))];
    AnimationIndex = 0;
    }
    }
    else
    {
    // Tick the damage timer
    damageTimer -= gameTime.ElapsedGameTime.Milliseconds;

    // Play the hurt sound again if it’s done
    soundTimer -= gameTime.ElapsedGameTime.Milliseconds;
    if (soundTimer <= 0)
    {
    SoundFactory.PlaySound(SoundFactory.SoundType.LinkHurt);
    soundTimer = 200;
    }

    // Check if Link is done being damaged
    if (damageTimer <= 0)
    {
    isBeingDamaged = false;
    //GameContext.State.LinkIsFrozen = false;
    }
    else
    {
    // Continue being damaged
    Vector2 moveDir = directionToXYMap[(Direction)damageDir];

    // Continue moving Link in the damage direction
    x += (int)(moveDir.X * DAMAGE_MOVE_SPEED);
    y += (int)(moveDir.Y * DAMAGE_MOVE_SPEED);

    }
    }
    }

    // Update animation based on timer
    UpdateAnimation(gameTime);

    // Check if Link is out of bounds in the room, and if so, reverse.
    KeepLinkInBounds();
    }

    ///

    /// Keeps Link inside the bounds of the room or transitions to new room if possible
    ///

    private void KeepLinkInBounds()
    {
    int offset = 48;
    Rectangle roomBounds = GameContext.World.CurrentRoomTileSet.GetRoomBounds(GameContext.Window.RoomX, GameContext.Window.RoomY);

    // Block boundaries
    Point blockSize = new Point(GameContext.Window.Scale * 16, GameContext.Window.Scale * 16);
    Rectangle upperLeftBlock = new Rectangle(roomBounds.X, roomBounds.Y, blockSize.X, blockSize.Y);
    Rectangle upperRightBlock = new Rectangle(roomBounds.X + roomBounds.Width – blockSize.X, roomBounds.Y, blockSize.X, blockSize.Y);
    Rectangle lowerLeftBlock = new Rectangle(roomBounds.X, roomBounds.Y + roomBounds.Height – blockSize.Y, blockSize.X, blockSize.Y);
    Rectangle lowerRightBlock = new Rectangle(roomBounds.X + roomBounds.Width – blockSize.X, roomBounds.Y + roomBounds.Height – blockSize.Y, blockSize.X, blockSize.Y);

    // Only transition from certain areas to avoid being caught in an infinite transition loop
    if (!GameContext.State.TransitioningScreens)
    {
    // Don’t transition if holding a sword or item
    if (!(stillAttacking || usingItem || isBeingDamaged || isDying))
    {
    Rectangle bounds = Bounds;
    Room currentRoom = GameContext.World.CurrentWorldRoom;

    // Check for transitions to a new room
    if (bounds.X <= roomBounds.X + offset && currentRoom.LeftDoorwayExists && !bounds.Intersects(upperLeftBlock) && !bounds.Intersects(lowerLeftBlock))
    {
    currentRoom.LeftDoorSpriteObj = GameContext.World.CurrentRoomTileSet.GetLeftDoorwaySprite();
    GameContext.State.TransitioningScreens = true;
    GameContext.State.TransitionDirection = GameContext.State.MovementDirection.West;
    GameContext.State.DoorTransitionStarted = true;

    // Update the cache for the transition
    Tuple roomCoordsWest = new Tuple(GameContext.World.CurrentRoomRow, GameContext.World.CurrentRoomCol – 1);
    Tuple roomCoordsCurr = new Tuple(GameContext.World.CurrentRoomRow, GameContext.World.CurrentRoomCol);
    if (!GameContext.State.transitionCache.ContainsKey(roomCoordsWest))
    {
    GameContext.State.transitionCache.Add(roomCoordsWest, new List<Tuple>());
    }
    if (!GameContext.State.transitionCache.ContainsKey(roomCoordsCurr))
    {
    GameContext.State.transitionCache.Add(roomCoordsCurr, new List<Tuple>());
    }

    if (!GameContext.State.transitionCache[roomCoordsWest].Contains(roomCoordsCurr))
    GameContext.State.transitionCache[roomCoordsWest].Add(roomCoordsCurr);
    if (!GameContext.State.transitionCache[roomCoordsCurr].Contains(roomCoordsWest))
    GameContext.State.transitionCache[roomCoordsCurr].Add(roomCoordsWest);

    SoundFactory.PlaySound(SoundFactory.SoundType.DoorSlam);
    }
    else if (bounds.Right >= roomBounds.X + roomBounds.Width – offset && currentRoom.RightDoorwayExists && !bounds.Intersects(upperRightBlock) && !bounds.Intersects(lowerRightBlock))
    {
    currentRoom.RightDoorSpriteObj = GameContext.World.CurrentRoomTileSet.GetRightDoorwaySprite();
    GameContext.State.TransitioningScreens = true;
    GameContext.State.TransitionDirection = GameContext.State.MovementDirection.East;
    GameContext.State.DoorTransitionStarted = true;

    // Update the cache for the transition
    Tuple roomCoordsEast = new Tuple(GameContext.World.CurrentRoomRow, GameContext.World.CurrentRoomCol + 1);
    Tuple roomCoordsCurr = new Tuple(GameContext.World.CurrentRoomRow, GameContext.World.CurrentRoomCol);
    if (!GameContext.State.transitionCache.ContainsKey(roomCoordsEast))
    {
    GameContext.State.transitionCache.Add(roomCoordsEast, new List<Tuple>());
    }
    if (!GameContext.State.transitionCache.ContainsKey(roomCoordsCurr))
    {
    GameContext.State.transitionCache.Add(roomCoordsCurr, new List<Tuple>());
    }

    if (!GameContext.State.transitionCache[roomCoordsEast].Contains(roomCoordsCurr))
    GameContext.State.transitionCache[roomCoordsEast].Add(roomCoordsCurr);
    if (!GameContext.State.transitionCache[roomCoordsCurr].Contains(roomCoordsEast))
    GameContext.State.transitionCache[roomCoordsCurr].Add(roomCoordsEast);

    SoundFactory.PlaySound(SoundFactory.SoundType.DoorSlam);
    }
    else if (bounds.Y <= roomBounds.Y + offset && currentRoom.TopDoorwayExists && !bounds.Intersects(upperLeftBlock) && !bounds.Intersects(upperRightBlock))
    {
    currentRoom.TopDoorSpriteObj = GameContext.World.CurrentRoomTileSet.GetTopDoorwaySprite();
    GameContext.State.TransitioningScreens = true;
    GameContext.State.TransitionDirection = GameContext.State.MovementDirection.North;
    GameContext.State.DoorTransitionStarted = true;

    // Update the cache for the transition
    Tuple roomCoordsNorth = new Tuple(GameContext.World.CurrentRoomRow – 1, GameContext.World.CurrentRoomCol);
    Tuple roomCoordsCurr = new Tuple(GameContext.World.CurrentRoomRow, GameContext.World.CurrentRoomCol);
    if (!GameContext.State.transitionCache.ContainsKey(roomCoordsNorth))
    {
    GameContext.State.transitionCache.Add(roomCoordsNorth, new List<Tuple>());
    }
    if (!GameContext.State.transitionCache.ContainsKey(roomCoordsCurr))
    {
    GameContext.State.transitionCache.Add(roomCoordsCurr, new List<Tuple>());
    }

    if (!GameContext.State.transitionCache[roomCoordsNorth].Contains(roomCoordsCurr))
    GameContext.State.transitionCache[roomCoordsNorth].Add(roomCoordsCurr);
    if (!GameContext.State.transitionCache[roomCoordsCurr].Contains(roomCoordsNorth))
    GameContext.State.transitionCache[roomCoordsCurr].Add(roomCoordsNorth);
    SoundFactory.PlaySound(SoundFactory.SoundType.DoorSlam);
    }
    else if (bounds.Bottom >= roomBounds.Y + roomBounds.Height – offset && currentRoom.BottomDoorwayExists && !bounds.Intersects(lowerLeftBlock) && !bounds.Intersects(lowerRightBlock))
    {
    currentRoom.BottomDoorSpriteObj = GameContext.World.CurrentRoomTileSet.GetBottomDoorwaySprite();
    GameContext.State.TransitioningScreens = true;
    GameContext.State.TransitionDirection = GameContext.State.MovementDirection.South;
    GameContext.State.DoorTransitionStarted = true;

    // Update the cache for the transition
    Tuple roomCoordsSouth = new Tuple(GameContext.World.CurrentRoomRow + 1, GameContext.World.CurrentRoomCol);
    Tuple roomCoordsCurr = new Tuple(GameContext.World.CurrentRoomRow, GameContext.World.CurrentRoomCol);
    if (!GameContext.State.transitionCache.ContainsKey(roomCoordsSouth))
    {
    GameContext.State.transitionCache.Add(roomCoordsSouth, new List<Tuple>());
    }
    if (!GameContext.State.transitionCache.ContainsKey(roomCoordsCurr))
    {
    GameContext.State.transitionCache.Add(roomCoordsCurr, new List<Tuple>());
    }

    if (!GameContext.State.transitionCache[roomCoordsSouth].Contains(roomCoordsCurr))
    GameContext.State.transitionCache[roomCoordsSouth].Add(roomCoordsCurr);
    if (!GameContext.State.transitionCache[roomCoordsCurr].Contains(roomCoordsSouth))
    GameContext.State.transitionCache[roomCoordsCurr].Add(roomCoordsSouth);
    SoundFactory.PlaySound(SoundFactory.SoundType.DoorSlam);
    }
    }
    }

    // Separate checking to keep in bounds
    if (!GameContext.State.TransitioningScreens)
    {
    // Check normal boundary restrictions
    Rectangle bounds = Bounds;
    if (bounds.X roomBounds.X + roomBounds.Width) x = roomBounds.X + roomBounds.Width – Width;
    if (bounds.Y roomBounds.Y + roomBounds.Height) y = roomBounds.Y + roomBounds.Height – Height;
    }
    }

    ///

    /// Make Link take damage. If Link is already taking damage, the damage is ignored.
    ///

    /// Amount of damage Link should take (reduces heart count)
    /// The direction Link should be knocked back after being damaged
    public void TakeDamage(int damage, ILink.Direction direction)
    {
    // Don’t apply damage if already taking damage
    if (isBeingDamaged || isDying) return;

    // Update health state
    if (damage > 0)
    {
    // Redo the player state
    Player playerState = GameManager.Instance.Player;

    // Apply and cap health reduction
    playerState.Health -= damage;

    // Become damaged
    BecomeDamaged();

    // Remember which direction Link was hit from
    damageDir = DirectionFromILinkDirection(direction);
    }
    }

    ///

    /// Begin link damaged animation without actually changing health
    ///

    public void BecomeDamaged()
    {
    if (isDying) return;

    // Set taking damage
    isBeingDamaged = true;
    stillAttacking = false;
    usingItem = false;
    linkState = ILink.State.StillFacing;

    // Set up damage animation
    damageTimer = damageDuration;

    // Set up animation to flash
    soundTimer = 0;
    SoundFactory.PlaySound(SoundFactory.SoundType.LinkHurt);
    }

    public ILink.Direction FacingDirection
    {
    get { return linkFacingDirection; }
    }

    public ILink.State LinkState
    {
    get { return linkState; }
    }

    public bool IsBeingDamaged
    {
    get { return isBeingDamaged; }
    }

    public bool IsDead
    {
    get { return isDying; }
    }

    public void MoveTo(int x, int y)
    {
    this.x = x;
    this.y = y;
    }

    ///

    /// Cycle which item Link has selected
    ///

    public void CycleSelectedItem()
    {
    if (isBeingDamaged || stillAttacking || usingItem || GameContext.State.LinkIsFrozen) return;

    // Move to the next item slot
    var playerState = GameManager.Instance.Player;
    playerState.CurrentItemSlot = (playerState.CurrentItemSlot + 1) % PlayerState.NUM_ITEM_SLOTS;

    // Make a selection sound
    SoundFactory.PlaySound(SoundFactory.SoundType.MenuSelect);
    }

    ///

    /// Reset which item Link has selected
    ///

    public void ResetSelectedItem()
    {
    GameManager.Instance.Player.CurrentItemSlot = 0;
    }

    ///

    /// Reset Link’s position to the center of the screen
    ///

    public void ResetPosition()
    {
    x = GameContext.Window.CenterX – 8 * GameContext.Window.Scale;
    y = GameContext.Window.CenterY – 8 * GameContext.Window.Scale;
    }

    ///

    /// Reset’s Link to his default state
    ///

    public void ResetState()
    {
    Reset();
    }

    ///

    /// Perform the death animation for Link and return if he is „dead”
    ///

    /// True if Link died fully, false otherwise
    public bool Die()
    {
    isDying = true;
    return false;
    }

    #endregion

    #region Direction Helper Methods

    ///

    /// Convert a LinkDirection from ILink to a Direction in BasicLink
    ///

    /// Direction to convert from the ILink implementation
    /// Direction to use in LinkBasic (internal enum)
    private Direction DirectionFromILinkDirection(ILink.Direction direction)
    {
    switch (direction)
    {
    case ILink.Direction.East:
    return Direction.East;
    case ILink.Direction.North:
    return Direction.North;
    case ILink.Direction.South:
    return Direction.South;
    case ILink.Direction.West:
    return Direction.West;
    default:
    return Direction.South; // Default to south
    }
    }

    ///

    /// Get a direction vector from the keyboard state.
    ///

    /// A directional Vector2, already normalized, to represent where Link should move
    private Vector2 GetMovementKeysDirectionVector()
    {
    // Default state – no movement
    KeyboardState kstate = Keyboard.GetState();
    Vector2 direction = Vector2.Zero;

    // Check North
    if (kstate.IsKeyDown(Keys.W) || kstate.IsKeyDown(Keys.Up))
    {
    direction += Vector2.UnitY * -1;
    if (linkFacingDirection != ILink.Direction.North)
    {
    linkFacingDirection = ILink.Direction.North;
    animArray = animTable[new Tuple((Direction)((int)DirectionFromILinkDirection(linkFacingDirection)), (State)((int)linkState))];
    AnimationIndex = 0;
    }
    }
    // Check South
    else if (kstate.IsKeyDown(Keys.S) || kstate.IsKeyDown(Keys.Down))
    {
    direction += Vector2.UnitY;
    if (linkFacingDirection != ILink.Direction.South)
    {
    linkFacingDirection = ILink.Direction.South;
    animArray = animTable[new Tuple((Direction)((int)DirectionFromILinkDirection(linkFacingDirection)), (State)((int)linkState))];
    AnimationIndex = 0;
    }
    }

    // Check East
    if (kstate.IsKeyDown(Keys.D) || kstate.IsKeyDown(Keys.Right))
    {
    direction += Vector2.UnitX;
    if (direction.Y == 0 && linkFacingDirection != ILink.Direction.East)
    {
    linkFacingDirection = ILink.Direction.East;
    animArray = animTable[new Tuple((Direction)((int)DirectionFromILinkDirection(linkFacingDirection)), (State)((int)linkState))];
    AnimationIndex = 0;
    }
    }
    // Check West
    else if (kstate.IsKeyDown(Keys.A) || kstate.IsKeyDown(Keys.Left))
    {
    direction += Vector2.UnitX * -1;
    if (direction.Y == 0 && linkFacingDirection != ILink.Direction.West)
    {
    linkFacingDirection = ILink.Direction.West;
    animArray = animTable[new Tuple((Direction)((int)DirectionFromILinkDirection(linkFacingDirection)), (State)((int)linkState))];
    AnimationIndex = 0;
    }
    }

    // Return a normalied vector
    if (direction != Vector2.Zero)
    {
    direction.Normalize();
    }

    return direction;
    }

    #endregion

    #region Animation Helper Methods

    ///

    /// Update Link’s animation based on game timer
    ///

    /// GameTime XNA class
    private void UpdateAnimation(GameTime gameTime)
    {
    // Track animation timer
    animTimer += gameTime.ElapsedGameTime.Milliseconds;

    // Update frame if it’s time
    if (animTimer >= ANIM_SPEED)
    {
    animTimer = 0;

    if (animArray.Length < 2) return;

    AnimationIndex = (AnimationIndex + 1) % animArray.Length;
    }
    }

    #endregion

    #region Projectile Helper Methods

    ///

    /// Create a new sword in the projectile manager
    ///

    private void CreateSword()
    {
    int weaponOffset = 12;
    int x = this.X, y = this.Y;

    // Adjust position for the direction Link is facing
    switch (linkFacingDirection)
    {
    case ILink.Direction.North:
    y -= weaponOffset;
    break;
    case ILink.Direction.South:
    y += weaponOffset;
    break;
    case ILink.Direction.East:
    x += weaponOffset;
    break;
    case ILink.Direction.West:
    x -= weaponOffset;
    break;
    }

    // Create the projectile in the ProjectileManager
    IProjectile sword = ProjectileFactory.CreateLinkSword(x, y, linkFacingDirection);
    GameManager.Instance.ProjectileManager.AddProjectile(sword);
    }

    ///

    /// Create a new boomerang in the projectile manager
    ///

    private void CreateBoomerang()
    {
    int weaponOffset = 12;
    int x = this.X, y = this.Y;

    // Adjust position for the direction Link is facing
    switch (linkFacingDirection)
    {
    case ILink.Direction.North:
    y -= weaponOffset;
    break;
    case ILink.Direction.South:
    y += weaponOffset;
    break;
    case ILink.Direction.East:
    x += weaponOffset;
    break;
    case ILink.Direction.West:
    x -= weaponOffset;
    break;
    }

    // Create the projectile in the ProjectileManager
    GameManager.Instance.ProjectileManager.AddProjectile(ProjectileFactory.CreateLinkBoomerang(x, y, linkFacingDirection));
    }

    ///

    /// Create a new arrow in the projectile manager
    ///

    private void CreateArrow()
    {
    int weaponOffset = 12;
    int x = this.X, y = this.Y;

    // Adjust position for the direction Link is facing
    switch (linkFacingDirection)
    {
    case ILink.Direction.North:
    y -= weaponOffset;
    break;
    case ILink.Direction.South:
    y += weaponOffset;
    break;
    case ILink.Direction.East:
    x += weaponOffset;
    break;
    case ILink.Direction.West:
    x -= weaponOffset;
    break;
    }

    // Create the projectile in the ProjectileManager
    GameManager.Instance.ProjectileManager.AddProjectile(ProjectileFactory.CreateLinkArrow(x, y, linkFacingDirection));
    }

    ///

    /// Create a new fireball in the projectile manager
    ///

    private void CreateFireball()
    {
    int weaponOffset = 12;
    int x = this.X, y = this.Y;

    // Adjust position for the direction Link is facing
    switch (linkFacingDirection)
    {
    case ILink.Direction.North:
    y -= weaponOffset;
    break;
    case ILink.Direction.South:
    y += weaponOffset;
    break;
    case ILink.Direction.East:
    x += weaponOffset;
    break;
    case ILink.Direction.West:
    x -= weaponOffset;
    break;
    }

    // Create the projectile in the ProjectileManager
    GameManager.Instance.ProjectileManager.AddProjectile(ProjectileFactory.CreateLinksFireball(x, y, linkFacingDirection));
    }

    ///

    /// Create a new bomb in the projectile manager
    ///

    private void CreateBomb()
    {
    int weaponOffset = 12;
    int x = this.X, y = this.Y;

    // Adjust position for the direction Link is facing
    switch (linkFacingDirection)
    {
    case ILink.Direction.North:
    y -= weaponOffset;
    break;
    case ILink.Direction.South:
    y += weaponOffset;
    break;
    case ILink.Direction.East:
    x += weaponOffset;
    break;
    case ILink.Direction.West:
    x -= weaponOffset;
    break;
    }

    // Create the projectile in the ProjectileManager
    GameManager.Instance.ProjectileManager.AddProjectile(ProjectileFactory.CreateLinkBomb(x, y));
    }

    #endregion

    #region ICollidable Interface

    public override Rectangle Bounds
    {
    get
    {
    return new Rectangle(x + 4 * GameContext.Window.Scale, y + 4 * GameContext.Window.Scale,
    8 * GameContext.Window.Scale, 10 * GameContext.Window.Scale);
    }
    }

    public override CollisionGroup CollisionGroup
    {
    get
    {
    return CollisionGroup.Link;
    }
    }

    public override Point Location
    {
    get
    {
    return new Point(x, y);
    }
    }

    public override Point Size
    {
    get
    {
    return new Point(Width, Height);
    }
    }

    public override int Width
    {
    get
    {
    return 16 * GameContext.Window.Scale;
    }
    }

    public override int Height
    {
    get
    {
    return 16 * GameContext.Window.Scale;
    }
    }

    public override void OnCollision(ICollidable obj)
    {

    }

    ///

    /// Get the X position of Link
    ///

    public int X
    {
    get
    {
    return this.x;
    }
    set
    {
    this.x = value;
    }
    }

    ///

    /// Get the Y position of Link
    ///

    public int Y
    {
    get
    {
    return this.y;
    }
    set
    {
    this.y = value;
    }
    }

    public override int ZIndex
    {
    get
    {
    return 0;
    }
    }

    public Point Center
    {
    get { return new Point(x + Width / 2, y + Height / 2); }
    }

    #endregion

    #region Helper Methods

    ///

    /// Reset the position and state of Link
    ///

    private void Reset()
    {
    // Reset animation state
    linkState = ILink.State.StillFacing;
    linkFacingDirection = ILink.Direction.South;
    stillAttacking = false;
    usingItem = false;
    isDying = false;
    isBeingDamaged = false;
    damageTimer = 0;
    soundTimer = 0;
    frameTimer = 0;

    // Reset position
    x = GameContext.Window.CenterX – 8 * GameContext.Window.Scale;
    y = GameContext.Window.CenterY – 10 * GameContext.Window.Scale;

    // Reset item slot
    GameManager.Instance.Player.CurrentItemSlot = 0;

    // Set up first animation
    animArray = animTable[new Tuple(Direction.South, State.StillFacing)];
    AnimationIndex = 0;
    animTimer = 0;
    }

    ///

    /// Let Link become visible again
    ///

    public new bool IsVisible
    {
    get
    {
    return base.IsVisible;
    }
    set
    {
    base.IsVisible = value;
    }
    }

    #endregion

    }
    }

    # auks256/cse3902
    /* Author — Allen Antony Ukani
    * Contact — auks256ATcs.washington.edu
    * Created Date — 9.19.2012
    * Last Modified Date — 10.25.2012
    * Last Modified By — Allen Antony Ukani
    */

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Graphics;
    using LegendOfZelda.Collisions;

    namespace LegendOfZelda
    {
    ///

    /// Interface to represent Link. Can be used by Link himself as well as any decorator for Link.
    ///

    public interface ILink : ICollidable
    {
    ///

    /// An enumeration of possible directions Link could face
    ///

    enum Direction
    {
    North, South, East, West
    }

    ///

    /// An enumeration of possible states Link could be in
    ///

    enum State
    {
    StillFacing, Moving, Sword, ItemUse
    }

    ///

    /// Make Link attack (attemp to use his weapon), if possible
    ///

    void Attack();

    ///

    /// Set the direction that Link should face
    ///

    /// The direction Link should face
    void ChangeDirection(Direction direction);

    ///

    /// Draw Link to the screen
    ///

    /// SpriteBatch object for drawing
    void Draw(SpriteBatch spriteBatch);

    ///

    /// Move Link to the given position on the screen.
    ///

    /// X-position to place Link at
    /// Y-position to place Link at
    void MoveTo(int x, int y);

    ///

    /// Update Link’s logic (movement, animation, etc)
    ///

    /// GameTime structure provided by XNA
    void Update(GameTime gameTime);

    ///

    /// Make Link take damage
    ///

    /// Amount of damage Link should take (reduces heart count)
    /// The direction Link should be knocked back after being damaged
    void TakeDamage(int damage, Direction direction);

    ///

    /// Make Link use the item that he has currently selected, if possible
    ///

    void UseItem();

    ///

    /// Get the center of the link
    ///

    /// The Point where the Link’s center is.
    Point Center { get; }

    ///

    /// Get the X position of Link
    ///

    int X { get; set; }

    ///

    /// Get the Y position of Link
    ///

    int Y { get; set; }

    ///

    /// Get the direction Link is facing
    ///

    Direction FacingDirection { get; }

    ///

    /// Get the state Link is in
    ///

    State LinkState { get; }

    ///

    /// Get/set whether Link is visible or not
    ///

    bool IsVisible { get; set; }

    ///

    /// Get whether link is dead or not
    ///

    bool IsDead { get; }

    ///

    /// Get whether Link is being damaged or not
    ///

    bool IsBeingDamaged { get; }

    ///

    /// Reset Link to his default state
    ///

    void ResetState();

    ///

    /// Set Link to his damaged state. This is different from TakeDamage(), which actually reduces health.
    ///

    void BecomeDamaged();

    ///

    /// Switch which item Link has selected
    ///

    void CycleSelectedItem();

    ///

    /// Reset the item Link has selected
    ///

    void ResetSelectedItem();

    ///

    /// Reset Links position
    ///

    void ResetPosition();

    ///

    /// Start animating Links death. Returns true if the Link is dead, false otherwise
    ///

    ///
    bool Die();

    }
    }

    /* Author — Allen Antony Ukani
    * Contact — auks256ATcs.washington.edu
    * Created Date — 9.29.2012
    * Last Modified Date — 10.11.2012
    * Last Modified By — Allen Antony Ukani
    */

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Graphics;
    using LegendOfZelda.Particles;
    using LegendOfZelda.Monsters;
    using LegendOfZelda.Items;

    namespace LegendOfZelda
    {
    /**
    * Creates visual particle effects (that have no collision) in the game.
    *
    * Similar to the ProjectileManager, except for effects that have no collision.
    */
    class ParticleManager
    {
    private LinkedList particleList = new LinkedList();
    private LinkedList newParticleList = new LinkedList();

    ///

    /// Create a new ParticleManager
    ///

    public ParticleManager()
    {

    }

    ///

    /// Add a new particle to the manager.
    ///

    /// The particle to add
    public void AddParticle(IParticle particle)
    {
    newParticleList.AddLast(particle);
    }

    ///

    /// Update all particles in the manager.
    ///

    /// GameTime structure from XNA
    public void Update(GameTime gameTime)
    {
    // Add in the new particles at the beginning of this update loop
    if (newParticleList.Count > 0)
    {
    foreach (var p in newParticleList)
    {
    particleList.AddLast(p);
    }
    newParticleList.Clear();
    }

    // Go through all particles and update them, removing any expired particles
    var node = particleList.First;
    while (node != null)
    {
    // Cache the next pointer since we might change the list
    var next = node.Next;
    var particle = node.Value;

    if (particle.IsExpired)
    {
    // Remove the particle from the linked list
    particleList.Remove(node);
    }
    else
    {
    // Update the particle
    particle.Update(gameTime);
    }

    // Move on to the next node
    node = next;
    }
    }

    ///

    /// Draw all particles in the manager.
    ///

    /// SpriteBatch to draw with
    public void Draw(SpriteBatch spriteBatch)
    {
    // Draw all particles
    foreach (var particle in particleList)
    {
    particle.Draw(spriteBatch);
    }
    }

    ///

    /// Clear out all particles in the manager.
    ///

    public void Clear()
    {
    // Clear both linked lists
    particleList.Clear();
    newParticleList.Clear();
    }

    ///

    /// Create an explosion at the given point, with the given parameters.
    ///

    /// X coordinate of the center of the explosion
    /// Y coordinate of the center of the explosion
    /// Number of particles to create (default: 75)
    /// Lifetime of the explosion in milliseconds (default: 1500)
    public void CreateExplosion(int x, int y, int numParticles = 40, int lifetime = 1500)
    {
    for (int i = 0; i < numParticles; i++)
    {
    // Create a particle at the center
    var particle = new BaseBombParticle();
    particle.X = x;
    particle.Y = y;

    // Fire the particle at a random angle
    double theta = MathHelper.ToRadians(Utility.RandomRange(0, 359));
    double magnitude = Utility.RandomRange(1, 4);

    // Set a velocity
    particle.VelocityX = (float)(Math.Cos(theta) * magnitude);
    particle.VelocityY = (float)(Math.Sin(theta) * magnitude);

    // Set the lifetime
    particle.LifetimeMilliseconds = (int)(lifetime * Utility.RandomRange(0.6f, 1.0f));

    // Add the particle
    AddParticle(particle);
    }
    }

    ///

    /// Create a poof at the given point, with the given parameters
    ///

    /// X coordinate of the center of the explosion
    /// Y coordinate of the center of the explosion
    /// Number of particles to create (default: 5)
    /// Lifetime of the explosion in milliseconds (default: 400)
    public void CreatePoof(int x, int y, int numParticles = 5, int lifetime = 400)
    {
    for (int i = 0; i < numParticles; i++)
    {
    // Create a particle at the center
    var particle = new BaseParticle();
    particle.X = x;
    particle.Y = y;

    // Fire the particle at a random angle
    double theta = MathHelper.ToRadians(Utility.RandomRange(0, 359));
    double magnitude = Utility.RandomRange(0.5f, 1.5f);

    // Set a velocity
    particle.VelocityX = (float)(Math.Cos(theta) * magnitude);
    particle.VelocityY = (float)(Math.Sin(theta) * magnitude);

    // Set the lifetime
    particle.LifetimeMilliseconds = (int)(lifetime * Utility.RandomRange(0.7f, 1.0f));

    // Add the particle
    AddParticle(particle);
    }
    }

    ///

    /// Create an explosion for a particular monster
    ///

    /// X coordinate of the center of the poof
    /// Y coordinate of the center of the poof
    /// EnemyAnimatedSprite enumeration for the monster that’s exploding
    public void CreateMonsterExplosion(int x, int y, MonsterSprite.MonsterType type)
    {
    for (int i = 0; i < 6; i++)
    {
    // Create a particle at the center
    var particle = new MonsterDeathParticle(type);
    particle.X = x;
    particle.Y = y;

    // Fire the particle at a random angle
    double theta = MathHelper.ToRadians(Utility.RandomRange(0, 359));
    double magnitude = Utility.RandomRange(1.0f, 2.5f);

    // Set a velocity
    particle.VelocityX = (float)(Math.Cos(theta) * magnitude);
    particle.VelocityY = (float)(Math.Sin(theta) * magnitude);

    // Set the lifetime
    particle.LifetimeMilliseconds = (int)(400 * Utility.RandomRange(0.7f, 1.0f));

    // Add the particle
    AddParticle(particle);
    }
    }

    ///

    /// Create a reward that’s picked up by Link
    ///

    /// X coordinate of the Reward
    /// Y coordinate of the Reward
    /// ItemType enumeration for which reward appears
    /// Description of the item that displays on-screen
    public void CreateReward(int x, int y, ItemSprite.ItemType type, string description = „”)
    {
    RewardParticle reward = new RewardParticle(type, description);
    reward.X = x;
    reward.Y = y;
    reward.LifetimeMilliseconds = 3000;
    AddParticle(reward);
    }
    }
    }

    # LegendOfZelda/LegendOfZelda/Control/BasicKeyboardController.cs
    /* Author — Allen Antony Ukani
    * Contact — auks256ATcs.washington.edu
    * Created Date — 10.01.2012
    * Last Modified Date — 10.19.2012
    * Last Modified By — Allen Antony Ukani
    */

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Input;

    namespace LegendOfZelda
    {
    /**
    * Accepts keyboard input to control the game.
    * Pattern: Adapter (?)
    */
    class BasicKeyboardController : IController
    {
    private KeyboardState oldState, currentState;
    private string[] argsArray;

    private static BasicKeyboardController instance;

    public static BasicKeyboardController GetInstance()
    {
    if (instance == null)
    {
    instance = new BasicKeyboardController();
    }
    return instance;
    }

    private BasicKeyboardController()
    {
    oldState = Keyboard.GetState();
    argsArray = new string[0];
    }

    public void ProcessInput(GameTime gameTime, ICommandProcessor commandProcessor)
    {
    currentState = Keyboard.GetState();

    // Process a back key separately if transitioning screens
    if (GameContext.State.TransitioningScreens)
    {
    // Determine if we should cancel the transition or not
    if (CheckKeyPress(Keys.Escape))
    {
    commandProcessor.ProcessCommand(„global-back”, argsArray);
    }
    oldState = currentState;
    return;
    }

    // Only check keys based on what’s being displayed
    switch (GameContext.State.CurrentScreen)
    {
    case GameContext.State.Screen.Title:
    ProcessTitleScreenInput(commandProcessor);
    break;
    case GameContext.State.Screen.FileSelect:
    ProcessFileSelectInput(commandProcessor);
    break;
    case GameContext.State.Screen.Game:
    ProcessGameInput(commandProcessor);
    break;
    case GameContext.State.Screen.Inventory:
    ProcessInventoryInput(commandProcessor);
    break;
    case GameContext.State.Screen.GameOver:
    ProcessGameOverInput(commandProcessor);
    break;
    case GameContext.State.Screen.Win:
    ProcessWinInput(commandProcessor);
    break;
    case GameContext.State.Screen.Credits:
    ProcessCreditsInput(commandProcessor);
    break;
    default:
    break;
    }

    oldState = currentState;
    }

    private void ProcessWinInput(ICommandProcessor commandProcessor)
    {
    if (CheckKeyPress(Keys.Escape) || CheckKeyPress(Keys.Enter))
    {
    commandProcessor.ProcessCommand(„global-back”, argsArray);
    }
    }

    private void ProcessCreditsInput(ICommandProcessor commandProcessor)
    {
    if (CheckKeyPress(Keys.Escape))
    {
    commandProcessor.ProcessCommand(„global-back”, argsArray);
    }
    else if (CheckKeyPress(Keys.Enter))
    {
    commandProcessor.ProcessCommand(„credits-select”, argsArray);
    }
    }

    private void ProcessGameOverInput(ICommandProcessor commandProcessor)
    {
    if (CheckKeyPress(Keys.Escape))
    {
    commandProcessor.ProcessCommand(„global-back”, argsArray);
    }
    else if (CheckKeyPress(Keys.Enter))
    {
    commandProcessor.ProcessCommand(„gameover-select”, argsArray);
    }
    }

    private void ProcessInventoryInput(ICommandProcessor commandProcessor)
    {
    if (CheckKeyPress(Keys.Escape))
    {
    commandProcessor.ProcessCommand(„global-back”, argsArray);
    }
    else if (CheckKeyPress(Keys.Tab))
    {
    commandProcessor.ProcessCommand(„inventory-close”, argsArray);
    }
    }

    private void ProcessGameInput(ICommandProcessor commandProcessor)
    {
    // Check for escaping to menu
    if (CheckKeyPress(Keys.Escape))
    {
    commandProcessor.ProcessCommand(„global-back”, argsArray);
    }
    // Check for pausing and restarting the game
    else if (CheckKeyPress(Keys.Enter))
    {
    commandProcessor.ProcessCommand(„game-pause”, argsArray);
    }
    // Check for pause from the inventory
    else if (CheckKeyPress(Keys.Tab))
    {
    commandProcessor.ProcessCommand(„inventory-open”, argsArray);
    }

    // Check for debug commands
    if (CheckKeyPress(Keys.OemTilde))
    {
    commandProcessor.ProcessCommand(„debug-toggle”, argsArray);
    }
    if (CheckKeyPress(Keys.D1))
    {
    commandProcessor.ProcessCommand(„debug-mode1”, argsArray);
    }
    if (CheckKeyPress(Keys.D2))
    {
    commandProcessor.ProcessCommand(„debug-mode2”, argsArray);
    }
    if (CheckKeyPress(Keys.D3))
    {
    commandProcessor.ProcessCommand(„debug-mode3”, argsArray);
    }
    if (CheckKeyPress(Keys.D4))
    {
    commandProcessor.ProcessCommand(„debug-mode4”, argsArray);
    }
    if (CheckKeyPress(Keys.D5))
    {
    commandProcessor.ProcessCommand(„debug-mode5”, argsArray);
    }
    if (CheckKeyPress(Keys.D6))
    {
    commandProcessor.ProcessCommand(„debug-mode6”, argsArray);
    }
    if (CheckKeyPress(Keys.D7))
    {
    commandProcessor.ProcessCommand(„debug-mode7”, argsArray);
    }
    if (CheckKeyPress(Keys.D8))
    {
    commandProcessor.ProcessCommand(„debug-mode8”, argsArray);
    }
    if (CheckKeyPress(Keys.D9))
    {
    commandProcessor.ProcessCommand(„debug-mode9”, argsArray);
    }
    if (CheckKeyPress(Keys.D0))
    {
    commandProcessor.ProcessCommand(„debug-mode0”, argsArray);
    }
    if (CheckKeyPress(Keys.R))
    {
    commandProcessor.ProcessCommand(„debug-restart”, argsArray);
    }
    if (CheckKeyPress(Keys.L))
    {
    commandProcessor.ProcessCommand(„debug-clearCache”, argsArray);
    }
    if (CheckKeyPress(Keys.N))
    {
    commandProcessor.ProcessCommand(„debug-next-room”, argsArray);
    }
    if (CheckKeyPress(Keys.M))
    {
    commandProcessor.ProcessCommand(„debug-previous-room”, argsArray);
    }
    if (CheckKeyPress(Keys.J))
    {
    commandProcessor.ProcessCommand(„debug-jump-first-dungeon”, argsArray);
    }
    if (CheckKeyPress(Keys.K))
    {
    commandProcessor.ProcessCommand(„debug-jump-final-dungeon”, argsArray);
    }

    // Let the player change their weapons
    if (CheckKeyPress(Keys.Q))
    {
    commandProcessor.ProcessCommand(„game-link-cycle-item”, argsArray);
    }

    // Move Link
    if (GameContext.State.IsDying == false && !GameContext.State.LinkIsFrozen)
    {
    // Check attack command
    if (CheckKeyPress(Keys.Z))
    {
    commandProcessor.ProcessCommand(„game-link-attack”, argsArray);
    }

    // Check item use
    if (CheckKeyPress(Keys.X) || CheckKeyPress(Keys.Space))
    {
    commandProcessor.ProcessCommand(„game-link-use-item”, argsArray);
    }
    }
    }

    private void ProcessFileSelectInput(ICommandProcessor commandProcessor)
    {
    if (CheckKeyPress(Keys.Escape))
    {
    commandProcessor.ProcessCommand(„global-back”, argsArray);
    }
    else if (CheckKeyPress(Keys.Enter))
    {
    commandProcessor.ProcessCommand(„file-select”, argsArray);
    }
    else if (CheckKeyPress(Keys.Down) || CheckKeyPress(Keys.S))
    {
    // Move selection down
    commandProcessor.ProcessCommand(„file-cursor-down”, argsArray);
    }
    else if (CheckKeyPress(Keys.Up) || CheckKeyPress(Keys.W))
    {
    // Move selection up
    commandProcessor.ProcessCommand(„file-cursor-up”, argsArray);
    }
    }

    private void ProcessTitleScreenInput(ICommandProcessor commandProcessor)
    {
    if (CheckKeyPress(Keys.Escape))
    {
    commandProcessor.ProcessCommand(„global-back”, argsArray);
    }
    else if (CheckKeyPress(Keys.Enter))
    {
    commandProcessor.ProcessCommand(„title-select”, argsArray);
    }
    else if (CheckKeyPress(Keys.Down) || CheckKeyPress(Keys.S))
    {
    // Move selection down
    commandProcessor.ProcessCommand(„title-cursor-down”, argsArray);
    }
    else if (CheckKeyPress(Keys.Up) || CheckKeyPress(Keys.W))
    {
    // Move selection up
    commandProcessor.ProcessCommand(„title-cursor-up”, argsArray);
    }
    }

    private bool CheckKeyPress(Keys key)
    {
    return currentState.IsKeyDown(key) && !oldState.IsKeyDown(key);
    }
    }
    }

    # auks256/cse3902
    /* Author — Allen Antony Ukani, Dominic Doty
    * Contact — auks256ATcs.washington.edu, ddoty21ATwashington.edu
    * Created Date — 10.06.2012
    * Last Modified Date — 10.14.2012
    * Last Modified By — Dominic Doty
    */

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.Xna.Framework;

    namespace LegendOfZelda
    {
    public delegate void CommandExecutionHandler(string[] args);

    /**
    * A processor that can execute commands. Manages a map of commands to the methods
    * that execute those commands.
    *
    * Pattern: Command
    */
    class CommandProcessor : ICommandProcessor
    {
    private Dictionary commandMap = new Dictionary();
    private LinkedList commandHistory = new LinkedList(); // For debugging/macro purposes

    public CommandProcessor()
    {
    }

    ///

    /// Register a command with its execution handler.
    ///

    /// The command to register as a string
    /// The handler that will process this command when its executed
    public void RegisterCommand(string command, CommandExecutionHandler handler)
    {
    // Don’t register a command if it already exists
    if (commandMap.ContainsKey(command))
    {
    return;
    }

    // Register the command
    commandMap.Add(command, handler);
    }

    ///

    /// Process a given command along with the command arguments.
    ///

    /// The command to run, as a string
    /// The arguments to pass to the command, as a string array
    public void ProcessCommand(string command, string[] args)
    {
    // Don’t process commands that aren’t registered
    if (!commandMap.ContainsKey(command))
    {
    return;
    }

    // Add the command to the history
    if (commandHistory.Count > 100)
    {
    commandHistory.RemoveFirst();
    }
    commandHistory.AddLast(command);

    // Execute the command handler with the arguments
    commandMap[command](args);
    }

    ///

    /// Process a given command with no arguments.
    ///

    /// The command to run, as a string
    public void ProcessCommand(string command)
    {
    // Call the regular process method with empty args
    ProcessCommand(command, new string[0]);
    }

    ///

    /// Gets the command history for the processor.
    ///

    /// A list of all the commands passed to the processor.
    public IEnumerable GetCommandHistory()
    {
    return commandHistory;
    }
    }
    }

    /* Author — Gary Stremlow
    * Contact — [email protected]
    * Created Date — 10.02.2012
    * Last Modified Date — 10.15.2012
    * Last Modified By — Gary Stremlow
    */

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Audio;
    using Microsoft.Xna.Framework.Content;
    using Microsoft.Xna.Framework.GamerServices;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Input;
    using Microsoft.Xna.Framework.Media;
    using LegendOfZelda.Collisions;

    namespace LegendOfZelda
    {
    public class Block : ICollidable
    {
    private int x, y;
    protected int width, height;
    protected CollisionGroup collisionGroup;
    protected bool isPassable;
    protected bool isFalling;
    protected bool isDoor;
    protected Texture2D texture;
    protected Rectangle sourceRectangle;
    protected Color color;
    protected Color deathColor;

    protected Room currentRoom;

    ///

    /// Initialize a block to the given parameters.
    ///

    /// X position of the block
    /// Y position of the block
    /// Width of the block
    /// Height of the block
    /// Whether the block can be passed through
    /// The texture to use for the block
    /// The part of the texture to use
    public Block(int x, int y, int width, int height, bool isPassable, Texture2D texture, Rectangle sourceRectangle)
    {
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
    this.collisionGroup = isPassable ? CollisionGroup.PassableBlock : CollisionGroup.Block;
    this.isPassable = isPassable;
    this.isFalling = false;
    this.isDoor = false;
    this.texture = texture;
    this.sourceRectangle = sourceRectangle;
    this.color = Color.White;
    this.deathColor = Color.White;
    }

    ///

    /// Initialize a block to the given parameters.
    ///

    /// X position of the block
    /// Y position of the block
    /// Width of the block
    /// Height of the block
    /// Whether the block can be passed through
    /// The texture to use for the block
    /// The part of the texture to use
    /// Whether the block is a door
    public Block(int x, int y, int width, int height, bool isPassable, Texture2D texture, Rectangle sourceRectangle, bool isDoor)
    {
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
    this.collisionGroup = isPassable ? CollisionGroup.PassableBlock : CollisionGroup.Block;
    this.isPassable = isPassable;
    this.isFalling = false;
    this.isDoor = isDoor;
    this.texture = texture;
    this.sourceRectangle = sourceRectangle;
    this.color = Color.White;
    this.deathColor = Color.White;
    }

    ///

    /// Initialize a block to the given parameters.
    ///

    /// X position of the block
    /// Y position of the block
    /// Width of the block
    /// Height of the block
    /// Whether the block can be passed through
    /// The texture to use for the block
    /// The part of the texture to use
    /// Color tint for the block
    public Block(int x, int y, int width, int height, bool isPassable, Texture2D texture, Rectangle sourceRectangle, Color color)
    {
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
    this.collisionGroup = isPassable ? CollisionGroup.PassableBlock : CollisionGroup.Block;
    this.isPassable = isPassable;
    this.isFalling = false;
    this.isDoor = false;
    this.texture = texture;
    this.sourceRectangle = sourceRectangle;
    this.color = color;
    this.deathColor = color;
    }

    ///

    /// Create a new Block with the given location and passability
    ///

    /// X position of the block
    /// Y position of the block
    /// Whether the block is passable or not
    public Block(int x, int y, bool isPassable)
    {
    this.x = x;
    this.y = y;
    this.width = 16;
    this.height = 16;
    this.collisionGroup = isPassable ? CollisionGroup.PassableBlock : CollisionGroup.Block;
    this.isPassable = isPassable;
    this.isFalling = false;
    this.isDoor = false;
    }

    ///

    /// Draw the block on screen
    ///

    /// SpriteBatch to draw to
    public virtual void Draw(SpriteBatch spriteBatch)
    {
    // Base block for debugging to make sure there is something to draw
    if (texture == null)
    {
    Texture2D pixel = ResourceManager.GetInstance().GetTexture2D(„Pixel”);
    spriteBatch.Draw(pixel, new Rectangle(X, Y, Width, Height), Color.Magenta * 0.5f);
    }
    else if (isFalling)
    {
    spriteBatch.Draw(texture, new Rectangle(X, Y, Width, Height), sourceRectangle, deathColor);
    }
    else
    {
    spriteBatch.Draw(texture, new Rectangle(X, Y, Width, Height), sourceRectangle, color);
    }
    }

    ///

    /// Get the bounds of the Block
    ///

    public virtual Rectangle Bounds
    {
    get
    {
    return new Rectangle(X, Y, width, height);
    }
    }

    ///

    /// Gets a value indicating whether this block is passable.
    ///

    ///
    /// true if this instance is passable; otherwise, false.
    ///
    public bool IsPassable
    {
    get { return isPassable; }
    set {
    isPassable = value;
    collisionGroup = isPassable ? CollisionGroup.PassableBlock : CollisionGroup.Block;
    }
    }

    ///

    /// Get the collision group type of the Block.
    /// (Link, Enemy, Block, Projectile, PassableBlock)
    ///

    public virtual CollisionGroup CollisionGroup
    {
    get
    {
    return collisionGroup;
    }
    }

    ///

    /// Get the location of the Block
    ///

    public virtual Point Location
    {
    get { return new Point(x, y); }
    }

    ///

    /// Get the X position of the Block
    ///

    public int X
    {
    get { return x; }
    set { x = value; }
    }

    ///

    /// Get the Y position of the Block
    ///

    public int Y
    {
    get { return y; }
    set { y = value; }
    }

    ///

    /// Get the size of the Block as a Point
    ///

    public Point Size
    {
    get
    {
    return new Point(width, height);
    }
    }

    ///

    /// Get the width of the Block
    ///

    public virtual int Width
    {
    get
    {
    return width;
    }
    }

    ///

    /// Get the height of the Block
    ///

    public virtual int Height
    {
    get
    {
    return height;
    }
    }

    ///

    /// Whether the block is falling (for example, a push block that’s falling into a hole)
    ///

    public bool IsFalling
    {
    get { return isFalling; }
    set { isFalling = value; }
    }

    ///

    /// Gets a value indicating whether this block a door.
    ///

    ///
    /// true if this instance is door; otherwise, false.
    ///
    public bool IsDoor
    {
    get { return isDoor; }
    }

    ///

    /// Update a block
    ///

    /// GameTime structure
    public virtual void Update(GameTime gameTime)
    {
    // No update by default in a Block
    }

    public virtual void OnCollision(ICollidable obj)
    {
    // Do nothing
    }

    ///

    /// Gets an integer representing the layer that this object should be drawn on, with higher values being drawn on top of lower values.
    /// Objects with equivalent z-indices have an undefined render order relative to each other.
    ///

    public virtual int ZIndex
    {
    get { return -1; }
    }

    ///

    /// Gets the current room that the block is part of.
    ///

    ///
    /// The current room.
    ///
    public Room CurrentRoom
    {
    get { return currentRoom; }
    set { currentRoom = value; }
    }
    }
    }

    # auks256/cse3902
    /* Author — Allen Antony Ukani, Terence Leung
    * Contact — auks256ATcs.washington.edu, terryATcs.washington.edu
    * Created Date — 9.30.2012
    * Last Modified Date — 10.17.2012
    * Last Modified By — Allen Antony Ukani
    */

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Audio;
    using Microsoft.Xna.Framework.Content;
    using Microsoft.Xna.Framework.GamerServices;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Input;
    using Microsoft.Xna.Framework.Media;
    using LegendOfZelda.Collisions;

    namespace LegendOfZelda
    {
    public class PushBlock : Block
    {
    // Map for cardinal movement
    private static Dictionary directionToXYMap = new Dictionary()
    {
    {0, new Vector2(0,-1)}, // North
    {1, new Vector2(0,1)}, // South
    {2, new Vector2(1,0)}, // East
    {3, new Vector2(-1,0)} // West
    };

    private int moveDist;
    private Vector2 direction;
    private int moveSpeed;
    private bool isMoving;
    private bool isOnHole;
    private const int deathSpeed = 1;
    private float deathAlpha;

    ///

    /// Initialize a push block to the given parameters.
    ///

    /// X position of the block.
    /// Y position of the block
    /// Width of the block
    /// Height of the block
    /// Whether the block is passable by Link
    /// Texture to use for the block
    /// Part of the texture to use
    /// Tint of the block
    public PushBlock(int x, int y, int width, int height, bool isPassable, Texture2D texture, Rectangle sourceRectangle, Color color) :
    base(x, y, width, height, isPassable, texture, sourceRectangle, color)
    {
    this.collisionGroup = CollisionGroup.PushBlock;
    moveSpeed = 2;
    moveDist = 16 * GameContext.Window.Scale;
    isMoving = false;
    isOnHole = false;
    deathAlpha = 1.0f;
    deathColor = Color.White;
    }

    ///

    /// Draw the push block on screen
    ///

    /// SpriteBatch to draw to
    public override void Draw(SpriteBatch spriteBatch)
    {
    // Draw the block
    if (texture == null)
    {
    Texture2D pixel = ResourceManager.GetInstance().GetTexture2D(„Pixel”);
    spriteBatch.Draw(pixel, new Rectangle(X, Y, Width, Height), Color.Green * 0.5f);
    }
    else if (isFalling)
    {
    spriteBatch.Draw(texture, new Rectangle(X, Y, Width, Height), sourceRectangle, new Color(deathColor.R, deathColor.G, deathColor.B, (byte)(255 * deathAlpha)));
    }
    else
    {
    spriteBatch.Draw(texture, new Rectangle(X, Y, Width, Height), sourceRectangle, color);
    }
    }

    ///

    /// Handle when the pushblock is pushed
    ///

    /// Which object is colliding with the block
    public override void OnCollision(ICollidable collision)
    {
    // If a LinkBlock is colliding with a Player && is NOT moving
    if (collision.CollisionGroup == CollisionGroup.Link && !isMoving)
    {
    // Find out what direction the collision caused the block to move
    HandleLinkPush(collision.Bounds, collision);
    }

    // Check if we’re entering a hole
    if (collision.CollisionGroup == CollisionGroup.Hole && isMoving)
    {
    isOnHole = true;
    // Make the PushBlock fall in
    SoundFactory.PlaySound(SoundFactory.SoundType.PushBlocked);
    }
    }

    ///

    /// Update the push block’s logic and location
    ///

    /// GameTime structure from XNA framework
    public override void Update(GameTime gameTime)
    {
    // Handle the block falling
    if (isFalling)
    {
    Y += deathSpeed;
    deathAlpha = Math.Max(0, deathAlpha – 0.01f);

    // If the block has lost alpha, remove it
    if (deathAlpha <= 0)
    {
    isFalling = false;
    }
    }

    if (isMoving)
    {
    // Move block in direction
    X += (int)(direction.X * moveSpeed);
    Y += (int)(direction.Y * moveSpeed);
    moveDist -= moveSpeed;

    if (moveDist <= 0)
    {
    isMoving = false;
    if (isOnHole)
    {
    isFalling = true;
    isPassable = true;
    collisionGroup = CollisionGroup.PassableBlock;
    }
    }
    }
    }

    ///

    /// Handle logic when Link pushes the block
    ///

    /// Link’s location
    /// Link collision object
    private void HandleLinkPush(Rectangle linkBounds, ICollidable link)
    {
    // Check if we can push
    if (GameContext.State.LinkIsFrozen) return;

    // If Link’s center is above the block
    if (linkBounds.Center.Y Bounds.Bottom)
    {
    direction = directionToXYMap[0]; // North
    isMoving = true;
    moveDist = 16 * GameContext.Window.Scale;
    }
    // If Link’s center is to the left of the block
    else if (linkBounds.Center.X Bounds.Right)
    {
    direction = directionToXYMap[3]; // West
    isMoving = true;
    moveDist = 16 * GameContext.Window.Scale;
    }

    // Make sure we’ve actually calculated a move
    if (isMoving)
    {
    // Play sound
    SoundFactory.PlaySound(SoundFactory.SoundType.PushBlock);

    // Check if Link is frozen for pushing the block
    if (link is ILink)
    {
    GameContext.State.LinkIsFrozen = true;
    GameManager.Instance.ActiveStopWatch = new SchedulableStopWatch(gameTime =>
    {
    GameContext.State.LinkIsFrozen = false;
    }, 300);
    }
    }
    }

    ///

    /// Gets a value indicating whether this block is moving.
    ///

    ///
    /// true if this block is moving; otherwise, false.
    ///
    public bool IsMoving
    {
    get { return isMoving; }
    }

    ///

    /// Gets an integer representing the layer that this object should be drawn on, with higher values being drawn on top of lower values.
    /// Objects with equivalent z-indices have an undefined render order relative to each other.
    ///

    public override int ZIndex
    {
    get { return 0; }
    }
    }
    }

    # auks256/cse3902
    /* Author — Allen Antony Ukani
    * Contact — auks256ATcs.washington.edu
    * Created Date — 9.30.2012
    * Last Modified Date — 10.10.2012
    * Last Modified By — Allen Antony Ukani
    */

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Graphics;

    namespace LegendOfZelda
    {
    ///

    /// Keeps track of all the blocks in a room for the game, including collision detection.
    ///

    class BlockManager
    {
    private LinkedList blockList = new LinkedList();
    private LinkedList newBlocksList = new LinkedList();

    ///

    /// Create the BlockManager
    ///

    public BlockManager()
    {

    }

    ///

    /// Add a block to the manager
    ///

    /// Block to add
    public void AddBlock(Block block)
    {
    newBlocksList.AddLast(block);
    }

    ///

    /// Add a set of blocks to the manager
    ///

    /// Blocks to add
    public void AddBlocks(IEnumerable blocks)
    {
    foreach (Block block in blocks)
    {
    AddBlock(block);
    }
    }

    ///

    /// Update all blocks in the manager
    ///

    /// GameTime structure from XNA
    public void Update(GameTime gameTime)
    {
    // Add new blocks to the manager
    if (newBlocksList.Count > 0)
    {
    foreach (var block in newBlocksList)
    {
    blockList.AddLast(block);
    }
    newBlocksList.Clear();
    }

    // Update all blocks that need updating
    foreach (var block in blockList)
    {
    block.Update(gameTime);
    }
    }

    ///

    /// Draw all blocks in the manager
    ///

    /// SpriteBatch to draw with
    public void Draw(SpriteBatch spriteBatch)
    {
    // Sort all blocks by Z-Index
    var sortedBlocks = blockList.OrderBy(b => b.ZIndex);

    // Draw all blocks
    foreach (var block in sortedBlocks)
    {
    block.Draw(spriteBatch);
    }
    }

    ///

    /// Get all the blocks in the manager (returns both new blocks and existing blocks)
    ///

    /// List of all blocks
    public IEnumerable GetBlocks()
    {
    foreach (var block in blockList)
    {
    yield return block;
    }

    foreach (var block in newBlocksList)
    {
    yield return block;
    }
    }

    ///

    /// Clear out the manager’s list of blocks
    ///

    public void Clear()
    {
    blockList.Clear();
    newBlocksList.Clear();
    }

    ///

    /// Get a count of all the blocks in the manager
    ///

    public int Count
    {
    get
    {
    return blockList.Count + newBlocksList.Count;
    }
    }
    }
    }

    /* Author — Halle Luttrell
    * Contact — [email protected]
    * Created Date — 10.5.2012
    * Last Modified Date — 10.12.2012
    * Last Modified By — Allen Antony Ukani
    */

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Audio;
    using Microsoft.Xna.Framework.Content;
    using Microsoft.Xna.Framework.GamerServices;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Input;
    using Microsoft.Xna.Framework.Media;
    using LegendOfZelda.Collisions;

    namespace LegendOfZelda
    {
    ///

    /// This class represents a door block that can be opened with keys
    ///

    class LockedDoor : Block
    {
    ///

    /// Create a locked door to block entry into another area of the dungeon
    ///

    /// X position of the door
    /// Y position of the door
    /// Width of the door block
    /// Height of the door block
    /// Texture to use for the locked door
    /// Source rectangle for the texture to draw the door
    public LockedDoor(int x, int y, int width, int height, Texture2D texture, Rectangle sourceRect)
    : base(x, y, width, height, false, texture, sourceRect, true)
    {
    // Add any logic for locked doors here
    }

    ///

    /// Draw the door using the sprite sheet
    ///

    /// SpriteBatch to use to draw the door
    public override void Draw(SpriteBatch spriteBatch)
    {
    base.Draw(spriteBatch);
    }

    ///

    /// Update the door appearance and state
    ///

    /// GameTime object from XNA
    public override void Update(GameTime gameTime)
    {
    base.Update(gameTime);
    }

    ///

    /// Detect a collision with the locked door and handle it
    ///

    /// The item that’s colliding with the door (usually a key)
    public override void OnCollision(ICollidable obj)
    {
    // Check for Link colliding and having a key (to open the door)
    if (obj.CollisionGroup == CollisionGroup.Link)
    {
    // Check if Link has a key to use
    if (GameManager.Instance.Player.KeyCount > 0)
    {
    // Use a key to open the door
    UnlockDoor();
    }
    }
    }

    ///

    /// Unlock the door, removing it as an obstacle in the room.
    ///

    public void UnlockDoor()
    {
    // Door is now open
    isPassable = true;
    collisionGroup = CollisionGroup.PassableBlock;

    // Use up a key
    GameManager.Instance.Player.KeyCount–;

    // Play a sound
    SoundFactory.PlaySound(SoundFactory.SoundType.KeyDoor);

    // Remove the map
    CurrentRoom.KeyDoorOpen(this);
    }

    ///

    /// Gets an integer representing the layer that this object should be drawn on, with higher values being drawn on top of lower values.
    /// Objects with equivalent z-indices have an undefined render order relative to each other.
    ///

    public override int ZIndex
    {
    get { return 1; }
    }
    }
    }

    # auks256/cse3902
    /* Original Author — Allen Antony Ukani
    * Original Contact — auks256ATcs.washington.edu
    * Created Date — 09.29.2012
    * Last Modified Date — 10.28.2012
    * Last Modified By — Allen Antony Ukani
    */

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Audio;
    using Microsoft.Xna.Framework.Content;
    using Microsoft.Xna.Framework.GamerServices;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Input;
    using Microsoft.Xna.Framework.Media;
    using LegendOfZelda.Collisions;

    namespace LegendOfZelda.Projectiles
    {
    ///

    /// A fireball shot by an enemy
    ///

    public class Fireball : AnimatedSprite, IProjectile
    {
    private double moveSpeed = 1.7;
    private int lifetime = 9000;
    private int timeAlive = 0;
    private ILink.Direction direction;

    // Original direction, in case we want to switch back
    private ILink.Direction oldDirection;

    private Vector2 directionVector;

    // Fixed movement for a specific angle
    private float angle = -1;
    private Vector2 fixedDirection = Vector2.Zero;

    private bool willExpireOnCollide = true; // If true, the fireball disappears when it hits

    private int damage = 1;

    ///

    /// Map for cardinal movement
    ///

    private static Dictionary directionToXYMap = new Dictionary()
    {
    {ILink.Direction.North, new Vector2(0,-1)},
    {ILink.Direction.South, new Vector2(0,1)},
    {ILink.Direction.East, new Vector2(1,0)},
    {ILink.Direction.West, new Vector2(-1,0)}
    };

    private enum FireballAnims
    {
    Frame1, Frame2, Frame3, Frame4
    }

    private static Dictionary GetAnimationTable()
    {
    Dictionary table = new Dictionary();

    // Fireball animation
    table.Add(FireballAnims.Frame1, new Rectangle(276, 3, 8, 10));
    table.Add(FireballAnims.Frame2, new Rectangle(276, 19, 8, 10));
    table.Add(FireballAnims.Frame3, new Rectangle(276, 35, 8, 10));
    table.Add(FireballAnims.Frame4, new Rectangle(276, 51, 8, 10));

    return table;
    }

    ///

    /// Create a new fireball traveling in a specific direction.
    ///

    /// X position of fireball
    /// Y position of fireball
    /// Direction to travel in
    public Fireball(int x, int y, ILink.Direction direction)
    : base(„Projectiles”)
    {
    this.X = x;
    this.Y = y;
    this.direction = direction;
    this.directionVector = directionToXYMap[direction];
    this.oldDirection = direction;

    // Set up animations
    ChangeAnimationTable(GetAnimationTable());
    PlayAnimation(new int[] { (int)FireballAnims.Frame1, (int)FireballAnims.Frame2, (int)FireballAnims.Frame3, (int)FireballAnims.Frame4 }, 75);
    RandomizeAnimationIndex();
    }

    ///

    /// Create a new fireball traveling in a specific direction at a specific angle.
    ///

    /// X position of fireball
    /// Y position of fireball
    /// Angle to travel in (radians)
    public Fireball(int x, int y, float angle)
    : base(„Projectiles”)
    {
    this.X = x;
    this.Y = y;
    this.angle = angle;
    this.fixedDirection = new Vector2((float)Math.Cos(angle), (float)Math.Sin(angle));
    this.fixedDirection.Normalize();
    this.direction = ILink.Direction.East; // placeholder
    this.directionVector = fixedDirection;
    this.oldDirection = direction;

    // Set up animations
    ChangeAnimationTable(GetAnimationTable());
    PlayAnimation(new int[] { (int)FireballAnims.Frame1, (int)FireballAnims.Frame2, (int)FireballAnims.Frame3, (int)FireballAnims.Frame4 }, 75);
    RandomizeAnimationIndex();
    }

    ///

    /// Update the position and animation of the fireball.
    ///

    /// GameTime structure from XNA
    public override void Update(GameTime gameTime)
    {
    // Only update logic for fireballs on screen
    if (!GameContext.State.TransitioningScreens)
    {
    // Update the location of the fireball
    if (angle = lifetime)
    {
    IsActive = false;
    }
    }

    // Update animation as well
    base.Update(gameTime);
    }

    ///

    /// Draw the fireball
    ///

    /// SpriteBatch to draw with
    public override void Draw(SpriteBatch spriteBatch)
    {
    base.Draw(spriteBatch);
    }

    ///

    /// Bounds of the projectile for collision detection
    ///

    public override Rectangle Bounds
    {
    get
    {
    return new Rectangle(X + 2 * GameContext.Window.Scale, Y + 2 * GameContext.Window.Scale,
    4 * GameContext.Window.Scale, 4 * GameContext.Window.Scale);
    }
    }

    ///

    /// Collision group of the fireball
    ///

    public override CollisionGroup CollisionGroup
    {
    get
    {
    return CollisionGroup.EnemyProjectile;
    }
    }

    ///

    /// Check what to do when the fireball collides with a collidable object
    ///

    /// The object the fireball hit
    public override void OnCollision(ICollidable obj)
    {
    // See what the fireball hit
    if (obj.CollisionGroup == CollisionGroup.Link && obj is ILink)
    {
    // Damage Link
    ILink link = obj as ILink;
    if (!link.IsBeingDamaged)
    {
    link.TakeDamage(damage, DetermineCollisionDirection(link.Bounds));
    IsActive = false;
    }
    }
    else if (obj.CollisionGroup == CollisionGroup.LinkProjectile || obj.CollisionGroup == CollisionGroup.Block)
    {
    // Expire on collision with blocks
    IsActive = false;
    }
    else if (obj.CollisionGroup == CollisionGroup.PassableBlock)
    {
    // Don’t expire on collision with passable blocks
    }
    }

    ///

    /// Convert from the object hit’s bounds to a direction for the collision (north, south, east, west)
    ///

    /// Bounds of the object hit by the fireball
    /// Direction for the collision knockback to go in
    private ILink.Direction DetermineCollisionDirection(Rectangle objBounds)
    {
    Rectangle bounds = Bounds;
    var center1 = new Vector2(bounds.Center.X, bounds.Center.Y);
    var center2 = new Vector2(objBounds.Center.X, objBounds.Center.Y);
    var diff = center1 – center2;

    // Use the inverse of current direction, because that’s where we’re coming from
    if (Math.Abs(diff.X) > Math.Abs(diff.Y))
    {
    // Left/Right
    if (diff.X > 0) return ILink.Direction.East;
    else if (diff.X 0) return ILink.Direction.South;
    else if (diff.Y < 0) return ILink.Direction.North;
    }

    return ILink.Direction.East; // default
    }

    ///

    /// Get the current speed of the projectile
    ///

    public double Speed
    {
    get
    {
    return moveSpeed;
    }
    set
    {
    moveSpeed = value;
    }
    }

    ///

    /// Get the direction the projectile is moving in
    ///

    public ILink.Direction Direction
    {
    get
    {
    return direction;
    }
    set
    {
    // Don’t switch direction if we’re using a fixed angle
    if (angle < 0)
    {
    direction = value;
    directionVector = directionToXYMap[value];
    }
    }
    }

    ///

    /// Get the location of the fireball
    ///

    public override Point Location
    {
    get
    {
    return new Point(X, Y);
    }
    }

    ///

    /// Get the size of the fireball
    ///

    public override Point Size
    {
    get
    {
    return new Point(Width, Height);
    }
    }

    ///

    /// Get or set the X position of the fireball
    ///

    public int X { get; set; }

    ///

    /// Get or set the Y position of the fireball
    ///

    public int Y { get; set; }

    ///

    /// Get the width of the fireball
    ///

    public override int Width
    {
    get
    {
    return 8 * GameContext.Window.Scale;
    }
    }

    ///

    /// Get the height of the fireball
    ///

    public override int Height
    {
    get
    {
    return 10 * GameContext.Window.Scale;
    }
    }

    ///

    /// Gets an integer representing the layer that this object should be drawn on, with higher values being drawn on top of lower values.
    /// Objects with equivalent z-indices have an undefined render order relative to each other.
    ///

    public override int ZIndex
    {
    get { return 0; }
    }

    }
    }

    /* Original Author — Allen Antony Ukani
    * Original Contact — auks256ATcs.washington.edu
    * Created Date — 09.29.2012
    * Last Modified Date — 10.17.2012
    * Last Modified By — Allen Antony Ukani
    */

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Audio;
    using Microsoft.Xna.Framework.Content;
    using Microsoft.Xna.Framework.GamerServices;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Input;
    using Microsoft.Xna.Framework.Media;
    using LegendOfZelda.Collisions;

    namespace LegendOfZelda.Projectiles
    {
    ///

    /// A boomerang projectile launched by Link.
    ///

    public class LinkBoomerang : AnimatedSprite, IProjectile
    {
    private const double maxMove = 1.5;
    private const double moveAccel = 0.1;
    private double currentMove;
    private ILink.Direction direction;
    private Vector2 directionVector;
    private int distanceTraveled;

    // State checking
    private bool returningToLink;
    private bool hasDamagedSomething;

    private int damage = 1;

    ///

    /// Map for cardinal movement
    ///

    private static Dictionary directionToXYMap = new Dictionary()
    {
    {ILink.Direction.North, new Vector2(0,-1)},
    {ILink.Direction.South, new Vector2(0,1)},
    {ILink.Direction.East, new Vector2(1,0)},
    {ILink.Direction.West, new Vector2(-1,0)}
    };

    private enum BoomerangAnims
    {
    North1, North2, North3, North4,
    South1, South2, South3, South4,
    East1, East2, East3, East4,
    West1, West2, West3, West4
    }

    private static Dictionary GetAnimationTable()
    {
    Dictionary table = new Dictionary();

    // North facing boomerang
    table.Add(BoomerangAnims.North1, new Rectangle(95, 204, 8, 8));
    table.Add(BoomerangAnims.North2, new Rectangle(87, 204, 8, 8));
    table.Add(BoomerangAnims.North3, new Rectangle(79, 204, 8, 8));
    table.Add(BoomerangAnims.North4, new Rectangle(71, 204, 8, 8));

    // East facing boomerang
    table.Add(BoomerangAnims.East1, new Rectangle(95, 196, 8, 8));
    table.Add(BoomerangAnims.East2, new Rectangle(87, 196, 8, 8));
    table.Add(BoomerangAnims.East3, new Rectangle(79, 196, 8, 8));
    table.Add(BoomerangAnims.East4, new Rectangle(71, 196, 8, 8));

    // South facing boomerang
    table.Add(BoomerangAnims.South1, new Rectangle(95, 220, 8, 8));
    table.Add(BoomerangAnims.South2, new Rectangle(87, 220, 8, 8));
    table.Add(BoomerangAnims.South3, new Rectangle(79, 220, 8, 8));
    table.Add(BoomerangAnims.South4, new Rectangle(71, 220, 8, 8));

    // West facing boomerang
    table.Add(BoomerangAnims.West1, new Rectangle(95, 212, 8, 8));
    table.Add(BoomerangAnims.West2, new Rectangle(87, 212, 8, 8));
    table.Add(BoomerangAnims.West3, new Rectangle(79, 212, 8, 8));
    table.Add(BoomerangAnims.West4, new Rectangle(71, 212, 8, 8));

    return table;
    }

    ///

    /// Create a new Link boomerang traveling in a specific direction.
    ///

    /// X position of boomerang
    /// Y position of boomerang
    /// Direction to travel in
    public LinkBoomerang(int x, int y, ILink.Direction direction)
    : base(„Projectiles”)
    {
    this.X = x;
    this.Y = y;
    this.direction = direction;
    this.directionVector = directionToXYMap[direction];
    this.returningToLink = false;
    this.hasDamagedSomething = false;
    this.currentMove = maxMove;
    this.distanceTraveled = 0;

    // Set up animations
    ChangeAnimationTable(GetAnimationTable());

    // Start spinning at frame 1 and use the right animation for the direction
    AnimationIndex = 0;
    SetDirectionAnimation(direction);
    }

    ///

    /// Update the position and animation of the boomerang.
    ///

    /// GameTime structure from XNA
    public override void Update(GameTime gameTime)
    {
    if (!returningToLink)
    {
    // Check if it’s time to turn around
    if (distanceTraveled >= 48 * GameContext.Window.Scale)
    {
    returningToLink = true;
    currentMove = 0; // Reset speed
    }
    else
    {
    // Update the location of the Arrow
    X += (int)(directionVector.X * currentMove * gameTime.ElapsedGameTime.Milliseconds / 16.0);
    Y += (int)(directionVector.Y * currentMove * gameTime.ElapsedGameTime.Milliseconds / 16.0);
    distanceTraveled += (int)(maxMove * gameTime.ElapsedGameTime.Milliseconds / 16.0);
    }
    }
    else
    {
    // Seek out Link’s position
    try
    {
    var link = GameManager.Instance.Link;
    int linkCenterX = link.Bounds.Center.X;
    int linkCenterY = link.Bounds.Center.Y;
    int x = X, y = Y;

    // Calculate the distance to Link
    double distance = Math.Sqrt(Math.Pow(X – linkCenterX, 2) + Math.Pow(Y – linkCenterY, 2));

    // Update the location of the boomerang
    if (distance > 4)
    {
    // Get the unit vector from this location to Link’s
    double dx = (linkCenterX – X) / distance;
    double dy = (linkCenterY – Y) / distance;

    // Accelerate to max speed
    currentMove += moveAccel * gameTime.ElapsedGameTime.Milliseconds / 16.0;
    if (currentMove > maxMove) currentMove = maxMove;

    // Move towards the hero
    x += (int)(dx * currentMove * gameTime.ElapsedGameTime.Milliseconds / 16.0);
    y += (int)(dy * currentMove * gameTime.ElapsedGameTime.Milliseconds / 16.0);

    // Update game state
    if (!GameContext.State.LinkIsFrozen && !link.IsDead && !link.IsBeingDamaged)
    {
    X = x;
    Y = y;
    }
    }
    else
    {
    // Close enough to be collected
    IsActive = false;
    }
    }
    catch (Exception)
    {
    // Just in case Link gets destroyed somehow, clean up this projectile too
    IsActive = false;
    }
    }

    // Update animation as well
    base.Update(gameTime);
    }

    ///

    /// Draw the boomerang
    ///

    /// SpriteBatch to draw with
    public override void Draw(SpriteBatch spriteBatch)
    {
    base.Draw(spriteBatch);
    }

    ///

    /// Bounds of the projectile for collision detection
    ///

    public override Rectangle Bounds
    {
    get
    {
    // Smaller hitbox on the boomerang
    return new Rectangle(X + 2 * GameContext.Window.Scale, Y + 2 * GameContext.Window.Scale,
    4 * GameContext.Window.Scale, 4 * GameContext.Window.Scale);
    }
    }

    ///

    /// Collision group of the boomerang
    ///

    public override CollisionGroup CollisionGroup
    {
    get
    {
    return CollisionGroup.LinkProjectile;
    }
    }

    ///

    /// Check what to do when the boomerang collides with a collidable object
    ///

    /// The object the boomerang hit
    public override void OnCollision(ICollidable obj)
    {
    // See what the boomerang hit
    if (obj.CollisionGroup == CollisionGroup.Enemy)
    {
    // Move back towards Link
    if (!returningToLink)
    {
    returningToLink = true;
    currentMove = 0; // Reset speed
    }

    // Track if boomerang has hit an enemy
    hasDamagedSomething = true;
    }
    else if (obj.CollisionGroup == CollisionGroup.EnemyProjectile)
    {
    // Make the boomerang able to block projectiles if it hits them
    hasDamagedSomething = true;
    }
    else if (obj.CollisionGroup == CollisionGroup.Block && !hasDamagedSomething)
    {
    // Bounce the boomerang back towards Link
    returningToLink = true;
    currentMove = 0; // Reset speed

    // Play a sound when it bounces
    SoundFactory.PlaySound(SoundFactory.SoundType.BoomerangBounce);
    }
    else if (obj.CollisionGroup == CollisionGroup.Item)
    {
    // Collect the item
    returningToLink = true;
    currentMove = 0; // Reset speed
    }
    }

    ///

    /// Set the correct animation based on which direction the player is facing
    ///

    /// Direction for the animation
    private void SetDirectionAnimation(ILink.Direction direction)
    {
    switch (direction)
    {
    case ILink.Direction.North:
    PlayAnimation(new int[] { (int)BoomerangAnims.North1, (int)BoomerangAnims.North2, (int)BoomerangAnims.North3, (int)BoomerangAnims.North4 }, 50);
    break;
    case ILink.Direction.South:
    PlayAnimation(new int[] { (int)BoomerangAnims.South1, (int)BoomerangAnims.South2, (int)BoomerangAnims.South3, (int)BoomerangAnims.South4 }, 50);
    break;
    case ILink.Direction.East:
    PlayAnimation(new int[] { (int)BoomerangAnims.East1, (int)BoomerangAnims.East2, (int)BoomerangAnims.East3, (int)BoomerangAnims.East4 }, 50);
    break;
    case ILink.Direction.West:
    PlayAnimation(new int[] { (int)BoomerangAnims.West1, (int)BoomerangAnims.West2, (int)BoomerangAnims.West3, (int)BoomerangAnims.West4 }, 50);
    break;
    }
    }

    ///

    /// Get the current speed of the projectile
    ///

    public double Speed
    {
    get
    {
    return maxMove;
    }
    set
    {
    // can’t change speed
    }
    }

    ///

    /// Get the direction the projectile is moving in
    ///

    public ILink.Direction Direction
    {
    get
    {
    return direction;
    }
    set
    {
    if (!returningToLink)
    {
    direction = value;
    directionVector = directionToXYMap[value];
    SetDirectionAnimation(direction);
    }
    }
    }

    ///

    /// Get the location of the boomerang
    ///

    public override Point Location
    {
    get
    {
    return new Point(X, Y);
    }
    }

    ///

    /// Get the size of the boomerang
    ///

    public override Point Size
    {
    get
    {
    return new Point(Width, Height);
    }
    }

    ///

    /// Get or set the X position of the boomerang
    ///

    public int X { get; set; }

    ///

    /// Get or set the Y position of the boomerang
    ///

    public int Y { get; set; }

    ///

    /// Get the width of the boomerang
    ///

    public override int Width
    {
    get
    {
    return 8 * GameContext.Window.Scale;
    }
    }

    ///

    /// Get the height of the boomerang
    ///

    public override int Height
    {
    get
    {
    return 8 * GameContext.Window.Scale;
    }
    }

    ///

    /// Gets an integer representing the layer that this object should be drawn on, with higher values being drawn on top of lower values.
    /// Objects with equivalent z-indices have an undefined render order relative to each other.
    ///

    public override int ZIndex
    {
    get { return 1; }
    }

    }
    }

    # auks256/cse3902
    # LegendOfZelda/LegendOfZelda/Projectiles/EnemyBoomerang.cs
    /* Original Author — Allen Antony Ukani
    * Original Contact — auks256ATcs.washington.edu
    * Created Date — 09.29.2012
    * Last Modified Date — 10.17.2012
    * Last Modified By — Allen Antony Ukani
    */

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Audio;
    using Microsoft.Xna.Framework.Content;
    using Microsoft.Xna.Framework.GamerServices;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Input;
    using Microsoft.Xna.Framework.Media;
    using LegendOfZelda.Collisions;

    namespace LegendOfZelda.Projectiles
    {
    ///

    /// A boomerang projectile launched by an enemy
    ///

    public class EnemyBoomerang : AnimatedSprite, IProjectile
    {
    private const double maxMove = 1.5;
    private const double moveAccel = 0.1;
    private double currentMove;
    private ILink.Direction direction;
    private Vector2 directionVector;
    private int distanceTraveled;

    // Movement and returning
    private bool returningToSource;
    private bool hasDamagedLink;

    // The enemy controller
    private ICollidable source;

    private int damage = 1; // How much damage the boomerang does to link

    ///

    /// Map for cardinal movement
    ///

    private static Dictionary directionToXYMap = new Dictionary()
    {
    {ILink.Direction.North, new Vector2(0,-1)},
    {ILink.Direction.South, new Vector2(0,1)},
    {ILink.Direction.East, new Vector2(1,0)},
    {ILink.Direction.West, new Vector2(-1,0)}
    };

    private enum BoomerangAnims
    {
    North1, North2, North3, North4,
    South1, South2, South3, South4,
    East1, East2, East3, East4,
    West1, West2, West3, West4
    }

    private static Dictionary GetAnimationTable()
    {
    Dictionary table = new Dictionary();

    // North facing boomerang
    table.Add(BoomerangAnims.North1, new Rectangle(95, 204, 8, 8));
    table.Add(BoomerangAnims.North2, new Rectangle(87, 204, 8, 8));
    table.Add(BoomerangAnims.North3, new Rectangle(79, 204, 8, 8));
    table.Add(BoomerangAnims.North4, new Rectangle(71, 204, 8, 8));

    // East facing boomerang
    table.Add(BoomerangAnims.East1, new Rectangle(95, 196, 8, 8));
    table.Add(BoomerangAnims.East2, new Rectangle(87, 196, 8, 8));
    table.Add(BoomerangAnims.East3, new Rectangle(79, 196, 8, 8));
    table.Add(BoomerangAnims.East4, new Rectangle(71, 196, 8, 8));

    // South facing boomerang
    table.Add(BoomerangAnims.South1, new Rectangle(95, 220, 8, 8));
    table.Add(BoomerangAnims.South2, new Rectangle(87, 220, 8, 8));
    table.Add(BoomerangAnims.South3, new Rectangle(79, 220, 8, 8));
    table.Add(BoomerangAnims.South4, new Rectangle(71, 220, 8, 8));

    // West facing boomerang
    table.Add(BoomerangAnims.West1, new Rectangle(95, 212, 8, 8));
    table.Add(BoomerangAnims.West2, new Rectangle(87, 212, 8, 8));
    table.Add(BoomerangAnims.West3, new Rectangle(79, 212, 8, 8));
    table.Add(BoomerangAnims.West4, new Rectangle(71, 212, 8, 8));

    return table;
    }

    ///

    /// Create a new enemy boomerang traveling in a specific direction.
    ///

    /// X position of boomerang
    /// Y position of boomerang
    /// Direction to travel in
    /// Enemy that threw the boomerang
    public EnemyBoomerang(int x, int y, ILink.Direction direction, ICollidable source)
    : base(„Projectiles”)
    {
    this.X = x;
    this.Y = y;
    this.direction = direction;
    this.directionVector = directionToXYMap[direction];
    this.returningToSource = false;
    this.hasDamagedLink = false;
    this.currentMove = maxMove;
    this.distanceTraveled = 0;
    this.source = source;

    // Set up animations
    ChangeAnimationTable(GetAnimationTable());

    // Start spinning at frame 1 and use the right animation for the direction
    AnimationIndex = 0;
    SetDirectionAnimation(direction);
    }

    ///

    /// Update the position and animation of the boomerang.
    ///

    /// GameTime structure from XNA
    public override void Update(GameTime gameTime)
    {
    // Don’t update the movement if the source is gone
    if (source != null)
    {
    if (!returningToSource)
    {
    // Check if it’s time to turn around
    if (distanceTraveled >= 48 * GameContext.Window.Scale)
    {
    returningToSource = true;
    currentMove = 0; // Reset speed
    }
    else
    {
    // Update the location of the Arrow
    X += (int)(directionVector.X * currentMove * gameTime.ElapsedGameTime.Milliseconds / 16.0);
    Y += (int)(directionVector.Y * currentMove * gameTime.ElapsedGameTime.Milliseconds / 16.0);
    distanceTraveled += (int)(maxMove * gameTime.ElapsedGameTime.Milliseconds / 16.0);
    }
    }
    else
    {
    // Return the boomerang
    int sourceCenterX = source.Bounds.Center.X;
    int sourceCenterY = source.Bounds.Center.Y;
    int x = X, y = Y;

    // Calculate the distance to the source
    double distance = Math.Sqrt(Math.Pow(X – sourceCenterX, 2) + Math.Pow(Y – sourceCenterY, 2));

    // Update the location of the boomerang
    if (distance > 4)
    {
    // Get the unit vector from this location to the source
    double dx = (sourceCenterX – X) / distance;
    double dy = (sourceCenterY – Y) / distance;

    // Accelerate to max speed
    currentMove += moveAccel * gameTime.ElapsedGameTime.Milliseconds / 16.0;
    if (currentMove > maxMove) currentMove = maxMove;

    // Move towards the enemy
    x += (int)(dx * currentMove * gameTime.ElapsedGameTime.Milliseconds / 16.0);
    y += (int)(dy * currentMove * gameTime.ElapsedGameTime.Milliseconds / 16.0);

    X = x;
    Y = y;
    }
    else
    {
    // Close enough to be considered collected
    IsActive = false;
    }
    }
    }
    else
    {
    // Make the boomerang disappear if the source is gone
    IsActive = false;
    }

    // Update animation as well
    base.Update(gameTime);
    }

    ///

    /// Draw the boomerang
    ///

    /// SpriteBatch to draw with
    public override void Draw(SpriteBatch spriteBatch)
    {
    base.Draw(spriteBatch);
    }

    ///

    /// Bounds of the projectile for collision detection
    ///

    public override Rectangle Bounds
    {
    get
    {
    // Smaller hitbox on the boomerang
    return new Rectangle(X + 2 * GameContext.Window.Scale, Y + 2 * GameContext.Window.Scale,
    4 * GameContext.Window.Scale, 4 * GameContext.Window.Scale);
    }
    }

    ///

    /// Collision group of the boomerang
    ///

    public override CollisionGroup CollisionGroup
    {
    get
    {
    return CollisionGroup.EnemyProjectile;
    }
    }

    ///

    /// Check what to do when the boomerang collides with a collidable object
    ///

    /// The object the boomerang hit
    public override void OnCollision(ICollidable obj)
    {
    // See what the boomerang hit
    if (obj.CollisionGroup == CollisionGroup.Link)
    {
    // Boomerang hit Link, inflict damage
    if (!hasDamagedLink && obj is ILink)
    {
    ILink link = obj as ILink;
    link.TakeDamage(damage, Direction);
    hasDamagedLink = true;
    }

    // Move back towards the source
    if (!returningToSource)
    {
    returningToSource = true;
    currentMove = 0; // Reset speed
    }
    }
    else if (obj.CollisionGroup == CollisionGroup.LinkProjectile)
    {

    }
    else if (obj.CollisionGroup == CollisionGroup.Block)
    {
    // Turn the boomerang around
    returningToSource = true;
    currentMove = 0; // Reset speed
    }
    else if (obj is ICollidable && obj == source)
    {
    // Collected by source
    IsActive = false;
    }
    }

    ///

    /// Set the correct animation based on which direction the player is facing
    ///

    /// Direction for the animation
    private void SetDirectionAnimation(ILink.Direction direction)
    {
    switch (direction)
    {
    case ILink.Direction.North:
    PlayAnimation(new int[] { (int)BoomerangAnims.North1, (int)BoomerangAnims.North2, (int)BoomerangAnims.North3, (int)BoomerangAnims.North4 }, 50);
    break;
    case ILink.Direction.South:
    PlayAnimation(new int[] { (int)BoomerangAnims.South1, (int)BoomerangAnims.South2, (int)BoomerangAnims.South3, (int)BoomerangAnims.South4 }, 50);
    break;
    case ILink.Direction.East:
    PlayAnimation(new int[] { (int)BoomerangAnims.East1, (int)BoomerangAnims.East2, (int)BoomerangAnims.East3, (int)BoomerangAnims.East4 }, 50);
    break;
    case ILink.Direction.West:
    PlayAnimation(new int[] { (int)BoomerangAnims.West1, (int)BoomerangAnims.West2, (int)BoomerangAnims.West3, (int)BoomerangAnims.West4 }, 50);
    break;
    }
    }

    ///

    /// Get the current speed of the projectile
    ///

    public double Speed
    {
    get
    {
    return maxMove;
    }
    set
    {
    // can’t change speed
    }
    }

    ///

    /// Get the direction the projectile is moving in
    ///

    public ILink.Direction Direction
    {
    get
    {
    return direction;
    }
    set
    {
    if (!returningToSource)
    {
    direction = value;
    directionVector = directionToXYMap[value];
    SetDirectionAnimation(direction);
    }
    }
    }

    ///

    /// Get the location of the boomerang
    ///

    public override Point Location
    {
    get
    {
    return new Point(X, Y);
    }
    }

    ///

    /// Get the size of the boomerang
    ///

    public override Point Size
    {
    get
    {
    return new Point(Width, Height);
    }
    }

    ///

    /// Get or set the X position of the boomerang
    ///

    public int X { get; set; }

    ///

    /// Get or set the Y position of the boomerang
    ///

    public int Y { get; set; }

    ///

    /// Get the width of the boomerang
    ///

    public override int Width
    {
    get
    {
    return 8 * GameContext.Window.Scale;
    }
    }

    ///

    /// Get the height of the boomerang
    ///

    public override int Height
    {
    get
    {
    return 8 * GameContext.Window.Scale;
    }
    }

    ///

    /// Gets an integer representing the layer that this object should be drawn on, with higher values being drawn on top of lower values.
    /// Objects with equivalent z-indices have an undefined render order relative to each other.
    ///

    public override int ZIndex
    {
    get { return 1; }
    }
    }
    }

    /* Original Author — Allen Antony Ukani
    * Original Contact — auks256ATcs.washington.edu
    * Created Date — 09.29.2012
    * Last Modified Date — 10.17.2012
    * Last Modified By — Allen Antony Ukani
    */

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Audio;
    using Microsoft.Xna.Framework.Content;
    using Microsoft.Xna.Framework.GamerServices;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Input;
    using Microsoft.Xna.Framework.Media;
    using LegendOfZelda.Collisions;

    namespace LegendOfZelda.Projectiles
    {
    ///

    /// Arrow projectile that can be shot by Link.
    ///

    public class LinkArrow : AnimatedSprite, IProjectile
    {
    private double moveSpeed = -2;
    private ILink.Direction direction;
    private Vector2 directionVector;
    private int damage = 2;

    ///

    /// Map for cardinal movement
    ///

    private static Dictionary directionToXYMap = new Dictionary()
    {
    {ILink.Direction.North, new Vector2(0,-1)},
    {ILink.Direction.South, new Vector2(0,1)},
    {ILink.Direction.East, new Vector2(1,0)},
    {ILink.Direction.West, new Vector2(-1,0)}
    };

    private enum ArrowAnims
    {
    North, South, East, West
    }

    private static Dictionary GetAnimationTable()
    {
    Dictionary table = new Dictionary();

    // North facing arrow
    table.Add(ArrowAnims.North, new Rectangle(9, 188, 9, 17));

    // South facing arrow
    table.Add(ArrowAnims.South, new Rectangle(9, 206, 9, 17));

    // East facing arrow
    table.Add(ArrowAnims.East, new Rectangle(26, 188, 17, 9));

    // West facing arrow
    table.Add(ArrowAnims.West, new Rectangle(26, 198, 17, 9));

    return table;
    }

    ///

    /// Create a new LinkArrow traveling in a specific direction.
    ///

    /// X position of arrow
    /// Y position of arrow
    /// Direction to travel in
    public LinkArrow(int x, int y, ILink.Direction direction)
    : base(„Projectiles”)
    {
    this.X = x;
    this.Y = y;
    this.direction = direction;
    this.directionVector = directionToXYMap[direction];

    // Set up animations
    ChangeAnimationTable(GetAnimationTable());

    // Select the animation frame for the right direction
    switch (direction)
    {
    case ILink.Direction.North:
    SetAnimation((int)ArrowAnims.North);
    break;
    case ILink.Direction.South:
    SetAnimation((int)ArrowAnims.South);
    break;
    case ILink.Direction.East:
    SetAnimation((int)ArrowAnims.East);
    break;
    case ILink.Direction.West:
    SetAnimation((int)ArrowAnims.West);
    break;
    }
    }

    ///

    /// Update the position and animation of the arrow.
    ///

    /// GameTime structure from XNA
    public override void Update(GameTime gameTime)
    {
    // Only update logic for arrows on screen
    if (!GameContext.State.TransitioningScreens)
    {
    // Update the location of the Arrow
    X += (int)(directionVector.X * moveSpeed * gameTime.ElapsedGameTime.Milliseconds / 16.0);
    Y += (int)(directionVector.Y * moveSpeed * gameTime.ElapsedGameTime.Milliseconds / 16.0);
    }

    // Check if arrow is onscreen and deactivate if no
    if (!IsOnScreen())
    {
    IsActive = false;
    }

    // Update animation as well
    base.Update(gameTime);
    }

    ///

    /// Draw the arrow
    ///

    /// SpriteBatch to draw with
    public override void Draw(SpriteBatch spriteBatch)
    {
    base.Draw(spriteBatch);
    }

    ///

    /// Check if the projectile is on screen, with some padding around the edge
    ///

    /// True if the projectile is still on screen, false otherwise
    private bool IsOnScreen()
    {
    // Check that the object is actually located on screen, with some padding (100px)
    Rectangle bounds = Bounds;
    Rectangle roomBounds = GameContext.World.CurrentRoomTileSet.GetRoomBounds(GameContext.Window.RoomX, GameContext.Window.RoomY);
    roomBounds.Inflate(100, 100);
    return bounds.Intersects(roomBounds);
    }

    ///

    /// Bounds of the projectile for collision detection
    ///

    public override Rectangle Bounds
    {
    get
    {
    return new Rectangle(X, Y, Width, Height);
    }
    }

    ///

    /// Collision group of the arrow
    ///

    public override CollisionGroup CollisionGroup
    {
    get
    {
    return CollisionGroup.LinkProjectile;
    }
    }

    ///

    /// Check what to do when the arrow collides with a collidable object
    ///

    /// The object the arrow hit
    public override void OnCollision(ICollidable obj)
    {
    // See what the arrow hit
    if (obj.CollisionGroup == CollisionGroup.Enemy)
    {
    // Damage enemy (handled by enemy)
    IsActive = false;
    GameManager.Instance.ParticleManager.CreatePoof(Bounds.Center.X, Bounds.Center.Y);
    }
    else if (obj.CollisionGroup == CollisionGroup.Block)
    {
    // Hit a wall
    IsActive = false;
    GameManager.Instance.ParticleManager.CreatePoof(Bounds.Center.X, Bounds.Center.Y);
    }
    }

    ///

    /// Get the current speed of the projectile
    ///

    public double Speed
    {
    get
    {
    return moveSpeed;
    }
    set
    {
    moveSpeed = value;
    }
    }

    ///

    /// Get the direction the projectile is moving in
    ///

    public ILink.Direction Direction
    {
    get
    {
    return direction;
    }
    set
    {
    direction = value;
    directionVector = directionToXYMap[value];

    // Update the animation to match the direction
    switch (direction)
    {
    case ILink.Direction.North:
    SetAnimation((int)ArrowAnims.North);
    break;
    case ILink.Direction.South:
    SetAnimation((int)ArrowAnims.South);
    break;
    case ILink.Direction.East:
    SetAnimation((int)ArrowAnims.East);
    break;
    case ILink.Direction.West:
    SetAnimation((int)ArrowAnims.West);
    break;
    }
    }
    }

    ///

    /// Get the location of the arrow
    ///

    public override Point Location
    {
    get
    {
    return new Point(X, Y);
    }
    }

    ///

    /// Get the size of the arrow
    ///

    public override Point Size
    {
    get
    {
    if (direction == ILink.Direction.North || direction == ILink.Direction.South)
    {
    return new Point(9 * GameContext.Window.Scale, 17 * GameContext.Window.Scale);
    }
    else
    {
    return new Point(17 * GameContext.Window.Scale, 9 * GameContext.Window.Scale);
    }
    }
    }

    ///

    /// Get or set the X position of the arrow
    ///

    public int X { get; set; }

    ///

    /// Get or set the Y position of the arrow
    ///

    public int Y { get; set; }

    ///

    /// Get the width of the arrow
    ///

    public override int Width
    {
    get
    {
    if (direction == ILink.Direction.North || direction == ILink.Direction.South)
    {
    return 9 * GameContext.Window.Scale;
    }
    else
    {
    return 17 * GameContext.Window.Scale;
    }
    }
    }

    ///

    /// Get the height of the arrow
    ///

    public override int Height
    {
    get
    {
    if (direction == ILink.Direction.North || direction == ILink.Direction.South)
    {
    return 17 * GameContext.Window.Scale;
    }
    else
    {
    return 9 * GameContext.Window.Scale;
    }
    }
    }

    ///

    /// Gets an integer representing the layer that this object should be drawn on, with higher values being drawn on top of lower values.
    /// Objects with equivalent z-indices have an undefined render order relative to each other.
    ///

    public override int ZIndex
    {
    get { return 1; }
    }

    }
    }

    # auks256/cse3902
    /* Original Author — Allen Antony Ukani
    * Original Contact — auks256ATcs.washington.edu
    * Created Date — 09.29.2012
    * Last Modified Date — 10.17.2012
    * Last Modified By — Allen Antony Ukani
    */

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Audio;
    using Microsoft.Xna.Framework.Content;
    using Microsoft.Xna.Framework.GamerServices;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Input;
    using Microsoft.Xna.Framework.Media;
    using LegendOfZelda.Collisions;

    namespace LegendOfZelda.Projectiles
    {
    ///

    /// Implementation of a bomb, which blows up after a certain amount of time
    ///

    public class LinkBomb : AnimatedSprite, IProjectile
    {
    private int fuseDuration = 2000; // For how long does the bomb show a fuse
    private int fuseRemaining;
    private int blastDuration = 500; // For how long does explosion last
    private int blastRemaining;
    private bool exploded;
    private int damage = 3; // Amount of damage an explosion deals
    private int blastRadius = 24;

    private enum BombAnims
    {
    BombFuse, Explosion1, Explosion2, Explosion3
    }

    private static Dictionary GetAnimationTable()
    {
    Dictionary table = new Dictionary();

    // Bomb with fuse animation
    table.Add(BombAnims.BombFuse, new Rectangle(129, 185, 8, 14));

    // Explosion animations
    table.Add(BombAnims.Explosion1, new Rectangle(164, 198, 16, 16));
    table.Add(BombAnims.Explosion2, new Rectangle(187, 198, 16, 16));
    table.Add(BombAnims.Explosion3, new Rectangle(210, 198, 16, 16));

    return table;
    }

    ///

    /// Create a new bomb at the given position
    ///

    /// X position of the bomb
    /// Y position of the bomb
    public LinkBomb(int x, int y)
    : base(„Projectiles”)
    {
    this.X = x;
    this.Y = y;
    this.fuseRemaining = fuseDuration;
    this.blastRemaining = blastDuration;
    this.exploded = false;

    // Set up animations
    ChangeAnimationTable(GetAnimationTable());
    SetAnimation((int)BombAnims.BombFuse);
    }

    ///

    /// Draw the bomb
    ///

    /// SpriteBatch to draw with
    public override void Draw(SpriteBatch spriteBatch)
    {
    base.Draw(spriteBatch);
    }

    ///

    /// Update the bomb status
    ///

    /// GameTime structure from XNA
    public override void Update(GameTime gameTime)
    {
    // Check the bomb state
    if (!exploded)
    {
    // Count down the fuse
    fuseRemaining -= gameTime.ElapsedGameTime.Milliseconds;
    if (fuseRemaining <= 0)
    {
    // Explode
    Explode();
    }
    }
    else
    {
    // Count down the explosion
    blastRemaining -= gameTime.ElapsedGameTime.Milliseconds;
    if (blastRemaining <= 0)
    {
    // Explosion is done
    IsActive = false;
    }
    }

    // Update animation as well
    base.Update(gameTime);
    }

    ///

    /// Make the bomb explode
    ///

    private void Explode()
    {
    // Don’t allow multiple explosions
    if (exploded) return;

    // See if link is in range of the explosion
    Rectangle blastBox = new Rectangle(Bounds.X – blastRadius, Bounds.Y – blastRadius, Bounds.Width + blastRadius * 2, Bounds.Height + blastRadius * 2);
    ILink link = GameManager.Instance.Link;
    if (link.Bounds.Intersects(blastBox))
    {
    // Calculate the direction for damage knockback
    Point linkCenter = new Point(link.Bounds.Center.X, link.Bounds.Center.Y);
    Point center = new Point(Bounds.Center.X, Bounds.Center.Y);
    Vector2 direction = new Vector2(linkCenter.X – center.X, linkCenter.Y – center.Y);
    if (direction != Vector2.Zero) direction.Normalize();

    // Link was hit by the explosion
    ILink.Direction knockbackDir;
    if (Math.Abs(direction.X) > Math.Abs(direction.Y))
    {
    if (direction.X >= 0) knockbackDir = ILink.Direction.East;
    else knockbackDir = ILink.Direction.West;
    }
    else
    {
    if (direction.Y >= 0) knockbackDir = ILink.Direction.South;
    else knockbackDir = ILink.Direction.North;
    }

    link.TakeDamage(damage, knockbackDir);
    }

    // Set the bomb to the exploded state
    exploded = true;
    PlayAnimation(new int[] { (int)BombAnims.Explosion1, (int)BombAnims.Explosion2, (int)BombAnims.Explosion3 }, 150);

    SoundFactory.PlaySound(SoundFactory.SoundType.Bomb);

    // Add some particles to the explosion, going out from the center of the bomb
    GameManager.Instance.ParticleManager.CreateExplosion(Bounds.Center.X, Bounds.Center.Y);

    // Make a bigger hitbox for the bomb
    X -= (16 * GameContext.Window.Scale) / 2;
    Y -= (16 * GameContext.Window.Scale) / 2;
    }

    ///

    /// Bounds of the projectile for collision detection
    ///

    public override Rectangle Bounds
    {
    get
    {
    if (!exploded)
    {
    return new Rectangle(X, Y, Width, Height);
    }
    else
    {
    // When the bomb is exploding, it has a bigger hitbox
    return new Rectangle(X, Y, 16 * GameContext.Window.Scale, 16 * GameContext.Window.Scale);
    }
    }
    }

    ///

    /// Collision group of the bomb
    ///

    public override CollisionGroup CollisionGroup
    {
    get
    {
    return (exploded) ? CollisionGroup.LinkProjectile : CollisionGroup.PassableBlock;
    }
    }

    ///

    /// Check what to do when the bomb collides with a collidable object
    ///

    /// The object the bomb hit
    public override void OnCollision(ICollidable obj)
    {
    // See what the bomb hit
    if (obj.CollisionGroup == CollisionGroup.Enemy)
    {
    // Only checks for collision once the bomb explodes
    // Damage enemy (handled by enemy)
    }
    }

    ///

    /// Get the current speed of the projectile
    ///

    public double Speed
    {
    get
    {
    return 0;
    }
    set
    {
    // do nothing
    }
    }

    ///

    /// Get the direction the projectile is moving in
    ///

    public ILink.Direction Direction
    {
    get
    {
    return ILink.Direction.North; // doesn’t matter
    }
    set
    {
    // do nothing
    }
    }

    ///

    /// Get the location of the bomb
    ///

    public override Point Location
    {
    get
    {
    return new Point(X, Y);
    }
    }

    ///

    /// Get the size of the bomb
    ///

    public override Point Size
    {
    get
    {
    if (!exploded)
    {
    return new Point(8 * GameContext.Window.Scale, 14 * GameContext.Window.Scale);
    }
    else
    {
    return new Point(16 * GameContext.Window.Scale, 16 * GameContext.Window.Scale);
    }
    }
    }

    ///

    /// Get or set the X position of the bomb
    ///

    public int X { get; set; }

    ///

    /// Get or set the Y position of the bomb
    ///

    public int Y { get; set; }

    ///

    /// Get the width of the bomb
    ///

    public override int Width
    {
    get
    {
    if (!exploded)
    {
    return 8 * GameContext.Window.Scale;
    }
    else
    {
    return 16 * GameContext.Window.Scale;
    }
    }
    }

    ///

    /// Get the height of the bomb
    ///

    public override int Height
    {
    get
    {
    if (!exploded)
    {
    return 14 * GameContext.Window.Scale;
    }
    else
    {
    return 16 * GameContext.Window.Scale;
    }
    }
    }

    ///

    /// Gets an integer representing the layer that this object should be drawn on, with higher values being drawn on top of lower values.
    /// Objects with equivalent z-indices have an undefined render order relative to each other.
    ///

    public override int ZIndex
    {
    get
    {
    if (exploded)
    {
    return 1;
    }
    else
    {
    return 0;
    }
    }
    }

    }
    }

    /* Original Author — Allen Antony Ukani
    * Original Contact — auks256ATcs.washington.edu
    * Created Date — 09.29.2012
    * Last Modified Date — 10.17.2012
    * Last Modified By — Allen Antony Ukani
    */

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Audio;
    using Microsoft.Xna.Framework.Content;
    using Microsoft.Xna.Framework.GamerServices;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Input;
    using Microsoft.Xna.Framework.Media;
    using LegendOfZelda.Collisions;

    namespace LegendOfZelda.Projectiles
    {
    ///

    /// Sword projectile for Link’s sword attack
    ///

    public class LinkSword : AnimatedSprite, IProjectile
    {
    private float moveDistance = 1;
    private ILink.Direction direction;
    private Vector2 directionVector;
    private int damage = 1;
    private int currentSwordFrame = 0;
    private int timer = 100;
    private bool isExtended = false;
    private bool beamActivated = false;
    private int beamPos = 0;
    private bool isShooting = false;
    private bool canUseBeams;

    // Constants
    private const int LINK_SWORD_OFFSET = 10;
    private const int BEAM_SPEED = 4;
    private const int BEAM_DAMAGE = 2;

    ///

    /// Map for cardinal movement
    ///

    private static Dictionary directionToXYMap = new Dictionary()
    {
    {ILink.Direction.North, new Vector2(0,-1)},
    {ILink.Direction.South, new Vector2(0,1)},
    {ILink.Direction.East, new Vector2(1,0)},
    {ILink.Direction.West, new Vector2(-1,0)}
    };

    private enum SwordAnims
    {
    North1, North2, North3, North4,
    South1, South2, South3, South4,
    East1, East2, East3, East4,
    West1, West2, West3, West4,
    NorthBeam, SouthBeam, EastBeam, WestBeam,
    }

    private static Dictionary GetAnimationTable()
    {
    Dictionary table = new Dictionary();

    // North sword animation
    table.Add(SwordAnims.North1, new Rectangle(1, 97, 16, 27));
    table.Add(SwordAnims.North2, new Rectangle(18, 97, 16, 27));
    table.Add(SwordAnims.North3, new Rectangle(35, 97, 16, 27));
    table.Add(SwordAnims.North4, new Rectangle(52, 97, 16, 27));

    // East sword animation
    table.Add(SwordAnims.East1, new Rectangle(1, 147, 27, 16));
    table.Add(SwordAnims.East2, new Rectangle(35, 147, 27, 16));
    table.Add(SwordAnims.East3, new Rectangle(69, 147, 27, 16));
    table.Add(SwordAnims.East4, new Rectangle(103, 147, 27, 16));

    // South sword animation
    table.Add(SwordAnims.South1, new Rectangle(1, 124, 16, 27));
    table.Add(SwordAnims.South2, new Rectangle(18, 124, 16, 27));
    table.Add(SwordAnims.South3, new Rectangle(35, 124, 16, 27));
    table.Add(SwordAnims.South4, new Rectangle(52, 124, 16, 27));

    // West sword animation
    table.Add(SwordAnims.West1, new Rectangle(1, 173, 27, 16));
    table.Add(SwordAnims.West2, new Rectangle(35, 173, 27, 16));
    table.Add(SwordAnims.West3, new Rectangle(69, 173, 27, 16));
    table.Add(SwordAnims.West4, new Rectangle(103, 173, 27, 16));

    // Sword beam animations
    table.Add(SwordAnims.NorthBeam, new Rectangle(42, 154, 8, 16));
    table.Add(SwordAnims.SouthBeam, new Rectangle(26, 154, 8, 16));
    table.Add(SwordAnims.EastBeam, new Rectangle(10, 172, 16, 8));
    table.Add(SwordAnims.WestBeam, new Rectangle(10, 188, 16, 8));

    return table;
    }

    ///

    /// Create a new LinkSword traveling in a specific direction.
    ///

    /// X position of sword
    /// Y position of sword
    /// Direction to travel in
    public LinkSword(int x, int y, ILink.Direction direction)
    : base(„Link”)
    {
    this.X = x;
    this.Y = y;
    this.direction = direction;
    this.directionVector = directionToXYMap[direction];

    // Set up the animation table
    ChangeAnimationTable(GetAnimationTable());
    SetAnimation(getSwordAnim(direction, 0));

    // Check health state
    if (GameManager.Instance.Player.Health >= GameManager.Instance.Player.MaxHealth)
    canUseBeams = true;
    else
    canUseBeams = false;
    }

    ///

    /// Convert the current direction and frame into a sword animation
    ///

    /// Direction of the sword
    /// Frame of the animation
    /// SwordAnims enumeration to put in the animation table
    private int getSwordAnim(ILink.Direction direction, int frame)
    {
    switch (direction)
    {
    case ILink.Direction.North:
    switch (frame)
    {
    case 0: return (int)SwordAnims.North1;
    case 1: return (int)SwordAnims.North2;
    case 2: return (int)SwordAnims.North3;
    case 3: return (int)SwordAnims.North4;
    default: return (int)SwordAnims.North1;
    }
    case ILink.Direction.South:
    switch (frame)
    {
    case 0: return (int)SwordAnims.South1;
    case 1: return (int)SwordAnims.South2;
    case 2: return (int)SwordAnims.South3;
    case 3: return (int)SwordAnims.South4;
    default: return (int)SwordAnims.South1;
    }
    case ILink.Direction.East:
    switch (frame)
    {
    case 0: return (int)SwordAnims.East1;
    case 1: return (int)SwordAnims.East2;
    case 2: return (int)SwordAnims.East3;
    case 3: return (int)SwordAnims.East4;
    default: return (int)SwordAnims.East1;
    }
    case ILink.Direction.West:
    switch (frame)
    {
    case 0: return (int)SwordAnims.West1;
    case 1: return (int)SwordAnims.West2;
    case 2: return (int)SwordAnims.West3;
    case 3: return (int)SwordAnims.West4;
    default: return (int)SwordAnims.West1;
    }
    default: return 0;
    }
    }

    private SwordAnims getBeamAnim(ILink.Direction direction)
    {
    switch (direction)
    {
    case ILink.Direction.North: return SwordAnims.NorthBeam;
    case ILink.Direction.South: return SwordAnims.SouthBeam;
    case ILink.Direction.East: return SwordAnims.EastBeam;
    case ILink.Direction.West: return SwordAnims.WestBeam;
    default: return SwordAnims.NorthBeam;
    }
    }

    ///

    /// Update the position and animation of the sword.
    ///

    /// GameTime structure from XNA
    public override void Update(GameTime gameTime)
    {
    if (!isShooting)
    {
    // Update sword position
    ILink link = GameManager.Instance.Link;
    int offsetX = (int)(directionVector.X * LINK_SWORD_OFFSET * 5);
    int offsetY = (int)(directionVector.Y * LINK_SWORD_OFFSET * 5);

    // Figure out where to place the sword
    if (link.IsVisible)
    {
    X = link.X;
    Y = link.Y;

    // Update the sword animation frame
    currentSwordFrame = Math.Min(currentSwordFrame + 1, 3);
    SetAnimation(getSwordAnim(direction, currentSwordFrame));

    // Check for shooting a beam
    if (currentSwordFrame == 3)
    {
    // Can’t start a beam after the sword finishes extension
    isExtended = true;
    }

    if (currentSwordFrame == 2 && !isExtended && canUseBeams)
    {
    // Shoot the beam!
    beamActivated = true;
    beamPos = 0;
    isShooting = true;
    SoundFactory.PlaySound(SoundFactory.SoundType.SwordShot);
    }
    }
    else
    {
    IsActive = false;
    }
    }
    else
    {
    // A sword beam is being shot! Make it travel across the screen
    // Update the sword animation frame
    SetAnimation((int)getBeamAnim(direction));
    X += (int)(directionVector.X * BEAM_SPEED * gameTime.ElapsedGameTime.Milliseconds / 16.0);
    Y += (int)(directionVector.Y * BEAM_SPEED * gameTime.ElapsedGameTime.Milliseconds / 16.0);

    // Check if sword is on screen
    if (!IsOnScreen())
    {
    IsActive = false;
    }
    }

    // Update animation as well
    base.Update(gameTime);
    }

    ///

    /// Check if the projectile is on screen, with some padding around the edge
    ///

    /// True if the projectile is still on screen, false otherwise
    private bool IsOnScreen()
    {
    // Check that the object is actually located on screen, with some padding (100px)
    Rectangle bounds = Bounds;
    Rectangle roomBounds = GameContext.World.CurrentRoomTileSet.GetRoomBounds(GameContext.Window.RoomX, GameContext.Window.RoomY);
    roomBounds.Inflate(100, 100);
    return bounds.Intersects(roomBounds);
    }

    ///

    /// Draw the sword
    ///

    /// SpriteBatch to draw with
    public override void Draw(SpriteBatch spriteBatch)
    {
    if (isShooting)
    {
    // The sword is outside Link, draw it
    base.Draw(spriteBatch);
    }
    }

    ///

    /// Bounds of the projectile for collision detection
    ///

    public override Rectangle Bounds
    {
    get
    {
    if (isShooting)
    {
    // Smaller hitbox on the beam
    return new Rectangle(X + Width / 4, Y + Height / 4, Width / 2, Height / 2);
    }
    else
    {
    // Rectangular bounds for the sword
    int width = 14 * GameContext.Window.Scale;
    int height = 14 * GameContext.Window.Scale;
    int offsetX = (int)(directionVector.X * LINK_SWORD_OFFSET);
    int offsetY = (int)(directionVector.Y * LINK_SWORD_OFFSET);

    // Move it in the right direction, but only after a couple frames
    if (currentSwordFrame >= 2)
    {
    X += offsetX;
    Y += offsetY;

    // Return bounds relative to sword point
    return new Rectangle(X + offsetX, Y + offsetY, width, height);
    }
    else
    {
    return Rectangle.Empty;
    }
    }
    }
    }

    ///

    /// Collision group of the sword
    ///

    public override CollisionGroup CollisionGroup
    {
    get
    {
    return CollisionGroup.LinkProjectile;
    }
    }

    ///

    /// Check what to do when the sword collides with a collidable object
    ///

    /// The object the sword hit
    public override void OnCollision(ICollidable obj)
    {
    // See what the sword hit
    if (obj.CollisionGroup == CollisionGroup.Enemy)
    {
    if (isShooting)
    {
    // Damage enemy (handled by enemy)
    IsActive = false;
    GameManager.Instance.ParticleManager.CreatePoof(Bounds.Center.X, Bounds.Center.Y);
    }
    }
    else if (obj.CollisionGroup == CollisionGroup.Block && isShooting)
    {
    // Hit a wall
    IsActive = false;
    GameManager.Instance.ParticleManager.CreatePoof(Bounds.Center.X, Bounds.Center.Y);
    }
    }

    ///

    /// Get the current speed of the projectile
    ///

    public double Speed
    {
    get
    {
    return 0; // Can’t change this
    }
    set
    {
    // do nothing
    }
    }

    ///

    /// Get the direction the projectile is moving in
    ///

    public ILink.Direction Direction
    {
    get
    {
    return direction;
    }
    set
    {
    if (!isShooting)
    {
    direction = value;
    directionVector = directionToXYMap[value];
    SetAnimation(getSwordAnim(direction, currentSwordFrame));
    }
    }
    }

    ///

    /// Get the location of the sword
    ///

    public override Point Location
    {
    get
    {
    return new Point(X, Y);
    }
    }

    ///

    /// Get the size of the sword
    ///

    public override Point Size
    {
    get
    {
    if (isShooting)
    {
    // Beam sprite
    switch (direction)
    {
    case ILink.Direction.North:
    case ILink.Direction.South:
    return new Point(8 * GameContext.Window.Scale, 16 * GameContext.Window.Scale);
    case ILink.Direction.East:
    case ILink.Direction.West:
    return new Point(16 * GameContext.Window.Scale, 8 * GameContext.Window.Scale);
    default:
    return new Point(16 * GameContext.Window.Scale, 8 * GameContext.Window.Scale);
    }
    }
    else
    {
    // Link’s sword animation
    switch (direction)
    {
    case ILink.Direction.North:
    case ILink.Direction.South:
    return new Point(16 * GameContext.Window.Scale, 27 * GameContext.Window.Scale);
    case ILink.Direction.East:
    case ILink.Direction.West:
    return new Point(27 * GameContext.Window.Scale, 16 * GameContext.Window.Scale);
    default:
    return new Point(27 * GameContext.Window.Scale, 16 * GameContext.Window.Scale);
    }
    }
    }
    }

    ///

    /// Get or set the X position of the sword
    ///

    public int X { get; set; }

    ///

    /// Get or set the Y position of the sword
    ///

    public int Y { get; set; }

    ///

    /// Get the width of the sword based on direction
    ///

    public override int Width
    {
    get
    {
    if (isShooting)
    {
    // Beam sprite
    switch (direction)
    {
    case ILink.Direction.North:
    case ILink.Direction.South:
    return 8 * GameContext.Window.Scale;
    case ILink.Direction.East:
    case ILink.Direction.West:
    return 16 * GameContext.Window.Scale;
    default:
    return 16 * GameContext.Window.Scale;
    }
    }
    else
    {
    // Link’s sword animation
    switch (direction)
    {
    case ILink.Direction.North:
    case ILink.Direction.South:
    return 16 * GameContext.Window.Scale;
    case ILink.Direction.East:
    case ILink.Direction.West:
    return

    Kolejne rozdziały

    Zapraszamy do dalszego czytania naszego leksykonu.

    Wybierz kolejny rozdział z menu poniżej, aby otworzyć nową podstronę kompedium wiedzy i uzyskać szczegółowe informację o leku, substancji lub chorobie.

  1. 15.04.2026
  2. www.leksykon.com.pl

Materiały źródłowe

  • #1
    https://journals.lww.com/cancerjournal/fulltext/2016/12020/oral_cancer__etiology_and_risk_factors__a_review.4.aspx
    Oral cancer is the sixth most common malignancy in the world. Oral cancer is of major concern in Southeast Asia primarily because of the prevalent oral habits of betel quid chewing, smoking, and alcohol consumption. This paper is an overview of the various etiological agents and risk factors implicated in the development of oral cancer. […] Development of oral or head and neck squamous cell carcinoma (HNSCC) and minor salivary gland carcinomas is influenced by both these factors namely tobacco, alcohol, diet and nutrition, viruses, radiation, ethnicity, familial and genetic predisposition, oral thrush, immunosuppression, use of mouthwash, syphilis, dental factors, occupational risks, and mate. […] Tobacco consumption continues to prevail as the most important cancer risk as it alone accounts for millions of cancer deaths annually. The relationship between smoking and oral cancer has been established firmly by epidemiological studies.
  • #2 Mouth cancer – Symptoms and causes – Mayo Clinic
    https://www.mayoclinic.org/diseases-conditions/mouth-cancer/symptoms-causes/syc-20350997
    Oral cancer forms when cells on the lips or in the mouth mutate. Most often they begin in the flat, thin cells that line your lips and the inside of your mouth. These are called squamous cells. Small changes to the DNA of the squamous cells make the cells grow abnormally. These mutated cells accumulate, forming a tumor that grows in the mouth and often spread to lymph nodes in the neck. […] There are several known risk factors that could increase your risk of developing oral cancer. If you use any kind of tobacco, cigarettes, cigars, pipes, chewing tobacco, and others, you’re at a greater risk. Heavy alcohol use also increases the risk. Those with HPV, human papillomavirus, have a higher chance of developing oral cancer as well. Other risk factors include a diet that lacks fruit and vegetables, chronic irritation or inflammation in the mouth, and a weakened immune system.
  • #3 Mouth cancer: Symptoms, diagnosis, and treatment
    https://www.medicalnewstoday.com/articles/165331
    Oral, or mouth cancer can appear anywhere in the mouth, including the inside of the cheeks and the gums. It is a type of head and neck cancer. […] According to the American Cancer Society (ACS), around 53,000 Americans will receive a diagnosis of oral or oropharyngeal cancer in 2019. […] Smokers and heavy drinkers should have regular checkups with the dentist, as tobacco and alcohol are risk factors for mouth cancer. […] Many oral lesions may be precancerous. […] Cancer happens when a genetic change in the body results in cells growing without control. As these unwanted cells continue to grow, they form a tumor. In time, the cells can migrate to other parts of the body. […] Around 90% of mouth cancers are squamous cell carcinoma. They start in the squamous cells that line the lips and the inside of the mouth.
  • #4 Oral Cancer Facts – Oral Cancer Foundation | Information and Resources about Oral Head and Neck Cancer
    https://oralcancerfoundation.org/facts/
    Close to 58,500 Americans will be diagnosed with oral or oropharyngeal cancer this year. […] However, this is due to the increase of HPV16-caused cancers, which are more vulnerable to existing treatment modalities, conferring a significant survival advantage. […] The exact causes of those affected at a younger age are becoming more apparent in peer-reviewed research, revealing a viral etiology (cause), the human papillomavirus version 16. […] It is confirmed that a younger age group, including those who have never used any tobacco products, has a cause that is HPV16 viral based. […] This is the same virus that is the causative agent, along with other versions of the virus, in more than 90% of all cervical cancers. […] HPV16 may even be replacing tobacco as the primary causative agent in the initiation of the disease process in the posterior oral cavity/oropharynx, predominantly in the tonsil and on the base of the tongue.
  • #5 Oral Cancer Causes, Symptoms, Diagnosis, Treatment | National Institute of Dental and Craniofacial Research
    https://www.nidcr.nih.gov/health-info/oral-cancer
    Oral cancer most often occurs in people over the age of 40 and affects more than twice as many men as women. Most cancers in the mouth are related to tobacco use, drinking alcohol, or both, and most throat cancers are caused by the human papilloma virus (HPV). The incidence of HPV-positive oral cancer has risen in recent years. […] Tobacco use of any kind, including cigarette, pipe and cigar, and electronic cigarette smoking, as well as chewing tobacco and snuff puts you at risk for developing oral cancers. Heavy alcohol use also increases the risk. Using both tobacco and alcohol increases the risk even further. […] Infection with the sexually transmitted human papillomavirus (specifically the HPV 16 type) has been linked to oral cancers. […] Risk increases with age. Oral cancers most often occur in people over the age of 40. […] Cancer of the lip can be caused by sun exposure. […] A diet low in fruits and vegetables has been linked with increased risk of oral cancer. […] People with inherited defects in certain genes have a high risk of mouth and middle throat cancer.
  • #6 How Common Is Mouth Cancer and Who’s at Risk for It?
    https://www.healthline.com/health/oral-cancer/how-common-is-mouth-cancer
    Mouth cancer affects the mouth area, lips, gums, and throat. This type of cancer is usually found in smokers, heavy drinkers, or people with a history of HPV. Adjusting certain lifestyle habits may reduce your risk. […] The exact causes of mouth cancer are unknown, but the following risk factors increase your chances of mouth cancer developing: […] Most mouth cancers are related to or tobacco use. Any form of tobacco use will increase your risk of oral cancer. Its estimated that about 90% of mouth cancers worldwide are due to tobacco use, alcohol consumption, or a combination of both. […] Heavy alcohol use is known to increase your risk. Heavy smoking and drinking combined will increase that risk further. […] Infection with some forms of HPV can cause mouth cancers. […] People over 40 have a higher risk of mouth cancer. […] Too much sun exposure can also increase your mouth cancer risk. […] People assigned male at birth are almost twice as likely to get oral cancer.
  • #7 Mouth cancer – Symptoms and causes – Mayo Clinic
    https://www.mayoclinic.org/diseases-conditions/mouth-cancer/symptoms-causes/syc-20350997
    Oral cancer forms when cells on the lips or in the mouth mutate. Most often they begin in the flat, thin cells that line your lips and the inside of your mouth. These are called squamous cells. Small changes to the DNA of the squamous cells make the cells grow abnormally. These mutated cells accumulate, forming a tumor that grows in the mouth and often spread to lymph nodes in the neck. […] There are several known risk factors that could increase your risk of developing oral cancer. If you use any kind of tobacco, cigarettes, cigars, pipes, chewing tobacco, and others, you’re at a greater risk. Heavy alcohol use also increases the risk. Those with HPV, human papillomavirus, have a higher chance of developing oral cancer as well. Other risk factors include a diet that lacks fruit and vegetables, chronic irritation or inflammation in the mouth, and a weakened immune system.
  • #8 Oral Cavity Cancer: Causes & Treatment | Baptist Cancer Center
    https://www.baptistcancercenter.com/Cancers-We-Treat/Oral-Cavity-Cancer
    Did you know tobacco and alcohol are risk factors for oral cavity cancer? […] More than 90% of oral cavity and oropharynx cancers are squamous cell carcinomas. They start in the lining of the throat and mouth. […] Salivary gland cancer starts in the glands of the lining of the mouth or throat. […] Recognizing the signs of oral cavity cancer allows for timely intervention, potentially increasing the chances of successful treatment and improving your quality of life. […] Many symptoms of oral cavity cancer are signs of noncancerous conditions. However, if you have persistent symptoms, see your doctor.
  • #9 Mouth cancer: Symptoms, diagnosis, and treatment
    https://www.medicalnewstoday.com/articles/165331
    Oral, or mouth cancer can appear anywhere in the mouth, including the inside of the cheeks and the gums. It is a type of head and neck cancer. […] According to the American Cancer Society (ACS), around 53,000 Americans will receive a diagnosis of oral or oropharyngeal cancer in 2019. […] Smokers and heavy drinkers should have regular checkups with the dentist, as tobacco and alcohol are risk factors for mouth cancer. […] Many oral lesions may be precancerous. […] Cancer happens when a genetic change in the body results in cells growing without control. As these unwanted cells continue to grow, they form a tumor. In time, the cells can migrate to other parts of the body. […] Around 90% of mouth cancers are squamous cell carcinoma. They start in the squamous cells that line the lips and the inside of the mouth.
  • #10 Mouth cancer – Symptoms and causes – Mayo Clinic
    https://www.mayoclinic.org/diseases-conditions/mouth-cancer/symptoms-causes/syc-20350997
    It’s not always clear what causes mouth cancer. This cancer starts as a growth of cells in the mouth. It most often starts in cells called squamous cells. These are flat, thin cells that line the lips and the inside of the mouth. Most oral cancers are squamous cell carcinomas. […] Mouth cancer happens when cells on the lips or in the mouth develop changes in their DNA. A cell’s DNA holds the instructions that tell the cell what to do. In healthy cells, the DNA tells the cells to grow and multiply at a set rate. The DNA also tells the cells to die at a set time. […] In cancer cells, the DNA changes give different instructions. The changes tell the cancer cells to grow and multiply quickly. Cancer cells can keep living when healthy cells would die. This causes too many cells. […] The cancer cells might form a mass called a tumor. The tumor can grow to invade and destroy healthy body tissue. In time, the cancer cells can break away and spread to other parts of the body. When cancer spreads, it’s called metastatic cancer.
  • #11 Mouth cancer – Symptoms and causes – Mayo Clinic
    https://www.mayoclinic.org/diseases-conditions/mouth-cancer/symptoms-causes/syc-20350997
    It’s not always clear what causes mouth cancer. This cancer starts as a growth of cells in the mouth. It most often starts in cells called squamous cells. These are flat, thin cells that line the lips and the inside of the mouth. Most oral cancers are squamous cell carcinomas. […] Mouth cancer happens when cells on the lips or in the mouth develop changes in their DNA. A cell’s DNA holds the instructions that tell the cell what to do. In healthy cells, the DNA tells the cells to grow and multiply at a set rate. The DNA also tells the cells to die at a set time. […] In cancer cells, the DNA changes give different instructions. The changes tell the cancer cells to grow and multiply quickly. Cancer cells can keep living when healthy cells would die. This causes too many cells. […] The cancer cells might form a mass called a tumor. The tumor can grow to invade and destroy healthy body tissue. In time, the cancer cells can break away and spread to other parts of the body. When cancer spreads, it’s called metastatic cancer.
  • #12 Floor of the mouth cancer – Symptoms and causes – Mayo Clinic
    https://www.mayoclinic.org/diseases-conditions/floor-mouth-cancer/symptoms-causes/syc-20354179
    Floor of the mouth cancer causes changes in the look and feel of the tissue under the tongue. These changes may include a lump or a sore that doesn’t heal. […] Floor of the mouth cancer happens when cells under the tongue develop changes in their DNA. A cell’s DNA holds the instructions that tell a cell what to do. In healthy cells, the DNA gives instructions to grow and multiply at a set rate. The instructions also tell the cells to die at a set time. In cancer cells, the DNA changes give different instructions. The changes tell the cancer cells to make many more cells quickly. Cancer cells can keep living when healthy cells would die. This causes too many cells. […] The cancer cells might form a mass called a tumor. The tumor can grow to invade and destroy healthy body tissue. In time, cancer cells can break away and spread to other parts of the body. When cancer spreads, it’s called metastatic cancer.
  • #13 Causes of Oral Cancer – Oral Cancer – Dentalcare
    https://www.dentalcare.com/en-us/ce-courses/ce348/causes-of-oral-cancer
    Two separate lines of research converged to unravel the complex series of events that lead to oral cancer. One area has clearly identified site-specific alterations of oncogenes such as EGFR and tumor suppressor genes such as p53. The other is based on epidemiological evidence that linked exposure to exogenous agents to the development of specific forms of cancer. […] Cigarette smoking is well established as the most important risk factor in oral cancer. Tobacco smoke contains a large number of chemical carcinogens including aromatic hydrocarbons such as benzopyrene and nitrosamines. These carcinogens have been shown to induce specific genetic changes of the p53 and H-ras genes. […] All forms of alcohol have been implicated in the development of oral cancer. Importantly, the effects of tobacco and alcohol are additive with alcohol acting synergistically to promote the carcinogenic effects of tobacco products.
  • #14 Mouth cancer – Symptoms and causes – Mayo Clinic
    https://www.mayoclinic.org/diseases-conditions/mouth-cancer/symptoms-causes/syc-20350997
    Factors that can increase the risk of mouth cancer include: All forms of tobacco increase the risk of mouth cancer. This includes cigarettes, cigars, pipes, chewing tobacco and snuff. […] Frequent and heavy drinking increases the risk of mouth cancer. Using alcohol and tobacco together increases the risk even more. […] Ultraviolet light from the sun and tanning lamps increases the risk of lip cancer. […] Human papillomavirus, also called HPV, is a common virus that’s passed through sexual contact. For most people, it causes no problems and goes away on its own. For others, it causes changes in the cells that can lead to many types of cancer, including mouth cancer. […] If the body’s germ-fighting immune system is weakened by medicines or illness, there might be a higher risk of mouth cancer. People with a weakened immune system include those taking medicines to control the immune system, such as after an organ transplant. Certain medical conditions, such as infection with HIV, also can weaken the immune system.
  • #15 Causes of Oral Cancer – Oral Cancer – Dentalcare
    https://www.dentalcare.com/en-us/ce-courses/ce348/causes-of-oral-cancer
    Two separate lines of research converged to unravel the complex series of events that lead to oral cancer. One area has clearly identified site-specific alterations of oncogenes such as EGFR and tumor suppressor genes such as p53. The other is based on epidemiological evidence that linked exposure to exogenous agents to the development of specific forms of cancer. […] Cigarette smoking is well established as the most important risk factor in oral cancer. Tobacco smoke contains a large number of chemical carcinogens including aromatic hydrocarbons such as benzopyrene and nitrosamines. These carcinogens have been shown to induce specific genetic changes of the p53 and H-ras genes. […] All forms of alcohol have been implicated in the development of oral cancer. Importantly, the effects of tobacco and alcohol are additive with alcohol acting synergistically to promote the carcinogenic effects of tobacco products.
  • #16 Oral Cancer: Causes, Symptoms & Treatment
    https://my.clevelandclinic.org/health/diseases/11184-oral-cancer
    Oral cancer starts in the squamous cells in your oral cavity. Squamous cells are flat and, when viewed under a microscope, look like a fish scale. […] Normal squamous cells become cancerous when their DNA changes and cells begin growing and multiplying. Over time, these cancerous cells can spread to other areas inside of your mouth and then to other areas of your head and neck or other areas of your body. […] About 75% of people who develop oral cancer have the following habits: Smoke cigarettes, cigars or pipes. Use smokeless tobacco products such as chewing tobacco, dip, snuff or water pipes (hookah or shush). Regularly drink excessive amounts of alcohol. Spend a lot of time in the sun without protecting their lips with sunblock. Have human papillomavirus (HPV). Have a family history of oral cancer. […] Its important to note that 25% of people who develop oral cancer dont smoke or have other known risk factors.
  • #17 Causes and Prevention of Mouth Cancer
    https://www.mouthcancerfoundation.org/causes-and-prevention/
    Mouth cancer, also known as oral cancer, describes one of the areas where head and neck cancers can occur and includes various kinds of tumours affecting the lips, salivary glands, tongue, gums, palate and inside of the cheeks. […] Tobacco use is still considered the main cause of mouth cancer. According to the World Health Organisation, up to half of current smokers will die of a tobacco-related illness including mouth cancer. […] Tobacco users are 6 times more likely to develop head neck cancer. […] 75% of mouth and throat cancers occur in tobacco users. […] Alcohol is another common cause of mouth cancer. Drinking to excess can increase the risk of mouth cancer by four times. […] 3 in 4 people, who have mouth cancer, smoke and consume alcohol. […] Experts suggest the Human Papilloma Virus (HPV), transmitted through oral sex, could overtake tobacco and alcohol as the main risk factor within the coming decade. […] Poor diet is linked to a third of all mouth cancer cases.
  • #18 Cancers of the Oral Mucosa: Background, Pathophysiology, Etiology
    https://emedicine.medscape.com/article/1075729-overview
    Mouth (oral) cancer is a major neoplasm worldwide and accounts for most head and neck cancers. The etiology of oral SCC appears to be multifactorial and strongly related to lifestyle, mostly habits (particularly tobacco alone or in combination with betel, and/or alcohol use), and a poor diet. […] Tobacco and alcohol use are independent risk factors for mouth cancer and tongue cancer. Heavy tobacco smokers have a 20-fold greater risk; heavy alcohol drinkers a 5-fold greater risk; those who do both have a 50-fold greater risk. […] Finally, a diet low in fresh vegetables and fruits has also been implicated in causing oral SCC, and HPVs have been implicated in oropharyngeal cancers. […] The following factors are associated with the etiology of oral cancers: Cigarette smoking: Compared with persons who do not smoke, the risk of oral cancer in persons who smoke low/medium-tar cigarettes and high-tar cigarettes was 8.5- and 16.4-fold greater, respectively.
  • #19 Oral Cancer: Causes, Symptoms, & Treatment
    https://www.webmd.com/oral-health/oral-cancer
    Drinking too much alcohol. Oral cancers are about five times more common in drinkers than in nondrinkers. Using alcohol and tobacco together increases your chances even more. […] Human papillomavirus (HPV). A specific type of HPV is linked to more than two-thirds of oropharyngeal cancers, which affect areas such as the back of the tongue, throat, and tonsils. It’s becoming more common in younger people and in people who have multiple sex partners. […] Poor diet. Studies show a link between oral cancer and not eating enough vegetables and fruits. […] Weakened immune system. When your body’s natural defenses against infection are lowered because of an illness (such as an HIV infection) or medications (such as chemotherapy), you’re more vulnerable to HPV.
  • #20 What Causes Mouth Cancer: Early Signs & Prevention
    https://www.matthewsfamilydentistry.com/blog/what-causes-mouth-cancer/
    High-Risk Factors: Smoking, heavy alcohol use, HPV infection, and a weakened immune system are major risk factors that can increase the likelihood of developing mouth cancer. […] Mouth cancer, also known as oral cancer, can quickly appear and spread. […] Knowing what causes mouth cancer and how to reduce your risk can minimize the likelihood that you might develop this type of cancer. […] Oral cancer happens when cell growth inside the mouth goes out of control. Many lifestyle habits or conditions correlate to mouth cancer development, but these issues do not necessarily directly cause cancer. However, the following conditions have links to increased chances of mouth cancer: […] Smoking or tobacco use can lead to many types of cancer, including oral cancer. […] Even more closely related to developing oral cancer is smokeless tobacco use. Those who chew tobacco have a 50 times higher chance of mouth cancer than those who don’t.
  • #21 Risks And Causes Of Mouth And Oropharyngeal Cancer | Cancer Research UK
    https://www.cancerresearchuk.org/about-cancer/mouth-cancer/risks-causes
    We dont know what causes most mouth or oropharyngeal cancers. But there are some risk factors that can increase your risk of developing it. These include smoking, drinking alcohol, and HPV infection. Some people get mouth and oropharyngeal cancer despite not having these risk factors. […] Smoking tobacco increases your risk of developing mouth and oropharyngeal cancer. This includes cigarettes, pipes and cigars. Research suggests that around 17 out of 100 (17%) of mouth cancers in the UK are caused by smoking. […] Drinking alcohol increases your risk of mouth and oropharyngeal cancer. It causes around 35 out of 100 (around 35%) of mouth cancers in the UK. […] Smokeless tobacco is linked with causing mouth cancer. […] The human papillomavirus (HPV) is a type of virus that infects the skin and the cells lining body cavities.
  • #22 Mouth cancer – Symptoms and causes – Mayo Clinic
    https://www.mayoclinic.org/diseases-conditions/mouth-cancer/symptoms-causes/syc-20350997
    Factors that can increase the risk of mouth cancer include: All forms of tobacco increase the risk of mouth cancer. This includes cigarettes, cigars, pipes, chewing tobacco and snuff. […] Frequent and heavy drinking increases the risk of mouth cancer. Using alcohol and tobacco together increases the risk even more. […] Ultraviolet light from the sun and tanning lamps increases the risk of lip cancer. […] Human papillomavirus, also called HPV, is a common virus that’s passed through sexual contact. For most people, it causes no problems and goes away on its own. For others, it causes changes in the cells that can lead to many types of cancer, including mouth cancer. […] If the body’s germ-fighting immune system is weakened by medicines or illness, there might be a higher risk of mouth cancer. People with a weakened immune system include those taking medicines to control the immune system, such as after an organ transplant. Certain medical conditions, such as infection with HIV, also can weaken the immune system.
  • #23 Cancers of the Oral Mucosa: Background, Pathophysiology, Etiology
    https://emedicine.medscape.com/article/1075729-overview
    Mouth (oral) cancer is a major neoplasm worldwide and accounts for most head and neck cancers. The etiology of oral SCC appears to be multifactorial and strongly related to lifestyle, mostly habits (particularly tobacco alone or in combination with betel, and/or alcohol use), and a poor diet. […] Tobacco and alcohol use are independent risk factors for mouth cancer and tongue cancer. Heavy tobacco smokers have a 20-fold greater risk; heavy alcohol drinkers a 5-fold greater risk; those who do both have a 50-fold greater risk. […] Finally, a diet low in fresh vegetables and fruits has also been implicated in causing oral SCC, and HPVs have been implicated in oropharyngeal cancers. […] The following factors are associated with the etiology of oral cancers: Cigarette smoking: Compared with persons who do not smoke, the risk of oral cancer in persons who smoke low/medium-tar cigarettes and high-tar cigarettes was 8.5- and 16.4-fold greater, respectively.
  • #24 Oral Cancer Causes and Risk Factors
    https://www.cancercenter.com/cancer-types/oral-cancer/risk-factors
    Cancers of the lip are more common among people who work outdoors and visit tanning beds, and among those with prolonged exposure to sunlight. […] Studies have found a link between diets low in fruits and vegetables and an increased oral cancer risk. […] About 85 percent of patients with oral cancers use tobacco in the form of cigarettes, chewing tobacco or snuff. […] About 70 percent of people diagnosed with oral cancer are heavy drinkers. […] Chewing gutka, a combination of betel quid and tobacco, is also common. Both of these substances are associated with an increased oral cancer risk. […] Taking drugs that suppress the immune system, such as those used to prevent rejection of a transplant organ or to treat certain immune diseases, may increase the risk of oral cancer. […] People with a severe case of this illness, which usually causes an itchy rash but sometimes appears as white lines or spots in the mouth and throat, may have a higher risk of oral cancer. […] GVHD increases the likelihood of oral cancer, which may develop as soon as two years later.
  • #25 Risks And Causes Of Mouth And Oropharyngeal Cancer | Cancer Research UK
    https://www.cancerresearchuk.org/about-cancer/mouth-cancer/risks-causes
    We dont know what causes most mouth or oropharyngeal cancers. But there are some risk factors that can increase your risk of developing it. These include smoking, drinking alcohol, and HPV infection. Some people get mouth and oropharyngeal cancer despite not having these risk factors. […] Smoking tobacco increases your risk of developing mouth and oropharyngeal cancer. This includes cigarettes, pipes and cigars. Research suggests that around 17 out of 100 (17%) of mouth cancers in the UK are caused by smoking. […] Drinking alcohol increases your risk of mouth and oropharyngeal cancer. It causes around 35 out of 100 (around 35%) of mouth cancers in the UK. […] Smokeless tobacco is linked with causing mouth cancer. […] The human papillomavirus (HPV) is a type of virus that infects the skin and the cells lining body cavities.
  • #26 Mouth cancer | Causes, Symptoms & Treatments | Cancer Council
    https://www.cancer.org.au/cancer-information/types-of-cancer/mouth-cancer
    Mouth cancer, also known as oral cancer or cancer of the oral cavity, is often used to describe a number of cancers that start in the region of the mouth. […] The main risk factors for most mouth cancers are tobacco and alcohol consumption. Other risk factors can include: human papillomavirus (HPV), epstein-barr virus (EBV), family history of mouth cancers, poor oral hygiene and gum disease, exposure to the sun, chewing the seed of the areca palm tree (sometimes called areca or betel nut). […] Around 59% of mouth cancers in Australia are caused by smoking. Around 31% are caused by excess alcohol consumption. So quitting smoking and moderating alcohol consumption will significantly reduce your risk of developing mouth cancer, especially those inside the mouth. Cancers of the lip are commonly associated with UV exposure, so it is also important to protect yourself from the sun when the UV is 3 or above.
  • #27 Root causes of mouth cancer and tips to prevent it | HealthShots
    https://www.healthshots.com/preventive-care/self-care/root-causes-of-mouth-cancer-and-tips-to-prevent-it/
    Mouth cancer is a type of cancer that develops in any of the parts that make up the mouth (oral cavity). […] the biggest risk factors are alcohol and cigarette use. However, not only smokers but also people who drink alcohol are at a risk of developing mouth cancer. […] research suggests that the human papillomavirus (HPV) is also one of the main causes of mouth cancer. […] Tobacco use, including cigarettes, cigars, and chewing tobacco, is a major risk factor for oral cancer. […] Certain strains of the human papillomavirus (HPV), which are transmitted through sexual contact, can cause oral cancer. […] Drinking alcohol excessively and frequently can increase the risk of oral cancer. Alcohol can damage the cells in the mouth and throat and weaken the immune system, making it harder for the body to fight off cancerous growths.
  • #28 Causes of Oral Cancer – Oral Cancer – Dentalcare
    https://www.dentalcare.com/en-us/ce-courses/ce348/causes-of-oral-cancer
    Two separate lines of research converged to unravel the complex series of events that lead to oral cancer. One area has clearly identified site-specific alterations of oncogenes such as EGFR and tumor suppressor genes such as p53. The other is based on epidemiological evidence that linked exposure to exogenous agents to the development of specific forms of cancer. […] Cigarette smoking is well established as the most important risk factor in oral cancer. Tobacco smoke contains a large number of chemical carcinogens including aromatic hydrocarbons such as benzopyrene and nitrosamines. These carcinogens have been shown to induce specific genetic changes of the p53 and H-ras genes. […] All forms of alcohol have been implicated in the development of oral cancer. Importantly, the effects of tobacco and alcohol are additive with alcohol acting synergistically to promote the carcinogenic effects of tobacco products.
  • #29 Causes of oral cancer – an appraisal of controversies | British Dental Journal
    https://www.nature.com/articles/sj.bdj.2009.1009
    Major risk factors for oral cancer in the UK population are cigarette smoking and alcohol misuse. […] Smokeless tobacco (ST) use also significantly increases the risk of oral cancer. […] Betel quid is carcinogenic to humans (both with and without added tobacco) and is an important risk factor among people with this habit in the Asian ethnic minorities residing the UK. […] The estimated elevated risks from these different agents and exposures (among smokers, regular users of alcohol and betel quid; adjusted for each other) compared to non-users are reported consistently from many populations. […] The synergistic effect on the carcinogenic potency of tobacco in oral cancer by alcohol consumption is well documented. […] There is sufficient evidence based on recent studies (mostly conducted in the USA) that infection with HPV (subtypes 6 and 16) is a risk factor particularly for the oropharynx.
  • #30 Mouth Cancer Causes, Risk Factors & Prevention | Memorial Sloan Kettering Cancer Center
    https://www.mskcc.org/cancer-care/types/mouth/mouth-cancer-risk-factors-prevention
    Mouth cancer can affect anyone, but using tobacco products and regularly drinking too much alcohol greatly increase your chances. […] Other major risk factors include sun exposure and tanning bed use. Infection with the sexually transmitted disease human papillomavirus (HPV) has been associated with mouth cancer as well, but there is a much stronger link between HPV and throat cancer. […] Studies have shown that as many as eight in ten people with mouth cancer are tobacco users. Tobacco includes both smoking and smokeless tobacco (snuff and chewing tobacco). […] Excessive consumption of alcohol is the other major risk factor for mouth cancer besides tobacco use. Most people who are diagnosed with mouth cancer drink heavily. […] The combination of tobacco and alcohol increases the risk for mouth cancer even further than either two risk factors alone. Studies have shown that people who use tobacco and alcohol together have a substantially greater risk for mouth cancer than people who don’t smoke or drink.
  • #31 Oral Cancer: Symptoms, Causes, Diagnosis, Treatment, Coping
    https://www.verywellhealth.com/what-is-oral-cancer-514254
    Tobacco and alcohol use are the major risk factors for the disease, but there are others, including infection with the human papillomavirus (HPV). […] Perhaps the most significant risk factor for developing oral cancer is tobacco use. Smoking cigarettes, cigars, and pipes all increase your risk of cancer anywhere in the mouth or throat. Moreover, smokeless or oral tobacco products often called „dip” or „chew,” heighten the risk for developing cancers of the cheek, gums, and inner part of the lips. […] Other risk factors linked to the development of oral cancer include: Heavy alcohol consumption: Risk dramatically increases when a person both smokes and drinks heavily. […] Human papillomavirus (HPV), especially HPV type 16, which is transmitted through sexual contact. Note, it is rarely related to oral cancer. Oropharynx cancer (occurs in tonsils, base of tongue, etc.) is the type of cancer commonly associated with HPV infection. […] Oral cancer is more common in men, perhaps because men are more likely to use tobacco and alcohol than women. […] Oral cancer is also more common in adults over age 55, although this is changing as cancers related to HPV infection are increasing in number.
  • #32 Oral & Oropharyngeal Cancer Causes | Delta Dental NC Blog
    https://deltadentalnc.com/ddnc-blog/causes-of-oral-and-oropharyngeal-cancer
    All tobacco use can lead to mouth and throat cancer. […] Drinking more than four alcoholic drinks per day increases risk, in part because your body breaks down alcohol into harmful chemicals that can damage your DNA. […] Using both tobacco and alcohol increases your risk even more, perhaps because alcohol aids tobacco in having an effect on cells and causing cancer. […] Human papillomavirus (HPV) is the leading cause of cancers of the tonsils and base of the tongue. These cancers have multiplied in the past decade.
  • #33 Oral Squamous Cell Carcinoma – Ear, Nose, and Throat Disorders – Merck Manual Professional Edition
    https://www.merckmanuals.com/professional/ear-nose-and-throat-disorders/tumors-of-the-head-and-neck/oral-squamous-cell-carcinoma
    Oral cancer refers to cancer occurring between the vermilion border of the lips and the junction of the hard and soft palates or the posterior one-third of the tongue. Over 95% of people with oral squamous cell carcinoma smoke tobacco, drink alcohol, or both. […] The chief risk factors for oral squamous cell carcinoma are Smoking (especially 2 packs/day) and Alcohol use. Risk increases dramatically when alcohol use exceeds 177 mL (6 oz) of distilled liquor, 148 mL (5 oz) of wine, or 1065 mL (36 oz) of beer/day. The combination of heavy smoking and heavy alcohol consumption is estimated to raise the risk 100-fold in females and 38-fold in males. […] Squamous cell carcinoma of the tongue may also result from any chronic irritation, such as dental caries, overuse of mouthwash, chewing tobacco, or the use of betel quid. Oral human papillomavirus (HPV), typically acquired via oral-genital contact, may have a role in the etiology of some oral cancers; however, HPV is identified in oral cancer much less often than it is in oropharyngeal cancer, and its presence in resected tissue does not necessarily imply causation. […] The chief risk factors for oral squamous cell carcinoma are heavy smoking and alcohol use.
  • #34 Mouth cancer – Symptoms and causes – Mayo Clinic
    https://www.mayoclinic.org/diseases-conditions/mouth-cancer/symptoms-causes/syc-20350997
    Factors that can increase the risk of mouth cancer include: All forms of tobacco increase the risk of mouth cancer. This includes cigarettes, cigars, pipes, chewing tobacco and snuff. […] Frequent and heavy drinking increases the risk of mouth cancer. Using alcohol and tobacco together increases the risk even more. […] Ultraviolet light from the sun and tanning lamps increases the risk of lip cancer. […] Human papillomavirus, also called HPV, is a common virus that’s passed through sexual contact. For most people, it causes no problems and goes away on its own. For others, it causes changes in the cells that can lead to many types of cancer, including mouth cancer. […] If the body’s germ-fighting immune system is weakened by medicines or illness, there might be a higher risk of mouth cancer. People with a weakened immune system include those taking medicines to control the immune system, such as after an organ transplant. Certain medical conditions, such as infection with HIV, also can weaken the immune system.
  • #35 Oral Cancer Causes, Symptoms, Diagnosis, Treatment | National Institute of Dental and Craniofacial Research
    https://www.nidcr.nih.gov/health-info/oral-cancer
    Oral cancer most often occurs in people over the age of 40 and affects more than twice as many men as women. Most cancers in the mouth are related to tobacco use, drinking alcohol, or both, and most throat cancers are caused by the human papilloma virus (HPV). The incidence of HPV-positive oral cancer has risen in recent years. […] Tobacco use of any kind, including cigarette, pipe and cigar, and electronic cigarette smoking, as well as chewing tobacco and snuff puts you at risk for developing oral cancers. Heavy alcohol use also increases the risk. Using both tobacco and alcohol increases the risk even further. […] Infection with the sexually transmitted human papillomavirus (specifically the HPV 16 type) has been linked to oral cancers. […] Risk increases with age. Oral cancers most often occur in people over the age of 40. […] Cancer of the lip can be caused by sun exposure. […] A diet low in fruits and vegetables has been linked with increased risk of oral cancer. […] People with inherited defects in certain genes have a high risk of mouth and middle throat cancer.
  • #36 Risks And Causes Of Mouth And Oropharyngeal Cancer | Cancer Research UK
    https://www.cancerresearchuk.org/about-cancer/mouth-cancer/risks-causes
    The link to HPV is much stronger for oropharyngeal cancers than it is for mouth cancers. HPV causes around 50 out of every 100 (around 50%) of oropharyngeal cancers in the UK. […] Research shows an increased risk of mouth and oropharyngeal cancer in people with HIV/AIDS – there are higher rates of Human papillomavirus (HPV) infection in people with HIV. […] Changes can happen in the cells in the lining of the mouth. […] Head and neck cancer risk is higher in people with a brother or sister (sibling) who had head and neck cancer. […] People who have the following cancers are also at increased risk of mouth cancer: a type of cervical cancer called squamous cell cancer, cancer of the food pipe (oesophageal squamous cell cancer), lung cancer.
  • #37 Risks And Causes Of Mouth And Oropharyngeal Cancer | Cancer Research UK
    https://www.cancerresearchuk.org/about-cancer/mouth-cancer/risks-causes
    The link to HPV is much stronger for oropharyngeal cancers than it is for mouth cancers. HPV causes around 50 out of every 100 (around 50%) of oropharyngeal cancers in the UK. […] Research shows an increased risk of mouth and oropharyngeal cancer in people with HIV/AIDS – there are higher rates of Human papillomavirus (HPV) infection in people with HIV. […] Changes can happen in the cells in the lining of the mouth. […] Head and neck cancer risk is higher in people with a brother or sister (sibling) who had head and neck cancer. […] People who have the following cancers are also at increased risk of mouth cancer: a type of cervical cancer called squamous cell cancer, cancer of the food pipe (oesophageal squamous cell cancer), lung cancer.
  • #38 Tongue Cancer: Symptoms, Causes (Smoking, HPV) & Survival Rate
    https://www.cancercenter.com/cancer-types/oral-cancer/types/tongue-cancer
    Tongue cancer, a type of oral cancer, originates in the long, flat, muscular organ in the mouth known as the tongue. […] What causes tongue cancer? […] Most tongue cancer develops from the flat squamous cells that line the surface of the tongue. When they begin dividing into a cluster of abnormal cells, that creates a tumor. Like many mouth and throat cancers, tongue cancer is associated with heavy tobacco and alcohol use, as well as with the human papillomavirus (HPV). […] HPV infection may cause about 70 percent of oropharyngeal cancers, including cancers of the base of the tongue and tonsils, according to the U.S. Centers for Disease Control and Prevention (CDC). […] The risk for developing tongue cancer is approximately five times higher among those who smoke compared to people who don’t use tobacco. People who smoke and also drink alcohol face a 30 times higher risk for developing head and neck cancers, including tongue cancer, than those in the general population. […] In addition to tobacco and alcohol use and HPV infection, other risk factors for mouth and throat cancers are listed below.
  • #39 Causes of oral cancer – an appraisal of controversies | British Dental Journal
    https://www.nature.com/articles/sj.bdj.2009.1009
    The aetiological role of HPV in cervical cancer has been well established and new data confirm that a proportion of oral and oropharyngeal cancers can be attributed to HPV infection and seropositive status. […] There is accumulating evidence that indicates a positive correlation between low intake of fresh vegetables and fruits and an increased risk of oral cancer. […] Higher risks are also associated with high intake of meat and processed meat products. […] Oral cancer is seen more often in people from lower socio-economic groups and those living in deprived areas. […] It has been speculated that susceptibility to oral cancer from tobacco and alcohol use may differ by race and ethnicity. […] Although poor oral hygiene and poor dentition (faulty restorations, sharp teeth and ill-fitting dentures) have been implicated in a few epidemiological studies, it is not clear whether confounding by tobacco and alcohol have been addressed in these studies.
  • #40 Symptoms and Causes of Oral cancer
    https://www.hcgoncology.com/types-of-cancers/oral-cancer-symptoms-and-causes/
    Excessive alcohol consumption is one of the possible reasons for oral cancer. […] Exposure to solar radiation may cause lip cancer. Continuous solar radiation on the lips results in disruptive and non-disruptive mutations, causing lip cancer. […] People with one or more family members diagnosed with oral cancer may also have a higher risk of developing oral cancer. […] Often, it is observed that oral cancer is caused by an HPV infection. HPV alters the normal cellular characteristics of the oral epithelium, which may be one of the reasons for oral cancer. […] Possible causes for oral cancer include excessive consumption of tobacco and alcohol, solar exposure, family history of oral cancer, and HPV infection.
  • #41 Oral Cancer Facts – Oral Cancer Foundation | Information and Resources about Oral Head and Neck Cancer
    https://oralcancerfoundation.org/facts/
    Close to 58,500 Americans will be diagnosed with oral or oropharyngeal cancer this year. […] However, this is due to the increase of HPV16-caused cancers, which are more vulnerable to existing treatment modalities, conferring a significant survival advantage. […] The exact causes of those affected at a younger age are becoming more apparent in peer-reviewed research, revealing a viral etiology (cause), the human papillomavirus version 16. […] It is confirmed that a younger age group, including those who have never used any tobacco products, has a cause that is HPV16 viral based. […] This is the same virus that is the causative agent, along with other versions of the virus, in more than 90% of all cervical cancers. […] HPV16 may even be replacing tobacco as the primary causative agent in the initiation of the disease process in the posterior oral cavity/oropharynx, predominantly in the tonsil and on the base of the tongue.
  • #42 Oral Cancer Facts – Oral Cancer Foundation | Information and Resources about Oral Head and Neck Cancer
    https://oralcancerfoundation.org/facts/
    Tobacco use in all its forms is number one on the list of risk factors for true oral cavity cancers in individuals over 50. […] Tobacco and alcohol are essentially chemical factors, but they can also be considered lifestyle factors since we have some control over them. […] The human papillomavirus, particularly HPV16, has been definitively implicated in oropharyngeal cancers. […] Infection with even a high-risk HPV virus does not mean that you will develop oral cancer. […] It is likely that the changes in sexual behaviors of young adults over the last few decades, which are continuing today, are increasing the spread of HPV and the oncogenic versions of it.
  • #43 Mouth cancer | Causes, Symptoms & Treatments | Cancer Council
    https://www.cancer.org.au/cancer-information/types-of-cancer/mouth-cancer
    Mouth cancer, also known as oral cancer or cancer of the oral cavity, is often used to describe a number of cancers that start in the region of the mouth. […] The main risk factors for most mouth cancers are tobacco and alcohol consumption. Other risk factors can include: human papillomavirus (HPV), epstein-barr virus (EBV), family history of mouth cancers, poor oral hygiene and gum disease, exposure to the sun, chewing the seed of the areca palm tree (sometimes called areca or betel nut). […] Around 59% of mouth cancers in Australia are caused by smoking. Around 31% are caused by excess alcohol consumption. So quitting smoking and moderating alcohol consumption will significantly reduce your risk of developing mouth cancer, especially those inside the mouth. Cancers of the lip are commonly associated with UV exposure, so it is also important to protect yourself from the sun when the UV is 3 or above.
  • #44 Head and Neck Cancers – NCI
    https://www.cancer.gov/types/head-and-neck/head-neck-fact-sheet
    Radiation to the head and neck, for noncancerous conditions or cancer, is a risk factor for cancer of the salivary glands. […] Infection with the Epstein-Barr virus is a risk factor for nasopharyngeal cancer and cancer of the salivary glands. […] Some genetic disorders, such as Fanconi anemia, can increase the risk of developing precancerous lesions and cancers early in life.