Пример #1
0
        private void HandleDirectionMove(Direction scanDirection, Vector2Int negativeEndPosition, Vector2Int positiveEndPosition, Stack <Command> tickCommands, bool canBounce)
        {
            var scanDisplacement = DirectionUtils.DirectionToDisplacement(scanDirection);

            var impactBlocks = DictionaryPool <Block, int> .Get();

            for (var position = negativeEndPosition + scanDisplacement; position != positiveEndPosition; position += scanDisplacement)
            {
                var blocks = m_logicGameManager.Map[position.x, position.y];
                foreach (var block in blocks)
                {
                    if (!HasAttribute(block, AttributeCategory.Move) || !DirectionUtils.IsParallel(scanDirection, block.direction))
                    {
                        continue;
                    }
                    var impactDirection    = 1;
                    var impactDisplacement = scanDisplacement;
                    if (block.direction != scanDirection)
                    {
                        impactDirection    = 2;
                        impactDisplacement = Vector2Int.zero - scanDisplacement;
                    }
                    impactBlocks[block] = impactBlocks.GetOrDefault(block, 0) | impactDirection;
                    if (HasAttribute(block, AttributeCategory.Push))
                    {
                        for (var pushPosition = position + impactDisplacement; m_logicGameManager.InMap(pushPosition); pushPosition += impactDisplacement)
                        {
                            var pushBlocks = m_logicGameManager.Map[pushPosition.x, pushPosition.y];
                            var hasPush    = false;
                            foreach (var pushBlock in pushBlocks)
                            {
                                if (HasAttribute(pushBlock, AttributeCategory.Push))
                                {
                                    impactBlocks[pushBlock] = impactBlocks.GetOrDefault(pushBlock, 0) | impactDirection;
                                    hasPush = true;
                                }
                            }
                            if (!hasPush)
                            {
                                break;
                            }
                        }
                    }
                    if (HasAttribute(block, AttributeCategory.Pull))
                    {
                        for (var pullPosition = position - impactDisplacement; m_logicGameManager.InMap(pullPosition); pullPosition -= impactDisplacement)
                        {
                            var pullBlocks = m_logicGameManager.Map[pullPosition.x, pullPosition.y];
                            var hasPull    = false;
                            foreach (var pullBlock in pullBlocks)
                            {
                                if (HasAttribute(pullBlock, AttributeCategory.Pull))
                                {
                                    impactBlocks[pullBlock] = impactBlocks.GetOrDefault(pullBlock, 0) | impactDirection;
                                    hasPull = true;
                                }
                            }
                            if (!hasPull)
                            {
                                break;
                            }
                        }
                    }
                }
            }

            for (var position = positiveEndPosition - scanDisplacement; position != negativeEndPosition; position -= scanDisplacement)
            {
                var blocks = m_logicGameManager.Map[position.x, position.y];
                foreach (var block in blocks)
                {
                    if (impactBlocks.GetOrDefault(block, 0) == 3)
                    {
                        impactBlocks[block] = 0;
                    }
                }
            }

            HandlePreMove(impactBlocks, scanDisplacement, tickCommands);

            {
                var stopPosition = positiveEndPosition - scanDisplacement;
                {
                    var blocks = m_logicGameManager.Map[stopPosition.x, stopPosition.y];
                    foreach (var block in blocks)
                    {
                        var impact = 0;
                        if (impactBlocks.TryGetValue(block, out impact))
                        {
                            impactBlocks[block] &= ~1;
                        }
                    }
                }
            }
            {
                var stopPosition = negativeEndPosition + scanDisplacement;
                {
                    var blocks = m_logicGameManager.Map[stopPosition.x, stopPosition.y];
                    foreach (var block in blocks)
                    {
                        var impact = 0;
                        if (impactBlocks.TryGetValue(block, out impact))
                        {
                            impactBlocks[block] &= ~2;
                        }
                    }
                }
            }
            for (var position = positiveEndPosition - scanDisplacement; position != negativeEndPosition + scanDisplacement; position -= scanDisplacement)
            {
                var hasStop = false;
                {
                    var blocks = m_logicGameManager.Map[position.x, position.y];
                    foreach (var block in blocks)
                    {
                        if (HasAttribute(block, AttributeCategory.Stop) || HasAttribute(block, AttributeCategory.Pull) || HasAttribute(block, AttributeCategory.Push))
                        {
                            if (impactBlocks.GetOrDefault(block, 0) != 1)
                            {
                                hasStop = true;
                                break;
                            }
                        }
                    }
                }
                if (hasStop)
                {
                    var stopPosition = position - scanDisplacement;
                    {
                        var blocks = m_logicGameManager.Map[stopPosition.x, stopPosition.y];
                        foreach (var block in blocks)
                        {
                            var impact = 0;
                            if (impactBlocks.TryGetValue(block, out impact))
                            {
                                impactBlocks[block] &= ~1;
                            }
                        }
                    }
                }
            }
            for (var position = negativeEndPosition + scanDisplacement; position != positiveEndPosition - scanDisplacement; position += scanDisplacement)
            {
                var hasStop = false;
                {
                    var blocks = m_logicGameManager.Map[position.x, position.y];
                    foreach (var block in blocks)
                    {
                        if (HasAttribute(block, AttributeCategory.Stop) || HasAttribute(block, AttributeCategory.Pull) || HasAttribute(block, AttributeCategory.Push))
                        {
                            if (impactBlocks.GetOrDefault(block, 0) != 2)
                            {
                                hasStop = true;
                                break;
                            }
                        }
                    }
                }
                if (hasStop)
                {
                    var stopPosition = position + scanDisplacement;
                    {
                        var blocks = m_logicGameManager.Map[stopPosition.x, stopPosition.y];
                        foreach (var block in blocks)
                        {
                            var impact = 0;
                            if (impactBlocks.TryGetValue(block, out impact))
                            {
                                impactBlocks[block] &= ~2;
                            }
                        }
                    }
                }
            }

            foreach (var impactBlockPair in impactBlocks)
            {
                var block  = impactBlockPair.Key;
                var impact = impactBlockPair.Value;

                if (canBounce)
                {
                    if (HasAttribute(block, AttributeCategory.Move) && impact == 0)
                    {
                        block.direction = DirectionUtils.GetOppositeDirection(block.direction);
                    }
                }
                else
                {
                    if (impact == 1)
                    {
                        PerformMoveBlockCommand(block, scanDirection, 1, tickCommands);
                    }
                    else if (impact == 2)
                    {
                        PerformMoveBlockCommand(block, DirectionUtils.GetOppositeDirection(scanDirection), 1, tickCommands);
                    }
                }
            }

            DictionaryPool <Block, int> .Release(impactBlocks);
        }
Пример #2
0
        public static string WrapUOHtmlColors(this string str, Color start, Color end)
        {
            if (start == end)
            {
                return(WrapUOHtmlColor(str, start));
            }

            var t = new StringBuilder();

            var tags = DictionaryPool <int, string> .AcquireObject();

            var tago = false;
            var tagi = 0;

            for (var i = 0; i < str.Length; i++)
            {
                if (str[i] == '<')
                {
                    tago = true;
                    tagi = i;
                }
                else if (tago && str[i] == '>')
                {
                    tago = false;
                }

                if (tago)
                {
                    if (i > tagi)
                    {
                        t.Append(str[i]);
                    }
                }
                else if (t.Length > 0)
                {
                    tags[tagi] = t.ToString();

                    t.Clear();
                }
            }

            t.Clear();

            double n, o = 0.0;
            string tag, s;

            for (var i = 0; i < str.Length; i++)
            {
                tag = tags.GetValue(i);

                if (tag != null)
                {
                    t.Append("<" + tag + ">");
                }

                n = i / (double)str.Length;

                if (n <= 0 || n >= o + 0.05)
                {
                    o = n;
                }

                s = str[i].ToString();

                t.Append(o == n ? s.WrapUOHtmlColor(start.Interpolate(end, n), false) : s);
            }

            DictionaryPool <int, string> .FreeObject(tags);

            return(t.ToString());
        }
Пример #3
0
        public void PooledDictionary_Simple4()
        {
            var pool = DictionaryPool <string, int> .Create(4, 16, EqualityComparer <string> .Default);

            PooledDictionary_Simple_Impl(pool);
        }
