#region File Description //----------------------------------------------------------------------------- // Party.cs // // Microsoft XNA Community Game Platform // Copyright (C) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- #endregion #region Using Statements using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.IO; using Microsoft.Xna.Framework.Content; using RolePlayingGameData; #endregion namespace RolePlaying { /// /// The group of players, under control of the user. /// public class Party { #region Party Members /// /// The ordered list of players in the party. /// /// The first entry is the leader. private List players = new List(); /// /// The ordered list of players in the party. /// /// The first entry is the leader. [ContentSerializerIgnore] public List Players { get { return players; } set { players = value; } } /// /// Add a new player to the party. /// /// The new player. /// Instead of using the lists directly, this fixes all data. public void JoinParty(Player player) { // check the parameter if (player == null) { throw new ArgumentNullException("player"); } if (players.Contains(player)) { throw new ArgumentException("The player was already in the party."); } // add the new player to the list players.Add(player); // add the initial gold partyGold += player.Gold; // only as NPCs are players allowed to have their own gold player.Gold = 0; // add the player's inventory items foreach (ContentEntry contentEntry in player.Inventory) { AddToInventory(contentEntry.Content, contentEntry.Count); } // only as NPCs are players allowed to have their own non-equipped gear player.Inventory.Clear(); } /// /// Gives the experience amount specified to all party members. /// public void GiveExperience(int experience) { // check the parameters if (experience < 0) { throw new ArgumentOutOfRangeException("experience"); } else if (experience == 0) { return; } List leveledUpPlayers = null; foreach (Player player in players) { int oldLevel = player.CharacterLevel; player.Experience += experience; if (player.CharacterLevel > oldLevel) { if (leveledUpPlayers == null) { leveledUpPlayers = new List(); } leveledUpPlayers.Add(player); } } if ((leveledUpPlayers != null) && (leveledUpPlayers.Count > 0)) { Session.ScreenManager.AddScreen(new LevelUpScreen(leveledUpPlayers)); } } #endregion #region Inventory /// /// The items held by the party. /// private List> inventory = new List>(); /// /// The items held by the party. /// [ContentSerializerIgnore] public ReadOnlyCollection> Inventory { get { return inventory.AsReadOnly(); } } /// /// Add the given gear, in the given quantity, to the party's inventory. /// public void AddToInventory(Gear gear, int count) { // check the parameters if ((gear == null) || (count <= 0)) { return; } // search for an existing entry ContentEntry existingEntry = inventory.Find( delegate(ContentEntry entry) { return (entry.Content == gear); }); // increment the existing entry, if any if (existingEntry != null) { existingEntry.Count += count; return; } // no existing entry - create a new entry ContentEntry newEntry = new ContentEntry(); newEntry.Content = gear; newEntry.Count = count; newEntry.ContentName = gear.AssetName; if (newEntry.ContentName.StartsWith(@"Gear\")) { newEntry.ContentName = newEntry.ContentName.Substring(5); } inventory.Add(newEntry); } /// /// Remove the given quantity of the given gear from the party's inventory. /// /// True if the quantity specified could be removed. public bool RemoveFromInventory(Gear gear, int count) { // check the parameters if (gear == null) { throw new ArgumentNullException("gear"); } if (count <= 0) { throw new ArgumentOutOfRangeException("count"); } // search for an existing entry ContentEntry existingEntry = inventory.Find( delegate(ContentEntry entry) { return (entry.Content == gear); }); // no existing entry, so this is moot if (existingEntry == null) { return false; } // decrement the existing entry existingEntry.Count -= count; bool fullRemoval = (existingEntry.Count >= 0); // if the entry is empty, then remove it if (existingEntry.Count <= 0) { inventory.Remove(existingEntry); } return fullRemoval; } /// /// The gold held by the party. /// private int partyGold; /// /// The gold held by the party. /// [ContentSerializer(Optional = true)] public int PartyGold { get { return partyGold; } set { partyGold = value; } } #endregion #region Quest Data /// /// The name and kill-count of monsters killed in the active quest. /// /// /// Used to determine if the requirements for the active quest have been met. /// private Dictionary monsterKills = new Dictionary(); /// /// The name and kill-count of monsters killed in the active quest. /// /// /// Used to determine if the requirements for the active quest have been met. /// public Dictionary MonsterKills { get { return monsterKills; } } /// /// Add a new monster-kill to the party's records. /// public void AddMonsterKill(Monster monster) { if (monsterKills.ContainsKey(monster.AssetName)) { monsterKills[monster.AssetName]++; } else { monsterKills.Add(monster.AssetName, 1); } } #endregion #region Initialization /// /// Creates a new Party object from the game-start description. /// public Party(GameStartDescription gameStartDescription, ContentManager contentManager) { // check the parameters if (gameStartDescription == null) { throw new ArgumentNullException("gameStartDescription"); } if (contentManager == null) { throw new ArgumentNullException("contentManager"); } // load the players foreach (string contentName in gameStartDescription.PlayerContentNames) { JoinParty(contentManager.Load( Path.Combine(@"Characters\Players", contentName)).Clone() as Player); } } /// /// Create a new Party object from serialized party data. /// public Party(PartySaveData partyData, ContentManager contentManager) { // check the parameters if (partyData == null) { throw new ArgumentNullException("partyData"); } if (contentManager == null) { throw new ArgumentNullException("contentManager"); } // load the players foreach (PlayerSaveData playerData in partyData.players) { Player player = contentManager.Load(playerData.assetName).Clone() as Player; player.CharacterLevel = playerData.characterLevel; player.Experience = playerData.experience; player.EquippedEquipment.Clear(); foreach (string equipmentAssetName in playerData.equipmentAssetNames) { player.Equip(contentManager.Load(equipmentAssetName)); } player.StatisticsModifiers = playerData.statisticsModifiers; JoinParty(player); } // load the party inventory inventory.Clear(); inventory.AddRange(partyData.inventory); foreach (ContentEntry entry in inventory) { entry.Content = contentManager.Load( Path.Combine(@"Gear", entry.ContentName)); } // set the party gold partyGold = partyData.partyGold; // load the monster kills for (int i = 0; i < partyData.monsterKillNames.Count; i++) { monsterKills.Add(partyData.monsterKillNames[i], partyData.monsterKillCounts[i]); } } #endregion } }