using System; using System.Collections.Generic; using System.Linq; using System.Text; using VBXSE; using Microsoft.Xna.Framework; using System.IO; namespace DIGIEVO { public enum Element { NORMAL, FIRE, WATER, GRASS, LIGHT, DARK } public class Creature { public const int VERSION = 1; public int version = 1; public string name = "UNKNOWN"; public string owner = "Anonymous"; public int HP = 25; public int maxHP = 25; public int ATK = 10; public int DEF = 5; public int SPC = 10; public int AGI = 100; public int EXP = 0; public int totalEXP = 100; public Element element = Element.NORMAL; public List traits = new List(); public List moves = new List(); public bool artificial = false; public byte[] pass = new byte[0]; public string code = ""; public static bool hax = false; //----------------------- Constructor - Generation ------------------------- //Creature generation public Creature() { System.Random random = new System.Random(); //----moves-- //Give the creature Tackle moves.Add(Move.allMoves[1]); if (hax) { moves.Add(Move.allMoves[8]); moves.Add(Move.allMoves[9]); moves.Add(Move.allMoves[11]); moves.Add(Move.allMoves[12]); moves.Add(Move.allMoves[20]); moves.Add(Move.allMoves[21]); //Give the creature an element traits.Add(Trait.allTraits[random.Next(0, 6)]); //Give the creature a body traits.Add(Trait.allTraits[random.Next(6, 12)]); } else { //Then give the creature a random move //-that isn't tackle //-that doesn't have any special requirements bool acceptable = false; while (!acceptable) { Move move = Move.allMoves[random.Next(2, Move.allMoves.Count)]; //Check if it's acceptable acceptable = true; if (!move.canLearn) acceptable = false; if (random.NextDouble() < move.rarity) acceptable = false; if (acceptable) { moves.Add(move); } } //---traits--- //Give the creature an element traits.Add(Trait.allTraits[random.Next(0, 6)]); //Give the creature a body traits.Add(Trait.allTraits[random.Next(6, 12)]); //Give the creature a random trait traits.Add(Trait.allTraits[random.Next(12, Trait.allTraits.Count)]); } ApplyTraits(); } //----------------------- Constructor - Type ------------------------- public enum EnemyType { TrainingDummy, Disabler, Fighter, Elemental, DummyEx, DisablerEx, FighterEx, ElementalEx } public Creature(EnemyType type) { float multiplier = 1.0f; artificial = true; switch (type) { case EnemyType.TrainingDummy: this.name = "DUMMY"; moves.Add(Move.allMoves[0]); totalEXP = 200; artificial = true; break; case EnemyType.Disabler: this.name = "DISABLER"; this.element = Element.DARK; Move move = Move.allMoves[9]; move.maxPP = 3; moves.Add(move); artificial = true; totalEXP = 400; multiplier = 1.1f; break; case EnemyType.Fighter: this.name = "FIGHTER"; moves.Add(Move.allMoves[7]); moves.Add(Move.allMoves[21]); moves.Add(Move.allMoves[1]); artificial = true; totalEXP = 600; multiplier = 1.2f; break; case EnemyType.Elemental: this.name = "ELEMENTAL"; this.element = Element.LIGHT; totalEXP = 800; artificial = true; moves.Add(Move.allMoves[2]); moves.Add(Move.allMoves[3]); moves.Add(Move.allMoves[4]); moves.Add(Move.allMoves[5]); moves.Add(Move.allMoves[6]); multiplier = 1.3f; break; case EnemyType.DummyEx: this.name = "DUMMY EX"; this.element = Element.GRASS; moves.Add(Move.allMoves[7]); moves.Add(Move.allMoves[21]); moves.Add(Move.allMoves[1]); moves.Add(Move.allMoves[2]); moves.Add(Move.allMoves[18]); totalEXP = 1000; artificial = true; multiplier = 1.4f; break; case EnemyType.DisablerEx: this.name = "DISABLER EX"; this.element = Element.WATER; moves.Add(Move.allMoves[9]); moves.Add(Move.allMoves[11]); moves.Add(Move.allMoves[17]); moves.Add(Move.allMoves[13]); totalEXP = 1200; multiplier = 1.5f; break; case EnemyType.FighterEx: this.element = Element.FIRE; this.name = "FIGHTER EX"; moves.Add(Move.allMoves[7]); moves.Add(Move.allMoves[8]); moves.Add(Move.allMoves[9]); moves.Add(Move.allMoves[11]); moves.Add(Move.allMoves[16]); moves.Add(Move.allMoves[12]); artificial = true; totalEXP = 1400; multiplier = 1.6f; break; case EnemyType.ElementalEx: this.element = (Element)(new Random().Next(5) + 1); this.name = "ELEMENTAL EX"; totalEXP = 1600; artificial = true; moves.Add(Move.allMoves[12]); moves.Add(Move.allMoves[13]); moves.Add(Move.allMoves[14]); moves.Add(Move.allMoves[15]); moves.Add(Move.allMoves[11]); moves.Add(Move.allMoves[9]); moves.Add(Move.allMoves[8]); multiplier = 1.8f; break; } this.maxHP = (int)Math.Round((float)this.maxHP * multiplier); this.ATK = (int)Math.Round((float)this.ATK * multiplier); this.DEF = (int)Math.Round((float)this.DEF * multiplier); this.AGI = (int)Math.Round((float)this.AGI * multiplier); this.SPC = (int)Math.Round((float)this.SPC * multiplier); ApplyTraits(); } //----------------------- Constructor - Serialization ------------------------- public Creature(byte[] serialization) { this.moves = new List(); this.traits = new List(); MemoryStream ms = new MemoryStream(serialization); this.version = ms.ReadByte(); //Length of name (1 byte) int namelength = ms.ReadByte(); //Length of code (1 byte) int codelength = ms.ReadByte(); //Length of owner (1 byte) int ownerlength = ms.ReadByte(); //Number of moves (1 byte) int numMoves = ms.ReadByte(); //Number of traits (2 bytes) int numTraits = TwoBytes(ms.ReadByte(), ms.ReadByte()); //Name byte[] buffer = new byte[namelength]; ms.Read(buffer, 0, namelength); this.name = Encoding.ASCII.GetString(buffer); //Code buffer = new byte[codelength]; ms.Read(buffer, 0, codelength); this.code = Encoding.ASCII.GetString(buffer); //Owner buffer = new byte[ownerlength]; ms.Read(buffer, 0, ownerlength); this.owner = Encoding.ASCII.GetString(buffer); //Moves (2 bytes each) for (int i = 0; i < numMoves; i++) { this.moves.Add(Move.allMoves[TwoBytes(ms.ReadByte(), ms.ReadByte())]); } //Traits (2 bytes each) for (int i = 0; i < numTraits; i++) { this.traits.Add(Trait.allTraits[TwoBytes(ms.ReadByte(), ms.ReadByte())]); } //Base HP (2 bytes) this.maxHP = TwoBytes(ms.ReadByte(), ms.ReadByte()); this.HP = this.maxHP; //Base ATK (2 bytes) this.ATK = TwoBytes(ms.ReadByte(), ms.ReadByte()); //Base DEF (2 bytes) this.DEF = TwoBytes(ms.ReadByte(), ms.ReadByte()); //Base SPC (2 bytes) this.SPC = TwoBytes(ms.ReadByte(), ms.ReadByte()); //Base AGI (2 bytes) this.AGI = TwoBytes(ms.ReadByte(), ms.ReadByte()); //EXP (4 bytes) this.EXP = FourBytes(ms.ReadByte(), ms.ReadByte(), ms.ReadByte(), ms.ReadByte()); //TOTAL EXP (4 bytes) this.totalEXP = FourBytes(ms.ReadByte(), ms.ReadByte(), ms.ReadByte(), ms.ReadByte()); //Element (1 byte) int el = ms.ReadByte(); switch (el) { case 0: this.element = Element.NORMAL; break; case 1: this.element = Element.FIRE; break; case 2: this.element = Element.WATER; break; case 3: this.element = Element.GRASS; break; case 4: this.element = Element.LIGHT; break; case 5: this.element = Element.DARK; break; } //Ignore the rest of the data, it's not interesting ApplyTraits(); } public static int TwoBytes(int byte1, int byte2) { byte1 = (byte)byte1; byte2 = (byte)byte2; return byte1 * 256 + byte2; } public static int FourBytes(int byte1, int byte2, int byte3, int byte4) { byte1 = (byte)byte1; byte2 = (byte)byte2; byte4 = (byte)byte4; byte3 = (byte)byte3; return byte1 * 256 * 256 * 256 + byte2 * 256 * 256 + byte3 * 256 + byte4; } //-------------------------------- public void ApplyTraits() { this.element = Element.NORMAL; for (int i = 0; i < traits.Count; i++) { traits[i].ApplyTrait(this); } } public Sprite CreateSprite(int x, int y) { LayeredSprite sprite = SpriteEngine.CreateLayeredSprite(new Sprite[] { }, new string[] { }, x, y); if (artificial) { sprite.AddLayer("body", new Sprite(SpriteEngine.textures[this.name], new Vector2(x, y))); //spriteParts.Add(SpriteEngine.CreateSprite(this.name, x, y, 1f)); } else { string body = "round"; if (this.HasTrait(6)) body = "round"; if (this.HasTrait(7)) body = "normalround"; if (this.HasTrait(8)) body = "smallarmor"; if (this.HasTrait(9)) body = "armor"; if (this.HasTrait(10)) body = "tiny"; if (this.HasTrait(11)) body = "large"; sprite.AddLayer("body", new Sprite(SpriteEngine.textures[body], new Vector2(x, y))); //spriteParts.Add(SpriteEngine.CreateSprite("DUMMY", x, y, 1f)); } //LayeredSprite sprite = SpriteEngine.CreateLayeredSprite(spriteParts.ToArray(), spritePartNames.ToArray(), x, y); switch (element) { case Element.FIRE: sprite.GetLayer("body").sprite.color = Color.Red; break; case Element.WATER: sprite.GetLayer("body").sprite.color = Color.Aqua; break; case Element.GRASS: sprite.GetLayer("body").sprite.color = Color.LightGreen; break; case Element.LIGHT: sprite.AddLayer("light", new Sprite(SpriteEngine.textures["light"], sprite.position)); break; case Element.DARK: sprite.GetLayer("body").sprite.color = Color.DarkGray; break; } return sprite; } public int GetMaxHP() { float tempStat = maxHP; for (int i = 0; i < traits.Count; i++) { tempStat *= traits[i].HPChange; } return (int)Math.Floor(tempStat); } public int GetATK() { float tempStat = ATK; for (int i = 0; i < traits.Count; i++) { tempStat *= traits[i].ATKChange; } return (int)Math.Floor(tempStat); } public int GetDEF() { float tempStat = DEF; for (int i = 0; i < traits.Count; i++) { tempStat *= traits[i].DEFChange; } return (int)Math.Floor(tempStat); } public int GetSPC() { float tempStat = SPC; for (int i = 0; i < traits.Count; i++) { tempStat *= traits[i].SPCChange; } return (int)Math.Floor(tempStat); } public int GetAGI() { float tempStat = AGI; for (int i = 0; i < traits.Count; i++) { tempStat *= traits[i].AGIChange; } return (int)Math.Floor(tempStat); } //Parameter is power rating of opponent, not amount of XP gained public int GainExperience(int powerRating) { float baseGain = (float)powerRating / (float)this.totalEXP * 25; int expGain = (int)Math.Ceiling(baseGain); this.EXP += expGain; this.totalEXP += expGain; return expGain; } public bool LearnMove(Move move) { if (this.moves.Count < 8) { this.moves.Add(move); return true; } else return false; } public void LearnTrait(Trait trait) { int toRemove = -1; for (int i = 0; i < traits.Count; i++) { if (traits[i].group == trait.group) toRemove = i; } if(toRemove != -1) traits.RemoveAt(toRemove); traits.Add(trait); ApplyTraits(); } public bool HasTrait(int number) { for (int i = 0; i < traits.Count; i++) { if (traits[i].type == number) return true; } return false; } public void FullHeal() { this.HP = GetMaxHP(); for (int i = 0; i < moves.Count; i++) { Move move = moves[i]; move.pp = move.maxPP; moves[i] = move; } } public byte[] Serialize() { List toReturn = new List(); toReturn.Add((byte)VERSION); //Length of pass (1 byte) toReturn.Add((byte)pass.Length); //Length of name (1 byte) toReturn.Add((byte)name.Length); //Length of code (1 byte) toReturn.Add((byte)code.Length); //Lenght of owner (1 byte) toReturn.Add((byte)owner.Length); //Number of moves (1 byte) toReturn.Add((byte)moves.Count); //Number of traits (2 bytes) byte[] tr = toTwoBytes(traits.Count); toReturn.Add(tr[0]); toReturn.Add(tr[1]); //Pass for (int i = 0; i < pass.Length; i++) { toReturn.Add(pass[i]); } //Name tr = Encoding.ASCII.GetBytes(name); for (int i = 0; i < name.Length; i++) { toReturn.Add(tr[i]); } //Code tr = Encoding.ASCII.GetBytes(code); for (int i = 0; i < code.Length; i++) { toReturn.Add(tr[i]); } //Owner tr = Encoding.ASCII.GetBytes(owner); for (int i = 0; i < owner.Length; i++) { toReturn.Add(tr[i]); } //Moves (2 bytes each) for(int i = 0; i < moves.Count; i++) { tr = toTwoBytes(moves[i].type); toReturn.Add(tr[0]); toReturn.Add(tr[1]); } //Traits (2 bytes each) for (int i = 0; i < traits.Count; i++) { tr = toTwoBytes(traits[i].type); toReturn.Add(tr[0]); toReturn.Add(tr[1]); } //Base HP (2 bytes) tr = toTwoBytes(maxHP); toReturn.Add(tr[0]); toReturn.Add(tr[1]); //Base ATK (2 bytes) tr = toTwoBytes(ATK); toReturn.Add(tr[0]); toReturn.Add(tr[1]); //Base DEF (2 bytes) tr = toTwoBytes(DEF); toReturn.Add(tr[0]); toReturn.Add(tr[1]); //Base SPC (2 bytes) tr = toTwoBytes(SPC); toReturn.Add(tr[0]); toReturn.Add(tr[1]); //Base AGI (2 bytes) tr = toTwoBytes(AGI); toReturn.Add(tr[0]); toReturn.Add(tr[1]); //EXP (4 bytes) tr = toFourBytes(EXP); toReturn.Add(tr[0]); toReturn.Add(tr[1]); toReturn.Add(tr[2]); toReturn.Add(tr[3]); //TOTAL EXP (4 bytes) tr = toFourBytes(totalEXP); toReturn.Add(tr[0]); toReturn.Add(tr[1]); toReturn.Add(tr[2]); toReturn.Add(tr[3]); //Element (1 byte) byte el = 0; switch (element) { case Element.NORMAL: el = 0; break; case Element.FIRE: el = 1; break; case Element.WATER: el = 2; break; case Element.GRASS: el = 3; break; case Element.LIGHT: el = 4; break; case Element.DARK: el = 5; break; } toReturn.Add(el); //HP (2 bytes) tr = toTwoBytes(GetMaxHP()); toReturn.Add(tr[0]); toReturn.Add(tr[1]); //ATK (2 bytes) tr = toTwoBytes(GetATK()); toReturn.Add(tr[0]); toReturn.Add(tr[1]); //DEF (2 bytes) tr = toTwoBytes(GetDEF()); toReturn.Add(tr[0]); toReturn.Add(tr[1]); //SPC (2 bytes) tr = toTwoBytes(GetSPC()); toReturn.Add(tr[0]); toReturn.Add(tr[1]); //AGI (2 bytes) tr = toTwoBytes(GetAGI()); toReturn.Add(tr[0]); toReturn.Add(tr[1]); return toReturn.ToArray(); } public byte[] toTwoBytes(int source) { byte[] toReturn = new byte[2]; toReturn[0] = (byte)Math.Floor((float)source / 256f); toReturn[1] = (byte)(source - toReturn[0] * 256); return toReturn; } public byte[] toFourBytes(int source) { byte[] toReturn = new byte[4]; toReturn[0] = (byte)Math.Floor((float)source / (float)(256 * 256 * 256)); source -= toReturn[0] * 256 * 256 * 256; toReturn[1] = (byte)Math.Floor((float)source / (float)(256 * 256)); source -= toReturn[1] * 256 * 256; toReturn[2] = (byte)Math.Floor((float)source / 256f); toReturn[3] = (byte)(source - toReturn[0] * 256); return toReturn; } } }