Пример #4
0
        // Internal validation
        // -------------------------------------------------

        public override void EvaluateDynamicMaterialSlots()
        {
            var dynamicInputSlotsToCompare = DictionaryPool <DynamicValueMaterialSlot, ConcreteSlotValueType> .Get();

            var skippedDynamicSlots = ListPool <DynamicValueMaterialSlot> .Get();

            // iterate the input slots
            using (var tempSlots = PooledList <MaterialSlot> .Get())
            {
                GetInputSlots(tempSlots);
                foreach (var inputSlot in tempSlots)
                {
                    inputSlot.hasError = false;

                    // if there is a connection
                    var edges = owner.GetEdges(inputSlot.slotReference).ToList();
                    if (!edges.Any())
                    {
                        if (inputSlot is DynamicValueMaterialSlot)
                        {
                            skippedDynamicSlots.Add(inputSlot as DynamicValueMaterialSlot);
                        }
                        continue;
                    }

                    // get the output details
                    var outputSlotRef = edges[0].outputSlot;
                    var outputNode    = outputSlotRef.node;
                    if (outputNode == null)
                    {
                        continue;
                    }

                    var outputSlot = outputNode.FindOutputSlot <MaterialSlot>(outputSlotRef.slotId);
                    if (outputSlot == null)
                    {
                        continue;
                    }

                    if (outputSlot.hasError)
                    {
                        inputSlot.hasError = true;
                        continue;
                    }

                    var outputConcreteType = outputSlot.concreteValueType;
                    // dynamic input... depends on output from other node.
                    // we need to compare ALL dynamic inputs to make sure they
                    // are compatable.
                    if (inputSlot is DynamicValueMaterialSlot)
                    {
                        dynamicInputSlotsToCompare.Add((DynamicValueMaterialSlot)inputSlot, outputConcreteType);
                        continue;
                    }
                }

                m_MultiplyType = GetMultiplyType(dynamicInputSlotsToCompare.Values);

                // Resolve dynamics depending on matrix/vector configuration
                switch (m_MultiplyType)
                {
                // If all matrix resolve as per dynamic matrix
                case MultiplyType.Matrix:
                    var dynamicMatrixType = ConvertDynamicMatrixInputTypeToConcrete(dynamicInputSlotsToCompare.Values);
                    foreach (var dynamicKvP in dynamicInputSlotsToCompare)
                    {
                        dynamicKvP.Key.SetConcreteType(dynamicMatrixType);
                    }
                    foreach (var skippedSlot in skippedDynamicSlots)
                    {
                        skippedSlot.SetConcreteType(dynamicMatrixType);
                    }
                    break;

                // If mixed handle differently:
                // Iterate all slots and set their concretes based on their edges
                // Find matrix slot and convert its type to a vector type
                // Reiterate all slots and set non matrix slots to the vector type
                case MultiplyType.Mixed:
                    foreach (var dynamicKvP in dynamicInputSlotsToCompare)
                    {
                        SetConcreteValueTypeFromEdge(dynamicKvP.Key);
                    }
                    MaterialSlot          matrixSlot = GetMatrixSlot();
                    ConcreteSlotValueType vectorType = SlotValueHelper.ConvertMatrixToVectorType(matrixSlot.concreteValueType);
                    foreach (var dynamicKvP in dynamicInputSlotsToCompare)
                    {
                        if (dynamicKvP.Key != matrixSlot)
                        {
                            dynamicKvP.Key.SetConcreteType(vectorType);
                        }
                    }
                    foreach (var skippedSlot in skippedDynamicSlots)
                    {
                        skippedSlot.SetConcreteType(vectorType);
                    }
                    break;

                // If all vector resolve as per dynamic vector
                default:
                    var dynamicVectorType = ConvertDynamicVectorInputTypeToConcrete(dynamicInputSlotsToCompare.Values);
                    foreach (var dynamicKvP in dynamicInputSlotsToCompare)
                    {
                        dynamicKvP.Key.SetConcreteType(dynamicVectorType);
                    }
                    foreach (var skippedSlot in skippedDynamicSlots)
                    {
                        skippedSlot.SetConcreteType(dynamicVectorType);
                    }
                    break;
                }

                tempSlots.Clear();
                GetInputSlots(tempSlots);
                bool inputError = tempSlots.Any(x => x.hasError);
                if (inputError)
                {
                    owner.AddConcretizationError(objectId, string.Format("Node {0} had input error", objectId));
                    hasError = true;
                }
                // configure the output slots now
                // their slotType will either be the default output slotType
                // or the above dynanic slotType for dynamic nodes
                // or error if there is an input error
                tempSlots.Clear();
                GetOutputSlots(tempSlots);
                foreach (var outputSlot in tempSlots)
                {
                    outputSlot.hasError = false;

                    if (inputError)
                    {
                        outputSlot.hasError = true;
                        continue;
                    }

                    if (outputSlot is DynamicValueMaterialSlot)
                    {
                        // Apply similar logic to output slot
                        switch (m_MultiplyType)
                        {
                        // As per dynamic matrix
                        case MultiplyType.Matrix:
                            var dynamicMatrixType = ConvertDynamicMatrixInputTypeToConcrete(dynamicInputSlotsToCompare.Values);
                            (outputSlot as DynamicValueMaterialSlot).SetConcreteType(dynamicMatrixType);
                            break;

                        // Mixed configuration
                        // Find matrix slot and convert type to vector
                        // Set output concrete to vector
                        case MultiplyType.Mixed:
                            MaterialSlot          matrixSlot = GetMatrixSlot();
                            ConcreteSlotValueType vectorType = SlotValueHelper.ConvertMatrixToVectorType(matrixSlot.concreteValueType);
                            (outputSlot as DynamicValueMaterialSlot).SetConcreteType(vectorType);
                            break;

                        // As per dynamic vector
                        default:
                            var dynamicVectorType = ConvertDynamicVectorInputTypeToConcrete(dynamicInputSlotsToCompare.Values);
                            (outputSlot as DynamicValueMaterialSlot).SetConcreteType(dynamicVectorType);
                            break;
                        }
                        continue;
                    }
                }

                tempSlots.Clear();
                GetOutputSlots(tempSlots);
                if (tempSlots.Any(x => x.hasError))
                {
                    owner.AddConcretizationError(objectId, string.Format("Node {0} had output error", objectId));
                    hasError = true;
                }
            }

            CalculateNodeHasError();

            ListPool <DynamicValueMaterialSlot> .Release(skippedDynamicSlots);

            DictionaryPool <DynamicValueMaterialSlot, ConcreteSlotValueType> .Release(dynamicInputSlotsToCompare);
        }
Пример #5
0
    /// <summary>
    /// Runs distribution algorithm on input.
    /// </summary>
    /// <param name="input"></param>
    /// <param name="output"></param>
    /// <param name="available">The amount you want to distribute</param>
    /// <returns>The overflow</returns>
    public static float ReqDistribute(List <DistributionInput> input, List <DistributionResult> output, float available)
    {
        List <TObject> tmp = ListPool <TObject> .Get();

        List <TObject> objs = ListPool <TObject> .Get();

        Dictionary <TObject, float> distributed = DictionaryPool <TObject, float> .Get();

        Dictionary <TObject, float> requested = DictionaryPool <TObject, float> .Get();

        float availablePrev = -available;

        // Parse
        foreach (var inp in input)
        {
            if (Mathf.Approximately(inp.requestedAmount, 0))
            {
                continue;
            }

            distributed.Add(inp.obj, 0);
            requested.Add(inp.obj, inp.requestedAmount);
            objs.Add(inp.obj);
        }

        int panic = 0;

        while (available > 0 && !Mathf.Approximately(available, availablePrev) && requested.Count > 0)
        {
            availablePrev = available;
            float perInput = available / (float)requested.Count;

            foreach (var obj in objs)
            {
                float alreadyDistributed = distributed[obj];
                float stillRequested     = requested[obj];

                float distributing = Mathf.Min(stillRequested, perInput);
                distributed[obj] += distributing;
                requested[obj]   -= distributing;
                available        -= distributing;

                if (Mathf.Approximately(requested[obj], 0))
                {
                    tmp.Add(obj);
                }
            }

            foreach (var obj in tmp)
            {
                objs.Remove(obj);
                requested.Remove(obj);
            }
            tmp.Clear();

            panic++;
            if (panic > 1000)
            {
                Debug.LogError("Distribution alrogithm triggered panic exit!");
                return(available);
            }
        }

        // Write back
        foreach (var kvp in distributed)
        {
            output.Add(new DistributionResult()
            {
                amount = kvp.Value,
                obj    = kvp.Key
            });
        }

        DictionaryPool <TObject, float> .Return(distributed);

        DictionaryPool <TObject, float> .Return(requested);

        ListPool <TObject> .Return(tmp);

        ListPool <TObject> .Return(objs);

        return(available);
    }
