Example #1
0
    /// <summary>
    /// honk on world click
    /// </summary>
    protected override void ServerPerformInteraction(PositionalHandApply interaction)
    {
        bool inCloseRange = PlayerScript.IsInReach(interaction.TargetVector);
        var  targetHealth = interaction.TargetObject.GetComponent <LivingHealthBehaviour>();
        bool isCrit       = Random.Range(0f, 1f) <= CritChance;

        // honking in someone's face
        if (inCloseRange && (targetHealth != null))
        {
            interaction.Performer.GetComponent <WeaponNetworkActions>().RpcMeleeAttackLerp(interaction.TargetVector, this.gameObject);

            PostToChatMessage.SendAttackMessage(interaction.Performer, interaction.TargetObject, isCrit ? 100 : 1, BodyPartType.None, this.gameObject);

            ClassicHonk();

            if (isCrit)
            {
                StartCoroutine(CritHonk(interaction, targetHealth));
            }
        }
        else
        {
            ClassicHonk();
        }

        StartCoroutine(StartCooldown());
    }
Example #2
0
    public void CmdRequestPunchAttack(GameObject victim, Vector2 punchDirection, BodyPartType damageZone)
    {
        var victimHealth       = victim.GetComponent <LivingHealthBehaviour>();
        var victimRegisterTile = victim.GetComponent <RegisterTile>();
        var rng = new System.Random();

        if (!playerScript.IsInReach(victim, true) || !victimHealth)
        {
            return;
        }

        // If the punch is not self inflicted, do the simple lerp attack animation.
        if (victim != gameObject)
        {
            RpcMeleeAttackLerp(punchDirection, null);
            playerMove.allowInput = false;
        }

        // This is based off the alien/humanoid/attack_hand punch code of TGStation's codebase.
        // Punches have 90% chance to hit, otherwise it is a miss.
        if (90 >= rng.Next(1, 100))
        {
            // The punch hit.
            victimHealth.ApplyDamage(gameObject, (int)fistDamage, AttackType.Melee, DamageType.Brute, damageZone);
            if (fistDamage > 0)
            {
                PostToChatMessage.SendAttackMessage(gameObject, victim, (int)fistDamage, damageZone);
            }

            // Make a random punch hit sound.
            SoundManager.PlayNetworkedAtPos("Punch#", victimRegisterTile.WorldPosition);

            StartCoroutine(AttackCoolDown());
        }
        else
        {
            // The punch missed.
            string victimName = victim.Player()?.Name;
            SoundManager.PlayNetworkedAtPos("PunchMiss", transform.position);
            ChatRelay.Instance.AddToChatLogServer(new ChatEvent
            {
                channels = ChatChannel.Local,
                message  = $"{gameObject.Player()?.Name} has attempted to punch {victimName}!"
            });
        }
    }
    /// <summary>
    /// Invoked when BulletColliderBehavior passes the event up to us.
    /// </summary>
    public void HandleTriggerEnter2D(Collider2D coll)
    {
        //only harm others if it's not a suicide
        if (coll.gameObject == shooter && !isSuicide)
        {
            return;
        }

        //only harm the shooter if it's a suicide
        if (coll.gameObject != shooter && isSuicide)
        {
            return;
        }

        //body or object?
        var livingHealth = coll.GetComponent <LivingHealthBehaviour>();
        var integrity    = coll.GetComponent <Integrity>();

        if (integrity != null)
        {
            //damage object
            integrity.ApplyDamage(damage, attackType, damageType);

            PostToChatMessage.SendAttackMessage(shooter, coll.gameObject, damage, BodyPartType.None, weapon.gameObject);
            Logger.LogTraceFormat("Hit {0} for {1} with HealthBehaviour! bullet absorbed", Category.Firearms, integrity.gameObject.name, damage);
        }
        else
        {
            //damage human if there is one
            if (livingHealth == null || livingHealth.IsDead)
            {
                return;
            }

            // Trigger for things like stuns
            GetComponent <BulletHitTrigger>()?.BulletHitInteract(coll.gameObject);

            var aim = isSuicide ? bodyAim : bodyAim.Randomize();
            livingHealth.ApplyDamage(shooter, damage, attackType, damageType, aim);
            PostToChatMessage.SendAttackMessage(shooter, coll.gameObject, damage, aim, weapon.gameObject);
            Logger.LogTraceFormat("Hit {0} for {1} with HealthBehaviour! bullet absorbed", Category.Firearms, livingHealth.gameObject.name, damage);
        }

        ReturnToPool();
    }
