/// <inheritdoc/> /// <exception cref="ArgumentNullException">Thrown if <paramref name="modUniqueId"/> or <paramref name="animal"/> is <see langword="null"/>.</exception> public void AddAnimal(string modUniqueId, ParsedCustomAnimal animal, SoundEffect customSound) { // validate if (modUniqueId == null) { throw new ArgumentNullException(nameof(modUniqueId)); } if (animal == null) { throw new ArgumentNullException(nameof(animal)); } var internalAnimalName = $"{modUniqueId}.{animal.Name}"; if (ModEntry.Instance.Api.GetAnimalByInternalName(internalAnimalName) != null) { ModEntry.Instance.Monitor.Log($"An animal with the internal name: {internalAnimalName} already exists", LogLevel.Error); return; } if (animal.Subtypes == null || animal.Subtypes.Count == 0) { ModEntry.Instance.Monitor.Log($"Cannot create animal: {internalAnimalName} as there was no subtypes", LogLevel.Error); return; } if (animal.Action != Action.Add) { ModEntry.Instance.Monitor.Log($"Tried to add an animal that had an action other then 'Add'", LogLevel.Error); return; } // ensure animal info is valid if the animal is buyable if ((animal.IsBuyable ?? true) && (animal.AnimalShopInfo == null || animal.AnimalShopInfo.BuyPrice <= 0 || string.IsNullOrEmpty(animal.AnimalShopInfo.Description))) { ModEntry.Instance.Monitor.Log($"Animal: {animal.Name} is set to buyable but the shop info is invalid", LogLevel.Error); animal.IsBuyable = false; } // convert objects var animalShopInfo = new AnimalShopInfo(animal.AnimalShopInfo?.Description, animal.AnimalShopInfo?.BuyPrice ?? -1); var animalTypes = new List <CustomAnimalType>(); foreach (var subtype in animal.Subtypes) { var internalSubtypeName = $"{modUniqueId}.{subtype.Name}"; AddSubtype(internalAnimalName, internalSubtypeName, subtype, animalTypes); } if (animalTypes.Count == 0) { ModEntry.Instance.Monitor.Log($"Cannot create animal: {internalAnimalName} as there were no valid subtypes", LogLevel.Error); return; } ModEntry.Instance.CustomAnimals.Add(new CustomAnimal(internalAnimalName, animal.Name, animal.IsBuyable ?? true, animal.CanSwim ?? false, animalShopInfo, animalTypes, customSound, animal.Buildings)); return; }
/// <inheritdoc/> /// <exception cref="ArgumentNullException">Thrown if <paramref name="modUniqueId"/> or <paramref name="animal"/> is <see langword="null"/>.</exception> public void EditAnimal(string modUniqueId, ParsedCustomAnimal animal, SoundEffect customSound) { // validate if (modUniqueId == null) { throw new ArgumentNullException(nameof(modUniqueId)); } if (animal == null) { throw new ArgumentNullException(nameof(animal)); } if (string.IsNullOrEmpty(animal.InternalName)) { ModEntry.Instance.Monitor.Log($"Cannot edit animal: {animal.Name} as no internal name was specified", LogLevel.Error); return; } if (animal.Action != Action.Edit) { ModEntry.Instance.Monitor.Log($"Tried to edit an animal that had an action other then 'Edit'", LogLevel.Error); return; } var animalToEdit = ModEntry.Instance.Api.GetAnimalByInternalName(animal.InternalName); if (animalToEdit == null) { ModEntry.Instance.Monitor.Log($"No animal could be found with the internal name of: {animal.InternalName}", LogLevel.Error); return; } // apply edits to the copy of the animal animalToEdit.AnimalShopInfo.BuyPrice = (animal.AnimalShopInfo?.BuyPrice > 0) ? animal.AnimalShopInfo.BuyPrice : animalToEdit.AnimalShopInfo?.BuyPrice ?? 0; animalToEdit.AnimalShopInfo.Description = animal.AnimalShopInfo?.Description ?? animalToEdit.AnimalShopInfo?.Description; animalToEdit.Name = animal.Name ?? animalToEdit.Name; if (animal.IsBuyable.HasValue) { animalToEdit.IsBuyable = animal.IsBuyable.Value && animalToEdit.AnimalShopInfo?.BuyPrice > 0; } animalToEdit.CanSwim = animal.CanSwim ?? animalToEdit.CanSwim; animalToEdit.CustomSound = customSound ?? animalToEdit.CustomSound; animalToEdit.Buildings = animal.Buildings ?? animalToEdit.Buildings; // order the subtypes by action first (so they get added first, then edited, then deleted) var subtypeEdits = animal.Subtypes.OrderBy(subtype => subtype.Action); foreach (var subtype in subtypeEdits) { switch (subtype.Action) { case (Action.Add): AddSubtype(animal.InternalName, $"{modUniqueId}.{subtype.Name}", subtype, animalToEdit.Subtypes); break; case (Action.Edit): EditSubtype(animal.InternalName, subtype.InternalName, subtype); break; case (Action.Delete): DeleteSubtype(animal.InternalName, subtype.InternalName); break; default: ModEntry.Instance.Monitor.Log($"Action: {subtype.Action} on animal: {animal.InternalName} subtype: {subtype.InternalName} is invalid", LogLevel.Error); break; } } }