Пример #6
0
        // Internal validation
        // -------------------------------------------------

        public override void ValidateNode()
        {
            var isInError    = false;
            var errorMessage = k_validationErrorMessage;

            var dynamicInputSlotsToCompare = DictionaryPool <DynamicValueMaterialSlot, ConcreteSlotValueType> .Get();

            var skippedDynamicSlots = ListPool <DynamicValueMaterialSlot> .Get();

            // iterate the input slots
            s_TempSlots.Clear();
            GetInputSlots(s_TempSlots);
            foreach (var inputSlot in s_TempSlots)
            {
                inputSlot.hasError = false;

                // if there is a connection
                var edges = owner.GetEdges(inputSlot.slotReference).ToList();
                if (!edges.Any())
                {
                    if (inputSlot is DynamicValueMaterialSlot)
                    {
                        skippedDynamicSlots.Add(inputSlot as DynamicValueMaterialSlot);
                    }
                    continue;
                }

                // get the output details
                var outputSlotRef = edges[0].outputSlot;
                var outputNode    = owner.GetNodeFromGuid(outputSlotRef.nodeGuid);
                if (outputNode == null)
                {
                    continue;
                }

                var outputSlot = outputNode.FindOutputSlot <MaterialSlot>(outputSlotRef.slotId);
                if (outputSlot == null)
                {
                    continue;
                }

                if (outputSlot.hasError)
                {
                    inputSlot.hasError = true;
                    continue;
                }

                var outputConcreteType = outputSlot.concreteValueType;
                // dynamic input... depends on output from other node.
                // we need to compare ALL dynamic inputs to make sure they
                // are compatable.
                if (inputSlot is DynamicValueMaterialSlot)
                {
                    dynamicInputSlotsToCompare.Add((DynamicValueMaterialSlot)inputSlot, outputConcreteType);
                    continue;
                }

                // if we have a standard connection... just check the types work!
                if (!ImplicitConversionExists(outputConcreteType, inputSlot.concreteValueType))
                {
                    inputSlot.hasError = true;
                }
            }

            m_MultiplyType = GetMultiplyType(dynamicInputSlotsToCompare.Values);

            // Resolve dynamics depending on matrix/vector configuration
            switch (m_MultiplyType)
            {
            // If all matrix resolve as per dynamic matrix
            case MultiplyType.Matrix:
                var dynamicMatrixType = ConvertDynamicMatrixInputTypeToConcrete(dynamicInputSlotsToCompare.Values);
                foreach (var dynamicKvP in dynamicInputSlotsToCompare)
                {
                    dynamicKvP.Key.SetConcreteType(dynamicMatrixType);
                }
                foreach (var skippedSlot in skippedDynamicSlots)
                {
                    skippedSlot.SetConcreteType(dynamicMatrixType);
                }
                break;

            // If mixed handle differently:
            // Iterate all slots and set their concretes based on their edges
            // Find matrix slot and convert its type to a vector type
            // Reiterate all slots and set non matrix slots to the vector type
            case MultiplyType.Mixed:
                foreach (var dynamicKvP in dynamicInputSlotsToCompare)
                {
                    SetConcreteValueTypeFromEdge(dynamicKvP.Key);
                }
                MaterialSlot          matrixSlot = GetMatrixSlot();
                ConcreteSlotValueType vectorType = SlotValueHelper.ConvertMatrixToVectorType(matrixSlot.concreteValueType);
                foreach (var dynamicKvP in dynamicInputSlotsToCompare)
                {
                    if (dynamicKvP.Key != matrixSlot)
                    {
                        dynamicKvP.Key.SetConcreteType(vectorType);
                    }
                }
                foreach (var skippedSlot in skippedDynamicSlots)
                {
                    skippedSlot.SetConcreteType(vectorType);
                }
                break;

            // If all vector resolve as per dynamic vector
            default:
                var dynamicVectorType = ConvertDynamicInputTypeToConcrete(dynamicInputSlotsToCompare.Values);
                foreach (var dynamicKvP in dynamicInputSlotsToCompare)
                {
                    dynamicKvP.Key.SetConcreteType(dynamicVectorType);
                }
                foreach (var skippedSlot in skippedDynamicSlots)
                {
                    skippedSlot.SetConcreteType(dynamicVectorType);
                }
                break;
            }

            s_TempSlots.Clear();
            GetInputSlots(s_TempSlots);
            var inputError = s_TempSlots.Any(x => x.hasError);

            // configure the output slots now
            // their slotType will either be the default output slotType
            // or the above dynanic slotType for dynamic nodes
            // or error if there is an input error
            s_TempSlots.Clear();
            GetOutputSlots(s_TempSlots);
            foreach (var outputSlot in s_TempSlots)
            {
                outputSlot.hasError = false;

                if (inputError)
                {
                    outputSlot.hasError = true;
                    continue;
                }

                if (outputSlot is DynamicValueMaterialSlot)
                {
                    // Apply similar logic to output slot
                    switch (m_MultiplyType)
                    {
                    // As per dynamic matrix
                    case MultiplyType.Matrix:
                        var dynamicMatrixType = ConvertDynamicMatrixInputTypeToConcrete(dynamicInputSlotsToCompare.Values);
                        (outputSlot as DynamicValueMaterialSlot).SetConcreteType(dynamicMatrixType);
                        break;

                    // Mixed configuration
                    // Find matrix slot and convert type to vector
                    // Set output concrete to vector
                    case MultiplyType.Mixed:
                        MaterialSlot          matrixSlot = GetMatrixSlot();
                        ConcreteSlotValueType vectorType = SlotValueHelper.ConvertMatrixToVectorType(matrixSlot.concreteValueType);
                        (outputSlot as DynamicValueMaterialSlot).SetConcreteType(vectorType);
                        break;

                    // As per dynamic vector
                    default:
                        var dynamicVectorType = ConvertDynamicInputTypeToConcrete(dynamicInputSlotsToCompare.Values);
                        (outputSlot as DynamicValueMaterialSlot).SetConcreteType(dynamicVectorType);
                        break;
                    }
                    continue;
                }
            }

            isInError |= inputError;
            s_TempSlots.Clear();
            GetOutputSlots(s_TempSlots);
            isInError |= s_TempSlots.Any(x => x.hasError);
            isInError |= CalculateNodeHasError(ref errorMessage);
            hasError   = isInError;

            if (isInError)
            {
                ((GraphData)owner).AddValidationError(tempId, errorMessage);
            }
            else
            {
                ++version;
            }

            ListPool <DynamicValueMaterialSlot> .Release(skippedDynamicSlots);

            DictionaryPool <DynamicValueMaterialSlot, ConcreteSlotValueType> .Release(dynamicInputSlotsToCompare);
        }
 public void Recycle()
 {
     DictionaryPool <KeyType, ObjectType, PoolIdentifier> .Free(this);
 }
Пример #8
0
        /// <summary>
        /// Applies decor values from the database.
        /// </summary>
        internal static void ApplyDatabase(DecorReimaginedOptions options)
        {
            DecorDbEntry[] entries = null;
            try {
                // Read in database from the embedded config json
                using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(
                           "ReimaginationTeam.DecorRework.buildings.json")) {
                    var jr = new JsonTextReader(new StreamReader(stream));
                    entries = new JsonSerializer {
                        MaxDepth = 2
                    }.Deserialize <DecorDbEntry[]>(jr);
                    jr.Close();
                }
            } catch (JsonException e) {
                // Error when loading decor
                PUtil.LogExcWarn(e);
            } catch (IOException e) {
                // Error when loading decor
                PUtil.LogExcWarn(e);
            }
            if (entries != null)
            {
                var editDecor = DictionaryPool <string, DecorDbEntry, DecorDbEntry> .Allocate();

                var tileLayer = PGameUtils.GetObjectLayer(nameof(ObjectLayer.FoundationTile),
                                                          ObjectLayer.FoundationTile);
                string id;
                // Add to dictionary, way faster
                foreach (var entry in entries)
                {
                    if (!string.IsNullOrEmpty(id = entry.id) && !editDecor.ContainsKey(id))
                    {
                        editDecor.Add(id, entry);
                    }
                }
                foreach (var def in Assets.BuildingDefs)
                {
                    // If PreserveTileDecor is set to true, ignore foundation tile decor mods
                    if (editDecor.TryGetValue(id = def.PrefabID, out DecorDbEntry entry) &&
                        (def.TileLayer != tileLayer || !options.PreserveTileDecor))
                    {
                        float decor    = entry.decor;
                        int   radius   = entry.radius;
                        var   provider = def.BuildingComplete.GetComponent <DecorProvider>();
                        // For reference, these do not alter the BuildingComplete
                        def.BaseDecor       = decor;
                        def.BaseDecorRadius = radius;
                        // Actual decor provider
                        if (provider != null)
                        {
                            PUtil.LogDebug("Patched: {0} Decor: {1:F1} Radius: {2:D}".F(id,
                                                                                        decor, radius));
                            provider.baseDecor  = decor;
                            provider.baseRadius = radius;
                        }
                    }
                }
                editDecor.Recycle();
            }
            // Patch in the debris decor
            var baseOreTemplate = typeof(EntityTemplates).GetFieldSafe("baseOreTemplate",
                                                                       true)?.GetValue(null) as GameObject;
            DecorProvider component;

            if (baseOreTemplate != null && (component = baseOreTemplate.
                                                        GetComponent <DecorProvider>()) != null)
            {
                int radius = Math.Max(1, options.DebrisRadius);
                component.baseDecor  = options.DebrisDecor;
                component.baseRadius = radius;
                PUtil.LogDebug("Debris: {0:F1} radius {1:D}".F(options.DebrisDecor, radius));
            }
            // Patch the suits
            PUtil.LogDebug("Snazzy Suit: {0:D} Warm/Cool Vest: {1:D}".F(options.
                                                                        SnazzySuitDecor, options.VestDecor));
            ClothingWearer.ClothingInfo.FANCY_CLOTHING.decorMod = options.SnazzySuitDecor;
            ClothingWearer.ClothingInfo.COOL_CLOTHING.decorMod  = options.VestDecor;
            ClothingWearer.ClothingInfo.WARM_CLOTHING.decorMod  = options.VestDecor;
        }
Пример #9
0
        public static void PickAllNonAlloc(List <ProbeHit> hits, ProbeFilter filter, SceneView sceneView, Vector2 guiPosition, int limit = DefaultLimit)
        {
            var screenPosition = HandleUtility.GUIPointToScreenPixelCoordinate(guiPosition);
            var ray3D          = HandleUtility.GUIPointToWorldRay(guiPosition);
            var worldPosition  = sceneView.camera.ScreenToWorldPoint(screenPosition);
            var layerMask      = PeekPlugin.Configuration.probeLayerMask;

            var raycastHits = ArrayPool <RaycastHit> .New(limit);

            var overlapHits = ArrayPool <Collider2D> .New(limit);

            var handleHits = HashSetPool <GameObject> .New();

            var ancestorHits = HashSetPool <ProbeHit> .New();

#if PROBUILDER_4_OR_NEWER
            var proBuilderHits = ListPool <ProbeHit> .New();
#endif

            var gameObjectHits = DictionaryPool <GameObject, ProbeHit> .New();

            try
            {
                // Raycast (3D)
                if (filter.raycast)
                {
                    var raycastHitCount = Physics.RaycastNonAlloc(ray3D, raycastHits, Mathf.Infinity, layerMask);

                    for (var i = 0; i < raycastHitCount; i++)
                    {
                        var raycastHit = raycastHits[i];

#if UNITY_2019_2_OR_NEWER
                        if (SceneVisibilityManager.instance.IsHidden(raycastHit.transform.gameObject))
                        {
                            continue;
                        }
#endif

                        var gameObject = raycastHit.transform.gameObject;

                        if (!gameObjectHits.TryGetValue(gameObject, out var hit))
                        {
                            hit = new ProbeHit(gameObject);
                        }

                        hit.point    = raycastHit.point;
                        hit.distance = raycastHit.distance;

                        gameObjectHits[gameObject] = hit;
                    }
                }

                // Overlap (2D)
                if (filter.overlap)
                {
                    var overlapHitCount = Physics2D.OverlapPointNonAlloc(worldPosition, overlapHits, layerMask);

                    for (var i = 0; i < overlapHitCount; i++)
                    {
                        var overlapHit = overlapHits[i];

#if UNITY_2019_2_OR_NEWER
                        if (SceneVisibilityManager.instance.IsHidden(overlapHit.transform.gameObject))
                        {
                            continue;
                        }
#endif

                        var gameObject = overlapHit.transform.gameObject;

                        if (!gameObjectHits.TryGetValue(gameObject, out var hit))
                        {
                            hit = new ProbeHit(gameObject);
                        }

                        hit.distance = hit.distance ?? Vector3.Distance(overlapHit.transform.position, worldPosition);

                        gameObjectHits[gameObject] = hit;
                    }
                }

                // Handles (Editor Default)
                if (filter.handles && canPickHandles)
                {
                    PickAllHandlesNonAlloc(handleHits, guiPosition, limit);

                    foreach (var handleHit in handleHits)
                    {
                        var gameObject = handleHit;

                        if (!gameObjectHits.TryGetValue(gameObject, out var hit))
                        {
                            hit = new ProbeHit(gameObject);
                        }

                        hit.distance = hit.distance ?? Vector3.Distance(handleHit.transform.position, worldPosition);

                        gameObjectHits[gameObject] = hit;
                    }
                }

                // Ancestors
                foreach (var gameObjectHit in gameObjectHits)
                {
                    var gameObject = gameObjectHit.Key;
                    var hit        = gameObjectHit.Value;

                    var parent = gameObject.transform.parent;

                    int depth = 0;

                    while (parent != null)
                    {
                        var parentGameObject = parent.gameObject;

                        var parentHit = new ProbeHit(parentGameObject);
                        parentHit.groupGameObject = gameObject;
                        parentHit.distance        = hit.distance ?? Vector3.Distance(parentHit.transform.position, worldPosition);
                        parentHit.groupOrder      = 1000 + depth;

                        ancestorHits.Add(parentHit);

                        parent = parent.parent;
                        depth++;
                    }
                }

#if PROBUILDER_4_OR_NEWER
                // ProBuilder
                if (filter.proBuilder && ProBuilderEditor.instance != null)
                {
                    var proBuilderMeshes = ListPool <ProBuilderMesh> .New();

                    try
                    {
                        foreach (var gameObjectHit in gameObjectHits.Values)
                        {
                            var proBuilderMesh = gameObjectHit.gameObject.GetComponent <ProBuilderMesh>();

                            if (proBuilderMesh != null)
                            {
                                proBuilderMeshes.Add(proBuilderMesh);
                            }
                        }

                        PickProBuilderElementsNonAlloc(proBuilderHits, proBuilderMeshes, sceneView, guiPosition);
                    }
                    finally
                    {
                        proBuilderMeshes.Free();
                    }
                }
#endif

                // Prepare final hits
                hits.Clear();

                // Add hits
                foreach (var gameObjectHit in gameObjectHits.Values)
                {
                    hits.Add(gameObjectHit);
                }

                foreach (var ancestorHit in ancestorHits)
                {
                    hits.Add(ancestorHit);
                }

#if PROBUILDER_4_OR_NEWER
                foreach (var proBuilderHit in proBuilderHits)
                {
                    hits.Add(proBuilderHit);
                }
#endif

                // Sort by distance
                hits.Sort(compareHits);
            }
            finally
            {
                raycastHits.Free();
                overlapHits.Free();
                handleHits.Free();
                ancestorHits.Free();

#if PROBUILDER_4_OR_NEWER
                proBuilderHits.Free();
#endif

                gameObjectHits.Free();
            }
        }
Пример #10
0
        /// <summary>
        /// Applied before UpdatePickups runs. A more optimized UpdatePickups whose aggregate
        /// runtime on a test world dropped from ~60 ms/1000 ms to ~45 ms/1000 ms.
        /// </summary>
        internal static bool BeforeUpdatePickups(FetchManager.FetchablesByPrefabId __instance,
                                                 Navigator worker_navigator, GameObject worker_go)
        {
            var canBePickedUp = Allocate();
            var pathCosts     = DictionaryPool <int, int, FetchManager> .Allocate();

            var finalPickups = __instance.finalPickups;
            // Will reflect the changes from Waste Not, Want Not and No Manual Delivery
            var  comparer       = FetchManager.ComparerIncludingPriority;
            bool needThreadSafe = FastTrackOptions.Instance.PickupOpts;
            var  fetchables     = __instance.fetchables.GetDataList();
            int  n = fetchables.Count;

            for (int i = 0; i < n; i++)
            {
                var fetchable = fetchables[i];
                var target    = fetchable.pickupable;
                int cell      = target.cachedCell;
                if (target.CouldBePickedUpByMinion(worker_go))
                {
                    // Look for cell cost, share costs across multiple queries to a cell
                    // If this is being run synchronous, no issue, otherwise the GSP patch will
                    // avoid races on the scene partitioner
                    if (!pathCosts.TryGetValue(cell, out int cost))
                    {
                        if (needThreadSafe)
                        {
                            worker_navigator.GetNavigationCostNU(target, cell, out cost);
                        }
                        else
                        {
                            cost = worker_navigator.GetNavigationCost(target);
                        }
                        pathCosts.Add(cell, cost);
                    }
                    // Exclude unreachable items
                    if (cost >= 0)
                    {
                        int hash      = fetchable.tagBitsHash;
                        var key       = new PickupTagKey(hash, target.KPrefabID);
                        var candidate = new FetchManager.Pickup {
                            pickupable     = target, tagBitsHash = hash, PathCost = (ushort)cost,
                            masterPriority = fetchable.masterPriority, freshness = fetchable.
                                                                                   freshness, foodQuality = fetchable.foodQuality
                        };
                        if (canBePickedUp.TryGetValue(key, out FetchManager.Pickup current))
                        {
                            // Is the new one better?
                            int result = comparer.Compare(candidate, current);
                            if (result < 0 || (result == 0 && candidate.pickupable.
                                               UnreservedAmount > current.pickupable.UnreservedAmount))
                            {
                                canBePickedUp[key] = candidate;
                            }
                        }
                        else
                        {
                            canBePickedUp.Add(key, candidate);
                        }
                    }
                }
            }
            // Copy the remaining pickups to the list, there are now way fewer because only
            // one was kept per possible tag bits (with the highest priority, best path cost,
            // etc)
            finalPickups.Clear();
            foreach (var pickup in canBePickedUp.Values)
            {
                finalPickups.Add(pickup);
            }
            pathCosts.Recycle();
            Recycle(canBePickedUp);
            // Prevent the original method from running
            return(false);
        }
Пример #11
0
 public void Dispose()
 {
     DictionaryPool.Release(Dictionary);
 }
Пример #12
0
 internal static PooledDictionary <TKey, TValue> Make()
 {
     return(new PooledDictionary <TKey, TValue>(DictionaryPool.Get()));
 }
Пример #13
0
        public void RegisterReplacementsForNames(params string[] origNames)
        {
            var needsTranslation = ListPool <string> .Get();

            try
            {
                needsTranslation.Capacity = origNames.Length;

                var fastReplacements = DictionaryPool <string, string> .Get();

                try
                {
                    foreach (var origString in origNames)
                    {
                        if (TranslationHelper.TryTranslateName(NameScope.DefaultNameScope, origString,
                                                               out var translatedString))
                        {
                            //fastReplacements[origString] = origString;
                            fastReplacements[translatedString] = translatedString;
                        }
                        else
                        {
                            needsTranslation.Add(origString);
                        }
                    }

                    if (fastReplacements.Count > 0)
                    {
                        RegisterReplacementStrings(fastReplacements);
                    }
                }
                finally
                {
                    DictionaryPool <string, string> .Release(fastReplacements);
                }

                foreach (var toTranslate in needsTranslation)
                {
                    void ResultHandler(ITranslationResult result)
                    {
                        var replacements = DictionaryPool <string, string> .Get();

                        try
                        {
                            if (!TranslationHelper.NameNeedsTranslation(toTranslate, NameScope.DefaultNameScope))
                            {
                                replacements[toTranslate] = toTranslate;
                            }

                            if (result.Succeeded)
                            {
                                replacements[result.TranslatedText] = result.TranslatedText;
                            }

                            RegisterReplacementStrings(replacements);
                        }
                        finally
                        {
                            DictionaryPool <string, string> .Release(replacements);
                        }
                    }

                    GeBoAPI.Instance.AutoTranslationHelper.TranslateAsync(toTranslate,
                                                                          NameScope.DefaultNameScope.TranslationScope, ResultHandler);
                }
            }
            finally
            {
                ListPool <string> .Release(needsTranslation);
            }
        }
Пример #14
0
        public void SendMetricsEvent()
        {
            ListPool <string, Manager> .PooledList pooledList = ListPool <string, Manager> .Allocate();

            foreach (Mod mod in mods)
            {
                if (mod.enabled)
                {
                    pooledList.Add(mod.title);
                }
            }
            DictionaryPool <string, object, Manager> .PooledDictionary pooledDictionary = DictionaryPool <string, object, Manager> .Allocate();

            pooledDictionary["ModCount"] = pooledList.Count;
            pooledDictionary["Mods"]     = pooledList;
            ThreadedHttps <KleiMetrics> .Instance.SendEvent(pooledDictionary);

            pooledDictionary.Recycle();
            pooledList.Recycle();
            KCrashReporter.haveActiveMods = (pooledList.Count > 0);
        }
Пример #15
0
        protected void OnEnable()
        {
            m_isExpandedById = DictionaryPool <string, bool> .Get();

            OnEnableEntityStoreEditor();
        }
        public override void EvaluateDynamicMaterialSlots()
        {
            var dynamicInputSlotsToCompare = DictionaryPool <DynamicVectorMaterialSlot, ConcreteSlotValueType> .Get();

            var skippedDynamicSlots = ListPool <DynamicVectorMaterialSlot> .Get();

            var dynamicMatrixInputSlotsToCompare = DictionaryPool <DynamicMatrixMaterialSlot, ConcreteSlotValueType> .Get();

            var skippedDynamicMatrixSlots = ListPool <DynamicMatrixMaterialSlot> .Get();

            // iterate the input slots
            using (var tempSlots = PooledList <MaterialSlot> .Get())
            {
                GetInputSlots(tempSlots);
                foreach (var inputSlot in tempSlots)
                {
                    inputSlot.hasError = false;

                    // if there is a connection
                    var edges = owner.GetEdges(inputSlot.slotReference).ToList();
                    if (!edges.Any())
                    {
                        if (inputSlot is DynamicVectorMaterialSlot)
                        {
                            skippedDynamicSlots.Add(inputSlot as DynamicVectorMaterialSlot);
                        }
                        if (inputSlot is DynamicMatrixMaterialSlot)
                        {
                            skippedDynamicMatrixSlots.Add(inputSlot as DynamicMatrixMaterialSlot);
                        }
                        continue;
                    }

                    // get the output details
                    var outputSlotRef = edges[0].outputSlot;
                    var outputNode    = outputSlotRef.node;
                    if (outputNode == null)
                    {
                        continue;
                    }

                    var outputSlot = outputNode.FindOutputSlot <MaterialSlot>(outputSlotRef.slotId);
                    if (outputSlot == null)
                    {
                        continue;
                    }

                    if (outputSlot.hasError)
                    {
                        inputSlot.hasError = true;
                        continue;
                    }

                    var outputConcreteType = outputSlot.concreteValueType;
                    // dynamic input... depends on output from other node.
                    // we need to compare ALL dynamic inputs to make sure they
                    // are compatable.
                    if (inputSlot is DynamicVectorMaterialSlot)
                    {
                        dynamicInputSlotsToCompare.Add((DynamicVectorMaterialSlot)inputSlot, outputConcreteType);
                        continue;
                    }
                    else if (inputSlot is DynamicMatrixMaterialSlot)
                    {
                        dynamicMatrixInputSlotsToCompare.Add((DynamicMatrixMaterialSlot)inputSlot, outputConcreteType);
                        continue;
                    }
                }

                // and now dynamic matrices
                var dynamicMatrixType = ConvertDynamicMatrixInputTypeToConcrete(dynamicMatrixInputSlotsToCompare.Values);
                foreach (var dynamicKvP in dynamicMatrixInputSlotsToCompare)
                {
                    dynamicKvP.Key.SetConcreteType(dynamicMatrixType);
                }
                foreach (var skippedSlot in skippedDynamicMatrixSlots)
                {
                    skippedSlot.SetConcreteType(dynamicMatrixType);
                }

                // we can now figure out the dynamic slotType
                // from here set all the
                var dynamicType = SlotValueHelper.ConvertMatrixToVectorType(dynamicMatrixType);
                foreach (var dynamicKvP in dynamicInputSlotsToCompare)
                {
                    dynamicKvP.Key.SetConcreteType(dynamicType);
                }
                foreach (var skippedSlot in skippedDynamicSlots)
                {
                    skippedSlot.SetConcreteType(dynamicType);
                }

                tempSlots.Clear();
                GetInputSlots(tempSlots);
                bool inputError = tempSlots.Any(x => x.hasError);
                if (inputError)
                {
                    owner.AddConcretizationError(objectId, string.Format("Node {0} had input error", objectId));
                    hasError = true;
                }
                // configure the output slots now
                // their slotType will either be the default output slotType
                // or the above dynanic slotType for dynamic nodes
                // or error if there is an input error
                tempSlots.Clear();
                GetOutputSlots(tempSlots);
                foreach (var outputSlot in tempSlots)
                {
                    outputSlot.hasError = false;

                    if (inputError)
                    {
                        outputSlot.hasError = true;
                        continue;
                    }

                    if (outputSlot is DynamicVectorMaterialSlot)
                    {
                        (outputSlot as DynamicVectorMaterialSlot).SetConcreteType(dynamicType);
                        continue;
                    }
                    else if (outputSlot is DynamicMatrixMaterialSlot)
                    {
                        (outputSlot as DynamicMatrixMaterialSlot).SetConcreteType(dynamicMatrixType);
                        continue;
                    }
                }


                tempSlots.Clear();
                GetOutputSlots(tempSlots);
                if (tempSlots.Any(x => x.hasError))
                {
                    owner.AddConcretizationError(objectId, string.Format("Node {0} had output error", objectId));
                    hasError = true;
                }
            }

            CalculateNodeHasError();

            ListPool <DynamicVectorMaterialSlot> .Release(skippedDynamicSlots);

            DictionaryPool <DynamicVectorMaterialSlot, ConcreteSlotValueType> .Release(dynamicInputSlotsToCompare);

            ListPool <DynamicMatrixMaterialSlot> .Release(skippedDynamicMatrixSlots);

            DictionaryPool <DynamicMatrixMaterialSlot, ConcreteSlotValueType> .Release(dynamicMatrixInputSlotsToCompare);
        }
Пример #17
0
        internal static GenericMenu BuildPopupList(Object target, UnityEventBase dummyEvent, SerializedProperty listener)
        {
            //special case for components... we want all the game objects targets there!
            var targetToUse = target;

            if (targetToUse is Component)
            {
                targetToUse = (target as Component).gameObject;
            }

            // find the current event target...
            var methodName = listener.FindPropertyRelative(kMethodNamePath);

            var menu = new GenericMenu();

            menu.AddItem(new GUIContent(kNoFunctionString),
                         string.IsNullOrEmpty(methodName.stringValue),
                         ClearEventFunction,
                         new UnityEventFunction(listener, null, null, PersistentListenerMode.EventDefined));

            if (targetToUse == null)
            {
                return(menu);
            }

            menu.AddSeparator("");

            // figure out the signature of this delegate...
            // The property at this stage points to the 'container' and has the field name
            Type delegateType = dummyEvent.GetType();

            // check out the signature of invoke as this is the callback!
            MethodInfo delegateMethod         = delegateType.GetMethod("Invoke");
            var        delegateArgumentsTypes = delegateMethod.GetParameters().Select(x => x.ParameterType).ToArray();

            var duplicateNames = DictionaryPool <string, int> .Get();

            var duplicateFullNames = DictionaryPool <string, int> .Get();

            GeneratePopUpForType(menu, targetToUse, targetToUse.GetType().Name, listener, delegateArgumentsTypes);
            duplicateNames[targetToUse.GetType().Name] = 0;
            if (targetToUse is GameObject)
            {
                Component[] comps = (targetToUse as GameObject).GetComponents <Component>();

                // Collect all the names and record how many times the same name is used.
                foreach (Component comp in comps)
                {
                    var duplicateIndex = 0;
                    if (duplicateNames.TryGetValue(comp.GetType().Name, out duplicateIndex))
                    {
                        duplicateIndex++;
                    }
                    duplicateNames[comp.GetType().Name] = duplicateIndex;
                }

                foreach (Component comp in comps)
                {
                    if (comp == null)
                    {
                        continue;
                    }

                    var    compType       = comp.GetType();
                    string targetName     = compType.Name;
                    int    duplicateIndex = 0;

                    // Is this name used multiple times? If so then use the full name plus an index if there are also duplicates of this. (case 1309997)
                    if (duplicateNames[compType.Name] > 0)
                    {
                        if (duplicateFullNames.TryGetValue(compType.FullName, out duplicateIndex))
                        {
                            targetName = $"{compType.FullName} ({duplicateIndex})";
                        }
                        else
                        {
                            targetName = compType.FullName;
                        }
                    }
                    GeneratePopUpForType(menu, comp, targetName, listener, delegateArgumentsTypes);
                    duplicateFullNames[compType.FullName] = duplicateIndex + 1;
                }

                DictionaryPool <string, int> .Release(duplicateNames);

                DictionaryPool <string, int> .Release(duplicateFullNames);
            }
            return(menu);
        }
