public Monster(MonsterType monsterType) : base(GetNewId(), monsterType.Name, monsterType.Article, monsterType.MaxHitPoints, monsterType.MaxManaPoints, monsterType.Corpse) { Type = monsterType; Experience = monsterType.Experience; Speed += monsterType.Speed; Outfit = monsterType.Outfit; Inventory = new MonsterInventory(this, monsterType.InventoryComposition); foreach (var kvp in Type.Skills.ToList()) { Type.Skills[kvp.Key] = kvp.Value; } }
Dictionary <ushort, MonsterType> IMonsterLoader.LoadMonsters(string loadFromFile) { if (string.IsNullOrWhiteSpace(loadFromFile)) { throw new ArgumentNullException(nameof(loadFromFile)); } var monsFilePattern = "COMMO.Server.Data." + ServerConfiguration.MonsterFilesDirectory; var assembly = Assembly.GetExecutingAssembly(); var monsterDictionary = new Dictionary <ushort, MonsterType>(); var monsterFilePaths = assembly.GetManifestResourceNames().Where(s => s.Contains(monsFilePattern)); foreach (var monsterFilePath in monsterFilePaths) { using (var stream = assembly.GetManifestResourceStream(monsterFilePath)) { if (stream == null) { throw new Exception($"Failed to load {monsterFilePath}."); } using (var reader = new StreamReader(stream)) { var dataList = new List <Tuple <string, string> >(); var propName = string.Empty; var propData = string.Empty; foreach (var readLine in reader.ReadToEnd().Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)) { var inLine = readLine?.Split(new[] { ObjectsFileItemLoader.CommentSymbol }, 2).FirstOrDefault(); // ignore comments and empty lines. if (string.IsNullOrWhiteSpace(inLine)) { continue; } var data = inLine.Split(new[] { ObjectsFileItemLoader.PropertyValueSeparator }, 2); if (data.Length > 2) { throw new Exception($"Malformed line [{inLine}] in objects file: [{monsterFilePath}]"); } if (data.Length == 1) { // line is a continuation of the last prop. propData += data[0].ToLower().Trim(); } else { if (propName.Length > 0 && propData.Length > 0) { dataList.Add(new Tuple <string, string>(propName, propData)); } propName = data[0].ToLower().Trim(); propData = data[1].Trim(); } } if (propName.Length > 0 && propData.Length > 0) { dataList.Add(new Tuple <string, string>(propName, propData)); } var current = new MonsterType(); foreach (var tuple in dataList) { switch (tuple.Item1) { case "racenumber": current.SetId(Convert.ToUInt16(tuple.Item2)); break; case "name": current.SetName(tuple.Item2.Trim('\"')); break; case "article": current.SetArticle(tuple.Item2.Trim('\"')); break; case "outfit": current.SetOutfit(tuple.Item2.Trim('(', ')')); break; case "corpse": current.SetCorpse(Convert.ToUInt16(tuple.Item2)); break; case "blood": current.SetBlood(tuple.Item2); break; case "experience": current.SetExperience(Convert.ToUInt32(tuple.Item2)); break; case "summoncost": current.SetSummonCost(Convert.ToUInt16(tuple.Item2)); break; case "fleethreshold": current.SetFleeTreshold(Convert.ToUInt16(tuple.Item2)); break; case "attack": current.SetAttack(Convert.ToUInt16(tuple.Item2)); break; case "defend": current.SetDefend(Convert.ToUInt16(tuple.Item2)); break; case "armor": current.SetArmor(Convert.ToUInt16(tuple.Item2)); break; case "poison": current.SetConditionInfect(Convert.ToUInt16(tuple.Item2), ConditionType.Posion); break; case "losetarget": current.SetLoseTarget(Convert.ToByte(tuple.Item2)); break; case "strategy": current.SetStrategy(tuple.Item2.Trim('(', ')')); break; case "flags": current.SetFlags(tuple.Item2.Trim('{', '}')); break; case "skills": current.SetSkills(tuple.Item2.Trim('{', '}')); break; case "spells": current.SetSpells(tuple.Item2.Trim('{', '}')); break; case "inventory": current.SetInventory(tuple.Item2.Trim('{', '}')); break; case "talk": current.SetPhrases(tuple.Item2.Trim('{', '}')); break; } } current.LockChanges(); monsterDictionary.Add(current.RaceId, current); } } } return(monsterDictionary); }