Example #1
0
    public static List <GamblingConfig> ParseGamblings(string text)
    {
        List <RewardEnum>      rewardTypes = ParseRewardTypes(text);
        IEnumerable <string[]> source      = TSVParser.Parse(text).Skip(1);

        return(source.Select(delegate(string[] line)
        {
            GamblingConfig gamblingConfig = new GamblingConfig
            {
                Level = line.asInt(0, line.toError <int>()),
                FailChance = line.asFloat(1, line.toError <float>())
            };
            List <WeightedObject <RewardData> > list = new List <WeightedObject <RewardData> >();
            for (int i = 2; i < line.Length; i++)
            {
                RewardEnum type = rewardTypes[i - 2];
                AmountAndWeight amountAndWeight = line.asCustom(i, AmountAndWeightParser.ParseAmountAndWeight, line.toError <AmountAndWeight>());
                WeightedObject <RewardData> item = new WeightedObject <RewardData>
                {
                    Value = new RewardData(type, amountAndWeight.Amount),
                    Weight = amountAndWeight.Weight
                };
                list.Add(item);
            }
            gamblingConfig.Rewards = list;
            return gamblingConfig;
        }).ToList());
    }
Example #2
0
    void CheckPressure()
    {
        //NOTE: each stack is considered in isolation, so adjacent stacks to not compound pressure

        nextCheck = Time.time + PRESSURE_CHECK_DELAY;
        float maxPressure = 0;

        for (int i = 0; i < nearbyObjects.Count; i++)
        {
            WeightedObject obj = nearbyObjects[i];

            if (obj == null)
            {
                nearbyObjects.RemoveAt(i);
                i--;
                continue;
            }

            //only check the objects above us
            if (obj.transform.position.y > transform.position.y + radius + obj.radius)
            {
                maxPressure = Mathf.Max(maxPressure, obj.weight + obj.curPressure);
            }
        }

        //if there's been a change in pressure
        if (Mathf.Abs(maxPressure - curPressure) > PRESSURE_DIFF_BUFFER)
        {
            curPressure = maxPressure;
            OnWeightUpdate(curPressure);
        }
    }
 public void Remove(WeightedObject wo)
 {
     if (wo != null && objects.Contains(wo))
     {
         objects.Remove(wo);
     }
 }
    public void OnTriggerExit(Collider other)
    {
        WeightedObject wo = other.gameObject.GetComponent <WeightedObject>();

        if (wo != null && objects.Contains(wo))
        {
            objects.Remove(wo);
        }
    }
    public void OnTriggerEnter(Collider other)
    {
        WeightedObject wo = other.gameObject.GetComponent <WeightedObject>();

        if (wo != null && !objects.Contains(wo))
        {
            objects.Add(wo);
        }
    }
Example #6
0
    protected override void OnDieEnd()
    {
        if (drops.Length > 0)
        {
            var drop = WeightedObject.Select(drops);
            Instantiate(drop, transform.position + drop.transform.position, drop.transform.rotation);
            Toolbox.GameManager.EnemiesKilled++;
        }

        base.OnDieEnd();
    }
Example #7
0
    /// <summary>
    /// Returns the weight of an object, if it has a weighted component attached.
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    private float GetWeightOf(GameObject obj)
    {
        WeightedObject objectWeight = obj.GetComponent <WeightedObject>();

        if (objectWeight == null)
        {
            return(0);
        }
        else
        {
            return(objectWeight.Weight);
        }
    }
Example #8
0
    //may redo if this proves to be inconsistent
    void OnTriggerEnter2D(Collider2D other)
    {
        WeightedObject otherWeight = other.GetComponent <WeightedObject>();

        if (otherWeight != null && otherWeight != this)
        {
            if (nearbyObjects.Contains(otherWeight))
            {
                Debug.LogWarning("Double add");
                return;
            }

            nearbyObjects.Add(otherWeight);
        }
    }
Example #9
0
    private void OnTriggerExit2D(Collider2D other)
    {
        WeightedObject otherWeight = other.GetComponent <WeightedObject>();

        if (otherWeight && otherWeight != this)
        {
            if (!nearbyObjects.Contains(otherWeight))
            {
                Debug.LogWarning("Object not in list");
                return;
            }

            nearbyObjects.Remove(otherWeight);
        }
    }
Example #10
0
    public WeightedObject[] CreateWeightedObjectsArray(WeightedObject[] weightedObjects)
    {
        WeightedObject[] weightedArray = new WeightedObject[weightedObjects.Select(x => x.probability).Sum()];
        int itemCont = 0;

        foreach (WeightedObject item in weightedObjects)
        {
            for (int i = 0; i < item.probability; i++)
            {
                weightedArray[itemCont] = item;
                itemCont++;
            }
        }
        return(weightedArray);
    }
Example #11
0
    private void OnTriggerExit(Collider other)
    {
        WeightedObject o = other.GetComponent <WeightedObject>();

        if (o == null)
        {
            return;
        }
        bool wasActivated = Activated;

        activeObjects.Remove(o.gameObject);
        RemoveObject(o);
        if (wasActivated != Activated)
        {
            OnDisabled.Invoke();
        }
    }
Example #12
0
    private void OnTriggerEnter(Collider other)
    {
        WeightedObject o = other.GetComponent <WeightedObject>();

        if (o == null)
        {
            return;
        }
        bool wasActivated = Activated;

        activeObjects.Add(o.gameObject, o.Weight);
        AddObject(o);
        if (wasActivated != Activated)
        {
            OnActivated.Invoke();
        }
    }
Example #13
0
    public static A PredictableAllotObject <A>(this List <WeightedObject <A> > weights)
    {
        float num = 0f;

        for (int i = 0; i < weights.Count; i++)
        {
            num += weights[i].Weight;
        }
        float num2 = PredictableRandom.GetNextRangeFloat(0f, num);

        for (int j = 0; j < weights.Count; j++)
        {
            WeightedObject <A> weightedObject = weights[j];
            num2 -= weightedObject.Weight;
            if (num2 <= 0f)
            {
                return(weightedObject.Value);
            }
        }
        return(weights[weights.Count - 1].Value);
    }
Example #14
0
 //positive distances are on the right side of balance, negative distances are on the left
 private float DistanceFromAxisOfRotation(WeightedObject obj)
 {
     float distance;
     switch(axisOfRotation){
         case Axis.X:
             distance = Vector2.Distance(new Vector2(Center().y,Center().z), new Vector2(obj.CenterOfMass().y, obj.CenterOfMass().z));
             if (obj.CenterOfMass().z > Center().z)
                 return distance;
             return -distance;
         case Axis.Y:
             distance = Vector2.Distance(new Vector2(Center().x,Center().z), new Vector2(obj.CenterOfMass().x, obj.CenterOfMass().z));
             if (obj.CenterOfMass().x > Center().x)
                 return distance;
             return -distance;
         case Axis.Z:
             distance = Vector2.Distance(new Vector2(Center().x,Center().y), new Vector2(obj.CenterOfMass().x, obj.CenterOfMass().y));
             if (obj.CenterOfMass().x > Center().x)
                 return distance;
             return -distance;
         default:
             return 999;
     }
 }
Example #15
0
    public static List <ChunkGeneratingConfig> ParseChunkGeneratings(string text)
    {
        IEnumerable <string[]> source = TSVParser.Parse(text).Skip(1);

        return(source.Select(delegate(string[] line)
        {
            ChunkGeneratingConfig chunkGeneratingConfig = new ChunkGeneratingConfig
            {
                Chunk = line.asInt(0, line.toError <int>()),
                MaxBlocks = line.asInt(1, line.toError <int>()),
                FourBlockMin = line.asInt(2, line.toError <int>()),
                FourBlockMax = line.asInt(3, line.toError <int>()),
                TwoBlockMin = line.asInt(4, line.toError <int>()),
                TwoBlockMax = line.asInt(5, line.toError <int>())
            };
            List <WeightedObject <BlockType> > list = new List <WeightedObject <BlockType> >();
            for (int i = 6; i < line.Length - 7; i++)
            {
                BlockType value = (BlockType)(i - 6);
                WeightedObject <BlockType> item = new WeightedObject <BlockType>
                {
                    Value = value,
                    Weight = line.asFloat(i, line.toError <float>())
                };
                list.Add(item);
            }
            chunkGeneratingConfig.Materials = list;
            chunkGeneratingConfig.GoldBlockAverage = line.asInt(11, line.toError <int>());
            chunkGeneratingConfig.DiamondMin = line.asInt(12, line.toError <int>());
            chunkGeneratingConfig.DiamondMax = line.asInt(13, line.toError <int>());
            chunkGeneratingConfig.DiamondChance = line.asFloat(14, line.toError <float>());
            chunkGeneratingConfig.TNTMin = line.asInt(15, line.toError <int>());
            chunkGeneratingConfig.TNTMax = line.asInt(16, line.toError <int>());
            chunkGeneratingConfig.TNTChance = line.asFloat(17, line.toError <float>());
            return chunkGeneratingConfig;
        }).ToList());
    }
