/// <summary> /// Open the Spell Window /// </summary> /// <param name="hero">Hero handle</param> /// <param name="item">Item used to open the spell book</param> public void Open(Hero hero, Item item) { if (hero == null) return; Hero = hero; if (item.Type == ItemType.Book) Class = HeroClass.Mage; else if (item.Type == ItemType.HolySymbol) Class = HeroClass.Cleric; else return; IsVisible = true; }
/// <summary> /// Constructor /// </summary> public CharGen() { Heroes = new Hero[4]; HeroeBoxes = new Rectangle[] { new Rectangle(32, 128, 64, 64), new Rectangle(160, 128, 64, 64), new Rectangle(32, 256, 64, 64), new Rectangle(160, 256, 64, 64), }; NameLocations = new Point[] { new Point(4, 212), new Point(132, 212), new Point(4, 340), new Point(132, 340), }; HeroID = -1; BackButton = new Rectangle(528, 344, 76, 32); #region Allowed classes AllowedClass = new Dictionary<HeroRace, List<HeroClass>>(); AllowedClass.Add(HeroRace.Human, new List<HeroClass>() { HeroClass.Fighter, HeroClass.Ranger, HeroClass.Mage, HeroClass.Paladin, HeroClass.Cleric, HeroClass.Thief, }); AllowedClass.Add(HeroRace.Elf, new List<HeroClass>() { HeroClass.Fighter, HeroClass.Ranger, HeroClass.Mage, HeroClass.Cleric, HeroClass.Thief, HeroClass.Fighter | HeroClass.Thief, HeroClass.Fighter | HeroClass.Mage, HeroClass.Fighter | HeroClass.Mage | HeroClass.Thief, HeroClass.Thief | HeroClass.Mage, }); AllowedClass.Add(HeroRace.HalfElf, new List<HeroClass>() { HeroClass.Fighter, HeroClass.Ranger, HeroClass.Mage, HeroClass.Cleric, HeroClass.Thief, HeroClass.Fighter | HeroClass.Cleric, HeroClass.Fighter | HeroClass.Thief, HeroClass.Fighter | HeroClass.Mage, HeroClass.Fighter | HeroClass.Mage | HeroClass.Thief, HeroClass.Thief | HeroClass.Mage, HeroClass.Fighter | HeroClass.Cleric | HeroClass.Mage, HeroClass.Ranger | HeroClass.Cleric, HeroClass.Cleric | HeroClass.Mage }); AllowedClass.Add(HeroRace.Dwarf, new List<HeroClass>() { HeroClass.Fighter, HeroClass.Cleric, HeroClass.Thief, HeroClass.Fighter | HeroClass.Cleric, HeroClass.Fighter | HeroClass.Thief, }); AllowedClass.Add(HeroRace.Gnome, new List<HeroClass>() { HeroClass.Fighter, HeroClass.Cleric, HeroClass.Thief, HeroClass.Fighter | HeroClass.Cleric, HeroClass.Fighter | HeroClass.Thief, HeroClass.Cleric | HeroClass.Thief, }); AllowedClass.Add(HeroRace.Halfling, new List<HeroClass>() { HeroClass.Fighter, HeroClass.Cleric, HeroClass.Thief, HeroClass.Fighter | HeroClass.Thief, }); #endregion }
/// <summary> /// Update the scene /// </summary> /// <param name="time"></param> /// <param name="hasFocus"></param> /// <param name="isCovered"></param> public override void Update(GameTime time, bool hasFocus, bool isCovered) { // Go back to the main menu if (Keyboard.IsNewKeyPress(Keys.Escape)) { ScreenManager.AddScreen(new MainMenu()); ExitScreen(); } switch (CurrentState) { #region Select hero case CharGenStates.SelectHero: if (Mouse.IsButtonDown(MouseButtons.Left)) { for (int id = 0; id < 4; id++) { if (HeroeBoxes[id].Contains(Mouse.Location)) { HeroID = id; // Create a new hero or remove it if (Heroes[id] == null) { Heroes[id] = new Hero(); CurrentState = CharGenStates.SelectRace; } else CurrentState = CharGenStates.Delete; } } } break; #endregion #region Select race case CharGenStates.SelectRace: { Point point = new Point(302, 160); for (int i = 0; i < 12; i++) { if (new Rectangle(point.X, point.Y, 324, 16).Contains(Mouse.Location) && Mouse.IsNewButtonDown(MouseButtons.Left)) { CurrentHero.Race = (HeroRace) Enum.GetValues(typeof(HeroRace)).GetValue(i / 2); CurrentHero.Gender = (HeroGender)(i % 2); CurrentState = CharGenStates.SelectClass; } point.Y += 18; } } break; #endregion #region Select class case CharGenStates.SelectClass: { Point point = new Point(304, 0); for (int i = 0; i < 9; i++) { point.Y = 160 + i * 18; if (new Rectangle(point.X, point.Y, 324, 16).Contains(Mouse.Location) && Mouse.IsNewButtonDown(MouseButtons.Left)) { CurrentHero.Professions.Clear(); switch (i) { case 0: CurrentHero.Professions.Add(new Profession(0, HeroClass.Fighter)); break; case 1: CurrentHero.Professions.Add(new Profession(0, HeroClass.Ranger)); break; case 2: CurrentHero.Professions.Add(new Profession(0, HeroClass.Mage)); break; case 3: CurrentHero.Professions.Add(new Profession(0, HeroClass.Cleric)); break; case 4: CurrentHero.Professions.Add(new Profession(0, HeroClass.Thief)); break; case 5: CurrentHero.Professions.Add(new Profession(0, HeroClass.Fighter)); CurrentHero.Professions.Add(new Profession(0, HeroClass.Thief)); break; case 6: CurrentHero.Professions.Add(new Profession(0, HeroClass.Fighter)); CurrentHero.Professions.Add(new Profession(0, HeroClass.Mage)); break; case 7: CurrentHero.Professions.Add(new Profession(0, HeroClass.Fighter)); CurrentHero.Professions.Add(new Profession(0, HeroClass.Mage)); CurrentHero.Professions.Add(new Profession(0, HeroClass.Thief)); break; case 8: CurrentHero.Professions.Add(new Profession(0, HeroClass.Thief)); CurrentHero.Professions.Add(new Profession(0, HeroClass.Mage)); break; } CurrentState = CharGenStates.SelectAlignment; } // Back if (BackButton.Contains(Mouse.Location) && Mouse.IsNewButtonDown(MouseButtons.Left)) CurrentState = CharGenStates.SelectRace; } } break; #endregion #region Select alignment case CharGenStates.SelectAlignment: { Point point = new Point(304, 0); for (int i = 0; i < 9; i++) { point.Y = 176 + i * 18; if (new Rectangle(point.X, point.Y, 324, 16).Contains(Mouse.Location) && Mouse.IsNewButtonDown(MouseButtons.Left)) { EntityAlignment[] alignments = new EntityAlignment[] { EntityAlignment.LawfulGood, EntityAlignment.NeutralGood, EntityAlignment.ChaoticGood, EntityAlignment.LawfulNeutral, EntityAlignment.TrueNeutral, EntityAlignment.ChaoticNeutral, EntityAlignment.LawfulEvil, EntityAlignment.NeutralEvil, EntityAlignment.ChaoticEvil, }; CurrentHero.Alignment = alignments[i]; CurrentHero.RollAbilities(); CurrentState = CharGenStates.SelectFace; } } // Back if (BackButton.Contains(Mouse.Location) && Mouse.IsNewButtonDown(MouseButtons.Left)) CurrentState = CharGenStates.SelectClass; } break; #endregion #region Select face case CharGenStates.SelectFace: { if (Mouse.IsNewButtonDown(MouseButtons.Left)) { if (new Rectangle(288, 132, 64, 32).Contains(Mouse.Location)) FaceOffset--; if (new Rectangle(288, 164, 64, 32).Contains(Mouse.Location)) FaceOffset++; // Select a face for (int x = 0; x < 4; x++) { if (new Rectangle(352 + x * 64, 132, 64, 64).Contains(Mouse.Location)) { CurrentHero.Head = FaceOffset + x; CurrentState = CharGenStates.Confirm; break; } } } // Limit value if (CurrentHero.Gender == HeroGender.Male) { if (FaceOffset < 0) FaceOffset = 0; if (FaceOffset > 25) FaceOffset = 25; } else { if (FaceOffset < 29) FaceOffset = 29; if (FaceOffset > 40) FaceOffset = 40; } // Back if (BackButton.Contains(Mouse.Location) && Mouse.IsNewButtonDown(MouseButtons.Left)) CurrentState = CharGenStates.SelectAlignment; } break; #endregion #region Confirm case CharGenStates.Confirm: { if (Mouse.IsNewButtonDown(MouseButtons.Left)) { // Reroll if (new Rectangle(448, 318, 76, 32).Contains(Mouse.Location)) { CurrentHero.RollAbilities(); } // Faces if (new Rectangle(448, 350, 76, 32).Contains(Mouse.Location)) { CurrentHero.Head = -1; CurrentState = CharGenStates.SelectFace; } // Modify if (new Rectangle(528, 316, 76, 32).Contains(Mouse.Location)) { } // Keep if (new Rectangle(528, 350, 76, 32).Contains(Mouse.Location)) { CurrentState = CharGenStates.SelectName; CurrentHero.Name = GetRandomName(CurrentHero.Race, CurrentHero.Gender); Keyboard.KeyDown += new EventHandler<PreviewKeyDownEventArgs>(Keyboard_OnKeyDown); } } } break; #endregion #region Select name case CharGenStates.SelectName: { // Back //if (BackButton.Contains(Mouse.Location) && Mouse.IsNewButtonDown(MouseButtons.Left)) if (new Rectangle(448, 350, 80, 32).Contains(Mouse.Location) && Mouse.IsNewButtonDown(MouseButtons.Left)) { CurrentState = CharGenStates.Confirm; Keyboard.KeyDown -= Keyboard_OnKeyDown; } // OK if (new Rectangle(528, 350, 80, 32).Contains(Mouse.Location) && Mouse.IsNewButtonDown(MouseButtons.Left)) { Keyboard.KeyDown -= new EventHandler<PreviewKeyDownEventArgs>(Keyboard_OnKeyDown); CurrentState = CharGenStates.SelectHero; } } break; #endregion #region Delete hero case CharGenStates.Delete: { if (Mouse.IsNewButtonDown(MouseButtons.Left)) { // Delete if (new Rectangle(448, 344, 76, 32).Contains(Mouse.Location)) { Heroes[HeroID] = null; CurrentState = CharGenStates.SelectHero; } // Ok if (new Rectangle(528, 344, 76, 32).Contains(Mouse.Location)) { CurrentState = CharGenStates.SelectHero; } } } break; #endregion } // Update anim if (Anims != null) Anims.Update(time); // If the team is ready, let's go ! if (PlayButton.Rectangle.Contains(Mouse.Location) && Mouse.IsNewButtonDown(MouseButtons.Left))// && IsTeamReadyToPlay) { PrepareTeam(); PlayButton.OnSelectEntry(); } }
/// <summary> /// Removes a hero from the team /// </summary> /// <param name="position">Hero's position</param> public void DropHero(Hero hero) { if (hero == null) return; for (int i = 0; i < Heroes.Count; i++) { if (Heroes[i] == hero) { Heroes[i] = null; ReorderHeroes(); return; } } }
/// <summary> /// Adds a hero to the team /// </summary> /// <param name="hero"></param> /// <param name="position"></param> public void AddHero(Hero hero, HeroPosition position) { Heroes[(int)position] = hero; }
/// <summary> /// Returns the ground position of a hero /// </summary> /// <param name="Hero">Hero handle</param> /// <returns>Ground position of the hero</returns> public SquarePosition GetHeroGroundPosition(Hero Hero) { SquarePosition groundpos = SquarePosition.Center; // Get the hero position in the team HeroPosition pos = GetHeroPosition(Hero); switch (Location.Direction) { case CardinalPoint.North: { if (pos == HeroPosition.FrontLeft) groundpos = SquarePosition.NorthWest; else if (pos == HeroPosition.FrontRight) groundpos = SquarePosition.NorthEast; else if (pos == HeroPosition.MiddleLeft || pos == HeroPosition.RearLeft) groundpos = SquarePosition.SouthWest; else groundpos = SquarePosition.SouthEast; } break; case CardinalPoint.East: { if (pos == HeroPosition.FrontLeft) groundpos = SquarePosition.NorthEast; else if (pos == HeroPosition.FrontRight) groundpos = SquarePosition.SouthEast; else if (pos == HeroPosition.MiddleLeft || pos == HeroPosition.RearLeft) groundpos = SquarePosition.NorthWest; else groundpos = SquarePosition.SouthWest; } break; case CardinalPoint.South: { if (pos == HeroPosition.FrontLeft) groundpos = SquarePosition.SouthEast; else if (pos == HeroPosition.FrontRight) groundpos = SquarePosition.SouthWest; else if (pos == HeroPosition.MiddleLeft || pos == HeroPosition.RearLeft) groundpos = SquarePosition.NorthEast; else groundpos = SquarePosition.NorthWest; } break; case CardinalPoint.West: { if (pos == HeroPosition.FrontLeft) groundpos = SquarePosition.SouthWest; else if (pos == HeroPosition.FrontRight) groundpos = SquarePosition.NorthWest; else if (pos == HeroPosition.MiddleLeft || pos == HeroPosition.RearLeft) groundpos = SquarePosition.SouthEast; else groundpos = SquarePosition.NorthEast; } break; } return groundpos; }
/// <summary> /// Gets if the hero is in front row /// </summary> /// <param name="hero">Hero handle</param> /// <returns>True if in front line</returns> public bool IsHeroInFront(Hero hero) { return GetHeroFromPosition(HeroPosition.FrontLeft) == hero || GetHeroFromPosition(HeroPosition.FrontRight) == hero; }
/// <summary> /// Returns the position of a hero in the team /// </summary> /// <param name="hero">Hero handle</param> /// <returns>Position of the hero in the team</returns> public HeroPosition GetHeroPosition(Hero hero) { int pos = -1; for (int id = 0; id < Heroes.Count; id++) { if (Heroes[id] == hero) { pos = id; break; } } if (pos == -1) throw new ArgumentOutOfRangeException("hero"); return (HeroPosition)pos; }
///// <summary> ///// Loads a team party ///// </summary> ///// <param name="filename">File name to load</param> ///// <returns>True if loaded</returns> //public bool LoadParty() //{ // return true; //} /// <summary> /// Loads a party /// </summary> /// <param name="filename">Xml data</param> /// <returns>True if team successfuly loaded, otherwise false</returns> public bool Load(XmlNode xml) { if (xml == null || xml.Name.ToLower() != "team") return false; // Clear the team for (int i = 0; i < Heroes.Count; i++) Heroes[i] = null; foreach (XmlNode node in xml) { if (node.NodeType == XmlNodeType.Comment) continue; switch (node.Name.ToLower()) { //case "dungeon": //{ // Dungeon = ResourceManager.CreateAsset<Dungeon>(node.Attributes["name"].Value); // //Dungeon.Team = this; //} //break; case "location": { Location = new DungeonLocation(node); } break; case "position": { HeroPosition position = (HeroPosition)Enum.Parse(typeof(HeroPosition), node.Attributes["slot"].Value, true); Hero hero = new Hero(); hero.Load(node.FirstChild); AddHero(hero, position); } break; case "message": { GameMessage.AddMessage(node.Attributes["text"].Value, Color.FromArgb(int.Parse(node.Attributes["A"].Value), int.Parse(node.Attributes["R"].Value), int.Parse(node.Attributes["G"].Value), int.Parse(node.Attributes["B"].Value))); } break; } } SelectedHero = Heroes[0]; return true; }
/// <summary> /// Heal a hero /// </summary> /// <param name="hero">Hero to heal</param> public void Heal(Hero hero) { if (!CanHeal() || hero == null) return; //Spell spell = Hero.PopSpell(Class, SpellLevel, i + 1); //if (spell != null && spell.Script.Instance != null) // spell.Script.Instance.OnCast(spell, Hero); List<Spell> spells = null; #region Level 1 - Cure Light Wounds spells = GetSpells(HeroClass.Cleric, 1); foreach (Spell spell in spells) { if (spell.Name == "Cure Light Wounds") { spell.Script.Instance.OnCast(spell, hero); return; } } #endregion #region Level 4 - Cure Serious Wounds spells = GetSpells(HeroClass.Cleric, 4); foreach (Spell spell in spells) if (spell.Name == "Cure Serious Wounds") { } #endregion #region Level 5 - Cure Critical Wounds spells = GetSpells(HeroClass.Cleric, 5); foreach (Spell spell in spells) if (spell.Name == "Cure Critical Wounds") { } #endregion #region Level 6 - Heal spells = GetSpells(HeroClass.Cleric, 6); foreach (Spell spell in spells) if (spell.Name == "Heal") { } #endregion }