// Functions public bool ReadMonster(string filename, out Monster monster) { XmlSerializer serializer = new XmlSerializer(typeof(TFSXmlMonster)); serializer.UnknownNode += new XmlNodeEventHandler(serializer_UnknownNode); serializer.UnknownAttribute += new XmlAttributeEventHandler(serializer_UnknownAttribute); // A FileStream is needed to read the XML document. FileStream fs = new FileStream(filename, FileMode.Open); // Use the Deserialize method to restore the object's state with data from the XML document. TFSXmlMonster tfsMonster = (TFSXmlMonster)serializer.Deserialize(fs); // convert from xml monster classes to generic class xmlToGeneric(tfsMonster, out monster); monster.FileName = Path.GetFileNameWithoutExtension(filename); return(true); }
private void xmlToGeneric(TFSXmlMonster tfsMonster, out Monster monster) { monster = new Monster() { Name = tfsMonster.name, Health = (uint)tfsMonster.health.max, Experience = (uint)tfsMonster.experience, Speed = (uint)tfsMonster.speed, Race = tfsToGenericBlood(tfsMonster.race), }; if (!string.IsNullOrEmpty(tfsMonster.nameDescription)) { monster.Description = tfsMonster.nameDescription; } if (!string.IsNullOrEmpty(tfsMonster.namedescription)) { monster.Description = tfsMonster.namedescription; } if (tfsMonster.targetchange != null) { monster.RetargetChance = (uint)tfsMonster.targetchange.chance; if ((tfsMonster.targetchange.interval != 0) && (tfsMonster.targetchange.speed == 0)) { monster.RetargetInterval = (uint)tfsMonster.targetchange.interval; } else if ((tfsMonster.targetchange.interval == 0) && (tfsMonster.targetchange.speed != 0)) { monster.RetargetInterval = (uint)tfsMonster.targetchange.speed; } else if ((tfsMonster.targetchange.interval != 0) && (tfsMonster.targetchange.speed != 0)) { System.Diagnostics.Debug.WriteLine("Warning duplicate target speed and target interval"); } } if (tfsMonster.look != null) { monster.CorpseId = (uint)tfsMonster.look.corpse; monster.OutfitIdLookType = (uint)tfsMonster.look.type; monster.LookTypeDetails = new DetailedLookType() { Head = (ushort)tfsMonster.look.head, Body = (ushort)tfsMonster.look.body, Legs = (ushort)tfsMonster.look.legs, Feet = (ushort)tfsMonster.look.feet, Addons = (ushort)tfsMonster.look.addons, Mount = (ushort)tfsMonster.look.mount }; monster.ItemIdLookType = (uint)tfsMonster.look.typeex; } // attack strategies if (tfsMonster.targetstrategies != null) { monster.AttackMinHealthPercent = tfsMonster.targetstrategies.health; monster.AttackMostDamagePercent = tfsMonster.targetstrategies.damage; monster.AttackNearestPercent = tfsMonster.targetstrategies.nearest; monster.AttackRandomPercent = tfsMonster.targetstrategies.random; } // flags if ((tfsMonster.flags != null) && (tfsMonster.flags.flag != null)) { foreach (var x in tfsMonster.flags.flag) { int value; if (int.TryParse(x.attr[0].Value, out value)) { if (x.attr[0].Name == "summonable") { monster.SummonCost = (uint)tfsMonster.manacost; } else if (x.attr[0].Name == "attackable") { monster.Attackable = value == 1; } else if (x.attr[0].Name == "hostile") { monster.Hostile = value == 1; } else if (x.attr[0].Name == "illusionable") { monster.Illusionable = value == 1; } else if (x.attr[0].Name == "convinceable") { monster.ConvinceCost = (uint)tfsMonster.manacost; } else if (x.attr[0].Name == "pushable") { monster.Pushable = value == 1; } else if (x.attr[0].Name == "canpushitems") { monster.PushItems = value == 1; } else if (x.attr[0].Name == "canpushcreatures") { monster.PushCreatures = value == 1; } else if (x.attr[0].Name == "targetdistance") { monster.TargetDistance = (uint)value; } else if (x.attr[0].Name == "staticattack") { monster.StaticAttack = (uint)value; } else if (x.attr[0].Name == "lightlevel") { monster.LightLevel = (uint)value; } else if (x.attr[0].Name == "lightcolor") { monster.LightColor = (uint)value; } else if (x.attr[0].Name == "runonhealth") { monster.RunOnHealth = (uint)value; } else if (x.attr[0].Name == "hidehealth") { monster.HideHealth = value == 1; } else if (x.attr[0].Name == "canwalkonenergy") { monster.AvoidEnergy = value != 1; } else if (x.attr[0].Name == "canwalkonfire") { monster.AvoidFire = value != 1; } else if (x.attr[0].Name == "canwalkonpoison") { monster.AvoidPoison = value != 1; } else if (x.attr[0].Name == "isboss") { monster.IsBoss = value == 1; } else { Console.WriteLine($"Unknown name {x.attr[0].Name}"); } } } } // sounds if ((tfsMonster.voices != null) && (tfsMonster.voices.voice != null)) { foreach (VoiceXml sound in tfsMonster.voices.voice) { Voice voice = new Voice(); voice.Sound = sound.sentence; if (!(string.IsNullOrEmpty(sound.yell)) && ((sound.yell == "1") || (sound.yell == "true"))) { voice.SoundLevel = SoundLevel.Yell; } else { voice.SoundLevel = SoundLevel.Say; } monster.Voices.Add(voice); } } // summons if (tfsMonster.summons != null) { monster.MaxSummons = (uint)tfsMonster.summons.maxSummons; foreach (TFSXmlSummon summon in tfsMonster.summons.summon) { monster.Summons.Add(new Summon() { Name = summon.name, Chance = Math.Min(1, (double)summon.chance / 100), Rate = (uint)((summon.interval > 0) ? summon.interval : summon.speed), Max = summon.max, Force = summon.force }); } } else { monster.MaxSummons = 0; } if (tfsMonster.attacks != null) { XmlSpellsToGeneric(ref monster, tfsMonster.attacks.attack, SpellCategory.Offensive); } // Defenses if (tfsMonster.defenses != null) { monster.TotalArmor = tfsMonster.defenses.armor; monster.Shielding = tfsMonster.defenses.defense; XmlSpellsToGeneric(ref monster, tfsMonster.defenses.defenses, SpellCategory.Defensive); } #region parseElements if ((tfsMonster.elements != null) && (tfsMonster.elements.element != null)) { foreach (var x in tfsMonster.elements.element) { int value; if (int.TryParse(x.attr[0].Value, out value)) { if (x.attr[0].Name == "physicalPercent") { monster.Physical = tfstoGenericElementalPercent(value); } else if (x.attr[0].Name == "icePercent") { monster.Ice = tfstoGenericElementalPercent(value); } else if (x.attr[0].Name == "poisonPercent") { monster.Earth = tfstoGenericElementalPercent(value); } else if (x.attr[0].Name == "earthPercent") { monster.Earth = tfstoGenericElementalPercent(value); } else if (x.attr[0].Name == "firePercent") { monster.Fire = tfstoGenericElementalPercent(value); } else if (x.attr[0].Name == "energyPercent") { monster.Energy = tfstoGenericElementalPercent(value); } else if (x.attr[0].Name == "holyPercent") { monster.Holy = tfstoGenericElementalPercent(value); } else if (x.attr[0].Name == "deathPercent") { monster.Death = tfstoGenericElementalPercent(value); } else if (x.attr[0].Name == "drownPercent") { monster.Drown = tfstoGenericElementalPercent(value); } else if (x.attr[0].Name == "lifedrainPercent") { monster.LifeDrain = tfstoGenericElementalPercent(value); } else if (x.attr[0].Name == "manadrainPercent") { monster.ManaDrain = tfstoGenericElementalPercent(value); } } } } #endregion #region paraseImmunities if ((tfsMonster.immunities != null) && (tfsMonster.immunities.immunity != null)) { foreach (Immunity immunity in tfsMonster.immunities.immunity) { if (immunity.name != namedImmunityXml.NA) { switch (immunity.name) { case namedImmunityXml.physical: monster.Physical = 0; break; case namedImmunityXml.energy: monster.Energy = 0; break; case namedImmunityXml.fire: monster.Fire = 0; break; case namedImmunityXml.poison: //namedImmunityXml.earth monster.Earth = 0; break; case namedImmunityXml.drown: monster.Drown = 0; break; case namedImmunityXml.ice: monster.Ice = 0; break; case namedImmunityXml.holy: monster.Holy = 0; break; case namedImmunityXml.death: monster.Death = 0; break; case namedImmunityXml.lifedrain: monster.LifeDrain = 0; break; case namedImmunityXml.manadrain: monster.ManaDrain = 0; break; case namedImmunityXml.paralyze: monster.IgnoreParalyze = true; break; case namedImmunityXml.outfit: monster.IgnoreOutfit = true; break; case namedImmunityXml.drunk: monster.IgnoreDrunk = true; break; case namedImmunityXml.invisible: //namedImmunityXml.invisibility monster.IgnoreInvisible = true; break; case namedImmunityXml.bleed: monster.IgnoreBleed = true; break; } } else if (immunity.physical != 0) { monster.Physical = 0; } else if (immunity.energy != 0) { monster.Energy = 0; } else if (immunity.fire != 0) { monster.Fire = 0; } else if (immunity.poison != 0) //poison and earth are the same { monster.Earth = 0; } else if (immunity.earth != 0) //poison and earth are the same { monster.Earth = 0; } else if (immunity.drown != 0) { monster.Drown = 0; } else if (immunity.ice != 0) { monster.Ice = 0; } else if (immunity.holy != 0) { monster.Holy = 0; } else if (immunity.death != 0) { monster.Death = 0; } else if (immunity.lifedrain != 0) { monster.LifeDrain = 0; } else if (immunity.manadrain != 0) { monster.ManaDrain = 0; } else if (immunity.paralyze != 0) { monster.IgnoreParalyze = true; } else if (immunity.outfit != 0) { monster.IgnoreOutfit = true; } else if (immunity.bleed != 0) { monster.IgnoreBleed = true; } else if (immunity.drunk != 0) { monster.IgnoreDrunk = true; } else if (immunity.invisible != 0) //invisible and invisibility are the same { monster.IgnoreInvisible = true; } else if (immunity.invisibility != 0) //invisible and invisibility are the same { monster.IgnoreInvisible = true; } } } #endregion // Loot if ((tfsMonster.loot != null) && (tfsMonster.loot.item != null)) { foreach (var item in tfsMonster.loot.item) { string itemType = ""; if (!string.IsNullOrEmpty(item.name)) { itemType = item.name; } else if (item.id > 0) { itemType = item.id.ToString(); } decimal chance = 1; if (item.chance > 0) { chance = item.chance; } else if (item.chance1 > 0) { chance = item.chance1; } chance /= MAX_LOOTCHANCE; Loot commonItem = new Loot() { Item = itemType, Chance = chance, Count = item.countmax }; monster.Items.Add(commonItem); } } }