Пример #18
0
    public void Render1000ms(float dt)
    {
        DictionaryPool <int, ListPool <FetchList2, FetchListStatusItemUpdater> .PooledList, FetchListStatusItemUpdater> .PooledDictionary pooledDictionary = DictionaryPool <int, ListPool <FetchList2, FetchListStatusItemUpdater> .PooledList, FetchListStatusItemUpdater> .Allocate();

        foreach (FetchList2 fetchList in fetchLists)
        {
            if (!((Object)fetchList.Destination == (Object)null))
            {
                ListPool <FetchList2, FetchListStatusItemUpdater> .PooledList value = null;
                int instanceID = fetchList.Destination.GetInstanceID();
                if (!pooledDictionary.TryGetValue(instanceID, out value))
                {
                    value = (pooledDictionary[instanceID] = ListPool <FetchList2, FetchListStatusItemUpdater> .Allocate());
                }
                value.Add(fetchList);
            }
        }
        DictionaryPool <Tag, float, FetchListStatusItemUpdater> .PooledDictionary pooledDictionary2 = DictionaryPool <Tag, float, FetchListStatusItemUpdater> .Allocate();

        DictionaryPool <Tag, float, FetchListStatusItemUpdater> .PooledDictionary pooledDictionary3 = DictionaryPool <Tag, float, FetchListStatusItemUpdater> .Allocate();

        foreach (KeyValuePair <int, ListPool <FetchList2, FetchListStatusItemUpdater> .PooledList> item in pooledDictionary)
        {
            ListPool <Tag, FetchListStatusItemUpdater> .PooledList pooledList2 = ListPool <Tag, FetchListStatusItemUpdater> .Allocate();

            Storage destination = item.Value[0].Destination;
            foreach (FetchList2 item2 in item.Value)
            {
                item2.UpdateRemaining();
                Dictionary <Tag, float> remaining = item2.GetRemaining();
                foreach (KeyValuePair <Tag, float> item3 in remaining)
                {
                    if (!pooledList2.Contains(item3.Key))
                    {
                        pooledList2.Add(item3.Key);
                    }
                }
            }
            ListPool <Pickupable, FetchListStatusItemUpdater> .PooledList pooledList3 = ListPool <Pickupable, FetchListStatusItemUpdater> .Allocate();

            foreach (GameObject item4 in destination.items)
            {
                if (!((Object)item4 == (Object)null))
                {
                    Pickupable component = item4.GetComponent <Pickupable>();
                    if (!((Object)component == (Object)null))
                    {
                        pooledList3.Add(component);
                    }
                }
            }
            DictionaryPool <Tag, float, FetchListStatusItemUpdater> .PooledDictionary pooledDictionary4 = DictionaryPool <Tag, float, FetchListStatusItemUpdater> .Allocate();

            foreach (Tag item5 in pooledList2)
            {
                float num = 0f;
                foreach (Pickupable item6 in pooledList3)
                {
                    if (item6.KPrefabID.HasTag(item5))
                    {
                        num += item6.TotalAmount;
                    }
                }
                pooledDictionary4[item5] = num;
            }
            foreach (Tag item7 in pooledList2)
            {
                if (!pooledDictionary2.ContainsKey(item7))
                {
                    pooledDictionary2[item7] = WorldInventory.Instance.GetTotalAmount(item7);
                }
                if (!pooledDictionary3.ContainsKey(item7))
                {
                    pooledDictionary3[item7] = WorldInventory.Instance.GetAmount(item7);
                }
            }
            foreach (FetchList2 item8 in item.Value)
            {
                bool should_add  = false;
                bool should_add2 = true;
                bool should_add3 = false;
                Dictionary <Tag, float> remaining2 = item8.GetRemaining();
                foreach (KeyValuePair <Tag, float> item9 in remaining2)
                {
                    Tag   key           = item9.Key;
                    float value2        = item9.Value;
                    float num2          = pooledDictionary4[key];
                    float b             = pooledDictionary2[key];
                    float num3          = pooledDictionary3[key];
                    float num4          = Mathf.Min(value2, b);
                    float num5          = num3 + num4;
                    float minimumAmount = item8.GetMinimumAmount(key);
                    if (num2 + num5 < minimumAmount)
                    {
                        should_add = true;
                    }
                    if (num5 < value2)
                    {
                        should_add2 = false;
                    }
                    if (num2 + num5 > value2 && value2 > num5)
                    {
                        should_add3 = true;
                    }
                }
                item8.UpdateStatusItem(Db.Get().BuildingStatusItems.WaitingForMaterials, ref item8.waitingForMaterialsHandle, should_add2);
                item8.UpdateStatusItem(Db.Get().BuildingStatusItems.MaterialsUnavailable, ref item8.materialsUnavailableHandle, should_add);
                item8.UpdateStatusItem(Db.Get().BuildingStatusItems.MaterialsUnavailableForRefill, ref item8.materialsUnavailableForRefillHandle, should_add3);
            }
            pooledDictionary4.Recycle();
            pooledList3.Recycle();
            pooledList2.Recycle();
            item.Value.Recycle();
        }
        pooledDictionary3.Recycle();
        pooledDictionary2.Recycle();
        pooledDictionary.Recycle();
    }
Пример #19
0
    private void UpdateOpenOrders()
    {
        ComplexRecipe[] recipes = GetRecipes();
        if (recipes.Length != openOrderCounts.Count)
        {
            Debug.LogErrorFormat(base.gameObject, "Recipe count {0} doesn't match open order count {1}", recipes.Length, openOrderCounts.Count);
        }
        bool flag = false;

        hasOpenOrders = false;
        for (int i = 0; i < recipes.Length; i++)
        {
            ComplexRecipe recipe = recipes[i];
            int           recipePrefetchCount = GetRecipePrefetchCount(recipe);
            if (recipePrefetchCount > 0)
            {
                hasOpenOrders = true;
            }
            int num = openOrderCounts[i];
            if (num != recipePrefetchCount)
            {
                if (recipePrefetchCount < num)
                {
                    flag = true;
                }
                openOrderCounts[i] = recipePrefetchCount;
            }
        }
        DictionaryPool <Tag, float, ComplexFabricator> .PooledDictionary pooledDictionary = DictionaryPool <Tag, float, ComplexFabricator> .Allocate();

        DictionaryPool <Tag, float, ComplexFabricator> .PooledDictionary pooledDictionary2 = DictionaryPool <Tag, float, ComplexFabricator> .Allocate();

        for (int j = 0; j < openOrderCounts.Count; j++)
        {
            int num2 = openOrderCounts[j];
            if (num2 > 0)
            {
                ComplexRecipe complexRecipe = recipe_list[j];
                ComplexRecipe.RecipeElement[] ingredients = complexRecipe.ingredients;
                ComplexRecipe.RecipeElement[] array       = ingredients;
                foreach (ComplexRecipe.RecipeElement recipeElement in array)
                {
                    pooledDictionary[recipeElement.material] = inStorage.GetAmountAvailable(recipeElement.material);
                }
            }
        }
        for (int l = 0; l < recipe_list.Length; l++)
        {
            int num3 = openOrderCounts[l];
            if (num3 > 0)
            {
                ComplexRecipe complexRecipe2 = recipe_list[l];
                ComplexRecipe.RecipeElement[] ingredients2 = complexRecipe2.ingredients;
                ComplexRecipe.RecipeElement[] array2       = ingredients2;
                foreach (ComplexRecipe.RecipeElement recipeElement2 in array2)
                {
                    float num4 = recipeElement2.amount * (float)num3;
                    float num5 = num4 - pooledDictionary[recipeElement2.material];
                    if (num5 > 0f)
                    {
                        pooledDictionary2.TryGetValue(recipeElement2.material, out float value);
                        pooledDictionary2[recipeElement2.material] = value + num5;
                        pooledDictionary[recipeElement2.material]  = 0f;
                    }
                    else
                    {
                        DictionaryPool <Tag, float, ComplexFabricator> .PooledDictionary pooledDictionary3;
                        Tag material;
                        (pooledDictionary3 = pooledDictionary)[material = recipeElement2.material] = pooledDictionary3[material] - num4;
                    }
                }
            }
        }
        if (flag)
        {
            CancelFetches();
        }
        if (pooledDictionary2.Count > 0)
        {
            UpdateFetches(pooledDictionary2);
        }
        UpdateMaterialNeeds(pooledDictionary2);
        pooledDictionary2.Recycle();
        pooledDictionary.Recycle();
    }
