Skip to content

Instantly share code, notes, and snippets.

@Zodiark1020
Last active August 20, 2018 10:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Zodiark1020/9e808b3f770114da4a2bbd219be13b9b to your computer and use it in GitHub Desktop.
Save Zodiark1020/9e808b3f770114da4a2bbd219be13b9b to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using Engine;
namespace SuperAdventure
{
public partial class SuperAdventure : Form
{
private Player _player;
private Monster _currentMonster;
private const string PLAYER_DATA_FILE_NAME = "PlayerData.xml";
public SuperAdventure()
{
InitializeComponent();
SetCurrentPlayer(new Player(10, 10, 20, 0));
MoveTo(World.LocationByID(World.LOCATION_ID_HOME));
}
private void SetCurrentPlayer(Player player)
{
//remove current databindings
lblHitPoints.DataBindings.Clear();
lblGold.DataBindings.Clear();
lblExperience.DataBindings.Clear();
lblLevel.DataBindings.Clear();
_player = player;
GivePlayerDefaultItems(player);
UpdatePotionListInUI(); //shows potion at the beginning, if any
//bindings of labels to player properties, they update automatically
lblHitPoints.DataBindings.Add("Text", player, "CurrentHitPoints");
lblGold.DataBindings.Add("Text", player, "Gold");
lblExperience.DataBindings.Add("Text", player, "ExperiencePoints");
lblLevel.DataBindings.Add("Text", player, "Level");
//linking of dataGridView to inventory item properties (datasource)
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",
Width = 197,
DataPropertyName = "Quantity"
});
//linking of dataGridView to player quest properties (data source)
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?",
Width = 197,
DataPropertyName = "IsCompletedYesNo"
});
}
private void GivePlayerDefaultItems(Player player)
{
// If the player's inventory does not contain a rusty sword,
// or a healing potion, give them to the player.
if (player.Inventory.All(i => i.Details.ID != World.ITEM_ID_RUSTY_SWORD))
{
player.Inventory.Add(new InventoryItem(World.ItemByID(World.ITEM_ID_RUSTY_SWORD), 1));
}
if (player.Inventory.All(i => i.Details.ID != World.ITEM_ID_HEALING_POTION))
{
player.Inventory.Add(new InventoryItem(World.ItemByID(World.ITEM_ID_HEALING_POTION), 1));
}
}
public void ResetByDeath()
{
//BindingList<PlayerQuest> previousQuests = _player.Quests;
List<Item> itemsToEnterLocations = World.Locations
.Where(x => x.ItemRequiredToEnter != null)
.Select(x => x.ItemRequiredToEnter)
.Distinct().ToList();
List<InventoryItem> itemsToRemoveFromPlayerInventory = new List<InventoryItem>();
foreach (InventoryItem ii in _player.Inventory)
{
foreach (Location location in World.Locations)
{
// Look at all the itemsToEnterLocations.
// If none of them have an ID that matches the current inventory item,
// add the inventory item to the list of items to remove.
if (itemsToEnterLocations.All(i => i.ID != ii.Details.ID))
{
itemsToRemoveFromPlayerInventory.Add(ii);
}
}
}
// Remove the non-location required items from the player's inventory.
// This needs to be done seperately from finding the list of items to remove,
// because you cannot remove objects from a collection
// while inside a "foreach" loop that is looking at the items in the collection.
// You would get an error that says "Collection was modified"
foreach (InventoryItem item in itemsToRemoveFromPlayerInventory)
{
_player.Inventory.Remove(item); //keeps only items that are required to enter places
}
GivePlayerDefaultItems(_player);
//_player.Quests = previousQuests; //keeps quest list and quests done when you die
// Heal the player
_player.CurrentHitPoints = _player.MaximumHitPoints;
//Lose all gold
_player.Gold = 20;
MoveTo(World.LocationByID(World.LOCATION_ID_HOME));
ScrollToBottomOfMessages();
rtbMessages.Text += Environment.NewLine + Environment.NewLine + Environment.NewLine;
}
private void btnNorth_Click(object sender, EventArgs e)
{
MoveTo(_player.CurrentLocation.LocationToNorth);
}
private void btnEast_Click(object sender, EventArgs e)
{
MoveTo(_player.CurrentLocation.LocationToEast);
}
private void btnSouth_Click(object sender, EventArgs e)
{
MoveTo(_player.CurrentLocation.LocationToSouth);
}
private void btnWest_Click(object sender, EventArgs e)
{
MoveTo(_player.CurrentLocation.LocationToWest);
}
public void MoveTo(Location newLocation)
{
if (!_player.HasRequiredItemToEnterThisLocation(newLocation))
{
ScrollToBottomOfMessages();
rtbMessages.Text += "You must have a/an " + newLocation.ItemRequiredToEnter.Name + " to enter this location." + Environment.NewLine;
return;
}
//Update the player's current location
_player.CurrentLocation = newLocation;
//Show/hide available movement buttons
btnNorth.Visible = (newLocation.LocationToNorth != null);
btnEast.Visible = (newLocation.LocationToEast != null);
btnSouth.Visible = (newLocation.LocationToSouth != null);
btnWest.Visible = (newLocation.LocationToWest != null);
//Display current location name and description
rtbLocation.Text = newLocation.Name + Environment.NewLine;
rtbLocation.Text += newLocation.Description + Environment.NewLine;
//Does the location have a quest?
if (newLocation.QuestAvailableHere != null)
{
//see if the player already has the quest, and if they've completed it
bool playerAlreadyHasQuest = _player.HasThisQuest(newLocation.QuestAvailableHere);
bool playerAlreadyHasCompletedQuest = _player.CompletedThisQuest(newLocation.QuestAvailableHere);
//See if the player already has the quest
if (playerAlreadyHasQuest)
{
//if the player has not completed the quest yet
if (!playerAlreadyHasCompletedQuest)
{
//See if the player has all the items needed to complete the quest
bool playerHasAllTheItemsToCompleteQuest = _player.HasAllQuestCompletionItems(newLocation.QuestAvailableHere);
if (playerHasAllTheItemsToCompleteQuest)
{
//display message
ScrollToBottomOfMessages();
rtbMessages.Text += Environment.NewLine;
ScrollToBottomOfMessages();
rtbMessages.Text += "You complete the " + "«" + newLocation.QuestAvailableHere.Name + "»" + " quest." + Environment.NewLine;
//remove quest items from inventory
_player.RemoveQuestCompletionItems(newLocation.QuestAvailableHere);
//give quest rewards
ScrollToBottomOfMessages();
rtbMessages.Text += "You receive: " + Environment.NewLine;
rtbMessages.Text += newLocation.QuestAvailableHere.RewardExperiencePoints.ToString() + " experience points" + Environment.NewLine;
rtbMessages.Text += newLocation.QuestAvailableHere.RewardGold.ToString() + " gold" + Environment.NewLine;
rtbMessages.Text += newLocation.QuestAvailableHere.RewardItem.Name + Environment.NewLine;
rtbMessages.Text += Environment.NewLine;
_player.AddExperiencePoints(newLocation.QuestAvailableHere.RewardExperiencePoints);
_player.Gold += newLocation.QuestAvailableHere.RewardGold;
//Add reward item to the player's inventory
_player.AddItemToInventory(newLocation.QuestAvailableHere.RewardItem);
//mark the quest as completed
_player.MarkQuestCompleted(newLocation.QuestAvailableHere);
//Update UI text
UpdatePotionListInUI();
}
}
}
else
{
//the player does not already have the quest
//display messages
ScrollToBottomOfMessages();
rtbMessages.Text += "You receive the " + "«" + newLocation.QuestAvailableHere.Name + "»" + " quest." + Environment.NewLine;
rtbMessages.Text += newLocation.QuestAvailableHere.Description + Environment.NewLine;
rtbMessages.Text += "To complete it, return with: " + Environment.NewLine;
foreach (QuestCompletionItem qci in newLocation.QuestAvailableHere.QuestCompletionItems)
{
if (qci.Quantity == 1)
{
ScrollToBottomOfMessages();
rtbMessages.Text += qci.Quantity.ToString() + " " + qci.Details.Name + Environment.NewLine;
}
else
{
ScrollToBottomOfMessages();
rtbMessages.Text += qci.Quantity.ToString() + " " + qci.Details.NamePlural + Environment.NewLine;
}
}
ScrollToBottomOfMessages();
rtbMessages.Text += Environment.NewLine;
//Add the quest to the player quest's list
_player.Quests.Add(new PlayerQuest(newLocation.QuestAvailableHere));
}
}
//Does the location have a monster?
if (newLocation.MonsterLivingHere != null)
{
ScrollToBottomOfMessages();
rtbMessages.Text += Environment.NewLine;
ScrollToBottomOfMessages();
rtbMessages.Text += "You see a " + newLocation.MonsterLivingHere.Name + "." + Environment.NewLine;
//make a new monster, using the values from the standard monster in the World.Monster list
Monster standardMonster = World.MonsterByID(newLocation.MonsterLivingHere.ID);
_currentMonster = new Monster(standardMonster.ID, standardMonster.Name, standardMonster.MaximumDamage,
standardMonster.RewardExperiencePoints, standardMonster.RewardGold, standardMonster.CurrentHitPoints, standardMonster.MaximumHitPoints);
foreach (LootItem lootItem in standardMonster.LootTable)
{
_currentMonster.LootTable.Add(lootItem);
}
cboWeapons.Visible = true;
btnUseWeapon.Visible = true;
}
else
{
_currentMonster = null;
cboWeapons.Visible = false;
btnUseWeapon.Visible = false;
}
//refresh player's weapons combobox
UpdateWeaponsListInUI();
//refresh player's potion combobox
UpdatePotionListInUI();
//Show/hide save button in presence of monsters
btnSave.Visible = (_currentMonster == null);
}
private void UpdateWeaponsListInUI()
{
List<Weapon> weapons = new List<Weapon>();
foreach (InventoryItem inventoryItem in _player.Inventory)
{
if (inventoryItem.Details is Weapon)
{
if (inventoryItem.Quantity > 0)
{
weapons.Add((Weapon)inventoryItem.Details);
}
}
}
if (weapons.Count == 0)
{
//the player has no weapons, hide the combobox and "use" button
cboWeapons.Visible = false;
btnUseWeapon.Visible = false;
}
else
{
cboWeapons.SelectedIndexChanged -= cboWeapons_SelectedIndexChanged;
cboWeapons.DataSource = weapons;
cboWeapons.SelectedIndexChanged += cboWeapons_SelectedIndexChanged;
cboWeapons.DisplayMember = "Name";
cboWeapons.ValueMember = "ID";
if (_player.CurrentWeapon != null)
{
cboWeapons.SelectedItem = _player.CurrentWeapon;
}
else
{
cboWeapons.SelectedIndex = 0;
}
}
}
private void UpdatePotionListInUI()
{
List<HealingPotion> healingPotions = new List<HealingPotion>();
foreach (InventoryItem inventoryItem in _player.Inventory)
{
if (inventoryItem.Details is HealingPotion)
{
if (inventoryItem.Quantity > 0)
{
healingPotions.Add((HealingPotion)inventoryItem.Details);
}
}
}
if (healingPotions.Count == 0)
{
//the player does not have any potions, hide the combobox and "use button
cboPotions.Visible = false;
btnUsePotion.Visible = false;
}
else
{
cboPotions.Visible = true;
btnUsePotion.Visible = true;
cboPotions.DataSource = healingPotions;
cboPotions.DisplayMember = "Name";
cboPotions.ValueMember = "ID";
cboPotions.SelectedIndex = 0;
}
}
private void btnUseWeapon_Click(object sender, EventArgs e)
{
//get the currently selected weapon from cboWeapons combobox
Weapon currentWeapon = (Weapon)cboWeapons.SelectedItem;
//Determine the amount of damage to do to the monster
int damageToMonster = RandomNumberGenerator.NumberBetween(currentWeapon.MinimumDamage, currentWeapon.MaximumDamage) + _player.BaseDamage;
//apply damage to monster's currenthitpoints
_currentMonster.CurrentHitPoints -= damageToMonster;
//display message
ScrollToBottomOfMessages();
rtbMessages.Text += "You hit the " + _currentMonster.Name + " for " + damageToMonster.ToString() + " points." + Environment.NewLine;
//check if the monster is dead
if (_currentMonster.CurrentHitPoints <= 0)
{
//Monster is dead
ScrollToBottomOfMessages();
rtbMessages.Text += "You defeated the " + _currentMonster.Name + "." + Environment.NewLine;
ScrollToBottomOfMessages();
rtbMessages.Text += Environment.NewLine;
btnUseWeapon.Visible = false;
cboWeapons.Visible = false;
//Give player experience for killing the monster
_player.AddExperiencePoints(_currentMonster.RewardExperiencePoints);
ScrollToBottomOfMessages();
rtbMessages.Text += "You receive " + _currentMonster.RewardExperiencePoints.ToString() + " experience points." + Environment.NewLine;
//Give player gold for killing the monster
_player.Gold += _currentMonster.RewardGold;
if (_currentMonster.RewardGold == 1)
{
ScrollToBottomOfMessages();
rtbMessages.Text += "You get " + _currentMonster.RewardGold.ToString() + " piece of gold." + Environment.NewLine;
}
else
{
ScrollToBottomOfMessages();
rtbMessages.Text += "You get " + _currentMonster.RewardGold.ToString() + " pieces of gold." + Environment.NewLine;
}
//get random loot items from the monster
List<InventoryItem> lootedItems = new List<InventoryItem>();
//Add items to the lootedItems list, comparing a random number to the drop percentage
foreach (LootItem lootItem in _currentMonster.LootTable)
{
if (RandomNumberGenerator.NumberBetween(1, 100) <= lootItem.DropPercentage)
{
lootedItems.Add(new InventoryItem(lootItem.Details, 1));
}
}
//if no items were randomly selected, then add the default loot item(s)
if (lootedItems.Count == 0)
{
foreach (LootItem lootItem in _currentMonster.LootTable)
{
if (lootItem.IsDefaultItem)
{
lootedItems.Add(new InventoryItem(lootItem.Details, 1));
}
}
}
//add the looted items to the player's inventory
foreach (InventoryItem inventoryItem in lootedItems)
{
_player.AddItemToInventory(inventoryItem.Details);
if (inventoryItem.Quantity == 1)
{
ScrollToBottomOfMessages();
rtbMessages.Text += "You loot " + inventoryItem.Quantity.ToString() + " " + inventoryItem.Details.Name + Environment.NewLine;
}
else
{
ScrollToBottomOfMessages();
rtbMessages.Text += "You loot " + inventoryItem.Quantity.ToString() + inventoryItem.Details.NamePlural + Environment.NewLine;
}
}
UpdateWeaponsListInUI();
UpdatePotionListInUI();
_currentMonster = null;
btnSave.Visible = (_currentMonster == null);
}
else
{
//monster is still alive
//determine the amount of damage the monster does to the player
int damageToPlayer = RandomNumberGenerator.NumberBetween(1, _currentMonster.MaximumDamage);
//display message
ScrollToBottomOfMessages();
rtbMessages.Text += "The " + _currentMonster.Name + " did " + damageToPlayer.ToString() + " points of damage." + Environment.NewLine;
//subtract damage from player
_player.CurrentHitPoints -= damageToPlayer;
if (_player.CurrentHitPoints <= 0)
{
ScrollToBottomOfMessages();
rtbMessages.Text += "The " + _currentMonster.Name + " killed you." + Environment.NewLine;
ResetByDeath();
}
}
}
private void cboWeapons_SelectedIndexChanged(object sender, EventArgs e)
{
_player.CurrentWeapon = (Weapon)cboWeapons.SelectedItem;
}
private void btnUsePotion_Click(object sender, EventArgs e)
{
//get the currently selected potion from the combobox
HealingPotion potion = (HealingPotion)cboPotions.SelectedItem;
//Add healing amount to the player's current hit points
_player.CurrentHitPoints += potion.AmountToHeal;
//current hit points cannot exceed player's max hit points
if (_player.CurrentHitPoints > _player.MaximumHitPoints)
{
_player.CurrentHitPoints = _player.MaximumHitPoints;
}
//remove the potion from the player's inventory
foreach (InventoryItem ii in _player.Inventory)
{
if (ii.Details.ID == potion.ID)
{
ii.Quantity--;
break;
}
}
//display message
ScrollToBottomOfMessages();
rtbMessages.Text += "You drink a " + potion.Name + " that replenishes " + potion.AmountToHeal.ToString() + " hit points." + Environment.NewLine;
if (_currentMonster != null)
{
//monster gets their turn to attack
//determine the amount of damage the monster does to the player
int damageToPlayer = RandomNumberGenerator.NumberBetween(1, _currentMonster.MaximumDamage);
//display message
ScrollToBottomOfMessages();
rtbMessages.Text += "The " + _currentMonster.Name + " did " + damageToPlayer.ToString() + " points of damage." + Environment.NewLine;
//subtract damage from player
_player.CurrentHitPoints -= damageToPlayer;
if (_player.CurrentHitPoints <= 0)
{
ScrollToBottomOfMessages();
rtbMessages.Text += "The " + _currentMonster.Name + " killed you." + Environment.NewLine;
ResetByDeath();
}
}
UpdatePotionListInUI();
}
private void ScrollToBottomOfMessages()
{
rtbMessages.SelectionStart = rtbMessages.Text.Length;
rtbMessages.ScrollToCaret();
}
private void btnSave_Click(object sender, EventArgs e)
{
File.WriteAllText(PLAYER_DATA_FILE_NAME, _player.ToXmlString());
ScrollToBottomOfMessages();
rtbMessages.Text += "You saved the game." + Environment.NewLine;
}
private void btnLoad_Click(object sender, EventArgs e)
{
DisplayAdditionalLoadButtons();
}
private void DisplayAdditionalLoadButtons()
{
mtbLoadDecide.Visible = true;
btnLoadDecideNo.Visible = true;
btnLoadDecideYes.Visible = true;
}
private void HideAdditionalLoadButtons()
{
mtbLoadDecide.Visible = false;
btnLoadDecideNo.Visible = false;
btnLoadDecideYes.Visible = false;
}
private void btnLoadDecideYes_Click(object sender, EventArgs e)
{
Player newPlayer;
if (File.Exists(PLAYER_DATA_FILE_NAME))
{
newPlayer = Player.CreatePlayerFromXmlString(File.ReadAllText(PLAYER_DATA_FILE_NAME));
ScrollToBottomOfMessages();
rtbMessages.Text += "You loaded the previous game save." + Environment.NewLine;
}
else
{
newPlayer = CreateNewPlayerForNewGame();
ScrollToBottomOfMessages();
rtbMessages.Text += "No data saved. Starting a new game." + Environment.NewLine;
}
SetCurrentPlayer(newPlayer);
MoveTo(_player.CurrentLocation);
HideAdditionalLoadButtons();
}
private void btnLoadDecideNo_Click(object sender, EventArgs e)
{
Player newPlayer = CreateNewPlayerForNewGame();
ScrollToBottomOfMessages();
rtbMessages.Text += "Starting a new game." + Environment.NewLine;
HideAdditionalLoadButtons();
SetCurrentPlayer(newPlayer);
MoveTo(World.LocationByID(World.LOCATION_ID_HOME));
}
private Player CreateNewPlayerForNewGame()
{
Player newPlayer = Player.CreateDefaultPlayer();
GivePlayerDefaultItems(newPlayer);
return newPlayer;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment