private void OnCreatureCreatedOrProducedItem(EventArgs args)
{
Creature creature;
int itemId;
string skill; // Is there a better way to check for skill match?
CreationEventArgs crargs = args as CreationEventArgs;
ProductionEventArgs prargs = args as ProductionEventArgs;
if (crargs != null) // Try cast as CreationEventArgs
{
creature = crargs.Creature;
itemId = crargs.Item.Info.Id;
skill = crargs.Method.ToString();
}
else if (prargs != null) // Try cast as ProductionEventArgs
{
// Cancel if it wasn't a success
if (!prargs.Success)
return;
creature = prargs.Creature;
itemId = prargs.ProductionData.ItemId; // Use production data in case Item is null
skill = prargs.ProductionData.Category.ToString();
if (skill == "Spinning")
skill = "Weaving"; // Shared SkillId.
}
else // Error: Cannot cast as either one.
{
Log.Exception(new InvalidCastException(String.Format("Unable to cast EventArgs as CreationEventArgs nor ProductionEventArgs (Quest Name: {0}, ID: {1})", this.Name, this.Id)));
return;
}
var quests = creature.Quests.GetAllIncomplete(this.Id);
foreach (var quest in quests)
{
if (!this.CanMakeProgress(creature, quest))
continue;
var progress = quest.CurrentObjectiveOrLast;
if (progress == null) return;
var objective = this.Objectives[progress.Ident];
if (objective == null || objective.Type != ObjectiveType.Create) return;
var createObjective = (objective as QuestObjectiveCreate);
if (!progress.Done && itemId == createObjective.ItemId && skill == createObjective.SkillId.ToString())
{
var done = (++progress.Count == createObjective.Amount);
if (done)
quest.SetDone(progress.Ident);
UpdateQuest(creature, quest);
// Hot-fix for #390, after a creation objective might
// come a collect objective for the finished items,
// the new active objective has to be checked.
// This should happen generally, but some refactoring is
// in order, to not make such a mess out of it.
if (done)
this.CheckCurrentObjective(creature);
}
}
}
}