protected override void OnItemsSpawned(string instanceId, LocationSpawnItemResults <LocationValuablesCollection> result) { if (result.SpawnItem.CollectOptions != null && result.SpawnItem.CollectOptions.CollectRange != null) { m_triggerPool.WatchLocation(GetPoolRequestId(instanceId, result.SourceLocation), result.SourceLocation, () => { ResourceActivationContext ctxt; if (m_activationContexts.TryGetValue(instanceId, out ctxt)) { ctxt.FireEvent("in_range"); } }, result.SpawnItem.CollectOptions.CollectRange); } base.OnItemsSpawned(instanceId, result); }
protected override void OnItemsRemoved(string instanceId, LocationSpawnItemResults <LocationValuablesCollection> result) { m_triggerPool.StopWatching(GetPoolRequestId(instanceId, result.SourceLocation)); base.OnItemsRemoved(instanceId, result); }
void ProcessValuables(IEnumerable <LocationValuablesCollectionItemContainer> locationValuables) { m_perf = new PerfCounters(); m_perf.Start("v"); // Group items by the sets of locations they reference. // The goal here is to reduce the number of locations we visit, ideally as close to 1 // visit per location as possible. SetDictionary <IEnumerable <Location>, LocationValuablesCollectionItemContainer> fixedSets = new SetDictionary <IEnumerable <Location>, LocationValuablesCollectionItemContainer>(); // Location sets per story tag Dictionary <string, IEnumerable <Location> > tagSets = new Dictionary <string, IEnumerable <Location> >(); // Location sets per location type Dictionary <string, IEnumerable <Location> > typeSets = new Dictionary <string, IEnumerable <Location> >(); SetDictionary <string, LocationValuablesCollectionItemContainer> tagLvcs = new SetDictionary <string, LocationValuablesCollectionItemContainer>(); SetDictionary <string, LocationValuablesCollectionItemContainer> typeLvcs = new SetDictionary <string, LocationValuablesCollectionItemContainer>(); foreach (var lvc in locationValuables) { if (lvc.SpawnItem.Locations != null) { fixedSets.Add(lvc.SpawnItem.Locations, lvc); } if (lvc.SpawnItem.LocationTypes != null) { foreach (var type in lvc.SpawnItem.LocationTypes) { if (!typeSets.ContainsKey(type)) { typeSets[type] = LocationCache.Instance.GetLocationsWithType(type); } typeLvcs.Add(type, lvc); } } if (lvc.SpawnItem.StoryTags != null) { foreach (var tag in lvc.SpawnItem.StoryTags) { if (!tagSets.ContainsKey(tag)) { tagSets[tag] = LocationCache.Instance.GetLocationsWithStoryTag(tag); } tagLvcs.Add(tag, lvc); } } } Dictionary <string, Location> processedLocations = new Dictionary <string, Location>(); // Processes the set of locations, optionally creating a union with an existing set Action <IEnumerable <Location>, IEnumerable <LocationValuablesCollectionItemContainer> > processLocations = (locs, lvcsIn) => { m_perf.Start("l"); m_perf.Start("u"); HashSet <LocationValuablesCollectionItemContainer> lvcs = new HashSet <LocationValuablesCollectionItemContainer>(); if (lvcsIn != null) { lvcs.UnionWith(lvcsIn); } m_perf.Stop("u"); m_perf.Start("locs"); if (locs != null) { foreach (var location in locs) { if (!processedLocations.ContainsKey(location.Id)) { processedLocations.Add(location.Id, location); if (location.LocationTypes != null) { foreach (var type in location.LocationTypes) { var tl = typeLvcs[type]; if (tl != null) { lvcs.UnionWith(tl); } } } if (location.StoryTags != null) { foreach (var tag in location.StoryTags) { var tl = tagLvcs[tag]; if (tl != null) { lvcs.UnionWith(tl); } } } m_perf.Start("c"); // Can be smarter here: if LVCs haven't changed, only locations, then // any location that's been checked can be skipped foreach (var lvc in lvcs) { // Have we processed this lvc/location combo recently?? // Note: this currently persists until the resource is deactivated. LocationSpawnItemResults <LocationValuablesCollection> results = null; lock (m_locationComputedItems) { results = GetResults(lvc.ActivationContext.InstanceId, location); if (results != null) { continue; } results = new LocationSpawnItemResults <LocationValuablesCollection>(lvc.ActivationContext.InstanceId, location, lvc.SpawnItem); var prob = lvc.SpawnItem.Probability.GetValueOrDefault(1); var rnd = Tools.RandomDouble(0, 1); if (rnd < prob) { // Tada! results.DidSpawn = true; } AddComputedResult(location, lvc.InstanceId, results); } if (results.DidSpawn) { OnItemsSpawned(lvc.InstanceId, results); } } m_perf.Stop("c"); } else { // TODO: locations re-used } } } m_perf.Stop("locs"); m_perf.Stop("l"); }; foreach (var set in fixedSets.Keys) { processLocations(set, fixedSets[set]); } foreach (var set in tagSets.Values) { processLocations(set, null); } foreach (var set in typeSets.Values) { processLocations(set, null); } /* * m_activationContexts.Add(e.ActivationContext.InstanceId, e.ActivationContext); */ //if (IsRunning) { //AddSpawnItems(e.LocationValuables, null/*e.ActivationContext.GetStorageAgent()*/); } m_perf.Stop("v"); m_logger.Debug("ProcessValuables perf={0}", m_perf.ToShortString()); }
internal LocationSpawnItemDriverEventArgs(LocationSpawnItemResults <T> results) { this.Results = results; }