Example #16
0
 private void AddObject(WeightedObject other)
 {
     totalWeight += other.Weight;
 }
Example #17
0
    public static void GenerateFromConfig(Vector3 pos, int chunk, int prestige, int retryNumber, Transform container, bool bossFight)
    {
        int[] array = new int[13]
        {
            50,
            70,
            50,
            30,
            20,
            10,
            5,
            3,
            0,
            0,
            0,
            0,
            0
        };
        ChunkGeneratingConfig chunkGeneratingConfig = Singleton <EconomyHelpers> .Instance.GetChunkGeneratingConfig(chunk, bossFight);

        int num = chunkGeneratingConfig.MaxBlocks;

        if (!bossFight)
        {
            Singleton <ChunkRunner> .Instance.BlocksInChunk.SetValueAndForceNotify(num);
        }
        else
        {
            Singleton <ChunkRunner> .Instance.BlocksInChunk.SetValueAndForceNotify(num - 64);
        }
        int num2 = (int)((float)chunkGeneratingConfig.GoldBlockAverage * (PredictableRandom.GetNextRangeFloat(0f, 0.5f) + 0.75f));

        Singleton <ChunkRunner> .Instance.GoldBlocks.SetValueAndForceNotify(num2);

        PredictableRandom.SetSeed((uint)chunk, (uint)(prestige + retryNumber));
        List <BlockSpawnPoint> list = new List <BlockSpawnPoint>();

        int[] array2 = new int[5];
        List <WeightedObject <int[]> > list2 = new List <WeightedObject <int[]> >();

        if (bossFight)
        {
            list2.AddRange(PersistentSingleton <Economies> .Instance.ChunkMaps[0].ChunkMapClone());
            list2 = RemoveSpawnLocationsForBossFight(list2);
        }
        else
        {
            list2.AddRange(PersistentSingleton <Economies> .Instance.ChunkMaps[chunk % 5].ChunkMapClone());
        }
        int nextRangeInt = PredictableRandom.GetNextRangeInt(chunkGeneratingConfig.FourBlockMin, chunkGeneratingConfig.FourBlockMax + 1);

        for (int num3 = nextRangeInt; num3 > 0; num3--)
        {
            List <WeightedObject <int[]> > list3 = list2.FindAll((WeightedObject <int[]> x) => x.Value[3] >= 4);
            if (list3.Count <= 0)
            {
                break;
            }
            int       nextRangeInt2 = PredictableRandom.GetNextRangeInt(0, list3.Count);
            int[]     spawnSpot     = list3[nextRangeInt2].Value;
            BlockType blockType     = chunkGeneratingConfig.Materials.PredictableAllotObject();
            string    prefabPath    = GetPrefabPath(blockType, 4);
            if (list.Count <= 0 && bossFight)
            {
                spawnSpot = new int[5]
                {
                    0,
                    0,
                    1,
                    4,
                    1
                };
                blockType  = BlockType.Invalid;
                prefabPath = ((!Singleton <DrJellyRunner> .Instance.DrJellyBattle.Value) ? "Blocks/BigBossCube_4x4" : "Blocks/DrJelly");
            }
            Vector3 coordinates = new Vector3(spawnSpot[0], spawnSpot[1] + 2, spawnSpot[2]) + pos;
            list.Add(new BlockSpawnPoint(blockType, prefabPath, coordinates));
            int i;
            for (i = -4; i <= 3; i++)
            {
                int j;
                for (j = -4; j <= 3; j++)
                {
                    int num4 = list2.FindIndex((WeightedObject <int[]> x) => x.Value[0] == spawnSpot[0] + i && x.Value[2] == spawnSpot[2] + j);
                    if (num4 == -1)
                    {
                        continue;
                    }
                    WeightedObject <int[]> weightedObject = list2[num4];
                    if (-2 <= i && i <= 1 && -2 <= j && j <= 1)
                    {
                        weightedObject.Value[1] += 4;
                        weightedObject.Weight    = array[weightedObject.Value[1]];
                    }
                    if (i == 0 && j == 0)
                    {
                        if (weightedObject.Value[1] > 4)
                        {
                            weightedObject.Value[3] = 2;
                        }
                    }
                    else if (-1 <= i && i <= 1 && -1 <= j && j <= 1)
                    {
                        weightedObject.Value[3] = 2;
                    }
                    else if (-2 <= i && i <= 2 && -2 <= j && j <= 2)
                    {
                        weightedObject.Value[3] = 1;
                    }
                    else
                    {
                        if (weightedObject.Value[3] == 4)
                        {
                            weightedObject.Value[3] = 2;
                        }
                        if (-3 <= i && i <= 2 && -3 <= j && j <= 2)
                        {
                            weightedObject.Weight = array[1];
                        }
                        else
                        {
                            weightedObject.Weight = array[0];
                        }
                    }
                    list2[num4] = weightedObject;
                }
            }
            num -= 64;
        }
        int   nextRangeInt3 = PredictableRandom.GetNextRangeInt(chunkGeneratingConfig.TwoBlockMin, chunkGeneratingConfig.TwoBlockMax + 1);
        float num5          = (float)(nextRangeInt3 * 8) / (float)num;
        int   num6          = Mathf.RoundToInt((float)num2 * num5 / 9f);

        for (int num7 = 0; num7 < nextRangeInt3; num7++)
        {
            array2[(int)chunkGeneratingConfig.Materials.PredictableAllotObject()]++;
        }
        int num8 = 0;

        if (PredictableRandom.GetNextRangeFloat(0f, 1f) < chunkGeneratingConfig.TNTChance)
        {
            num8 = PredictableRandom.GetNextRangeInt(chunkGeneratingConfig.TNTMin, chunkGeneratingConfig.TNTMax + 1);
        }
        nextRangeInt3 += num8;
        for (int num9 = nextRangeInt3; num9 > 0; num9--)
        {
            List <WeightedObject <int[]> > list4 = list2.FindAll((WeightedObject <int[]> x) => x.Value[3] >= 2);
            if (list4.Count <= 0)
            {
                break;
            }
            int[]     spawnSpot2 = list4.PredictableAllotObject();
            BlockType blockType2 = BlockType.Gold;
            for (int num10 = array2.Length - 1; num10 >= 0; num10--)
            {
                if (num8 > 0)
                {
                    blockType2 = BlockType.TNT;
                    num8--;
                    break;
                }
                if (num6 > 0)
                {
                    blockType2 = BlockType.Gold;
                    num6--;
                    num2 -= 9;
                    break;
                }
                if (array2[num10] > 0)
                {
                    blockType2 = (BlockType)num10;
                    array2[num10]--;
                    break;
                }
            }
            string  prefabPath2  = GetPrefabPath(blockType2, 2);
            Vector3 coordinates2 = new Vector3(spawnSpot2[0], spawnSpot2[1] + 1, spawnSpot2[2]) + pos;
            list.Add(new BlockSpawnPoint(blockType2, prefabPath2, coordinates2));
            int k;
            for (k = -2; k <= 1; k++)
            {
                int l;
                for (l = -2; l <= 1; l++)
                {
                    int num11 = list2.FindIndex((WeightedObject <int[]> x) => x.Value[0] == spawnSpot2[0] + k && x.Value[2] == spawnSpot2[2] + l);
                    if (num11 == -1)
                    {
                        continue;
                    }
                    WeightedObject <int[]> weightedObject2 = list2[num11];
                    if (-1 <= k && k <= 0 && -1 <= l && l <= 0)
                    {
                        weightedObject2.Value[1] += 2;
                    }
                    if (-1 <= k && k <= 1 && -1 <= l && l <= 1)
                    {
                        if (weightedObject2.Value[1] >= 10)
                        {
                            weightedObject2.Value[3] = 0;
                        }
                        else
                        {
                            weightedObject2.Value[3] = 1;
                            if (k == 0 && l == 0)
                            {
                                weightedObject2.Value[3] = 2;
                            }
                        }
                    }
                    weightedObject2.Weight = array[weightedObject2.Value[1]];
                    list2[num11]           = weightedObject2;
                }
            }
            num -= 8;
        }
        int num12 = 0;

        if (PredictableRandom.GetNextRangeFloat(0f, 1f) < chunkGeneratingConfig.DiamondChance)
        {
            num12 = PredictableRandom.GetNextRangeInt(chunkGeneratingConfig.DiamondMin, chunkGeneratingConfig.DiamondMax + 1);
        }
        for (int num13 = 0; num13 < num - num12 - num2; num13++)
        {
            array2[(int)chunkGeneratingConfig.Materials.PredictableAllotObject()]++;
        }
        List <WeightedObject <int[]> > list5 = list2.FindAll((WeightedObject <int[]> x) => x.Value[3] >= 1);

        for (int num14 = num; num14 > 0; num14--)
        {
            if (list5.Count > 0)
            {
                int[]     spawnSpot3 = list5.PredictableAllotObject();
                BlockType type       = BlockType.Diamond;
                for (int num15 = array2.Length - 1; num15 >= 0; num15--)
                {
                    if (num12 > 0)
                    {
                        type = BlockType.Diamond;
                        num12--;
                        break;
                    }
                    if (num2 > 0)
                    {
                        type = BlockType.Gold;
                        num2--;
                        break;
                    }
                    if (array2[num15] > 0)
                    {
                        type = (BlockType)num15;
                        array2[num15]--;
                        break;
                    }
                }
                Vector3 coordinates3 = new Vector3((float)spawnSpot3[0] + 0.5f, (float)spawnSpot3[1] + 0.5f, (float)spawnSpot3[2] + 0.5f) + pos;
                list.Add(new BlockSpawnPoint(type, string.Empty, coordinates3));
                int m;
                for (m = -1; m <= 1; m++)
                {
                    int n;
                    for (n = -1; n <= 1; n++)
                    {
                        WeightedObject <int[]> weightedObject3 = list5.Find((WeightedObject <int[]> x) => x.Value[0] == spawnSpot3[0] + m && x.Value[2] == spawnSpot3[2] + n);
                        if (weightedObject3 != null)
                        {
                            if (m == 0 && n == 0)
                            {
                                weightedObject3.Value[1]++;
                            }
                            if (weightedObject3.Value[1] >= 10)
                            {
                                list5.Remove(weightedObject3);
                            }
                            else
                            {
                                weightedObject3.Weight = array[weightedObject3.Value[1]];
                            }
                        }
                    }
                }
            }
        }
        List <BlockSpawnPoint> blocks = list.FindAll((BlockSpawnPoint x) => x.PrefabPath == string.Empty);

        for (int num16 = -5; num16 <= 4; num16++)
        {
            for (int num17 = -7; num17 <= 8; num17++)
            {
                List <BlockSpawnPoint> blocksNearCoordinates = GetBlocksNearCoordinates(blocks, (float)num16 + 0.5f + pos.x, (float)num17 + 0.5f + pos.z);
                BlockType blockType3 = BlockType.Invalid;
                if (blocksNearCoordinates.Count <= 0)
                {
                    continue;
                }
                for (int num18 = blocksNearCoordinates.Count - 1; num18 >= 0; num18--)
                {
                    string          empty           = string.Empty;
                    BlockType       num19           = blockType3;
                    BlockSpawnPoint blockSpawnPoint = blocksNearCoordinates[num18];
                    if (num19 != blockSpawnPoint.Type)
                    {
                        BlockSpawnPoint blockSpawnPoint2 = blocksNearCoordinates[num18];
                        empty = GetPrefabPath(blockSpawnPoint2.Type, 1, BlockAlignment.Top);
                    }
                    else if (num18 - 1 >= 0)
                    {
                        BlockSpawnPoint blockSpawnPoint3 = blocksNearCoordinates[num18];
                        BlockType       type2            = blockSpawnPoint3.Type;
                        BlockSpawnPoint blockSpawnPoint4 = blocksNearCoordinates[num18 - 1];
                        if (type2 == blockSpawnPoint4.Type)
                        {
                            BlockSpawnPoint blockSpawnPoint5 = blocksNearCoordinates[num18];
                            empty = GetPrefabPath(blockSpawnPoint5.Type, 1, BlockAlignment.Middle);
                        }
                        else
                        {
                            BlockSpawnPoint blockSpawnPoint6 = blocksNearCoordinates[num18];
                            empty = GetPrefabPath(blockSpawnPoint6.Type, 1, BlockAlignment.Bottom);
                        }
                    }
                    else
                    {
                        BlockSpawnPoint blockSpawnPoint7 = blocksNearCoordinates[num18];
                        empty = GetPrefabPath(blockSpawnPoint7.Type, 1, BlockAlignment.Bottom);
                    }
                    BlockSpawnPoint blockSpawnPoint8 = blocksNearCoordinates[num18];
                    blockType3 = blockSpawnPoint8.Type;
                    List <BlockSpawnPoint> list6      = list;
                    int             index             = list.IndexOf(blocksNearCoordinates[num18]);
                    BlockSpawnPoint blockSpawnPoint9  = blocksNearCoordinates[num18];
                    BlockType       type3             = blockSpawnPoint9.Type;
                    string          prefabPath3       = empty;
                    BlockSpawnPoint blockSpawnPoint10 = blocksNearCoordinates[num18];
                    list6[index] = new BlockSpawnPoint(type3, prefabPath3, blockSpawnPoint10.Coordinates);
                }
            }
        }
        for (int num20 = 0; num20 < list.Count; num20++)
        {
            EntityPoolManager instance           = Singleton <EntityPoolManager> .Instance;
            BlockSpawnPoint   blockSpawnPoint11  = list[num20];
            GameObject        orCreateGameObject = instance.GetOrCreateGameObject(blockSpawnPoint11.PrefabPath);
            BlockController   component          = orCreateGameObject.GetComponent <BlockController>();
            if (component != null)
            {
                BlockController blockController   = component;
                BlockSpawnPoint blockSpawnPoint12 = list[num20];
                blockController.Init(blockSpawnPoint12.Type);
            }
            else
            {
                BossBlockController component2 = orCreateGameObject.GetComponent <BossBlockController>();
                if (component2 != null)
                {
                    component2.Init();
                }
            }
            Transform       transform         = orCreateGameObject.transform;
            BlockSpawnPoint blockSpawnPoint13 = list[num20];
            transform.position = blockSpawnPoint13.Coordinates;
            orCreateGameObject.transform.rotation = Quaternion.identity;
            if (orCreateGameObject.transform.parent == null)
            {
                orCreateGameObject.transform.SetParent(container, worldPositionStays: true);
            }
        }
    }
