Skip to content

Instantly share code, notes, and snippets.

@ScottLilly ScottLilly/Player.cs Secret
Created Aug 18, 2017

Embed
What would you like to do?
Lesson 26.2 - Hiding Unvisited Locations on the World Map
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Xml;
namespace Engine
{
public class Player : LivingCreature
{
private int _gold;
private int _experiencePoints;
private Location _currentLocation;
public event EventHandler<MessageEventArgs> OnMessage;
public int Gold
{
get { return _gold; }
set
{
_gold = value;
OnPropertyChanged("Gold");
}
}
public int ExperiencePoints
{
get { return _experiencePoints; }
private set
{
_experiencePoints = value;
OnPropertyChanged("ExperiencePoints");
OnPropertyChanged("Level");
}
}
public int Level
{
get { return ((ExperiencePoints / 100) + 1); }
}
public Location CurrentLocation
{
get { return _currentLocation; }
set
{
_currentLocation = value;
OnPropertyChanged("CurrentLocation");
}
}
public Weapon CurrentWeapon { get; set; }
public BindingList<InventoryItem> Inventory { get; set; }
public List<Weapon> Weapons
{
get { return Inventory.Where(x => x.Details is Weapon).Select(x => x.Details as Weapon).ToList(); }
}
public List<HealingPotion> Potions
{
get { return Inventory.Where(x => x.Details is HealingPotion).Select(x => x.Details as HealingPotion).ToList(); }
}
public BindingList<PlayerQuest> Quests { get; set; }
public List<int> LocationsVisited { get; set; }
private Monster CurrentMonster { get; set; }
private Player(int currentHitPoints, int maximumHitPoints, int gold, int experiencePoints) : base(currentHitPoints, maximumHitPoints)
{
Gold = gold;
ExperiencePoints = experiencePoints;
Inventory = new BindingList<InventoryItem>();
Quests = new BindingList<PlayerQuest>();
LocationsVisited = new List<int>();
}
public static Player CreateDefaultPlayer()
{
Player player = new Player(10, 10, 20, 0);
player.Inventory.Add(new InventoryItem(World.ItemByID(World.ITEM_ID_RUSTY_SWORD), 1));
player.CurrentLocation = World.LocationByID(World.LOCATION_ID_HOME);
return player;
}
public static Player CreatePlayerFromXmlString(string xmlPlayerData)
{
try
{
XmlDocument playerData = new XmlDocument();
playerData.LoadXml(xmlPlayerData);
int currentHitPoints = Convert.ToInt32(playerData.SelectSingleNode("/Player/Stats/CurrentHitPoints").InnerText);
int maximumHitPoints = Convert.ToInt32(playerData.SelectSingleNode("/Player/Stats/MaximumHitPoints").InnerText);
int gold = Convert.ToInt32(playerData.SelectSingleNode("/Player/Stats/Gold").InnerText);
int experiencePoints = Convert.ToInt32(playerData.SelectSingleNode("/Player/Stats/ExperiencePoints").InnerText);
Player player = new Player(currentHitPoints, maximumHitPoints, gold, experiencePoints);
int currentLocationID = Convert.ToInt32(playerData.SelectSingleNode("/Player/Stats/CurrentLocation").InnerText);
player.CurrentLocation = World.LocationByID(currentLocationID);
if (playerData.SelectSingleNode("/Player/Stats/CurrentWeapon") != null)
{
int currentWeaponID = Convert.ToInt32(playerData.SelectSingleNode("/Player/Stats/CurrentWeapon").InnerText);
player.CurrentWeapon = (Weapon)World.ItemByID(currentWeaponID);
}
foreach (XmlNode node in playerData.SelectNodes("/Player/LocationsVisited/LocationVisited"))
{
int id = Convert.ToInt32(node.Attributes["ID"].Value);
player.LocationsVisited.Add(id);
}
foreach (XmlNode node in playerData.SelectNodes("/Player/InventoryItems/InventoryItem"))
{
int id = Convert.ToInt32(node.Attributes["ID"].Value);
int quantity = Convert.ToInt32(node.Attributes["Quantity"].Value);
for (int i = 0; i < quantity; i++)
{
player.AddItemToInventory(World.ItemByID(id));
}
}
foreach (XmlNode node in playerData.SelectNodes("/Player/PlayerQuests/PlayerQuest"))
{
int id = Convert.ToInt32(node.Attributes["ID"].Value);
bool isCompleted = Convert.ToBoolean(node.Attributes["IsCompleted"].Value);
PlayerQuest playerQuest = new PlayerQuest(World.QuestByID(id));
playerQuest.IsCompleted = isCompleted;
player.Quests.Add(playerQuest);
}
return player;
}
catch
{
// If there was an error with the XML data, return a default player object
return CreateDefaultPlayer();
}
}
public static Player CreatePlayerFromDatabase(int currentHitPoints, int maximumHitPoints, int gold, int experiencePoints, int currentLocationID)
{
Player player = new Player(currentHitPoints, maximumHitPoints, gold, experiencePoints);
player.MoveTo(World.LocationByID(currentLocationID));
return player;
}
public void MoveTo(Location location)
{
if (PlayerDoesNotHaveTheRequiredItemToEnter(location))
{
RaiseMessage("You must have a " + location.ItemRequiredToEnter.Name + " to enter this location.");
return;
}
// The player can enter this location
CurrentLocation = location;
if (!LocationsVisited.Contains(CurrentLocation.ID))
{
LocationsVisited.Add(CurrentLocation.ID);
}
CompletelyHeal();
if (location.HasAQuest)
{
if (PlayerDoesNotHaveThisQuest(location.QuestAvailableHere))
{
GiveQuestToPlayer(location.QuestAvailableHere);
}
else
{
if (PlayerHasNotCompleted(location.QuestAvailableHere) &&
PlayerHasAllQuestCompletionItemsFor(location.QuestAvailableHere))
{
GivePlayerQuestRewards(location.QuestAvailableHere);
}
}
}
SetTheCurrentMonsterForTheCurrentLocation(location);
}
public void MoveNorth()
{
if (CurrentLocation.LocationToNorth != null)
{
MoveTo(CurrentLocation.LocationToNorth);
}
}
public void MoveEast()
{
if (CurrentLocation.LocationToEast != null)
{
MoveTo(CurrentLocation.LocationToEast);
}
}
public void MoveSouth()
{
if (CurrentLocation.LocationToSouth != null)
{
MoveTo(CurrentLocation.LocationToSouth);
}
}
public void MoveWest()
{
if (CurrentLocation.LocationToWest != null)
{
MoveTo(CurrentLocation.LocationToWest);
}
}
public void UseWeapon(Weapon weapon)
{
int damage = RandomNumberGenerator.NumberBetween(weapon.MinimumDamage, weapon.MaximumDamage);
if (damage == 0)
{
RaiseMessage("You missed the " + CurrentMonster.Name);
}
else
{
CurrentMonster.CurrentHitPoints -= damage;
RaiseMessage("You hit the " + CurrentMonster.Name + " for " + damage + " points.");
}
if (CurrentMonster.IsDead)
{
LootTheCurrentMonster();
// "Move" to the current location, to refresh the current monster
MoveTo(CurrentLocation);
}
else
{
LetTheMonsterAttack();
}
}
private void LootTheCurrentMonster()
{
RaiseMessage("");
RaiseMessage("You defeated the " + CurrentMonster.Name);
RaiseMessage("You receive " + CurrentMonster.RewardExperiencePoints + " experience points");
RaiseMessage("You receive " + CurrentMonster.RewardGold + " gold");
AddExperiencePoints(CurrentMonster.RewardExperiencePoints);
Gold += CurrentMonster.RewardGold;
// Give monster's loot items to the player
foreach (InventoryItem inventoryItem in CurrentMonster.LootItems)
{
AddItemToInventory(inventoryItem.Details);
RaiseMessage(string.Format("You loot {0} {1}", inventoryItem.Quantity, inventoryItem.Description));
}
RaiseMessage("");
}
public void UsePotion(HealingPotion potion)
{
RaiseMessage("You drink a " + potion.Name);
HealPlayer(potion.AmountToHeal);
RemoveItemFromInventory(potion);
// The player used their turn to drink the potion, so let the monster attack now
LetTheMonsterAttack();
}
public void AddItemToInventory(Item itemToAdd, int quantity = 1)
{
InventoryItem existingItemInInventory = Inventory.SingleOrDefault(ii => ii.Details.ID == itemToAdd.ID);
if (existingItemInInventory == null)
{
Inventory.Add(new InventoryItem(itemToAdd, quantity));
}
else
{
existingItemInInventory.Quantity += quantity;
}
RaiseInventoryChangedEvent(itemToAdd);
}
public void RemoveItemFromInventory(Item itemToRemove, int quantity = 1)
{
InventoryItem item = Inventory.SingleOrDefault(ii => ii.Details.ID == itemToRemove.ID && ii.Quantity >= quantity);
if (item != null)
{
item.Quantity -= quantity;
if (item.Quantity == 0)
{
Inventory.Remove(item);
}
RaiseInventoryChangedEvent(itemToRemove);
}
}
public string ToXmlString()
{
XmlDocument playerData = new XmlDocument();
// Create the top-level XML node
XmlNode player = playerData.CreateElement("Player");
playerData.AppendChild(player);
// Create the "Stats" child node to hold the other player statistics nodes
XmlNode stats = playerData.CreateElement("Stats");
player.AppendChild(stats);
// Create the child nodes for the "Stats" node
CreateNewChildXmlNode(playerData, stats, "CurrentHitPoints", CurrentHitPoints);
CreateNewChildXmlNode(playerData, stats, "MaximumHitPoints", MaximumHitPoints);
CreateNewChildXmlNode(playerData, stats, "Gold", Gold);
CreateNewChildXmlNode(playerData, stats, "ExperiencePoints", ExperiencePoints);
CreateNewChildXmlNode(playerData, stats, "CurrentLocation", CurrentLocation.ID);
if (CurrentWeapon != null)
{
CreateNewChildXmlNode(playerData, stats, "CurrentWeapon", CurrentWeapon.ID);
}
// Create the "LocationsVisited" child node to hold each LocationVisited node
XmlNode locationsVisited = playerData.CreateElement("LocationsVisited");
player.AppendChild(locationsVisited);
// Create an "LocationVisited" node for each item in the player's inventory
foreach (int locationID in LocationsVisited)
{
XmlNode locationVisited = playerData.CreateElement("LocationVisited");
AddXmlAttributeToNode(playerData, locationVisited, "ID", locationID);
locationsVisited.AppendChild(locationVisited);
}
// Create the "InventoryItems" child node to hold each InventoryItem node
XmlNode inventoryItems = playerData.CreateElement("InventoryItems");
player.AppendChild(inventoryItems);
// Create an "InventoryItem" node for each item in the player's inventory
foreach (InventoryItem item in Inventory)
{
XmlNode inventoryItem = playerData.CreateElement("InventoryItem");
AddXmlAttributeToNode(playerData, inventoryItem, "ID", item.Details.ID);
AddXmlAttributeToNode(playerData, inventoryItem, "Quantity", item.Quantity);
inventoryItems.AppendChild(inventoryItem);
}
// Create the "PlayerQuests" child node to hold each PlayerQuest node
XmlNode playerQuests = playerData.CreateElement("PlayerQuests");
player.AppendChild(playerQuests);
// Create a "PlayerQuest" node for each quest the player has acquired
foreach (PlayerQuest quest in Quests)
{
XmlNode playerQuest = playerData.CreateElement("PlayerQuest");
AddXmlAttributeToNode(playerData, playerQuest, "ID", quest.Details.ID);
AddXmlAttributeToNode(playerData, playerQuest, "IsCompleted", quest.IsCompleted);
playerQuests.AppendChild(playerQuest);
}
return playerData.InnerXml; // The XML document, as a string, so we can save the data to disk
}
private bool HasRequiredItemToEnterThisLocation(Location location)
{
if (location.DoesNotHaveAnItemRequiredToEnter)
{
return true;
}
// See if the player has the required item in their inventory
return Inventory.Any(ii => ii.Details.ID == location.ItemRequiredToEnter.ID);
}
private void SetTheCurrentMonsterForTheCurrentLocation(Location location)
{
// Populate the current monster with this location's monster (or null, if there is no monster here)
CurrentMonster = location.NewInstanceOfMonsterLivingHere();
if (CurrentMonster != null)
{
RaiseMessage("You see a " + CurrentMonster.Name);
}
}
private bool PlayerDoesNotHaveTheRequiredItemToEnter(Location location)
{
return !HasRequiredItemToEnterThisLocation(location);
}
private bool PlayerDoesNotHaveThisQuest(Quest quest)
{
return Quests.All(pq => pq.Details.ID != quest.ID);
}
private bool PlayerHasNotCompleted(Quest quest)
{
return Quests.Any(pq => pq.Details.ID == quest.ID && !pq.IsCompleted);
}
private void GiveQuestToPlayer(Quest quest)
{
RaiseMessage("You receive the " + quest.Name + " quest.");
RaiseMessage(quest.Description);
RaiseMessage("To complete it, return with:");
foreach (QuestCompletionItem qci in quest.QuestCompletionItems)
{
RaiseMessage(string.Format("{0} {1}", qci.Quantity,
qci.Quantity == 1 ? qci.Details.Name : qci.Details.NamePlural));
}
RaiseMessage("");
Quests.Add(new PlayerQuest(quest));
}
private bool PlayerHasAllQuestCompletionItemsFor(Quest quest)
{
// See if the player has all the items needed to complete the quest here
foreach (QuestCompletionItem qci in quest.QuestCompletionItems)
{
// Check each item in the player's inventory, to see if they have it, and enough of it
if (!Inventory.Any(ii => ii.Details.ID == qci.Details.ID && ii.Quantity >= qci.Quantity))
{
return false;
}
}
// If we got here, then the player must have all the required items, and enough of them, to complete the quest.
return true;
}
private void RemoveQuestCompletionItems(Quest quest)
{
foreach (QuestCompletionItem qci in quest.QuestCompletionItems)
{
InventoryItem item = Inventory.SingleOrDefault(ii => ii.Details.ID == qci.Details.ID);
if (item != null)
{
RemoveItemFromInventory(item.Details, qci.Quantity);
}
}
}
private void AddExperiencePoints(int experiencePointsToAdd)
{
ExperiencePoints += experiencePointsToAdd;
MaximumHitPoints = (Level * 10);
}
private void GivePlayerQuestRewards(Quest quest)
{
RaiseMessage("");
RaiseMessage("You complete the '" + quest.Name + "' quest.");
RaiseMessage("You receive: ");
RaiseMessage(quest.RewardExperiencePoints + " experience points");
RaiseMessage(quest.RewardGold + " gold");
RaiseMessage(quest.RewardItem.Name, true);
AddExperiencePoints(quest.RewardExperiencePoints);
Gold += quest.RewardGold;
RemoveQuestCompletionItems(quest);
AddItemToInventory(quest.RewardItem);
MarkPlayerQuestCompleted(quest);
}
private void MarkPlayerQuestCompleted(Quest quest)
{
PlayerQuest playerQuest = Quests.SingleOrDefault(pq => pq.Details.ID == quest.ID);
if (playerQuest != null)
{
playerQuest.IsCompleted = true;
}
}
private void LetTheMonsterAttack()
{
int damageToPlayer = RandomNumberGenerator.NumberBetween(0, CurrentMonster.MaximumDamage);
RaiseMessage("The " + CurrentMonster.Name + " did " + damageToPlayer + " points of damage.");
CurrentHitPoints -= damageToPlayer;
if (IsDead)
{
RaiseMessage("The " + CurrentMonster.Name + " killed you.");
MoveHome();
}
}
private void HealPlayer(int hitPointsToHeal)
{
CurrentHitPoints = Math.Min(CurrentHitPoints + hitPointsToHeal, MaximumHitPoints);
}
private void CompletelyHeal()
{
CurrentHitPoints = MaximumHitPoints;
}
private void MoveHome()
{
MoveTo(World.LocationByID(World.LOCATION_ID_HOME));
}
private void CreateNewChildXmlNode(XmlDocument document, XmlNode parentNode, string elementName, object value)
{
XmlNode node = document.CreateElement(elementName);
node.AppendChild(document.CreateTextNode(value.ToString()));
parentNode.AppendChild(node);
}
private void AddXmlAttributeToNode(XmlDocument document, XmlNode node, string attributeName, object value)
{
XmlAttribute attribute = document.CreateAttribute(attributeName);
attribute.Value = value.ToString();
node.Attributes.Append(attribute);
}
private void RaiseInventoryChangedEvent(Item item)
{
if (item is Weapon)
{
OnPropertyChanged("Weapons");
}
if (item is HealingPotion)
{
OnPropertyChanged("Potions");
}
}
private void RaiseMessage(string message, bool addExtraNewLine = false)
{
if (OnMessage != null)
{
OnMessage(this, new MessageEventArgs(message, addExtraNewLine));
}
}
}
}
using System;
using System.Data;
using System.Data.SqlClient;
namespace Engine
{
public static class PlayerDataMapper
{
private static readonly string _connectionString = "Data Source=(local);Initial Catalog=SuperAdventure;Integrated Security=True";
public static Player CreateFromDatabase()
{
try
{
// This is our connection to the database
using(SqlConnection connection = new SqlConnection(_connectionString))
{
// Open the connection, so we can perform SQL commands
connection.Open();
Player player;
// Create a SQL command object, that uses the connection to our database
// The SqlCommand object is where we create our SQL statement
using(SqlCommand savedGameCommand = connection.CreateCommand())
{
savedGameCommand.CommandType = CommandType.Text;
// This SQL statement reads the first rows in teh SavedGame table.
// For this program, we should only ever have one row,
// but this will ensure we only get one record in our SQL query results.
savedGameCommand.CommandText = "SELECT TOP 1 * FROM SavedGame";
// Use ExecuteReader when you expect the query to return a row, or rows
SqlDataReader reader = savedGameCommand.ExecuteReader();
// Check if the query did not return a row/record of data
if(!reader.HasRows)
{
// There is no data in the SavedGame table,
// so return null (no saved player data)
return null;
}
// Get the row/record from the data reader
reader.Read();
// Get the column values for the row/record
int currentHitPoints = (int)reader["CurrentHitPoints"];
int maximumHitPoints = (int)reader["MaximumHitPoints"];
int gold = (int)reader["Gold"];
int experiencePoints = (int)reader["ExperiencePoints"];
int currentLocationID = (int)reader["CurrentLocationID"];
// Create the Player object, with the saved game values
player = Player.CreatePlayerFromDatabase(currentHitPoints, maximumHitPoints, gold,
experiencePoints, currentLocationID);
reader.Close();
}
// Read the rows/records from the Quest table, and add them to the player
using(SqlCommand questCommand = connection.CreateCommand())
{
questCommand.CommandType = CommandType.Text;
questCommand.CommandText = "SELECT * FROM Quest";
SqlDataReader reader = questCommand.ExecuteReader();
if(reader.HasRows)
{
while(reader.Read())
{
int questID = (int)reader["QuestID"];
bool isCompleted = (bool)reader["IsCompleted"];
// Build the PlayerQuest item, for this row
PlayerQuest playerQuest = new PlayerQuest(World.QuestByID(questID));
playerQuest.IsCompleted = isCompleted;
// Add the PlayerQuest to the player's property
player.Quests.Add(playerQuest);
}
}
reader.Close();
}
// Read the rows/records from the Inventory table, and add them to the player
using (SqlCommand inventoryCommand = connection.CreateCommand())
{
inventoryCommand.CommandType = CommandType.Text;
inventoryCommand.CommandText = "SELECT * FROM Inventory";
SqlDataReader reader = inventoryCommand.ExecuteReader();
if(reader.HasRows)
{
while(reader.Read())
{
int inventoryItemID = (int)reader["InventoryItemID"];
int quantity = (int)reader["Quantity"];
// Add the item to the player's inventory
player.AddItemToInventory(World.ItemByID(inventoryItemID), quantity);
}
}
reader.Close();
}
// Read the rows/records from the LocationVisited table, and add them to the player
using (SqlCommand locationVisitedCommand = connection.CreateCommand())
{
locationVisitedCommand.CommandType = CommandType.Text;
locationVisitedCommand.CommandText = "SELECT * FROM LocationVisited";
SqlDataReader reader = locationVisitedCommand.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
int id = (int)reader["ID"];
// Add the item to the player's LocationsVisited property
player.LocationsVisited.Add(id);
}
}
reader.Close();
}
// Now that the player has been built from the database, return it.
return player;
}
}
catch(Exception ex)
{
// Ignore errors. If there is an error, this function will return a "null" player.
}
return null;
}
public static void SaveToDatabase(Player player)
{
try
{
using(SqlConnection connection = new SqlConnection(_connectionString))
{
// Open the connection, so we can perform SQL commands
connection.Open();
// Insert/Update data in SavedGame table
using(SqlCommand existingRowCountCommand = connection.CreateCommand())
{
existingRowCountCommand.CommandType = CommandType.Text;
existingRowCountCommand.CommandText = "SELECT count(*) FROM SavedGame";
// Use ExecuteScalar when your query will return one value
int existingRowCount = (int)existingRowCountCommand.ExecuteScalar();
if(existingRowCount == 0)
{
// There is no existing row, so do an INSERT
using(SqlCommand insertSavedGame = connection.CreateCommand())
{
insertSavedGame.CommandType = CommandType.Text;
insertSavedGame.CommandText =
"INSERT INTO SavedGame " +
"(CurrentHitPoints, MaximumHitPoints, Gold, ExperiencePoints, CurrentLocationID) " +
"VALUES " +
"(@CurrentHitPoints, @MaximumHitPoints, @Gold, @ExperiencePoints, @CurrentLocationID)";
// Pass the values from the player object, to the SQL query, using parameters
insertSavedGame.Parameters.Add("@CurrentHitPoints", SqlDbType.Int);
insertSavedGame.Parameters["@CurrentHitPoints"].Value = player.CurrentHitPoints;
insertSavedGame.Parameters.Add("@MaximumHitPoints", SqlDbType.Int);
insertSavedGame.Parameters["@MaximumHitPoints"].Value = player.MaximumHitPoints;
insertSavedGame.Parameters.Add("@Gold", SqlDbType.Int);
insertSavedGame.Parameters["@Gold"].Value = player.Gold;
insertSavedGame.Parameters.Add("@ExperiencePoints", SqlDbType.Int);
insertSavedGame.Parameters["@ExperiencePoints"].Value = player.ExperiencePoints;
insertSavedGame.Parameters.Add("@CurrentLocationID", SqlDbType.Int);
insertSavedGame.Parameters["@CurrentLocationID"].Value = player.CurrentLocation.ID;
// Perform the SQL command.
// Use ExecuteNonQuery, because this query does not return any results.
insertSavedGame.ExecuteNonQuery();
}
}
else
{
// There is an existing row, so do an UPDATE
using(SqlCommand updateSavedGame = connection.CreateCommand())
{
updateSavedGame.CommandType = CommandType.Text;
updateSavedGame.CommandText =
"UPDATE SavedGame " +
"SET CurrentHitPoints = @CurrentHitPoints, " +
"MaximumHitPoints = @MaximumHitPoints, " +
"Gold = @Gold, " +
"ExperiencePoints = @ExperiencePoints, "+
"CurrentLocationID = @CurrentLocationID";
// Pass the values from the player object, to the SQL query, using parameters
// Using parameters helps make your program more secure.
// It will prevent SQL injection attacks.
updateSavedGame.Parameters.Add("@CurrentHitPoints", SqlDbType.Int);
updateSavedGame.Parameters["@CurrentHitPoints"].Value = player.CurrentHitPoints;
updateSavedGame.Parameters.Add("@MaximumHitPoints", SqlDbType.Int);
updateSavedGame.Parameters["@MaximumHitPoints"].Value = player.MaximumHitPoints;
updateSavedGame.Parameters.Add("@Gold", SqlDbType.Int);
updateSavedGame.Parameters["@Gold"].Value = player.Gold;
updateSavedGame.Parameters.Add("@ExperiencePoints", SqlDbType.Int);
updateSavedGame.Parameters["@ExperiencePoints"].Value = player.ExperiencePoints;
updateSavedGame.Parameters.Add("@CurrentLocationID", SqlDbType.Int);
updateSavedGame.Parameters["@CurrentLocationID"].Value = player.CurrentLocation.ID;
// Perform the SQL command.
// Use ExecuteNonQuery, because this query does not return any results.
updateSavedGame.ExecuteNonQuery();
}
}
}
// The Quest and Inventory tables might have more, or less, rows in the database
// than what the player has in their properties.
// So, when we save the player's game, we will delete all the old rows
// and add in all new rows.
// This is easier than trying to add/delete/update each individual rows
// Delete existing Quest rows
using(SqlCommand deleteQuestsCommand = connection.CreateCommand())
{
deleteQuestsCommand.CommandType = CommandType.Text;
deleteQuestsCommand.CommandText = "DELETE FROM Quest";
deleteQuestsCommand.ExecuteNonQuery();
}
// Insert Quest rows, from the player object
foreach(PlayerQuest playerQuest in player.Quests)
{
using(SqlCommand insertQuestCommand = connection.CreateCommand())
{
insertQuestCommand.CommandType = CommandType.Text;
insertQuestCommand.CommandText = "INSERT INTO Quest (QuestID, IsCompleted) VALUES (@QuestID, @IsCompleted)";
insertQuestCommand.Parameters.Add("@QuestID", SqlDbType.Int);
insertQuestCommand.Parameters["@QuestID"].Value = playerQuest.Details.ID;
insertQuestCommand.Parameters.Add("@IsCompleted", SqlDbType.Bit);
insertQuestCommand.Parameters["@IsCompleted"].Value = playerQuest.IsCompleted;
insertQuestCommand.ExecuteNonQuery();
}
}
// Delete existing Inventory rows
using(SqlCommand deleteInventoryCommand = connection.CreateCommand())
{
deleteInventoryCommand.CommandType = CommandType.Text;
deleteInventoryCommand.CommandText = "DELETE FROM Inventory";
deleteInventoryCommand.ExecuteNonQuery();
}
// Insert Inventory rows, from the player object
foreach(InventoryItem inventoryItem in player.Inventory)
{
using(SqlCommand insertInventoryCommand = connection.CreateCommand())
{
insertInventoryCommand.CommandType = CommandType.Text;
insertInventoryCommand.CommandText = "INSERT INTO Inventory (InventoryItemID, Quantity) VALUES (@InventoryItemID, @Quantity)";
insertInventoryCommand.Parameters.Add("@InventoryItemID", SqlDbType.Int);
insertInventoryCommand.Parameters["@InventoryItemID"].Value = inventoryItem.Details.ID;
insertInventoryCommand.Parameters.Add("@Quantity", SqlDbType.Int);
insertInventoryCommand.Parameters["@Quantity"].Value = inventoryItem.Quantity;
insertInventoryCommand.ExecuteNonQuery();
}
}
// Delete existing LocationVisited rows
using (SqlCommand deleteLocationVisitedCommand = connection.CreateCommand())
{
deleteLocationVisitedCommand.CommandType = CommandType.Text;
deleteLocationVisitedCommand.CommandText = "DELETE FROM LocationVisited";
deleteLocationVisitedCommand.ExecuteNonQuery();
}
// Insert LocationVisited rows, from the player object
foreach (int locationVisitedID in player.LocationsVisited)
{
using (SqlCommand insertLocationVisitedCommand = connection.CreateCommand())
{
insertLocationVisitedCommand.CommandType = CommandType.Text;
insertLocationVisitedCommand.CommandText = "INSERT INTO LocationVisited (ID) VALUES (@ID)";
insertLocationVisitedCommand.Parameters.Add("@ID", SqlDbType.Int);
insertLocationVisitedCommand.Parameters["@ID"].Value = locationVisitedID;
insertLocationVisitedCommand.ExecuteNonQuery();
}
}
}
}
catch(Exception ex)
{
// We are going to ignore errors, for now.
}
}
}
}
using System;
using System.ComponentModel;
using System.Linq;
using System.Windows.Forms;
using System.IO;
using Engine;
namespace SuperAdventure
{
public partial class SuperAdventure : Form
{
private const string PLAYER_DATA_FILE_NAME = "PlayerData.xml";
private Player _player;
public SuperAdventure()
{
InitializeComponent();
_player = PlayerDataMapper.CreateFromDatabase();
if(_player == null)
{
if(File.Exists(PLAYER_DATA_FILE_NAME))
{
_player = Player.CreatePlayerFromXmlString(File.ReadAllText(PLAYER_DATA_FILE_NAME));
}
else
{
_player = Player.CreateDefaultPlayer();
}
}
_player.AddItemToInventory(World.ItemByID(World.ITEM_ID_CLUB));
lblHitPoints.DataBindings.Add("Text", _player, "CurrentHitPoints");
lblGold.DataBindings.Add("Text", _player, "Gold");
lblExperience.DataBindings.Add("Text", _player, "ExperiencePoints");
lblLevel.DataBindings.Add("Text", _player, "Level");
dgvInventory.RowHeadersVisible = false;
dgvInventory.AutoGenerateColumns = false;
dgvInventory.DataSource = _player.Inventory;
dgvInventory.Columns.Add(new DataGridViewTextBoxColumn
{
HeaderText = "Name",
Width = 197,
DataPropertyName = "Description"
});
dgvInventory.Columns.Add(new DataGridViewTextBoxColumn
{
HeaderText = "Quantity",
DataPropertyName = "Quantity"
});
dgvInventory.ScrollBars = ScrollBars.Vertical;
dgvQuests.RowHeadersVisible = false;
dgvQuests.AutoGenerateColumns = false;
dgvQuests.DataSource = _player.Quests;
dgvQuests.Columns.Add(new DataGridViewTextBoxColumn
{
HeaderText = "Name",
Width = 197,
DataPropertyName = "Name"
});
dgvQuests.Columns.Add(new DataGridViewTextBoxColumn
{
HeaderText = "Done?",
DataPropertyName = "IsCompleted"
});
cboWeapons.DataSource = _player.Weapons;
cboWeapons.DisplayMember = "Name";
cboWeapons.ValueMember = "Id";
if(_player.CurrentWeapon != null)
{
cboWeapons.SelectedItem = _player.CurrentWeapon;
}
cboWeapons.SelectedIndexChanged += cboWeapons_SelectedIndexChanged;
cboPotions.DataSource = _player.Potions;
cboPotions.DisplayMember = "Name";
cboPotions.ValueMember = "Id";
_player.PropertyChanged += PlayerOnPropertyChanged;
_player.OnMessage += DisplayMessage;
_player.MoveTo(_player.CurrentLocation);
}
private void DisplayMessage(object sender, MessageEventArgs messageEventArgs)
{
rtbMessages.Text += messageEventArgs.Message + Environment.NewLine;
if(messageEventArgs.AddExtraNewLine)
{
rtbMessages.Text += Environment.NewLine;
}
rtbMessages.SelectionStart = rtbMessages.Text.Length;
rtbMessages.ScrollToCaret();
}
private void PlayerOnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
{
if(propertyChangedEventArgs.PropertyName == "Weapons")
{
cboWeapons.DataSource = _player.Weapons;
if(!_player.Weapons.Any())
{
cboWeapons.Visible = false;
btnUseWeapon.Visible = false;
}
}
if(propertyChangedEventArgs.PropertyName == "Potions")
{
cboPotions.DataSource = _player.Potions;
if(!_player.Potions.Any())
{
cboPotions.Visible = false;
btnUsePotion.Visible = false;
}
}
if(propertyChangedEventArgs.PropertyName == "CurrentLocation")
{
// Show/hide available movement buttons
btnNorth.Visible = (_player.CurrentLocation.LocationToNorth != null);
btnEast.Visible = (_player.CurrentLocation.LocationToEast != null);
btnSouth.Visible = (_player.CurrentLocation.LocationToSouth != null);
btnWest.Visible = (_player.CurrentLocation.LocationToWest != null);
btnTrade.Visible = (_player.CurrentLocation.VendorWorkingHere != null);
// Display current location name and description
rtbLocation.Text = _player.CurrentLocation.Name + Environment.NewLine;
rtbLocation.Text += _player.CurrentLocation.Description + Environment.NewLine;
if(!_player.CurrentLocation.HasAMonster)
{
cboWeapons.Visible = false;
cboPotions.Visible = false;
btnUseWeapon.Visible = false;
btnUsePotion.Visible = false;
}
else
{
cboWeapons.Visible = _player.Weapons.Any();
cboPotions.Visible = _player.Potions.Any();
btnUseWeapon.Visible = _player.Weapons.Any();
btnUsePotion.Visible = _player.Potions.Any();
}
}
}
private void btnNorth_Click(object sender, EventArgs e)
{
_player.MoveNorth();
}
private void btnEast_Click(object sender, EventArgs e)
{
_player.MoveEast();
}
private void btnSouth_Click(object sender, EventArgs e)
{
_player.MoveSouth();
}
private void btnWest_Click(object sender, EventArgs e)
{
_player.MoveWest();
}
private void btnUseWeapon_Click(object sender, EventArgs e)
{
// Get the currently selected weapon from the cboWeapons ComboBox
Weapon currentWeapon = (Weapon)cboWeapons.SelectedItem;
_player.UseWeapon(currentWeapon);
}
private void btnUsePotion_Click(object sender, EventArgs e)
{
// Get the currently selected potion from the combobox
HealingPotion potion = (HealingPotion)cboPotions.SelectedItem;
_player.UsePotion(potion);
}
private void SuperAdventure_FormClosing(object sender, FormClosingEventArgs e)
{
File.WriteAllText(PLAYER_DATA_FILE_NAME, _player.ToXmlString());
PlayerDataMapper.SaveToDatabase(_player);
}
private void cboWeapons_SelectedIndexChanged(object sender, EventArgs e)
{
_player.CurrentWeapon = (Weapon)cboWeapons.SelectedItem;
}
private void btnTrade_Click(object sender, EventArgs e)
{
TradingScreen tradingScreen = new TradingScreen(_player);
tradingScreen.StartPosition = FormStartPosition.CenterParent;
tradingScreen.ShowDialog(this);
}
private void btnMap_Click(object sender, EventArgs e)
{
WorldMap mapScreen = new WorldMap(_player);
mapScreen.StartPosition = FormStartPosition.CenterParent;
mapScreen.ShowDialog(this);
}
}
}
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using Engine;
namespace SuperAdventure
{
public partial class WorldMap : Form
{
readonly Assembly _thisAssembly = Assembly.GetExecutingAssembly();
public WorldMap(Player player)
{
InitializeComponent();
SetImage(pic_0_2, player.LocationsVisited.Contains(5) ? "HerbalistsGarden" : "FogLocation");
SetImage(pic_1_2, player.LocationsVisited.Contains(4) ? "HerbalistsHut" : "FogLocation");
SetImage(pic_2_0, player.LocationsVisited.Contains(7) ? "FarmFields" : "FogLocation");
SetImage(pic_2_1, player.LocationsVisited.Contains(6) ? "Farmhouse" : "FogLocation");
SetImage(pic_2_2, player.LocationsVisited.Contains(2) ? "TownSquare" : "FogLocation");
SetImage(pic_2_3, player.LocationsVisited.Contains(3) ? "TownGate" : "FogLocation");
SetImage(pic_2_4, player.LocationsVisited.Contains(8) ? "Bridge" : "FogLocation");
SetImage(pic_2_5, player.LocationsVisited.Contains(9) ? "SpiderForest" : "FogLocation");
SetImage(pic_3_2, player.LocationsVisited.Contains(1) ? "Home" : "FogLocation");
}
private void SetImage(PictureBox pictureBox, string imageName)
{
using (Stream resourceStream =
_thisAssembly.GetManifestResourceStream(
_thisAssembly.GetName().Name + ".Images." + imageName + ".png"))
{
if (resourceStream != null)
{
pictureBox.Image = new Bitmap(resourceStream);
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.