Example #4
0
    public void CmdRequestMeleeAttack(GameObject victim, GameObject weapon, Vector2 stabDirection,
                                      BodyPartType damageZone, LayerType layerType)
    {
        if (!playerMove.allowInput ||
            playerScript.IsGhost ||
            !victim ||
            !playerScript.playerHealth.serverPlayerConscious
            )
        {
            return;
        }

        if (!allowAttack)
        {
            return;
        }

        ItemAttributes weaponAttr = weapon.GetComponent <ItemAttributes>();

        // If Tilemap LayerType is not None then it is a tilemap being attacked
        if (layerType != LayerType.None)
        {
            TileChangeManager tileChangeManager = victim.GetComponent <TileChangeManager>();
            MetaTileMap       metaTileMap       = victim.GetComponentInChildren <MetaTileMap>();
            if (tileChangeManager == null)
            {
                return;
            }

            //Tilemap stuff:
            var tileMapDamage = metaTileMap.Layers[layerType].GetComponent <TilemapDamage>();
            if (tileMapDamage != null)
            {
                //Wire cutters should snip the grills instead:
                if (weaponAttr.itemName == "wirecutters" &&
                    tileMapDamage.Layer.LayerType == LayerType.Grills)
                {
                    tileMapDamage.WireCutGrill((Vector2)transform.position + stabDirection);
                    StartCoroutine(AttackCoolDown());
                    return;
                }

                tileMapDamage.DoMeleeDamage((Vector2)transform.position + stabDirection,
                                            gameObject, (int)weaponAttr.hitDamage);

                playerMove.allowInput = false;
                RpcMeleeAttackLerp(stabDirection, weapon);
                StartCoroutine(AttackCoolDown());
                return;
            }
            return;
        }

        //This check cannot be used with TilemapDamage as the transform position is always far away
        if (!playerScript.IsInReach(victim, true))
        {
            return;
        }

        // Consider moving this into a MeleeItemTrigger for knifes
        //Meaty bodies:
        LivingHealthBehaviour victimHealth = victim.GetComponent <LivingHealthBehaviour>();

        if (victimHealth != null && victimHealth.IsDead && weaponAttr.itemType == ItemType.Knife)
        {
            if (victim.GetComponent <SimpleAnimal>())
            {
                SimpleAnimal attackTarget = victim.GetComponent <SimpleAnimal>();
                RpcMeleeAttackLerp(stabDirection, weapon);
                playerMove.allowInput = false;
                attackTarget.Harvest();
                SoundManager.PlayNetworkedAtPos("BladeSlice", transform.position);
            }
            else
            {
                PlayerHealth attackTarget = victim.GetComponent <PlayerHealth>();
                RpcMeleeAttackLerp(stabDirection, weapon);
                playerMove.allowInput = false;
                attackTarget.Harvest();
                SoundManager.PlayNetworkedAtPos("BladeSlice", transform.position);
            }
        }

        if (victim != gameObject)
        {
            RpcMeleeAttackLerp(stabDirection, weapon);
            playerMove.allowInput = false;
        }

        var integrity = victim.GetComponent <Integrity>();

        if (integrity != null)
        {
            //damaging an object
            integrity.ApplyDamage((int)weaponAttr.hitDamage, AttackType.Melee, weaponAttr.damageType);
        }
        else
        {
            //damaging a living thing
            victimHealth.ApplyDamage(gameObject, (int)weaponAttr.hitDamage, AttackType.Melee, weaponAttr.damageType, damageZone);
        }

        SoundManager.PlayNetworkedAtPos(weaponAttr.hitSound, transform.position);


        if (weaponAttr.hitDamage > 0)
        {
            PostToChatMessage.SendAttackMessage(gameObject, victim, (int)weaponAttr.hitDamage, damageZone, weapon);
        }


        StartCoroutine(AttackCoolDown());
    }