public void RegisterTrade(Faction faction, ITrader trader, ThingDef thingDef, int count)
        {
            var timeToForget = trader is Settlement
                ? Capitalism.Settings.RememberSettlementMaxTime
                : trader is Pawn || trader is Caravan
                    ? Capitalism.Settings.RememberCaravanTime
                    : Capitalism.Settings.RememberOrbitalTradersTime;

            registeredTrades.Add(new ThingTrade()
            {
                expiresAtTick = Find.TickManager.TicksGame + timeToForget,
                count         = count,
                thingDef      = CapitalismUtils.GroupCertainThingDefs(thingDef),
                settlement    = trader as Settlement,
                faction       = faction
            });
            priceModifiers = null;
        }
        public Dictionary <ThingDef, float> GeneratePriceModifiers()
        {
            ExpireOldData(registeredTrades);
            ExpireOldData(temporaryTraders);


            var totalInCirculation = new Dictionary <ThingDef, int>();
            var totalTraded        = new Dictionary <ThingDef, int>();

            foreach (var settlement in Find.WorldObjects.Settlements)
            {
                var inStock = settlement.trader.StockListForReading;
                foreach (var t in inStock)
                {
                    var def = CapitalismUtils.GroupCertainThingDefs(t.def);
                    if (!totalInCirculation.ContainsKey(def))
                    {
                        totalInCirculation[def] = 0;
                    }
                    totalInCirculation[def] += t.stackCount;
                }
            }

            foreach (var trader in temporaryTraders)
            {
                foreach (var t in trader.goods)
                {
                    var def = CapitalismUtils.GroupCertainThingDefs(t.def);
                    if (!totalInCirculation.ContainsKey(def))
                    {
                        totalInCirculation[def] = 0;
                    }
                    totalInCirculation[def] += t.stackCount;
                }
            }

            foreach (var t in registeredTrades)
            {
                if (!totalTraded.ContainsKey(t.thingDef))
                {
                    totalTraded[t.thingDef] = 0;
                }
                totalTraded[t.thingDef] += t.count;
            }

            var priceModifiers = new Dictionary <ThingDef, float>();

            foreach (var pair in totalInCirculation)
            {
                if (totalTraded.ContainsKey(pair.Key))
                {
                    var inCirculation              = pair.Value;
                    var boughtByPlayer             = totalTraded[pair.Key];
                    var inCirculationWithoutPlayer = inCirculation + boughtByPlayer;
                    var initialModifier            = (float)Math.Sqrt(inCirculationWithoutPlayer / (float)inCirculation);
                    var multipliedModifier         = 1 + (initialModifier - 1) * Capitalism.Settings.EffectMultiplier;
                    var maxModifier = Capitalism.Settings.MaxSupplyDemandChangePercent / 100f;
                    priceModifiers[pair.Key] = Math.Min(Math.Max(multipliedModifier, 1 / maxModifier), maxModifier);
                }
            }

            CapitalismUtils.LogAndMessage("New price modifiers: " + string.Join(", ", priceModifiers.Select(kv => kv.Key.label + ":" + kv.Value.ToString("F"))));

            return(priceModifiers);
        }