Skip to content

Instantly share code, notes, and snippets.

@ScottLilly
Created January 25, 2016 01:16
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save ScottLilly/7e03a2e73cfb01db5d6d to your computer and use it in GitHub Desktop.
Lesson 21.4 - Completing the trading screen
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Engine
{
public class InventoryItem : INotifyPropertyChanged
{
private Item _details;
private int _quantity;
public Item Details
{
get { return _details; }
set
{
_details = value;
OnPropertyChanged("Details");
}
}
public int Quantity
{
get { return _quantity; }
set
{
_quantity = value;
OnPropertyChanged("Quantity");
OnPropertyChanged("Description");
}
}
public int ItemID
{
get { return Details.ID; }
}
public string Description
{
get { return Quantity > 1 ? Details.NamePlural : Details.Name; }
}
public int Price
{
get { return Details.Price; }
}
public InventoryItem(Item details, int quantity)
{
Details = details;
Quantity = quantity;
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
if(PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
}
}
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 Engine;
namespace SuperAdventure
{
public partial class TradingScreen : Form
{
private Player _currentPlayer;
// Commented out this property, because I chose to pass the player as a parameter in the constructor.
//public Player CurrentPlayer { get; set; }
public TradingScreen(Player player)
{
_currentPlayer = player;
InitializeComponent();
// Style, to display numeric column values
DataGridViewCellStyle rightAlignedCellStyle = new DataGridViewCellStyle();
rightAlignedCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
// Populate the datagrid for the player's inventory
dgvMyItems.RowHeadersVisible = false;
dgvMyItems.AutoGenerateColumns = false;
// This hidden column holds the item ID, so we know which item to sell
dgvMyItems.Columns.Add(new DataGridViewTextBoxColumn
{
DataPropertyName = "ItemID",
Visible = false
});
dgvMyItems.Columns.Add(new DataGridViewTextBoxColumn
{
HeaderText = "Name",
Width = 100,
DataPropertyName = "Description"
});
dgvMyItems.Columns.Add(new DataGridViewTextBoxColumn
{
HeaderText = "Qty",
Width = 30,
DefaultCellStyle = rightAlignedCellStyle,
DataPropertyName = "Quantity"
});
dgvMyItems.Columns.Add(new DataGridViewTextBoxColumn
{
HeaderText = "Price",
Width = 35,
DefaultCellStyle = rightAlignedCellStyle,
DataPropertyName = "Price"
});
dgvMyItems.Columns.Add(new DataGridViewButtonColumn
{
Text = "Sell 1",
UseColumnTextForButtonValue = true,
Width = 50,
DataPropertyName = "ItemID"
});
// Bind the player's inventory to the datagridview
dgvMyItems.DataSource = _currentPlayer.Inventory;
// When the user clicks on a row, call this function
dgvMyItems.CellClick += dgvMyItems_CellClick;
// Populate the datagrid for the vendor's inventory
dgvVendorItems.RowHeadersVisible = false;
dgvVendorItems.AutoGenerateColumns = false;
// This hidden column holds the item ID, so we know which item to sell
dgvVendorItems.Columns.Add(new DataGridViewTextBoxColumn
{
DataPropertyName = "ItemID",
Visible = false
});
dgvVendorItems.Columns.Add(new DataGridViewTextBoxColumn
{
HeaderText = "Name",
Width = 100,
DataPropertyName = "Description"
});
dgvVendorItems.Columns.Add(new DataGridViewTextBoxColumn
{
HeaderText = "Price",
Width = 35,
DefaultCellStyle = rightAlignedCellStyle,
DataPropertyName = "Price"
});
dgvVendorItems.Columns.Add(new DataGridViewButtonColumn
{
Text = "Buy 1",
UseColumnTextForButtonValue = true,
Width = 50,
DataPropertyName = "ItemID"
});
// Bind the vendor's inventory to the datagridview
dgvVendorItems.DataSource = _currentPlayer.CurrentLocation.VendorWorkingHere.Inventory;
// When the user clicks on a row, call this function
dgvVendorItems.CellClick += dgvVendorItems_CellClick;
}
private void dgvMyItems_CellClick(object sender, DataGridViewCellEventArgs e)
{
// The first column of a datagridview has a ColumnIndex = 0
// This is known as a "zero-based" array/collection/list.
// You start counting with 0.
//
// The 5th column (ColumnIndex = 4) is the column with the button.
// So, if the player clicked the button column, we will sell an item from that row.
if(e.ColumnIndex == 4)
{
// This gets the ID value of the item, from the hidden 1st column
// Remember, ColumnIndex = 0, for the first column
var itemID = dgvMyItems.Rows[e.RowIndex].Cells[0].Value;
// Get the Item object for the selected item row
Item itemBeingSold = World.ItemByID(Convert.ToInt32(itemID));
if(itemBeingSold.Price == World.UNSELLABLE_ITEM_PRICE)
{
MessageBox.Show("You cannot sell the " + itemBeingSold.Name);
}
else
{
// Remove one of these items from the player's inventory
_currentPlayer.RemoveItemFromInventory(itemBeingSold);
// Give the player the gold for the item being sold.
_currentPlayer.Gold += itemBeingSold.Price;
}
}
}
private void dgvVendorItems_CellClick(object sender, DataGridViewCellEventArgs e)
{
// The 4th column (ColumnIndex = 3) has the "Buy 1" button.
if(e.ColumnIndex == 3)
{
// This gets the ID value of the item, from the hidden 1st column
var itemID = dgvVendorItems.Rows[e.RowIndex].Cells[0].Value;
// Get the Item object for the selected item row
Item itemBeingBought = World.ItemByID(Convert.ToInt32(itemID));
// Check if the player has enough gold to buy the item
if(_currentPlayer.Gold >= itemBeingBought.Price)
{
// Add one of the items to the player's inventory
_currentPlayer.AddItemToInventory(itemBeingBought);
// Remove the gold to pay for the item
_currentPlayer.Gold -= itemBeingBought.Price;
}
else
{
MessageBox.Show("You do not have enough gold to buy the " + itemBeingBought.Name);
}
}
}
private void btnClose_Click(object sender, EventArgs e)
{
Close();
}
}
}
namespace SuperAdventure
{
partial class TradingScreen
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if(disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.dgvMyItems = new System.Windows.Forms.DataGridView();
this.dgvVendorItems = new System.Windows.Forms.DataGridView();
this.lblMyInventory = new System.Windows.Forms.Label();
this.lblVendorInventory = new System.Windows.Forms.Label();
this.btnClose = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.dgvMyItems)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.dgvVendorItems)).BeginInit();
this.SuspendLayout();
//
// dgvMyItems
//
this.dgvMyItems.AllowUserToAddRows = false;
this.dgvMyItems.AllowUserToDeleteRows = false;
this.dgvMyItems.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dgvMyItems.Location = new System.Drawing.Point(13, 43);
this.dgvMyItems.Name = "dgvMyItems";
this.dgvMyItems.ReadOnly = true;
this.dgvMyItems.Size = new System.Drawing.Size(240, 216);
this.dgvMyItems.TabIndex = 0;
//
// dgvVendorItems
//
this.dgvVendorItems.AllowUserToAddRows = false;
this.dgvVendorItems.AllowUserToDeleteRows = false;
this.dgvVendorItems.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dgvVendorItems.Location = new System.Drawing.Point(276, 43);
this.dgvVendorItems.Name = "dgvVendorItems";
this.dgvVendorItems.ReadOnly = true;
this.dgvVendorItems.Size = new System.Drawing.Size(240, 216);
this.dgvVendorItems.TabIndex = 1;
//
// lblMyInventory
//
this.lblMyInventory.AutoSize = true;
this.lblMyInventory.Location = new System.Drawing.Point(99, 13);
this.lblMyInventory.Name = "lblMyInventory";
this.lblMyInventory.Size = new System.Drawing.Size(68, 13);
this.lblMyInventory.TabIndex = 2;
this.lblMyInventory.Text = "My Inventory";
//
// lblVendorInventory
//
this.lblVendorInventory.AutoSize = true;
this.lblVendorInventory.Location = new System.Drawing.Point(349, 13);
this.lblVendorInventory.Name = "lblVendorInventory";
this.lblVendorInventory.Size = new System.Drawing.Size(95, 13);
this.lblVendorInventory.TabIndex = 3;
this.lblVendorInventory.Text = "Vendor\'s Inventory";
//
// btnClose
//
this.btnClose.Location = new System.Drawing.Point(441, 274);
this.btnClose.Name = "btnClose";
this.btnClose.Size = new System.Drawing.Size(75, 23);
this.btnClose.TabIndex = 4;
this.btnClose.Text = "Close";
this.btnClose.UseVisualStyleBackColor = true;
this.btnClose.Click += new System.EventHandler(this.btnClose_Click);
//
// TradingScreen
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(528, 310);
this.Controls.Add(this.btnClose);
this.Controls.Add(this.lblVendorInventory);
this.Controls.Add(this.lblMyInventory);
this.Controls.Add(this.dgvVendorItems);
this.Controls.Add(this.dgvMyItems);
this.Name = "TradingScreen";
this.Text = "Trade";
((System.ComponentModel.ISupportInitialize)(this.dgvMyItems)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.dgvVendorItems)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.DataGridView dgvMyItems;
private System.Windows.Forms.DataGridView dgvVendorItems;
private System.Windows.Forms.Label lblMyInventory;
private System.Windows.Forms.Label lblVendorInventory;
private System.Windows.Forms.Button btnClose;
}
}
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
namespace Engine
{
public class Vendor : INotifyPropertyChanged
{
public string Name { get; set; }
public BindingList<InventoryItem> Inventory { get; set; }
public Vendor(string name)
{
Name = name;
Inventory = new BindingList<InventoryItem>();
}
public void AddItemToInventory(Item itemToAdd, int quantity = 1)
{
InventoryItem item = Inventory.SingleOrDefault(ii => ii.Details.ID == itemToAdd.ID);
if(item == null)
{
// They didn't have the item, so add it to their inventory
Inventory.Add(new InventoryItem(itemToAdd, quantity));
}
else
{
// They have the item in their inventory, so increase the quantity
item.Quantity += quantity;
}
OnPropertyChanged("Inventory");
}
public void RemoveItemFromInventory(Item itemToRemove, int quantity = 1)
{
InventoryItem item = Inventory.SingleOrDefault(ii => ii.Details.ID == itemToRemove.ID);
if(item == null)
{
// The item is not in the player's inventory, so ignore it.
// We might want to raise an error for this situation
}
else
{
// They have the item in their inventory, so decrease the quantity
item.Quantity -= quantity;
// Don't allow negative quantities.
// We might want to raise an error for this situation
if(item.Quantity < 0)
{
item.Quantity = 0;
}
// If the quantity is zero, remove the item from the list
if(item.Quantity == 0)
{
Inventory.Remove(item);
}
// Notify the UI that the inventory has changed
OnPropertyChanged("Inventory");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string name)
{
if(PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment