Inheritance: MonoBehaviour
Ejemplo n.º 1
0
        static List <WeightedItem <T> > GetCumulativeWeightedList <T>(IEnumerable <WeightedItem <T> > items)
        {
            var result = new List <WeightedItem <T> >();

            var relevantItems = items
                                .Where(i => i.Weight > 0)
                                .ToArray();

            if (relevantItems.Length > 0)
            {
                var total = Sum(relevantItems.Select(i => i.Weight));

                uint threshold = 0;
                foreach (var i in relevantItems.Take(relevantItems.Length - 1))
                {
                    threshold += Scale(i.Weight, total);
                    result.Add(WeightedItem.Create(threshold, i.Item));
                }

                var lastItem = relevantItems[relevantItems.Length - 1].Item;
                result.Add(WeightedItem.Create(uint.MaxValue, lastItem));
            }

            return(result);
        }
        internal List <T> Select(int count)
        {
            Validate(count);

            //Create a shallow clone of the our items, because we're going to be removing
            //items from the list in some cases, and we want to preserve the original.
            var Items      = new List <WeightedItem <T> >(WeightedSelector.Items);
            var ResultList = new List <T>();

            do
            {
                WeightedItem <T> Item = null;

                if (WeightedSelector.Options.AllowDuplicates)
                {
                    Item = ExecuteSelect(Items); //Use binary search if we can.
                }
                else
                {
                    //Force linear search, since AllowDuplicates currently breaks binary search.
                    Item = ExecuteSelectWithLinearSearch(Items);
                }


                ResultList.Add(Item.Value);

                if (!WeightedSelector.Options.AllowDuplicates)
                {
                    Items.Remove(Item);
                }
            } while (ResultList.Count < count);

            return(ResultList);
        }
Ejemplo n.º 3
0
    /*
     * Returns a random object from our prefab list
     */
    private GameObject randomPrefab()
    {
        //Finding some random object with probability of the weights
        float sum_of_weights = 0;

        //Summing all the weights
        foreach (WeightedItem i in prefabs)
        {
            sum_of_weights += i.getWeight();
        }
        //Getting a random number between 0 and the sum of the weights
        float rnd = Random.Range(0, sum_of_weights);

        //Returning the random object
        foreach (WeightedItem i in prefabs)
        {
            if (rnd < i.getWeight())
            {
                return(i.getObject());
            }
            rnd -= i.getWeight();
        }

        //If we don't pick anything, just return some random prefab
        //We should never be here, this is just in case
        WeightedItem item = prefabs[Random.Range(0, prefabs.Length)];

        return(item.getObject());
    }
Ejemplo n.º 4
0
 public void CanEquipItemIntoEmptySlot()
 {
     var inventory = new Inventory();
     var item = new WeightedItem { Weight = Weight.Heavy, Name = "hello" };
     inventory.Add(item);
     Assert.True(inventory.Equip(item));
     Assert.Same(inventory.HeavySlotItem, item);
 }
Ejemplo n.º 5
0
 // This method is populating the ListView with WeightedItem objects
 // that have been entered by the user
 private void PopulateAssignments(WeightedItem item)
 {
     RetrieveAssignments();
     if (item != null)
     {
         Assignments.Add(item);
     }
     AssignmentsList.DataSource = Assignments;
     AssignmentsList.DataBind();
 }
Ejemplo n.º 6
0
        public void WeightedAverage_IEnumerableToScalar_FloatProperty_SourceCumulativePercentageToOverflow_NotInfinityReturned()
        {
            IEnumerable <WeightedItem <float> > source = new WeightedItem <float>[] {
                new WeightedItem <float>(float.MaxValue, float.MaxValue),
                new WeightedItem <float>(float.MaxValue, float.MaxValue)
            };


            var result = source.WeightedAverage(x => x.Value, x => x.Weight);

            float.IsPositiveInfinity(result).Should().BeFalse();
        }
Ejemplo n.º 7
0
 public void CanEquipItemIntoTakenSlotIfAutoUnequip()
 {
     var inventory = new Inventory();
     var item1 = new WeightedItem { Weight = Weight.Heavy, Name = "hello1" };
     var item2 = new WeightedItem { Weight = Weight.Heavy, Name = "hello2" };
     inventory.Add(item1);
     inventory.Add(item2);
     Assert.True(inventory.Equip(item1));
     Assert.Same(inventory.HeavySlotItem, item1);
     Assert.True(inventory.Equip(item2));
     Assert.Same(inventory.HeavySlotItem, item2);
 }
Ejemplo n.º 8
0
        // This method handles the list view's OnItemInserting command.
        // That command gets triggered by the linkbutton with the CommandName="Insert"
        protected void AssignmentsList_ItemInserting(object sender, ListViewInsertEventArgs e)
        {
            // Grab the values that were inserted.
            string name    = e.Values[nameof(WeightedItem.AssignmentName)].ToString();
            int    weight  = Convert.ToInt32(e.Values[nameof(WeightedItem.Weight)]);
            var    newItem = new WeightedItem {
                AssignmentName = name, Weight = weight
            };

            // bind the listview with the added information
            PopulateAssignments(newItem);
        }
Ejemplo n.º 9
0
        public Door GetFinishingDoorByTargetBuilding(Door selectedDoor, int targetBuildingId)
        //    TODO: Move this to DoorManager
        {
            List <WeightedItem <Door> > doorList = new List <WeightedItem <Door> >();

            foreach (var possibleDoor in GetBuilding(targetBuildingId).Doors)
            {
                var distance = Vector3.Distance(selectedDoor.transform.position, possibleDoor.transform.position);
                doorList.Add(new WeightedItem <Door>(possibleDoor, Mathf.Pow(1 / distance, 10)));
            }

            return(WeightedItem <Door> .Choose(doorList));
        }
Ejemplo n.º 10
0
        /// <summary>
        ///     Adds a new <see cref="WeightedItem{T}" /> to the selector
        /// </summary>
        /// <param name="item">The item to add</param>
        public void Add(WeightedItem <T> item)
        {
            if (item.Weight <= 0)
            {
                if (_options.HasFlag(SelectorOptions.IgnoreZeroWeight))
                {
                    return;
                }
                throw new InvalidOperationException("Scores must be >= 0");
            }

            _forceRecalculation = true;
            _items.Add(item);
        }
Ejemplo n.º 11
0
        public void WeightedAverage_IEnumerableToScalar_DecimalProperty_SourceCumulativePercentageToOverflow_OverflowExceptionThrown()
        {
            IEnumerable <WeightedItem <decimal> > source = new WeightedItem <decimal>[] {
                new WeightedItem <decimal>(decimal.MaxValue, decimal.MaxValue),
                new WeightedItem <decimal>(decimal.MaxValue, decimal.MaxValue)
            };

            Action comparison = () =>
            {
                source.WeightedAverage(x => x.Value, x => x.Weight);
            };

            comparison.ShouldThrow <OverflowException>();
        }
Ejemplo n.º 12
0
       public static List<WeightedItem<string>> CreateInputs(int minInputs, int maxInputs, int minWeight, int maxWeight)
        {
            var Gen = new Random();
            var InputCount = Gen.Next(minInputs, maxInputs);
            var Result = new List<WeightedItem<String>>();

            for (var i = 1; i <= InputCount; i++)
            {
                var Item = new WeightedItem<string>(GetInputName(), 
                                                    Gen.Next(minWeight, maxWeight));
                Result.Add(Item);
            }

            return Result;
        }
Ejemplo n.º 13
0
        public static List <WeightedItem <string> > CreateInputs(int minInputs, int maxInputs, int minWeight, int maxWeight)
        {
            var Gen        = new Random();
            var InputCount = Gen.Next(minInputs, maxInputs);
            var Result     = new List <WeightedItem <String> >();

            for (var i = 1; i <= InputCount; i++)
            {
                var Item = new WeightedItem <string>(GetInputName(),
                                                     Gen.Next(minWeight, maxWeight));
                Result.Add(Item);
            }

            return(Result);
        }
