/// <summary>Samples the attributes to apply to the item.</summary> /// <param name="manager">The manager.</param> /// <param name="cellCenter">The center of the cell for which the sun system is created.</param> /// <param name="random">The randomizer to use.</param> /// <return>The entity with the attributes applied.</return> public void SampleSunSystem(IManager manager, FarPosition cellCenter, IUniformRandom random) { var sun = FactoryLibrary.SampleSun(manager, _sun, cellCenter, random); if (_planets != null) { _planets.Sample(manager, sun, random); } }
/// <summary>Samples the attributes to apply to the item.</summary> /// <param name="manager"> </param> /// <param name="faction">The faction the ship belongs to.</param> /// <param name="position">The position at which to spawn the ship.</param> /// <param name="random">The randomizer to use.</param> /// <return>The entity with the attributes applied.</return> public int Sample(IManager manager, Factions faction, FarPosition position, IUniformRandom random) { var entity = CreateShip(manager, faction, position); // Create initial equipment. var equipment = (ItemSlot)manager.GetComponent(entity, ItemSlot.TypeId); equipment.Item = FactoryLibrary.SampleItem(manager, _items.Name, position, random); if (equipment.Item > 0) { foreach (var item in _items.Slots) { SampleItems(manager, position, random, equipment.Item, item); } } // Add our attributes. var attributes = (Attributes <AttributeType>)manager.GetComponent(entity, Attributes <AttributeType> .TypeId); foreach (var attribute in _attributes) { var modifier = attribute.SampleAttributeModifier(random); if (modifier.ComputationType == AttributeComputationType.Multiplicative) { throw new InvalidOperationException("Base attributes must be additive."); } attributes.SetBaseValue(modifier.Type, modifier.Value); } // Fill up our values. var health = ((Health)manager.GetComponent(entity, Health.TypeId)); var energy = ((Energy)manager.GetComponent(entity, Energy.TypeId)); health.Value = health.MaxValue; energy.Value = energy.MaxValue; // Add experience points if we're worth any. if (_xp > 0) { manager.AddComponent <ExperiencePoints>(entity).Initialize(_xp); } return(entity); }
/// <summary>Samples the items for the specified item info and children (recursively).</summary> /// <param name="manager">The manager.</param> /// <param name="position">The position.</param> /// <param name="random">The random.</param> /// <param name="parent">The parent.</param> /// <param name="itemInfo">The item info.</param> private static void SampleItems( IManager manager, FarPosition position, IUniformRandom random, int parent, ItemInfo itemInfo) { // Create the actual item. var itemId = FactoryLibrary.SampleItem(manager, itemInfo.Name, position, random); if (itemId < 1) { // No such item. return; } var item = (Item)manager.GetComponent(itemId, Item.TypeId); // Then equip it in the parent. foreach (ItemSlot slot in manager.GetComponents(parent, ItemSlot.TypeId)) { if (slot.Item == 0 && slot.Validate(item)) { // Found a suitable empty slot, equip here. slot.Item = itemId; // Recurse to generate children. foreach (var childInfo in itemInfo.Slots) { SampleItems(manager, position, random, itemId, childInfo); } // Done. return; } } // If we get here we couldn't find a slot to equip the item in. manager.RemoveEntity(itemId); Logger.Warn("Parent item did not have a slot for the requested child item."); }
/// <summary> /// Samples the specified number of attributes from the list of available attributes in the specified attribute /// pools. /// </summary> /// <param name="count">The number of attributes to sample.</param> /// <param name="random">The randomizer to use.</param> protected IEnumerable <AttributeModifier <AttributeType> > SampleAttributes(int count, IUniformRandom random) { if (count <= 0) { yield break; } // Get the cumulative weights, and figure out how many attributes // there are, so we don't have to resize our list of all attributes // while adding them. var summedWeights = 0; var attributeCount = 0; for (var i = 0; i < _additionalAttributes.Length; i++) { var pool = FactoryLibrary.GetAttributePool(_additionalAttributes[i]); attributeCount += pool.Attributes.Length; summedWeights += pool.Attributes.Sum(attribute => attribute.Weight); } // Get the actual list of available attributes. var attributes = new List <AttributePool.AttributeInfo>(attributeCount); for (var i = 0; i < _additionalAttributes.Length; i++) { attributes.AddRange(FactoryLibrary.GetAttributePool(_additionalAttributes[i]).Attributes); } // Sample some attributes! Make sure we always have some (may // remove some, if they may not be re-used). for (var i = 0; i < count && attributes.Count > 0; i++) { // Regarding the following... // Assume we have 5 attributes, when concatenating their // weights on an interval that might look like so: // |--|----|--|-|---------| // where one '-' represents one weight (i.e. '--' == 2). // Now, when sampling we multiply a uniform random value // with the sum of those weights, meaning that number // falls somewhere in that interval. What we need to do // then, is to figure out into which sub-interval it is, // meaning which attribute is to be picked. We do this by // starting with the left interval, moving to the right // and subtracting the weight of the current interval until // the remaining rolled value becomes negative, in which // case we it fell into the last one. (equal zero does // not count, because the roll is at max weight - 1, // because 0 counts for the first interval). // Note that the list does *not* have to be sorted for // this, because each point on the interval is equally // likely to be hit! // Get a random number determining the attribute we want. var roll = (int)(random.NextDouble() * summedWeights); // Figure out the interval, starting with the first. var j = 0; while (roll >= 0) { roll -= attributes[j].Weight; ++j; } // Get the attribute that was sampled. var attribute = attributes[j]; // Sample it! yield return(attribute.Attribute.SampleAttributeModifier(random)); // If the attribute may not be reused, remove it from our list. if (!attribute.AllowRedraw) { attributes.RemoveAt(j); summedWeights -= attribute.Weight; } } }