private void Strike()
    {
        int num = UnityEngine.Random.Range(0, this.room.TileWidth);

        if (this.room.GetTile(num, this.room.TileHeight - 1).Solid)
        {
            return;
        }
        int num2 = this.room.roomRain.rainReach[num];

        if (num2 >= this.room.TileHeight)
        {
            return;
        }
        if (num2 == 0)
        {
            num2 = -10;
        }
        this.pos         = this.room.MiddleOfTile(num, num2) + new Vector2(Mathf.Lerp(-10f, 10f, UnityEngine.Random.value), 10f);
        this.skyPos      = this.room.MiddleOfTile(num, num2 + this.room.TileHeight + 50) + new Vector2(Mathf.Lerp(-30f, 30f, UnityEngine.Random.value) - 30f * this.roomRain.globalRain.rainDirection, 0f);
        this.falling     = 0f;
        this.lastFalling = 0f;
        this.moveTip     = true;
        this.fallSpeed   = 1f / Mathf.Lerp(0.2f, 1.8f, UnityEngine.Random.value);
        this.delay       = UnityEngine.Random.Range(0, 60 - (int)(this.roomRain.globalRain.bulletRainDensity * 60f));
        SharedPhysics.CollisionResult collisionResult = new SharedPhysics.CollisionResult();
        if (roomRain.room.roomSettings.RainIntensity != 0.01086957f)
        {
            collisionResult = SharedPhysics.TraceProjectileAgainstBodyChunks(null, this.room, this.skyPos, ref this.pos, 0.5f, 1, null, false);
        }
        if (this.room.water && this.room.PointSubmerged(this.pos))
        {
            this.pos.y = this.room.FloatWaterLevel(this.pos.x) - 30f;
            this.room.waterObject.WaterfallHitSurface(this.pos.x, this.pos.x, 1f);
            this.room.PlaySound(SoundID.Small_Object_Into_Water_Fast, this.pos);
        }
        else
        {
            this.room.PlaySound(SoundID.Bullet_Drip_Strike, this.pos);
        }

        if (roomRain.room.roomSettings.RainIntensity != 0.01086957f)
        {
            if (collisionResult.chunk != null)
            {
                this.pos = collisionResult.collisionPoint;
                BodyChunk chunk = collisionResult.chunk;
                chunk.vel.y = chunk.vel.y - 2f / collisionResult.chunk.mass;
                if (collisionResult.chunk.owner is Creature)
                {
                    (collisionResult.chunk.owner as Creature).Stun(UnityEngine.Random.Range(0, 4));
                }
            }
        }
    }
        private static void PlayerUpdatePatch(On.Player.orig_Update orig, Player player, bool eu)
        {
            int playerNumber = player.playerState.playerNumber;

            bowStats[playerNumber].aimDir = GetAimDir(player).normalized;

            if (bowStats[playerNumber].aimDir.magnitude > 0.4f)
            {
                bowStats[playerNumber].lastAimDir = bowStats[playerNumber].aimDir;
            }

            if (!bowStats[playerNumber].isDrawing && bowStats[playerNumber].released)
            {
                PhysicalObject releasedObject = GetOppositeObject(player, 0);

                if (releasedObject != null && releasedObject.abstractPhysicalObject.type == EnumExt_NewItems.Arrow)
                {
                    Arrow arrow = releasedObject as Arrow;
                    bowStats[playerNumber].controlLocked = 10;
                    Vector2 launchDir = bowStats[playerNumber].aimDir;
                    Vector2 thrownPos = player.firstChunk.pos + launchDir * 10f + new Vector2(0f, 4f);
                    player.grasps[1].Release();
                    arrow.Thrown(player, thrownPos, player.mainBodyChunk.pos - launchDir * 10f, new IntVector2(player.ThrowDirection, 0), Mathf.Lerp(1f, 1.5f, player.Adrenaline), eu);

                    foreach (BodyChunk bodyChunk in arrow.bodyChunks)
                    {
                        bodyChunk.pos = player.mainBodyChunk.pos + bowStats[playerNumber].lastAimDir * 10f;
                        bodyChunk.vel = (bowStats[playerNumber].lastAimDir.normalized) * (40f * GetFireStrength(player));
                    }

                    player.bodyChunks[0].vel -= launchDir * 3f;
                    player.bodyChunks[1].vel -= launchDir * 4.5f;

                    arrow.arrowDamageBonus = (1f * GetFireStrength(player)) * bowStats[playerNumber].arrowLethality;

                    arrow.stillFlyingCounter = Arrow.maxFlyingCount;
                    arrow.rotation           = launchDir.normalized;
                }

                bowStats[playerNumber].released = false;
            }

            orig(player, eu);

            if (globalStats[playerNumber].backSlot == null)
            {
                globalStats[playerNumber].backSlot = new BackSlot(player);
            }
            if (globalStats[playerNumber].headSlot == null)
            {
                globalStats[playerNumber].headSlot = new EquippedArmor(player, Armor.ArmorSlot.Head);
            }
            if (globalStats[playerNumber].bodySlot == null)
            {
                globalStats[playerNumber].bodySlot = new EquippedArmor(player, Armor.ArmorSlot.Body);
            }
            if (globalStats[playerNumber].accessorySlot == null)
            {
                globalStats[playerNumber].accessorySlot = new EquippedArmor(player, Armor.ArmorSlot.Accessory);
            }

            if (player.input[0].pckp && !globalStats[playerNumber].backSlot.interactionLocked && ((CanPutWeaponToBack(player, (player.grasps[0]?.grabbed as Weapon)) || CanPutWeaponToBack(player, (player.grasps[1]?.grabbed as Weapon))) || CanRetrieveWeaponFromBack(player)) && player.CanPutSpearToBack)
            {
                globalStats[playerNumber].backSlot.increment = true;
            }
            else
            {
                globalStats[playerNumber].backSlot.increment = false;
            }

            if (player.input[0].pckp && player.grasps[0] != null && player.grasps[0].grabbed is Creature && player.CanEatMeat(player.grasps[0].grabbed as Creature) && (player.grasps[0].grabbed as Creature).Template.meatPoints > 0)
            {
                globalStats[playerNumber].backSlot.increment         = false;
                globalStats[playerNumber].backSlot.interactionLocked = true;
            }
            else if (player.swallowAndRegurgitateCounter > 90)
            {
                globalStats[playerNumber].backSlot.increment         = false;
                globalStats[playerNumber].backSlot.interactionLocked = true;
            }

            globalStats[playerNumber].backSlot.Update(eu);

            if (globalStats[playerNumber].backSlot.HasAWeapon && player.spearOnBack.increment)
            {
                player.spearOnBack.increment = false;
            }

            for (int i = 0; i < 2; i++)
            {
                if (player.grasps[i] == null)
                {
                    continue;
                }

                PhysicalObject usedObject = player.grasps[i].grabbed;

                switch (usedObject)
                {
                case Club club:

                    Vector2 clubTip = (usedObject.firstChunk.pos + (usedObject as Weapon).rotation * 50f);

                    SharedPhysics.CollisionResult collisionResult = SharedPhysics.TraceProjectileAgainstBodyChunks((usedObject as SharedPhysics.IProjectileTracer), player.room, usedObject.firstChunk.pos, ref clubTip, 10f, player.collisionLayer, player, true);

                    if (collisionResult.obj != null && clubStats[playerNumber].firstHit)
                    {
                        clubStats[playerNumber].firstHit = false;
                        bool arenaHit = false;
                        if (usedObject.abstractPhysicalObject.world.game.IsArenaSession && usedObject.abstractPhysicalObject.world.game.GetArenaGameSession.GameTypeSetup.spearHitScore != 0 && player != null && collisionResult.obj is Creature)
                        {
                            arenaHit = true;
                            if ((collisionResult.obj as Creature).State is HealthState && ((collisionResult.obj as Creature).State as HealthState).health <= 0f)
                            {
                                arenaHit = false;
                            }
                            else if (!((collisionResult.obj as Creature).State is HealthState) && (collisionResult.obj as Creature).State.dead)
                            {
                                arenaHit = false;
                            }
                        }

                        if (collisionResult.obj is Creature)
                        {
                            player.room.socialEventRecognizer.WeaponAttack(usedObject as Club, player, collisionResult.obj as Creature, hit: true);
                            player.room.PlaySound(SoundID.Rock_Hit_Creature, collisionResult.chunk);

                            bool iKilledThis = false;

                            if (((collisionResult.obj as Creature).State as HealthState).health > 0f)
                            {
                                iKilledThis = true;
                            }

                            (collisionResult.obj as Creature).Violence(usedObject.firstChunk, (usedObject as Weapon).rotation * usedObject.firstChunk.mass * 2f, collisionResult.chunk, collisionResult.onAppendagePos, Creature.DamageType.Blunt, globalStats[playerNumber].meleeSkill * 0.6f, 20f);

                            if (((collisionResult.obj as Creature).State as HealthState).health <= 0f && iKilledThis)
                            {
                                player.room.socialEventRecognizer.Killing(player, collisionResult.obj as Creature);
                            }

                            if (arenaHit)
                            {
                                usedObject.abstractPhysicalObject.world.game.GetArenaGameSession.PlayerLandSpear(player, collisionResult.obj as Creature);
                            }
                        }
                        else
                        {
                            player.room.PlaySound(SoundID.Rock_Hit_Wall, collisionResult.chunk);
                        }
                    }

                    break;
                }
            }

            if (clubStats[playerNumber].swingTimer > 0)
            {
                clubStats[playerNumber].swingTimer--;
            }
            if (bowStats[playerNumber].controlLocked > 0)
            {
                bowStats[playerNumber].controlLocked--;
            }
            if (clubStats[playerNumber].swingDelay > 0)
            {
                clubStats[playerNumber].swingDelay--;
            }

            if (clubStats[playerNumber].comboCooldown > 0)
            {
                clubStats[playerNumber].comboCooldown--;

                if (clubStats[playerNumber].comboCooldown == 0)
                {
                    clubStats[playerNumber].comboCount = 0;
                }
            }

            if (globalStats[playerNumber].animTimer > 0)
            {
                globalStats[playerNumber].animTimer--;

                if (globalStats[playerNumber].animTimer == 0 && clubStats[playerNumber].firstHit)
                {
                    clubStats[playerNumber].firstHit = false;
                }
            }

            if (bowStats[playerNumber].isDrawing)
            {
                bowStats[playerNumber].drawTime = Mathf.Clamp(bowStats[playerNumber].drawTime + bowStats[playerNumber].drawSpeed, 0.0f, maxDrawTime);
            }
            else
            {
                bowStats[playerNumber].drawTime = Mathf.Clamp(bowStats[playerNumber].drawTime - (bowStats[playerNumber].drawSpeed * 3.0f), 0.0f, maxDrawTime);
            }
        }