using System; using System.Collections.Generic; using System.Linq; using System.Text; using GenericNetplayImplementation; namespace mmoRLserver { public class Player : Creature { public int id = 10; public GNIClientInformation client; public string name = "Anonymous"; public string location = "unknown"; public string party = ""; public string instanceTarget = ""; public bool finishedTurn = true; public List learnPool = new List(); public List skills = new List(); public List items = new List(); public string key = ""; public bool ready = false; public bool firstTurn = true; //Prevent triggering a turn when you join public static int BASE_HP = 25; public static int BASE_STRENGTH = 10; public static float BASE_HITCHANCE = 1f; public static int BASE_ARMOR = 0; public static int MAX_EXPERIENCE = 32000; public Player(GNIClientInformation client) { this.client = client; this.id = (int)client.clientID + 10; } public void AddLearnable(int number) { Skill toAdd = Skill.GetSkill(number); if (toAdd != null) learnPool.Add(toAdd); } public Skill GetLearnable(int number) { Skill toFind = null; for (int i = 0; i < learnPool.Count; i++) { if (learnPool[i].id == number) toFind = learnPool[i]; } return toFind; } public bool Learn(int number) { bool success = true; Skill learning = GetLearnable(number); if (learning == null) success = false; else { if (learning.expCost > this.experience) success = false; } if (success) { this.experience -= learning.expCost; skills.Add(learning); learnPool.Remove(learning); RecalculateStats(); } return success; } public bool HasSkill(int skillNumber) { for (int i = 0; i < skills.Count; i++) { if (skills[i].id == skillNumber) return true; } return false; } public bool KnowsAboutSkill(int skillNumber) { for (int i = 0; i < learnPool.Count; i++) { if (learnPool[i].id == skillNumber) return true; } return false; } //========================================================================================== public void RecalculateStats() { this.maxHP = BASE_HP; this.strength = BASE_STRENGTH; this.hitChance = BASE_HITCHANCE; this.armor = BASE_ARMOR; //---Then modify the base values--- //Pre-equip skills if (HasSkill(4)) maxHP += 10; if (HasSkill(11)) armor += 1; if (HasSkill(12)) strength += 1; if (HasSkill(17)) maxHP += 20; if (HasSkill(18)) armor += 3; if (HasSkill(19)) strength += 3; if (HasSkill(21)) maxHP += 20; if (HasSkill(22)) armor += 5; if (HasSkill(23)) strength += 5; bool hasWeapon = false; bool armored = false; //Check equipment for (int i = 0; i < this.items.Count; i++) { if (items[i].equipped) { if (items[i].equipmentType == "weapon") hasWeapon = true; if ((items[i].equipmentType == "armor") || (items[i].equipmentType == "legs") || (items[i].equipmentType == "head")) { armored = true; } switch (items[i].id) { //--WEAPONS-- case 39: //Stick case 40: //Stick2 strength += 1; hitChance = 0.9f; break; case 54: //Primitive Spear strength += 3; hitChance = 0.9f; break; case 57: //Orcish Spear strength += 5; hitChance = 0.9f; break; //--ARMOR-- case 43: armor += 1; break; //Kobold Armor case 44: armor += 1; break; //Kobold Leggings case 45: armor += 1; break; //Kobold Helmet case 46: armor += 2; strength += 1; break; //Orcish Armor case 47: armor += 2; break; //Orcish Leggings case 48: armor += 3; strength += 1; break; //Orcish Helm case 49: armor += 3; break; //Leather Armor case 50: armor += 3; break; //Leather leggings case 51: armor += 2; break; //Leather Cap case 53: armor += 1; break; //Leather Boots case 58: armor += 3; break; //Enchanted Leather Boots case 69: armor += 1; break; //Boots of Water Walking } } } //Post-equip skills if (HasSkill(13) && !hasWeapon) strength += 10; if (HasSkill(20) && hasWeapon) strength += 15; if (HasSkill(24) && !armored) strength += 20; //Cut max HP if (this.HP > this.maxHP) this.HP = this.maxHP; //Update stats client-side Program.QueueSignal(client.clientID, new GNIData("mhp", maxHP)); Program.QueueSignal(client.clientID, new GNIData("hp", HP)); Program.QueueSignal(client.clientID, new GNIData("xp", experience)); Program.QueueSignal(client.clientID, new GNIData("str", strength)); Program.QueueSignal(client.clientID, new GNIData("arm", armor)); } //================================================================================= public byte[] Serialize() { List toReturn = new List(); toReturn.Add(0x02); //Version toReturn.Add(0); //To replace later; length toReturn.Add(0); //Write strings string[] serializableStrings = new string[] { name, location, instanceTarget }; foreach (string s in serializableStrings) { byte[] stringBytes = Encoding.ASCII.GetBytes(s); toReturn.Add((byte)stringBytes.Length); for (int i = 0; i < stringBytes.Length; i++) { toReturn.Add(stringBytes[i]); } } //Write skill lists List[] skillLists = new List[] { learnPool, skills }; foreach (List ls in skillLists) { int length = ls.Count; byte b1 = (byte)(Math.Floor((float)length / 256f)); byte b2 = (byte)(length - (256 * b1)); toReturn.Add(b1); toReturn.Add(b2); for (int i = 0; i < length; i++) { Skill skill = ls[i]; b1 = (byte)(Math.Floor((float)skill.id / 256f)); b2 = (byte)(skill.id - (256 * b1)); toReturn.Add(b1); toReturn.Add(b2); } } //Write items byte ic1 = (byte)(Math.Floor((float)items.Count / 256f)); byte ic2 = (byte)(items.Count - (256 * ic1)); toReturn.Add(ic1); toReturn.Add(ic2); for (int i = 0; i < items.Count; i++) { byte[] itemSer = items[i].Serialize(); for (int ii = 0; ii < itemSer.Length; ii++) { toReturn.Add(itemSer[ii]); } } //Write equipment data List equipped = new List(); for (int i = 0; i < items.Count; i++) { if (items[i].equipped) equipped.Add(i); } toReturn.Add((byte)equipped.Count); for (int i = 0; i < equipped.Count; i++) { toReturn.Add((byte)equipped[i]); } //Write ints int[] serializableInts = new int[] { x, y, HP, maxHP, strength, experience }; foreach (int j in serializableInts) { byte b1 = (byte)(Math.Floor((float)j / 256f)); byte b2 = (byte)(j - (256 * b1)); toReturn.Add(b1); toReturn.Add(b2); } int trLength = toReturn.Count - 3; byte c1 = (byte)(Math.Floor((float)trLength / 256f)); byte c2 = (byte)(trLength - (256 * c1)); toReturn[1] = c1; //Insert length toReturn[2] = c2; return toReturn.ToArray(); } public bool DeSerialize(byte[] serialized, bool skipIntro = false) { System.IO.MemoryStream ms = new System.IO.MemoryStream(serialized); System.IO.BinaryReader br = new System.IO.BinaryReader(ms); if (!skipIntro) { int version = br.ReadByte(); if (version != 0x02) return false; br.ReadBytes(2); //Length, not interesting } //Load strings for (int i = 0; i < 3; i++) { int length = br.ReadByte(); string theString = Encoding.ASCII.GetString(br.ReadBytes(length)); switch (i) { case 0: name = theString; break; case 1: location = theString; break; case 2: instanceTarget = theString; break; } } //Load skill lists learnPool.Clear(); skills.Clear(); for (int i = 0; i < 2; i++) { int length = ReadInt(br.ReadByte(), br.ReadByte()); for (int ii = 0; ii < length; ii++) { int skillNumber = ReadInt(br.ReadByte(), br.ReadByte()); switch (i) { case 0: learnPool.Add(Skill.GetSkill(skillNumber)); break; case 1: skills.Add(Skill.GetSkill(skillNumber)); break; } } } //Load items items.Clear(); int numItems = ReadInt(br.ReadByte(), br.ReadByte()); for (int i = 0; i < numItems; i++) { items.Add(new Item(br.ReadBytes(3))); } //Load equipment data int numberOfEquippedItems = br.ReadByte(); for (int i = 0; i < numberOfEquippedItems; i++) { items[br.ReadByte()].equipped = true; } //Load ints for (int i = 0; i < 6; i++) { int toWrite = ReadInt(br.ReadByte(), br.ReadByte()); switch (i) { case 0: x = toWrite; break; case 1: y = toWrite; break; case 2: HP = toWrite; break; case 3: maxHP = toWrite; break; case 4: strength = toWrite; break; case 5: experience = toWrite; break; } } br.Close(); ms.Close(); return true; } private static int ReadInt(byte b1, byte b2) { return b1 * 256 + b2; } public bool EquipItem(int itemID) { Item hasIt = null; //Check if player actually has item for (int i = 0; i < items.Count; i++) { if (hasIt == null) { if (items[i].id == itemID) hasIt = items[i]; } } if (hasIt == null) return false; if (hasIt.equipmentType == "") return false; //Unequip all equipment of the same class for (int i = 0; i < items.Count; i++) { if (items[i].equipped) { if (items[i].equipmentType == hasIt.equipmentType) items[i].equipped = false; } } hasIt.equipped = true; RecalculateStats(); return true; } public bool UnEquipItem(int itemID) { Item hasIt = null; //Check if player actually has item for (int i = 0; i < items.Count; i++) { if (hasIt == null) { if (items[i].id == itemID) hasIt = items[i]; } } if (hasIt == null) return false; if (hasIt.equipmentType == "") return false; hasIt.equipped = false; RecalculateStats(); return true; } public void GainExperience(int amount) { this.experience += amount; if (this.experience > MAX_EXPERIENCE) this.experience = MAX_EXPERIENCE; } } }