Ejemplo n.º 14
0
        public Door GetDoorByTargetBuilding(int startingBuildingId, int targetBuildingId)
        //    TODO: Move this to DoorManager
        {
            List <WeightedItem <Door> > doorList = new List <WeightedItem <Door> >();

            foreach (var possibleDoor in GetBuilding(startingBuildingId).Doors)
            {
                var distance = Vector3.Distance(
                    GetBuilding(targetBuildingId).AveragePosition,
                    possibleDoor.transform.position
                    );
                doorList.Add(new WeightedItem <Door>(possibleDoor, 1f / distance));
            }

            return(WeightedItem <Door> .Choose(doorList));
        }
Ejemplo n.º 15
0
    public T getItem()
    {
        int roll          = Random.Range(0, _totalWeight);
        int currentWeight = 0;

        for (int i = 0; i < _contents.Count; i++)
        {
            WeightedItem <T> currentItem = _contents[i];
            currentWeight += currentItem.getWeight();
            if (roll < currentWeight)
            {
                return(currentItem.getItem());
            }
        }
        return(default(T));
    }
Ejemplo n.º 16
0
    /// <summary>
    /// dynamically return a list with the correct weighting for the sector
    /// as determined by the game controller
    ///
    /// https://dotnetcodr.com/2014/10/17/dynamically-finding-the-value-of-a-static-field-with-reflection-in-net-c/
    /// </summary>
    /// <param name="weighting">class of arrays of weightings for the different arrays above</param>
    /// <param name="dataSet">which data set you wish to use: RelationType, Occupation,
    /// Priors, and anyothers that need to be implemented(please replace when written) </param>
    /// <returns></returns>
    public static List <WeightedItem> InitilizeSystem(Weightings[] weighting, String dataSet)
    {
        List <WeightedItem> tempList = new List <WeightedItem>();

        Debug.Log("Reflections DP string: " + dataSet);
        Type this_class = Type.GetType("StoredData_DataPoints");               // using reflections to dynamically build a list for the

        System.Reflection.FieldInfo stringtype = this_class.GetField(dataSet); //game controller for spawning npcs with data for the current sector
        WeightedItem temp = new WeightedItem();

        if (stringtype.FieldType == typeof(int[]))
        {
            int[] fieldFind = (int[])stringtype.GetValue(null);
            for (int i = 0; i < fieldFind.Length; i++)
            {
                //Debug.Log("Potato 1C Rep || i: " + i + " | " + dataSet + " | curr: " + fieldFind[i]);
                temp.weight.normal     = weighting[i].normal;
                temp.weight.redHerring = weighting[i].redHerring;
                temp.weight.Target     = weighting[i].Target;
                temp.item = fieldFind[i].ToString();

                tempList.Add(temp);
            }
        }
        else
        {
            string[] fieldFind = (string[])stringtype.GetValue(null);
            for (int i = 0; i < fieldFind.Length; i++)
            {
                Debug.Log("Potato 1C Rep || i: " + i + " | " + dataSet + " | curr: " + fieldFind[i]);
                temp.weight.normal     = weighting[i].normal;
                temp.weight.redHerring = weighting[i].redHerring;
                temp.weight.Target     = weighting[i].Target;
                temp.item = fieldFind[i];

                tempList.Add(temp);
            }
        }



        return(tempList);
    }
            public WeightedRandomPicker <T> Build()
            {
                if (this.weightedItems.Count == 0)
                {
                    throw new InvalidOperationException("Must have at least one item.");
                }

                // sort the weighted items in increasing order by weight.  if there's a *very* large
                // gap in weights, I *think* that sorting them like this improves how closely we'll
                // match the expected distribution for the low ones; if not, I apologize to your CPU
                // (but I'm pretty sure that at least it won't be *worse*).
                var weightedItemsArray = new WeightedItem[this.weightedItems.Count];

                this.weightedItems.CopyTo(weightedItemsArray);
                Array.Sort(weightedItemsArray, CompareWeightedItems);

                var items = new T[weightedItemsArray.Length];

                double[] newWeights = new double[items.Length];

                // reweight, step 1: set each weight to the sum of itself and all weights before it.
                double weightSoFar = 0;

                for (int i = 0; i < weightedItemsArray.Length; ++i)
                {
                    WeightedItem weightedItem = weightedItemsArray[i];
                    items[i]      = weightedItem.Item;
                    newWeights[i] = weightSoFar += weightedItem.Weight;
                }

                // reweight, step 2: divide each weight by the sum total of all weights observed.
                // the final entry's weight, therefore, should be 1.
                for (int i = 0; i < newWeights.Length; ++i)
                {
                    newWeights[i] /= weightSoFar;
                }

                Debug.Assert(newWeights[newWeights.Length - 1] == 1, "Any double value divided by itself should be 1...");
                newWeights[newWeights.Length - 1] = 1;

                return(new WeightedRandomPicker <T>(items, newWeights));
            }
Ejemplo n.º 18
0
            public static T Choose(List <WeightedItem <T> > items)
            {
                int cumulSum = 0;
                int cnt      = items.Count();

                for (int slot = 0; slot < cnt; slot++)
                {
                    cumulSum += items[slot].weight;
                    items[slot].cumulativeSum = cumulSum;
                }

                double           divSpot = rndInst.NextDouble() * cumulSum;
                WeightedItem <T> chosen  = items.FirstOrDefault(i => i.cumulativeSum >= divSpot);

                if (chosen == null)
                {
                    throw new Exception("No item chosen - there seems to be a problem with the probability distribution.");
                }
                return(chosen.value);
            }
Ejemplo n.º 19
0
        private void RetrieveAssignments()
        {
            // Loop through all the items in the ListView, and add them back to
            // our List<WeightedItem> field.
            foreach (ListViewDataItem item in AssignmentsList.Items)
            {
                // Use the item to find the control that has the data we want
                var nameLabel   = item.FindControl("AssignmentTitle") as Label;
                var weightLabel = item.FindControl("Weight") as Label;

                if (nameLabel != null && weightLabel != null)
                {
                    var existing = new WeightedItem
                    {
                        AssignmentName = nameLabel.Text,
                        Weight         = int.Parse(weightLabel.Text)
                    };
                    Assignments.Add(existing);
                }
            }
        }
Ejemplo n.º 20
0
        public static SerializableTrigramStatistics Count(IEnumerable <string> wordlist)
        {
            var count = GetTrigramCount(wordlist);

            var prefixWeights = count
                                .GroupBy(kv => Tuple.Create(kv.Key.Item1, kv.Key.Item2), kv => kv.Value)
                                .Select(g => WeightedItem.Create(Sum(g), g.Key))
                                .OrderBy(i => i.Item.Item1).ThenBy(i => i.Item.Item2);

            return(new SerializableTrigramStatistics
            {
                PrefixWeights = GetCumulativeWeightedList(prefixWeights),

                TrigramWeights = count
                                 .GroupBy(
                    kv => Tuple.Create(kv.Key.Item1, kv.Key.Item2),
                    kv => Tuple.Create(kv.Key.Item3, kv.Value))
                                 .ToDictionary(
                    g => g.Key,
                    g => GetCumulativeWeightedList(
                        g.Select(t => WeightedItem.Create(t.Item2, t.Item1)).OrderBy(i => i.Item))),
            });
        }
        public void Mutate(ref IWeightedList <ConcreteSpecimen> population)
        {
            // Mutate
            var numberOfMutableProperties      = 1;
            var totalNumberOfMutableProperties = population.Count * numberOfMutableProperties; // population size * number of mutable properties.

            var indexes = Enumerable.Range(0, totalNumberOfMutableProperties)
                          .OrderBy(x => Guid.NewGuid())
                          .Take((int)Math.Floor(_mutationProbability * totalNumberOfMutableProperties));

            iteration = (iteration + 1) % 10;

            var strength = Math.Sin((iteration / 10.0d) * Math.PI);

            var mutationFactorX = strength * (random.Next(0, 2) == 0 ? -1 : 1) * random.NextDouble() * 10d;

            foreach (var idx in indexes)
            {
                var cellIndex     = idx / numberOfMutableProperties;
                var propertyIndex = idx % numberOfMutableProperties;

                var specimen = population[cellIndex].Item;

                var x = specimen.X;

                switch (propertyIndex)
                {
                case 0: x = x + mutationFactorX; break;

                default: throw new ArgumentOutOfRangeException(nameof(propertyIndex));
                }

                var mutatedSpecimen = new ConcreteSpecimen(x);

                population[cellIndex] = new WeightedItem <ConcreteSpecimen>(mutatedSpecimen, 0);
            }
        }
Ejemplo n.º 22
0
        void RandomEventRoom()
        {
            ClearParagraph();
            WeightedItem <int> P50 = new WeightedItem <int>(1, 5);
            WeightedItem <int> P20 = new WeightedItem <int>(2, 2);
            WeightedItem <int> P10 = new WeightedItem <int>(3, 1);
            WeightedItem <int> P1  = new WeightedItem <int>(4, 1);
            var rerun = Room.CreateContainer("Rerun", () => RandomEventRoom());
            List <WeightedItem <int> > myList = new List <WeightedItem <int> > {
                P50, P20, P10, P1
            };
            int chosen = WeightedItem <int> .Choose(myList);

            Run pick = new Run();

            if (chosen == 1)
            {
                Player.HasKnot = true;
                pick           = Room.CreateRun($"It landed on one! {HasKnot("I will f**k you tonight")}");
            }
            else if (chosen == 2)
            {
                Player.HasKnot = false;
                pick           = Room.CreateRun($"It landed on two! {HasKnot("I will f**k you tonight")}");
            }
            else if (chosen == 3)
            {
                pick = Room.CreateRun("It landed on three!");
            }
            else if (chosen == 4)
            {
                pick = Room.CreateRun("It landed on four!");
            }
            Run stats = Room.CreateRun(GameStats());

            AddInline(pick, rerun, "\n\n", stats);
        }
Ejemplo n.º 23
0
 public void CanNotEquipItemIntoTakenSlotIfNoAutoUnequip()
 {
     var inventory = new Inventory();
     var item1 = new WeightedItem { Weight = Weight.Heavy, Name = "hello1" };
     var item2 = new WeightedItem { Weight = Weight.Heavy, Name = "hello2" };
     inventory.Add(item1);
     inventory.Add(item2);
     Assert.True(inventory.Equip(item1, false));
     Assert.Same(inventory.HeavySlotItem, item1);
     Assert.False(inventory.Equip(item2, false));
     Assert.Same(inventory.HeavySlotItem, item1);
     Assert.NotSame(inventory.HeavySlotItem, item2);
     Assert.NotNull(inventory.HeavySlotItem);
 }
Ejemplo n.º 24
0
        public void NaturalSelection(ref IWeightedList <ConcreteSpecimen> population)
        {
            var originalPopulation = population.ToArray();

            population.Clear();
            var count               = originalPopulation.Length;
            var numberOfParents     = 2;
            var sumFitness          = originalPopulation.Sum(x => x.Weight);
            var random              = new Random();
            var acceptableSpecimens = new List <ConcreteSpecimen>();

            /**************************************************************************************************
            *    Based on https://stackoverflow.com/questions/10765660/roulette-wheel-selection-procedure    *
            **************************************************************************************************
            *                                                                                                *
            *    For all members of population                                                               *
            *         sum += fitness ( member )                                                              *
            *    End for                                                                                     *
            *                                                                                                *
            *    Loop until new population is full                                                           *
            *         Do this twice                                                                          *
            *              Number = Random between 0 and sum                                                 *
            *              Currentfitness = 0.0                                                              *
            *              For each member in population                                                     *
            *                 Currentfitness += fitness(member)                                              *
            *                 if Number > Currentfitness then select member                                  *
            *              End for                                                                           *
            *         End                                                                                    *
            *    Create offspring                                                                            *
            *    End loop                                                                                    *
            *                                                                                                *
            **************************************************************************************************/

            for (var i = 0; i < count; i++)
            {
                var parents = new WeightedItem <ConcreteSpecimen> [2];
                for (var j = 0; j < numberOfParents; j++)
                {
                    while (parents[j] == null)
                    {
                        var number         = random.NextDouble() * sumFitness;
                        var currentFitness = 0.0d;

                        foreach (var item in originalPopulation)
                        {
                            currentFitness += item.Weight;

                            if (number > currentFitness)
                            {
                                parents[j] = item;
                            }
                        }
                    }
                }

                double x;

                switch (random.Next(4))
                {
                case 0:
                case 1:
                case 2:
                    x = (parents[0].Weight * parents[0].Item.X + parents[1].Weight * parents[1].Item.X) / (parents[0].Weight + parents[1].Weight);
                    break;

                default:
                    // Default case: let's just randomly select which gene is coming from which parent...
                    x = parents[random.Next(0, 2)].Item.X;
                    break;
                }

                var offSpring = new ConcreteSpecimen(x);

                population.Add(new WeightedItem <ConcreteSpecimen>(offSpring, 0));
            }
        }
Ejemplo n.º 25
0
 public void CanNotEquipItemNotInInventory()
 {
     var inventory = new Inventory();
     var item = new WeightedItem { Weight = Weight.Heavy, Name = "hello" };
     Assert.False(inventory.Equip(item));
     inventory.Add(item);
     Assert.True(inventory.Equip(item));
 }
Ejemplo n.º 26
0
 public void CollectionBehaviourIsCorrect()
 {
     var inventory = new Inventory();
     var item1 = new WeightedItem { Weight = Weight.Heavy, Name = "hello1" };
     var item2 = new WeightedItem { Weight = Weight.Heavy, Name = "hello2" };
     inventory.Add(item1);
     inventory.Add(item2);
     Assert.Contains(item1, inventory.AllItems);
     Assert.Contains(item2, inventory.AllItems);
     Assert.Contains(item1, inventory.UnequippedItems);
     Assert.Contains(item2, inventory.UnequippedItems);
     Assert.DoesNotContain(item1, inventory.EquippedItems);
     Assert.DoesNotContain(item2, inventory.EquippedItems);
     Assert.True(inventory.Equip(item1));
     Assert.DoesNotContain(item1, inventory.UnequippedItems);
     Assert.Contains(item2, inventory.UnequippedItems);
     Assert.Contains(item1, inventory.EquippedItems);
     Assert.DoesNotContain(item2, inventory.EquippedItems);
     Assert.True(inventory.Equip(item2));
     Assert.Contains(item1, inventory.UnequippedItems);
     Assert.DoesNotContain(item2, inventory.UnequippedItems);
     Assert.DoesNotContain(item1, inventory.EquippedItems);
     Assert.Contains(item2, inventory.EquippedItems);
 }
Ejemplo n.º 27
0
        private static bool Prefix(TechType techType, int num = 1, bool noMessage = false, bool spawnIfCantAdd = true)
        {
            if (techType == TechType.Titanium && num == 2 && !noMessage && spawnIfCantAdd)
            {
                TechType scannedFragment = PDAScanner.scanTarget.techType;
#if !RELEASE
                Logger.Log(Logger.Level.Debug, $"Intercepting scan of fragment {scannedFragment.ToString()}");
#endif

                TechData recipe; // "Variable declaration can be inlined" says Visual Studio, but I'm not sure if it would remain in-scope further down the function if it is.
                if (IngredientsFromScanning.Main.config.TryOverrideRecipe(scannedFragment, out recipe))
                {
#if !RELEASE
                    Logger.Log(Logger.Level.Debug, $"Using OverrideRecipe: {JsonConvert.SerializeObject(recipe, Oculus.Newtonsoft.Json.Formatting.Indented)}");
#endif
                }
                else if ((int)scannedFragment > 1112 && (int)scannedFragment < 1117)
                {
                    // TechTypes 1113 to 1116 are Cyclops fragments, which have no blueprint associated, so we need to process them specially.
                    recipe = new TechData();

                    /*CyclopsHullFragment = 1113,
                     * CyclopsBridgeFragment = 1114,
                     * CyclopsEngineFragment = 1115,
                     * CyclopsDockingBayFragment = 1116,*/

                    switch ((int)scannedFragment)
                    {
                    case 1113:
                        recipe.Ingredients.Add(new Ingredient(TechType.PlasteelIngot, 2));
                        recipe.Ingredients.Add(new Ingredient(TechType.Lead, 1));
                        break;

                    case 1114:
                        recipe.Ingredients.Add(new Ingredient(TechType.EnameledGlass, 3));
                        break;

                    case 1115:
                        recipe.Ingredients.Add(new Ingredient(TechType.Lubricant, 1));
                        recipe.Ingredients.Add(new Ingredient(TechType.AdvancedWiringKit, 1));
                        recipe.Ingredients.Add(new Ingredient(TechType.Lead, 1));
                        break;

                    case 1116:
                        recipe.Ingredients.Add(new Ingredient(TechType.PlasteelIngot, 2));
                        break;
                    }
                    recipe.Ingredients.Add(new Ingredient(TechType.Lead, 1));
                    recipe.Ingredients.Add(new Ingredient(TechType.PlasteelIngot, 1));
#if !RELEASE
                    Logger.Log(Logger.Level.Debug, $"Using recipe from manual override: {JsonConvert.SerializeObject(recipe, Oculus.Newtonsoft.Json.Formatting.Indented)}");
#endif
                }
                else
                {
                    PDAScanner.EntryData entryData = PDAScanner.GetEntryData(scannedFragment);
                    if (entryData == null) // Sanity check; this should always be true
                    {
#if !RELEASE
                        Logger.Log(Logger.Level.Debug, $"Failed to find EntryData for fragment");
#endif

                        /*CraftData.AddToInventory(TechType.Titanium);
                         * CraftData.AddToInventory(TechType.Titanium); // Adding them one-by-one so as to prevent it being caught by this very routine.*/
                        return(true);
                    }
                    //Logger.Log(Logger.Level.Debug, $"Found entryData {entryData.ToString()}");
#if !RELEASE
                    Logger.Log(Logger.Level.Debug, $"Found entryData {JsonConvert.SerializeObject(entryData, Oculus.Newtonsoft.Json.Formatting.Indented)}");
#endif


                    //CraftData.AddToInventory(TechType.Titanium);
                    //CraftData.AddToInventory(TechType.Copper);
                    recipe = CraftDataHandler.GetTechData(entryData.blueprint);
                    if (recipe == null)
                    {
#if !RELEASE
                        Logger.Log(Logger.Level.Debug, $"Failed to find blueprint for EntryData");
#endif

                        /*CraftData.AddToInventory(TechType.Titanium);
                         * CraftData.AddToInventory(TechType.Titanium); // One-by-one again, as above.*/
                        return(true);
                    }
                    //Logger.Log(Logger.Level.Debug, $"Found recipe {recipe.ToString()}");
#if !RELEASE
                    Logger.Log(Logger.Level.Debug, $"Using recipe from EntryData: {JsonConvert.SerializeObject(recipe, Oculus.Newtonsoft.Json.Formatting.Indented)}");
#endif
                }

                for (int i = 0; i < recipe.Ingredients.Count; i++)
                {
                    if (IngredientsFromScanning.Main.config.TrySubstituteIngredient(recipe.Ingredients[i].techType, out List <Ingredient> Substitutes))
                    {
                        foreach (Ingredient sub in Substitutes)
                        {
                            recipe.Ingredients.Add(sub);
                        }
                        recipe.Ingredients.RemoveAt(i); // Remove the current ingredient...
                        i--;                            // ...and make sure the loop continues at the item after this, not the one after that.
                    }
                }

                // I believe the easiest way to get a random item from the blueprint would be to make a list of techTypes; if an ingredient is used twice in the recipe, it will appear in the list twice.
                // That way, we can generate a random number where 0<=rnd<list.count, and select that item.
                List <TechType> bp = new List <TechType> {
                };
                for (int i = 0; i < recipe.Ingredients.Count; i++)
                {
                    for (int j = 0; j < recipe.Ingredients[i].amount; j++)
                    {
                        bp.Add(recipe.Ingredients[i].techType);
                    }
                }

                // Now build up weights
                List <WeightedItem> BlueprintPairs = new List <WeightedItem>();
                float TotalWeight = 0f;
                //Logger.Log(Logger.Level.Error, "Unidentified Vehicle Type!");
                for (int i = 0; i < bp.Count; i++)
                {
                    float thisWeight = IngredientsFromScanning.Main.config.GetWeightForTechType(bp[i]);
                    TotalWeight += thisWeight;
                    WeightedItem thisWeightedItem = new WeightedItem(TotalWeight, bp[i]);
#if !RELEASE
                    Logger.Log(Logger.Level.Debug, $"Adding item to drop list, TechType = {thisWeightedItem.tech.ToString()},   this weight = {thisWeight}, cumulative weight = {thisWeightedItem.Weight}");
#endif
                    BlueprintPairs.Add(thisWeightedItem);
                }

                // Now we should be able to pick a few random numbers between 0 and the list's total weight, and add those. We want to remove that entry afterwards, but that's not a big ask.
                System.Random rng            = new System.Random();
                int           numIngredients = Math.Min(IngredientsFromScanning.Main.config.GenerateGiftValue(), BlueprintPairs.Count);
#if !RELEASE
                Logger.Log(Logger.Level.Debug, $"Generated a value for this scan of {numIngredients} components.");
#endif

                int    awards = 0;
                double r;
                for (int i = 0; i < numIngredients && BlueprintPairs.Count > 0; i++)
                {
                    r = rng.NextDouble() * TotalWeight;
                    for (int j = 0; j < BlueprintPairs.Count; j++)
                    {
                        //                                               This part is for sanity checking
                        //                                   ___________________________|______________________________
                        //                                  /                                                          \
                        if (r < BlueprintPairs[j].Weight || ((j + 1) == BlueprintPairs.Count && awards < numIngredients))
                        {
#if !RELEASE
                            Logger.Log(Logger.Level.Debug, $"With randomised weight of {r}, adding tech {BlueprintPairs[j].tech} to player inventory");
#endif
                            AddInventory(BlueprintPairs[j].tech, 1, false, true);
                            //CraftData.AddToInventory(BlueprintPairs[j].tech, 1, false, true);
                            awards++;
                            TotalWeight -= IngredientsFromScanning.Main.config.GetWeightForTechType(BlueprintPairs[j].tech);
                            BlueprintPairs.RemoveAt(j);
                            break;
                        }
                    }
                }
                return(false);
            }
            return(true);
        }
Ejemplo n.º 28
0
 public void addWeightedItem(WeightedItem <T> item)
 {
     _contents.Add(item);
     _totalWeight += item.getWeight();
 }
Ejemplo n.º 29
0
 /// <summary>
 ///     Removes the specified <see cref="WeightedItem{T}" /> from the selector
 /// </summary>
 /// <param name="item">The item to remove</param>
 public void Remove(WeightedItem <T> item)
 {
     _forceRecalculation = true;
     _items.Remove(item);
 }