Пример #20
0
        private static void FreeHUpdateUI()
        {
            // for 3P the character names show in one extra place that the standard check doesn't cover.
            // easiest to just update each time.
            var freeHScene = Object.FindObjectOfType <FreeHScene>();

            if (freeHScene == null)
            {
                return;
            }
            var member = Traverse.Create(freeHScene).Field <FreeHScene.Member>("member")?.Value;

            if (member == null)
            {
                return;
            }

            Action <string> GetUpdateUIField(string fieldName)
            {
                void Callback(string value)
                {
                    if (string.IsNullOrEmpty(value) || freeHScene == null)
                    {
                        return;
                    }
                    var field = Traverse.Create(freeHScene).Field <TextMeshProUGUI>(fieldName)?.Value;

                    if (field == null)
                    {
                        return;
                    }
                    field.text = value;
                }

                return(Callback);
            }

            Action <string> GetUpdateTextCallback(string path)
            {
                void Callback(string value)
                {
                    if (string.IsNullOrEmpty(value))
                    {
                        return;
                    }

                    var obj = GameObject.Find(path);

                    if (obj == null)
                    {
                        return;
                    }
                    var uiText = obj.GetComponent <Text>();

                    if (uiText == null)
                    {
                        return;
                    }
                    uiText.text = value;
                }

                return(Callback);
            }

            var callbackMap = DictionaryPool <SaveData.Heroine, List <Action <string> > > .Get();

            try
            {
                if (member.resultHeroine.HasValue && member.resultHeroine.Value != null)
                {
                    if (!callbackMap.TryGetValue(member.resultHeroine.Value, out var callbacks))
                    {
                        callbackMap[member.resultHeroine.Value] =
                            callbacks = GeBoCommon.Utilities.ListPool <Action <string> > .Get();
                    }

                    callbacks.Add(GetUpdateUIField("textFemaleName1"));
                }

                if (member.resultPartner.HasValue && member.resultPartner.Value != null)
                {
                    if (!callbackMap.TryGetValue(member.resultPartner.Value, out var callbacks))
                    {
                        callbackMap[member.resultPartner.Value] =
                            callbacks = GeBoCommon.Utilities.ListPool <Action <string> > .Get();
                    }

                    callbacks.Add(GetUpdateUIField("textFemaleName2"));
                }

                // leaving traverse to work with earlier versions
                var resultDarkHeroine = Traverse.Create(member)
                                        .Field <ReactiveProperty <SaveData.Heroine> >("resultDarkHeroine")?.Value;
                if (resultDarkHeroine != null && resultDarkHeroine.HasValue && resultDarkHeroine.Value != null)
                {
                    if (!callbackMap.TryGetValue(resultDarkHeroine.Value, out var callbacks))
                    {
                        callbackMap[resultDarkHeroine.Value] =
                            callbacks = GeBoCommon.Utilities.ListPool <Action <string> > .Get();
                    }

                    callbacks.Add(
                        // ReSharper disable once StringLiteralTypo
                        GetUpdateTextCallback("/FreeHScene/Canvas/Panel/Dark/FemaleInfomation/Name/TextMeshPro Text"));
                }

                foreach (var entry in callbackMap)
                {
                    foreach (var heroineChaFile in entry.Key.GetRelatedChaFiles())
                    {
                        heroineChaFile.TranslateFullName(
                            translated =>
                        {
                            foreach (var callback in entry.Value)
                            {
                                try
                                {
                                    callback(translated);
                                }
                                catch (Exception err)
                                {
                                    Logger.LogException(err, freeHScene, nameof(FreeHUpdateUI));
                                }
                            }
                        });
                    }
                }
            }
            finally
            {
                foreach (var entry in callbackMap)
                {
                    GeBoCommon.Utilities.ListPool <Action <string> > .Release(entry.Value);
                }
                DictionaryPool <SaveData.Heroine, List <Action <string> > > .Release(callbackMap);
            }
        }
        /// <summary>
        /// The better and more optimized UpdatePickups. Aggregate runtime on a test world
        /// dropped from ~60 ms/1000 ms to ~45 ms/1000 ms.
        /// </summary>
        private static void UpdatePickups(FetchManager.FetchablesByPrefabId targets,
                                          Navigator navigator, GameObject worker)
        {
            var canBePickedUp = DictionaryPool <PickupTagKey, FetchManager.Pickup,
                                                FetchManager> .Allocate();

            var pathCosts = DictionaryPool <int, int, FetchManager> .Allocate();

            var finalPickups = targets.finalPickups;
            // Will reflect the changes from Waste Not, Want Not and No Manual Delivery
            var comparer = PICKUP_COMPARER.Get(null);

            foreach (var fetchable in targets.fetchables.GetDataList())
            {
                var target = fetchable.pickupable;
                int cell   = target.cachedCell;
                if (target.CouldBePickedUpByMinion(worker))
                {
                    // Look for cell cost, share costs across multiple queries to a cell
                    if (!pathCosts.TryGetValue(cell, out int cost))
                    {
                        pathCosts.Add(cell, cost = target.GetNavigationCost(navigator, cell));
                    }
                    // Exclude unreachable items
                    if (cost >= 0)
                    {
                        int hash      = fetchable.tagBitsHash;
                        var key       = new PickupTagKey(hash, target.KPrefabID);
                        var candidate = new FetchManager.Pickup {
                            pickupable     = target, tagBitsHash = hash, PathCost = (ushort)cost,
                            masterPriority = fetchable.masterPriority, freshness = fetchable.
                                                                                   freshness, foodQuality = fetchable.foodQuality
                        };
                        if (canBePickedUp.TryGetValue(key, out FetchManager.Pickup current))
                        {
                            // Is the new one better?
                            int result = comparer.Compare(current, candidate);
                            if (result > 0 || (result == 0 && candidate.pickupable.
                                               UnreservedAmount > current.pickupable.UnreservedAmount))
                            {
                                canBePickedUp[key] = candidate;
                            }
                        }
                        else
                        {
                            canBePickedUp.Add(key, candidate);
                        }
                    }
                }
            }
            // Copy the remaining pickups to the list, there are now way fewer because only
            // one was kept per possible tag bits (with the highest priority, best path cost,
            // etc)
            finalPickups.Clear();
            foreach (var pair in canBePickedUp)
            {
                finalPickups.Add(pair.Value);
            }
            pathCosts.Recycle();
            canBePickedUp.Recycle();
        }
Пример #22
0
        public void PooledDictionary_Simple3()
        {
            var pool = DictionaryPool <string, int> .Create(4, 16);

            PooledDictionary_Simple_Impl(pool);
        }
Пример #23
0
 public SuperGumpLayout()
 {
     _Entries = DictionaryPool <String, Action> .AcquireObject();
 }
