internal void SetInventory(string v) { if (Locked) { throw new InvalidOperationException("This MonsterType is locked and cannot be altered."); } var enclosingChars = new Dictionary <char, char> { { CipParser.CloseCurly, CipParser.OpenCurly }, { CipParser.CloseParenthesis, CipParser.OpenParenthesis } }; var enclosures = CipParser.GetEnclosedButPreserveQuoted(v, enclosingChars); foreach (var enclosure in enclosures) { var inventoryParams = enclosure.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); if (!inventoryParams.Any()) { continue; } if (inventoryParams.Length != 3) { throw new InvalidDataException($"Unexpected number of elements in inventory line {v} on monster type {Name}."); } InventoryComposition.Add(new Tuple <ushort, byte, ushort>(Convert.ToUInt16(inventoryParams[0]), Convert.ToByte(inventoryParams[1]), Convert.ToUInt16(inventoryParams[2]))); } }
internal void SetPhrases(string v) { if (Locked) { throw new InvalidOperationException("This MonsterType is locked and cannot be altered."); } Phrases.AddRange(CipParser.SplitByTokenPreserveQuoted(v, ',')); }
internal void SetSkills(string v) { if (Locked) { throw new InvalidOperationException("This MonsterType is locked and cannot be altered."); } var enclosingChars = new Dictionary <char, char> { { CipParser.CloseCurly, CipParser.OpenCurly }, { CipParser.CloseParenthesis, CipParser.OpenParenthesis } }; var enclosures = CipParser.GetEnclosedButPreserveQuoted(v, enclosingChars); foreach (var enclosure in enclosures) { var skillParams = enclosure.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); if (!skillParams.Any()) { continue; } if (skillParams.Length != 7) { throw new InvalidDataException($"Unexpected number of elements in skill line {v} on monster type {Name}."); } MonsterSkill mSkill; if (!Enum.TryParse(skillParams[0].ToUpper(), out mSkill)) { continue; } switch (mSkill) { case MonsterSkill.HITPOINTS: MaxHitPoints = Convert.ToUInt32(skillParams[1]); break; case MonsterSkill.GOSTRENGTH: try { Speed = Convert.ToUInt16(skillParams[1]); } catch { // TODO: handle -1 here... } break; case MonsterSkill.CARRYSTRENGTH: Capacity = Convert.ToUInt16(skillParams[1]); break; case MonsterSkill.FISTFIGHTING: var fistLevel = Convert.ToUInt16(skillParams[1]); if (fistLevel > 0) { Skills[SkillType.Fist] = new Skill(SkillType.Fist, fistLevel, 1.00, 1, fistLevel, (ushort)(fistLevel * 2)); } break; case MonsterSkill.AXEFIGHTING: var axeLevel = Convert.ToUInt16(skillParams[1]); if (axeLevel > 0) { Skills[SkillType.Fist] = new Skill(SkillType.Fist, axeLevel, 1.00, 1, axeLevel, (ushort)(axeLevel * 2)); } break; case MonsterSkill.SWORDFIGHTING: var swordLevel = Convert.ToUInt16(skillParams[1]); if (swordLevel > 0) { Skills[SkillType.Fist] = new Skill(SkillType.Fist, swordLevel, 1.00, 1, swordLevel, (ushort)(swordLevel * 2)); } break; case MonsterSkill.CLUBFIGHTING: var clubLevel = Convert.ToUInt16(skillParams[1]); if (clubLevel > 0) { Skills[SkillType.Fist] = new Skill(SkillType.Fist, clubLevel, 1.00, 1, clubLevel, (ushort)(clubLevel * 2)); } break; } } }
public Dictionary <ushort, ItemType> Load(string objectsFileName) { if (string.IsNullOrWhiteSpace(objectsFileName)) { throw new ArgumentNullException(nameof(objectsFileName)); } var itemDictionary = new Dictionary <ushort, ItemType>(); var objectsFilePath = "COMMO.Server.Data." + ServerConfiguration.DataFilesDirectory + "." + objectsFileName; var assembly = Assembly.GetExecutingAssembly(); using (var stream = assembly.GetManifestResourceStream(objectsFilePath)) { if (stream == null) { throw new Exception($"Failed to load {objectsFilePath}."); } using (var reader = new StreamReader(stream)) { var current = new ItemType(); foreach (var readLine in reader.ReadToEnd().Split("\r\n".ToCharArray())) { if (readLine == null) { continue; } var inLine = readLine.Split(new[] { CommentSymbol }, 2).FirstOrDefault(); // ignore comments and empty lines. if (string.IsNullOrWhiteSpace(inLine)) { // wrap up the current ItemType and add it if it has enought properties set: if (current.TypeId == 0 || string.IsNullOrWhiteSpace(current.Name)) { continue; } current.LockChanges(); itemDictionary.Add(current.TypeId, current); current = new ItemType(); continue; } var data = inLine.Split(new[] { PropertyValueSeparator }, 2); if (data.Length != 2) { throw new Exception($"Malformed line [{inLine}] in objects file: [{objectsFilePath}]"); } var propName = data[0].ToLower().Trim(); var propData = data[1].Trim(); switch (propName) { case "typeid": current.SetId(Convert.ToUInt16(propData)); break; case "name": current.SetName(propData.Substring(Math.Min(1, propData.Length), Math.Max(0, propData.Length - 2))); break; case "description": current.SetDescription(propData); break; case "flags": foreach (var element in CipParser.Parse(propData)) { var flagName = element.Attributes.FirstOrDefault()?.Name; if (Enum.TryParse(flagName, out ItemFlag flagMatch)) { current.SetFlag(flagMatch); } else { // TODO: proper logging. Console.WriteLine($"Unknown flag [{flagName}] found on item with TypeID [{current.TypeId}]."); } } break; case "attributes": foreach (var attrStr in propData.Substring(Math.Min(1, propData.Length), Math.Max(0, propData.Length - 2)).Split(',')) { var attrPair = attrStr.Split('='); if (attrPair.Length != 2) { throw new InvalidDataException($"Invalid attribute {attrStr}."); } current.SetAttribute(attrPair[0], Convert.ToInt32(attrPair[1])); } break; } } // wrap up the last ItemType and add it if it has enought properties set: if (current.TypeId != 0 && string.IsNullOrWhiteSpace(current.Name)) { current.LockChanges(); itemDictionary.Add(current.TypeId, current); } } } return(itemDictionary); }