EDIT: Got an answer, I changed the list Inv in player to a list of int, and imported the items on initial load of the game into a Dictionary like so:
public static class InitLoad
{
static List<ItemEquipmentWeapon> weapons;
public static Dictionary<int, Item> ItemIDList = new Dictionary<int, Item>();
public static void PreLoading()
{
string path, filePath,
weaponFile = @"\WeaponsItem.aid";
XmlSerializer SerializerObj;
FileStream ReadFileStream;
path = string.Format(@"{0}\AwesomeRPG\Data\Items",
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData));
filePath = string.Format(@"{0}\{1}", path, weaponFile);
SerializerObj = new XmlSerializer(typeof(ItemEquipmentWeapon));
ReadFileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
weapons = (List<ItemEquipmentWeapon>)SerializerObj.Deserialize(ReadFileStream);
foreach (Item item in weapons)
{
ItemIDList.Add(item.ID, item);
}
}
}
Meaning I can then do this with my player class:
[Serializable()]
public class Player : Entity
{
public string Name { get; set; }
public int MaxHP { get; set; }
public int Level { get; set; }
public int XP { get; set; }
public int Str { get; set; }
public int End { get; set; }
public int Dex { get; set; }
public int Agi { get; set; }
public int Wis { get; set; }
public int Int { get; set; }
//Create a list of Item Id's for inventory
public List<int> Inv { get; set; }
private int lHand;
private int rHand;
public int LHand
{
get
{ return lHand; }
set
{
if (!value.THand)
{
lHand = value;
}
else lHand = null;
}
}
public int RHand
{
get
{ return rHand; }
set
{ rHand = value; }
}
internal Player() { }
public Player(string name, int maxhp, int hp, int lvl, int exp, int str, int end, int dex, int agi, int wis, int inte)
: base(true, hp)
{
Name = name;
MaxHP = maxhp;
Level = lvl;
XP = exp;
Str = str;
End = end;
Dex = dex;
Agi = agi;
Wis = wis;
Int = inte;
Inv = new List<int>();
}
public List<string> GetInv()
{
List<string> val = new List<string>();
Item item;
foreach (int i in Inv)
{
InitLoad.ItemIDList.TryGetValue(i, out item);
val.Add(item.Name);
}
return val;
}
public void AddItem(Item i, int amt)
{
for (int j = 0; j < amt; j++)
{
Inv.Add(i.ID);
}
}
public void AddItem(Item i){
AddItem(i, 1); }
public void RemoveItem(Item i, int amt)
{
int count = 0;
foreach (int item in Inv)
{
if (item == i.ID)
{
Inv.Remove(item);
count++;
}
if (count == amt)
{
break;
}
}
}
public void RemoveItem(Item i){
RemoveItem(i, 1); }
public bool HasItem(Item i, int amt)
{
int count = 0;
foreach (int item in Inv)
{
if (item == i.ID)
{
count++;
}
}
return count >= amt;
}
public bool HasItem(Item i){
return HasItem(i, 1); }
}
Hope this helps anybody else!
Original Question:
So, I'm making a silly little RPG game with windows forms to test my skills, and I'm sorting out saving. At the moment it saves to an XML file, which a custom extention (.asd) Here's my save/load code:
public static class SaveGame
{
public static void Save(Player player)
{
string myfile = string.Format(@"{1}\AwesomeRPG\Saves\{0}Save.asd", player.Name, Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData));
//Delete file if it already exists
if (File.Exists(myfile)) System.IO.File.Delete(myfile);
//Create/Write to the file
FileStream outFile = File.Create(myfile);
XmlSerializer Serializer = new XmlSerializer(typeof(Player));
Serializer.Serialize(outFile, player);
outFile.Close();
}
public static Player Load(string FileName)
{
string myfile = string.Format(@"{1}\AwesomeRPG\Saves\{0}Save.asd", FileName, Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData));
if (!File.Exists(myfile)) return null;
XmlSerializer Serializer = new XmlSerializer(typeof(Player));
FileStream ReadFileStream = new FileStream(myfile, FileMode.Open, FileAccess.Read, FileShare.Read);
return (Player)Serializer.Deserialize(ReadFileStream);
}
}
As you can imagine, this saves all the details of any item in the Inv list. However, I want all items that exist to be loaded (instances of them to be created) when the game starts, and I need a way for the save file to hold references to those instances, rather than making new instances.
The instances loaded when the game starts are also held in XML files, and then loaded into separate lists based on the item type, eg all ItemEquipmentWeapon instances (Inherits ItemEquipment which inherits Item) are in a WeaponItem.aid file, which is in XML format, and is loaded into a List
Is there any way I can save and load the Inv contents to and from the player save file by reference so I can have them use the existing instances setup during initial loading?
EDIT: Just thought, it might help some to see how the Player class is coded, so here it is:
[Serializable()]
public class Player : Entity
{
public string Name { get; set; }
public int MaxHP { get; set; }
public int Level { get; set; }
public int XP { get; set; }
public int Str { get; set; }
public int End { get; set; }
public int Dex { get; set; }
public int Agi { get; set; }
public int Wis { get; set; }
public int Int { get; set; }
public List<Item> Inv { get; set; }
private ItemEquipmentWeapon lHand;
private ItemEquipmentWeapon rHand;
public ItemEquipmentWeapon LHand
{
get
{ return lHand; }
set
{
if (!value.THand)
{
lHand = value;
}
else lHand = null;
}
}
public ItemEquipmentWeapon RHand
{
get
{ return rHand; }
set
{ rHand = value; }
}
internal Player() { }
public Player(string name, int maxhp, int hp, int lvl, int exp, int str, int end, int dex, int agi, int wis, int inte)
: base(true, hp)
{
Name = name;
MaxHP = maxhp;
Level = lvl;
XP = exp;
Str = str;
End = end;
Dex = dex;
Agi = agi;
Wis = wis;
Int = inte;
Inv = new List<Item>();
}
public List<string> GetInv()
{
List<string> val = new List<string>();
foreach (Item item in Inv)
{
val.Add(item.Name);
}
return val;
}
public void AddItem(Item i, int amt)
{
for (int j = 0; j < amt; j++)
{
Inv.Add(i);
}
}
public void AddItem(Item i){
AddItem(i, 1); }
public void RemoveItem(Item i, int amt)
{
int count = 0;
foreach (Item item in Inv)
{
if (item == i)
{
Inv.Remove(item);
count++;
}
if (count == amt)
{
break;
}
}
}
public void RemoveItem(Item i){
RemoveItem(i, 1); }
public bool HasItem(Item i, int amt)
{
int count = 0;
foreach (Item item in Inv)
{
if (item == i)
{
count++;
}
}
return count >= amt;
}
public bool HasItem(Item i){
return HasItem(i, 1); }
}
Obviously the code that loads the item instances from XML on game load would also be very useful, but I haven't coded that yet, I'm not 100% sure how I would go about doing it. So far though, I have this:
public static class InitLoad
{
static List<ItemEquipmentWeapon> weapons;
public static void PreLoading()
{
string path, filePath,
weaponFile = @"\WeaponsItem.aid";
XmlSerializer SerializerObj;
FileStream ReadFileStream;
path = string.Format(@"{0}\AwesomeRPG\Data\Items",
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData));
filePath = string.Format(@"{0}\{1}", path, weaponFile);
SerializerObj = new XmlSerializer(typeof(ItemEquipmentWeapon));
ReadFileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
weapons = (List<ItemEquipmentWeapon>)SerializerObj.Deserialize(ReadFileStream);
}
}
Thanks in advance for any help!