Пример #24
0
        internal static void ExportSelected(LocaleIdentifier source, string dir, string name, XliffVersion version, Dictionary <StringTableCollection, HashSet <int> > collectionsWithSelectedIndexes, ITaskReporter reporter = null)
        {
            var documents = DictionaryPool <LocaleIdentifier, IXliffDocument> .Get();

            try
            {
                // Used for reporting
                int   totalTasks = collectionsWithSelectedIndexes.Sum(c => c.Value.Count);
                float taskStep   = 1.0f / (totalTasks * 2.0f);
                float progress   = 0;
                reporter?.Start($"Exporting {totalTasks} String Tables to XLIFF", string.Empty);

                foreach (var kvp in collectionsWithSelectedIndexes)
                {
                    var stringTableCollection = kvp.Key;
                    var sourceTable           = stringTableCollection.GetTable(source) as StringTable;
                    if (sourceTable == null)
                    {
                        var message = $"Collection {stringTableCollection.TableCollectionName} does not contain a table for the source language {source}";
                        reporter?.Fail(message);
                        throw new Exception(message);
                    }

                    foreach (var stringTableIndex in kvp.Value)
                    {
                        var stringTable = stringTableCollection.StringTables[stringTableIndex];

                        reporter?.ReportProgress($"Generating document for {stringTable.name}", progress);
                        progress += taskStep;

                        if (!documents.TryGetValue(stringTable.LocaleIdentifier, out var targetDoc))
                        {
                            targetDoc = CreateDocument(source, stringTable.LocaleIdentifier, version);
                            documents[stringTable.LocaleIdentifier] = targetDoc;
                        }

                        AddTableToDocument(targetDoc, sourceTable, stringTable);
                    }
                }

                // Now write the files
                foreach (var doc in documents)
                {
                    var cleanName = CleanFileName(name);
                    var fileName  = $"{cleanName}_{doc.Key.Code}.xlf";
                    var filePath  = Path.Combine(dir, fileName);

                    reporter?.ReportProgress($"Writing {fileName}", progress);
                    progress += taskStep;
                    using (var stream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
                    {
                        doc.Value.Serialize(stream);
                    }
                }

                reporter?.Completed($"Finished exporting");
            }
            catch (Exception e)
            {
                reporter?.Fail(e.Message);
                throw;
            }
            finally
            {
                DictionaryPool <LocaleIdentifier, IXliffDocument> .Release(documents);
            }
        }
        public List <Callback> GenerateDependencyGraph()
        {
            var callbacks     = GetCallbacks();
            var packageLookup = DictionaryPool <string, List <Callback> > .Get();

            var assemblyLookup = DictionaryPool <string, List <Callback> > .Get();

            var classLookup = DictionaryPool <Type, Callback> .Get();

            // First generate our lookups for class, assembly and package.
            foreach (var cb in callbacks)
            {
                classLookup[cb.classType] = cb;

                var assemblyName = cb.classType.Assembly.GetName().Name;
                if (!assemblyLookup.TryGetValue(assemblyName, out var assemblies))
                {
                    assemblies = new List <Callback>();
                    assemblyLookup[assemblyName] = assemblies;
                }
                assemblies.Add(cb);

                var package = cb.packageName;
                if (package != null)
                {
                    if (!packageLookup.TryGetValue(package, out var packages))
                    {
                        packages = new List <Callback>();
                        packageLookup[package] = packages;
                    }
                    packages.Add(cb);
                }
            }

            // Sort the methods so that the output order is deterministic.
            callbacks.Sort();

            // Now connect the dependency graph nodes
            foreach (var dependency in callbacks)
            {
                // Dependency by class
                foreach (var runAfter in dependency.GetCustomAttributes <RunAfterClassAttribute>())
                {
                    // Ignore classes that may not exist in the project
                    if (runAfter.classType == null)
                    {
                        continue;
                    }

                    if (classLookup.TryGetValue(runAfter.classType, out var runAfterMethodInfo))
                    {
                        dependency.AddIncomingConnection(runAfterMethodInfo);
                    }
                }
                foreach (var runBefore in dependency.GetCustomAttributes <RunBeforeClassAttribute>())
                {
                    // Ignore classes that may not exist in the project
                    if (runBefore.classType == null)
                    {
                        continue;
                    }

                    if (classLookup.TryGetValue(runBefore.classType, out var runBeforeMethodInfo))
                    {
                        dependency.AddOutgoingConnection(runBeforeMethodInfo);
                    }
                }

                // Dependency by package
                foreach (var runAfter in dependency.GetCustomAttributes <RunAfterPackageAttribute>())
                {
                    if (packageLookup.TryGetValue(runAfter.packageName, out var runAfterMethodInfos))
                    {
                        dependency.AddIncomingConnections(runAfterMethodInfos);
                    }
                }
                foreach (var runBefore in dependency.GetCustomAttributes <RunBeforePackageAttribute>())
                {
                    if (packageLookup.TryGetValue(runBefore.packageName, out var runBeforeMethodInfos))
                    {
                        dependency.AddOutgoingConnections(runBeforeMethodInfos);
                    }
                }

                // Dependency by Assembly
                foreach (var runAfter in dependency.GetCustomAttributes <RunAfterAssemblyAttribute>())
                {
                    if (assemblyLookup.TryGetValue(runAfter.assemblyName, out var runAfterMethodInfos))
                    {
                        dependency.AddIncomingConnections(runAfterMethodInfos);
                    }
                }
                foreach (var runBefore in dependency.GetCustomAttributes <RunBeforeAssemblyAttribute>())
                {
                    if (assemblyLookup.TryGetValue(runBefore.assemblyName, out var runBeforeMethodInfos))
                    {
                        dependency.AddOutgoingConnections(runBeforeMethodInfos);
                    }
                }
            }

            DictionaryPool <string, List <Callback> > .Release(packageLookup);

            DictionaryPool <string, List <Callback> > .Release(assemblyLookup);

            DictionaryPool <Type, Callback> .Release(classLookup);

            return(callbacks);
        }
        public virtual void ValidateNode()
        {
            var isInError    = false;
            var errorMessage = k_validationErrorMessage;

            var dynamicInputSlotsToCompare = DictionaryPool <DynamicVectorMaterialSlot, ConcreteSlotValueType> .Get();

            var skippedDynamicSlots = ListPool <DynamicVectorMaterialSlot> .Get();

            var dynamicMatrixInputSlotsToCompare = DictionaryPool <DynamicMatrixMaterialSlot, ConcreteSlotValueType> .Get();

            var skippedDynamicMatrixSlots = ListPool <DynamicMatrixMaterialSlot> .Get();

            // iterate the input slots
            s_TempSlots.Clear();
            GetInputSlots(s_TempSlots);
            foreach (var inputSlot in s_TempSlots)
            {
                inputSlot.hasError = false;
                // if there is a connection
                var edges = owner.GetEdges(inputSlot.slotReference).ToList();
                if (!edges.Any())
                {
                    if (inputSlot is DynamicVectorMaterialSlot)
                    {
                        skippedDynamicSlots.Add(inputSlot as DynamicVectorMaterialSlot);
                    }
                    if (inputSlot is DynamicMatrixMaterialSlot)
                    {
                        skippedDynamicMatrixSlots.Add(inputSlot as DynamicMatrixMaterialSlot);
                    }
                    continue;
                }

                // get the output details
                var outputSlotRef = edges[0].outputSlot;
                var outputNode    = owner.GetNodeFromGuid(outputSlotRef.nodeGuid);
                if (outputNode == null)
                {
                    continue;
                }

                var outputSlot = outputNode.FindOutputSlot <MaterialSlot>(outputSlotRef.slotId);
                if (outputSlot == null)
                {
                    continue;
                }

                if (outputSlot.hasError)
                {
                    inputSlot.hasError = true;
                    continue;
                }

                var outputConcreteType = outputSlot.concreteValueType;
                // dynamic input... depends on output from other node.
                // we need to compare ALL dynamic inputs to make sure they
                // are compatible.
                if (inputSlot is DynamicVectorMaterialSlot)
                {
                    dynamicInputSlotsToCompare.Add((DynamicVectorMaterialSlot)inputSlot, outputConcreteType);
                    continue;
                }
                else if (inputSlot is DynamicMatrixMaterialSlot)
                {
                    dynamicMatrixInputSlotsToCompare.Add((DynamicMatrixMaterialSlot)inputSlot, outputConcreteType);
                    continue;
                }

                // if we have a standard connection... just check the types work!
                if (!ImplicitConversionExists(outputConcreteType, inputSlot.concreteValueType))
                {
                    inputSlot.hasError = true;
                }
            }

            // we can now figure out the dynamic slotType
            // from here set all the
            var dynamicType = ConvertDynamicInputTypeToConcrete(dynamicInputSlotsToCompare.Values);

            foreach (var dynamicKvP in dynamicInputSlotsToCompare)
            {
                dynamicKvP.Key.SetConcreteType(dynamicType);
            }
            foreach (var skippedSlot in skippedDynamicSlots)
            {
                skippedSlot.SetConcreteType(dynamicType);
            }

            // and now dynamic matrices
            var dynamicMatrixType = ConvertDynamicMatrixInputTypeToConcrete(dynamicMatrixInputSlotsToCompare.Values);

            foreach (var dynamicKvP in dynamicMatrixInputSlotsToCompare)
            {
                dynamicKvP.Key.SetConcreteType(dynamicMatrixType);
            }
            foreach (var skippedSlot in skippedDynamicMatrixSlots)
            {
                skippedSlot.SetConcreteType(dynamicMatrixType);
            }

            s_TempSlots.Clear();
            GetInputSlots(s_TempSlots);
            var inputError = s_TempSlots.Any(x => x.hasError);

            // configure the output slots now
            // their slotType will either be the default output slotType
            // or the above dynamic slotType for dynamic nodes
            // or error if there is an input error
            s_TempSlots.Clear();
            GetOutputSlots(s_TempSlots);
            foreach (var outputSlot in s_TempSlots)
            {
                outputSlot.hasError = false;

                if (inputError)
                {
                    outputSlot.hasError = true;
                    continue;
                }

                if (outputSlot is DynamicVectorMaterialSlot)
                {
                    (outputSlot as DynamicVectorMaterialSlot).SetConcreteType(dynamicType);
                    continue;
                }
                else if (outputSlot is DynamicMatrixMaterialSlot)
                {
                    (outputSlot as DynamicMatrixMaterialSlot).SetConcreteType(dynamicMatrixType);
                    continue;
                }
            }

            isInError |= inputError;
            s_TempSlots.Clear();
            GetOutputSlots(s_TempSlots);
            isInError |= s_TempSlots.Any(x => x.hasError);
            isInError |= CalculateNodeHasError(ref errorMessage);
            hasError   = isInError;

            if (isInError)
            {
                ((GraphData)owner).AddValidationError(tempId, errorMessage);
            }
            else
            {
                ++version;
            }

            ListPool <DynamicVectorMaterialSlot> .Release(skippedDynamicSlots);

            DictionaryPool <DynamicVectorMaterialSlot, ConcreteSlotValueType> .Release(dynamicInputSlotsToCompare);

            ListPool <DynamicMatrixMaterialSlot> .Release(skippedDynamicMatrixSlots);

            DictionaryPool <DynamicMatrixMaterialSlot, ConcreteSlotValueType> .Release(dynamicMatrixInputSlotsToCompare);
        }
Пример #27
0
        private void HandleDirectionYou(Direction moveDirection, Vector2Int negativeEndPosition, Vector2Int positiveEndPosition, Stack <Command> tickCommands)
        {
            var displacement = DirectionUtils.DirectionToDisplacement(moveDirection);

            var impactBlocks = DictionaryPool <Block, int> .Get();

            for (var position = negativeEndPosition + displacement; position != positiveEndPosition; position += displacement)
            {
                var hasYou = false;
                {
                    var blocks = m_logicGameManager.Map[position.x, position.y];
                    foreach (var block in blocks)
                    {
                        if (HasAttribute(block, AttributeCategory.You))
                        {
                            impactBlocks[block] = impactBlocks.GetOrDefault(block, 0) | 1;
                            hasYou = true;
                        }
                    }
                }
                if (hasYou)
                {
                    for (var pullPosition = position - displacement; m_logicGameManager.InMap(pullPosition); pullPosition -= displacement)
                    {
                        var blocks  = m_logicGameManager.Map[pullPosition.x, pullPosition.y];
                        var hasPull = false;
                        foreach (var block in blocks)
                        {
                            if (HasAttribute(block, AttributeCategory.Pull))
                            {
                                impactBlocks[block] = impactBlocks.GetOrDefault(block, 0) | 1;
                                hasPull             = true;
                            }
                        }
                        if (!hasPull)
                        {
                            break;
                        }
                    }
                    for (var pushPosition = position + displacement; m_logicGameManager.InMap(pushPosition); pushPosition += displacement)
                    {
                        var blocks  = m_logicGameManager.Map[pushPosition.x, pushPosition.y];
                        var hasPush = false;
                        foreach (var block in blocks)
                        {
                            if (HasAttribute(block, AttributeCategory.Push))
                            {
                                impactBlocks[block] = impactBlocks.GetOrDefault(block, 0) | 1;
                                hasPush             = true;
                            }
                        }
                        if (!hasPush)
                        {
                            break;
                        }
                    }
                }
            }

            HandlePreMove(impactBlocks, displacement, tickCommands);

            {
                var stopPosition = positiveEndPosition - displacement;
                {
                    var blocks = m_logicGameManager.Map[stopPosition.x, stopPosition.y];
                    foreach (var block in blocks)
                    {
                        var impact = 0;
                        if (impactBlocks.TryGetValue(block, out impact))
                        {
                            impactBlocks[block] = 0;
                        }
                    }
                }
            }
            for (var position = positiveEndPosition - displacement; position != negativeEndPosition + displacement; position -= displacement)
            {
                var hasStop = false;
                {
                    var blocks = m_logicGameManager.Map[position.x, position.y];
                    foreach (var block in blocks)
                    {
                        if (HasAttribute(block, AttributeCategory.Stop) || HasAttribute(block, AttributeCategory.Pull) || HasAttribute(block, AttributeCategory.Push))
                        {
                            if (impactBlocks.GetOrDefault(block, 0) == 0)
                            {
                                hasStop = true;
                                break;
                            }
                        }
                    }
                }
                if (hasStop)
                {
                    var stopPosition = position - displacement;
                    {
                        var blocks = m_logicGameManager.Map[stopPosition.x, stopPosition.y];
                        foreach (var block in blocks)
                        {
                            var impact = 0;
                            if (impactBlocks.TryGetValue(block, out impact))
                            {
                                impactBlocks[block] = 0;
                            }
                        }
                    }
                }
            }

            foreach (var impactBlockPair in impactBlocks)
            {
                var block  = impactBlockPair.Key;
                var impact = impactBlockPair.Value;

                if (impact == 1)
                {
                    PerformMoveBlockCommand(block, moveDirection, 1, tickCommands);
                }
            }

            DictionaryPool <Block, int> .Release(impactBlocks);
        }