Example #18
0
        public void SampleReturnsDefaultValueOnEmptyCollections()
        {
            var collection = new WeightedObject[0];

            Assert.IsNull(collection.Sample());
        }
Example #19
0
        public void SampleReturnsDefaultValueOnEmptySequences()
        {
            var collection = new WeightedObject[0];

            Assert.IsNull(((IEnumerable <WeightedObject>)collection).Sample());
        }
Example #20
0
 private void RemoveObject(WeightedObject other)
 {
     totalWeight -= other.Weight;
 }
Example #21
0
    IEnumerator GrabSequence()
    {
        Vector3 mousePos = player.mousePos;
        Vector3 dir      = mousePos - grabCenter.position;

        grabHand.Reparent(false, false, grabTarget);

        RaycastHit2D hitInfo = Physics2D.Raycast(grabCenter.position, dir, reachDistance, grabbableLayers);
        Collider2D   hitCol  = null;

        if (hitInfo.collider != null)
        {
            WeightedObject obj = hitInfo.collider.GetComponent <WeightedObject>();
            if (obj != null && obj.isGrabbable)
            {
                hitCol = hitInfo.collider;
                grabTarget.transform.position = hitInfo.point;
                hitOffset = hitInfo.transform.InverseTransformPoint(grabTarget.transform.position);
            }
        }

        if (hitCol == null)
        {
            grabTarget.parent = grabCenter;
            grabTarget.transform.localPosition = dir.normalized * reachDistance;
        }

        float timer = 0.16f; //can't be bothered lol

        while (timer > 0f)
        {
            if (hitCol != null)
            {
                grabTarget.transform.position = hitCol.transform.TransformPoint(hitOffset);
            }
            yield return(null);

            timer -= Time.deltaTime;
        }

        bool tookTwoTries = false;

        if (hitCol == null)
        {
            //try again
            hitInfo = Physics2D.Raycast(grabCenter.position, dir, reachDistance, grabbableLayers);
            if (hitInfo.collider != null)
            {
                WeightedObject obj = hitInfo.collider.GetComponent <WeightedObject>();
                if (obj != null && obj.isGrabbable)
                {
                    hitCol = hitInfo.collider;
                    grabTarget.transform.position = hitInfo.point;
                    hitOffset    = hitInfo.transform.InverseTransformPoint(hitInfo.point);
                    tookTwoTries = true;
                }
            }
        }

        if (hitCol != null)
        {
            Grab(hitInfo.collider);
            if (tookTwoTries)
            {
                yield return(new WaitForSeconds(0.15f)); //super hacky but just prevents some jitteriness
            }
            grabHand.Reparent(false, false, grabTarget);
        }
        else
        {
            Drop();
        }
    }