예제 #1
0
    private IEnumerator CritHonk(PositionalHandApply clickData, LivingHealthMasterBase livingHealth)
    {
        yield return(WaitFor.Seconds(0.02f));

        AudioSourceParameters audioSourceParameters = new AudioSourceParameters(pitch: -1f);         //This plays it backwards, is that what you wanted?
        ShakeParameters       shakeParameters       = new ShakeParameters(true, 20, 5);

        SoundManager.PlayNetworkedAtPos(CommonSounds.Instance.ClownHonk, gameObject.AssumedWorldPosServer(), audioSourceParameters, true, sourceObj: GetHonkSoundObject(), shakeParameters: shakeParameters);
        livingHealth.ApplyDamageToBodyPart(clickData.Performer, CritDamage, AttackType.Energy, DamageType.Brute, BodyPartType.Head);
    }
예제 #2
0
        //We need to slow the attack down because clients are behind server
        private async Task AttackFleshRoutine(Vector2 dir, LivingHealthBehaviour targetHealth, LivingHealthMasterBase livingHealth,
                                              Vector3 worldPos, NetworkConnection ctc, float rtt)
        {
            if (targetHealth == null && livingHealth == null)
            {
                return;
            }
            if (ctc == null)
            {
                return;
            }

            ServerDoLerpAnimation(dir);

            if (PlayerManager.LocalPlayerScript != null &&
                PlayerManager.LocalPlayerScript.playerHealth != null &&
                PlayerManager.LocalPlayerScript.playerHealth == livingHealth ||
                rtt < 0.02f)
            {
                //Wait until the end of the frame
                await Task.Delay(1);
            }
            else
            {
                //Wait until RTT/2 seconds?
                Logger.Log($"WAIT FOR ATTACK: {rtt / 2f}", Category.Mobs);
                await Task.Delay((int)(rtt * 500));
            }

            if (Vector3.Distance(mobTile.WorldPositionServer, worldPos) < 1.5f)
            {
                var bodyPartTarget = defaultTarget.Randomize();
                if (targetHealth != null)
                {
                    targetHealth.ApplyDamageToBodyPart(gameObject, hitDamage, AttackType.Melee, DamageType.Brute,
                                                       bodyPartTarget);
                    Chat.AddAttackMsgToChat(gameObject, targetHealth.gameObject, bodyPartTarget, null, attackVerb);
                }
                else
                {
                    livingHealth.ApplyDamageToBodyPart(gameObject, hitDamage, AttackType.Melee, DamageType.Brute,
                                                       bodyPartTarget);
                    Chat.AddAttackMsgToChat(gameObject, livingHealth.gameObject, bodyPartTarget, null, attackVerb);
                }
                SoundManager.PlayNetworkedAtPos(attackSound, mobTile.WorldPositionServer, sourceObj: gameObject);
            }
        }
예제 #3
0
 protected void ApplyDamageToPartyType(LivingHealthMasterBase health, BodyPartType type)
 {
     health.ApplyDamageToBodyPart(gameObject, damageToGive, attackType, damageType, type, armorPentration, traumaChance, traumaType);
 }
예제 #4
0
    public void ServerPerformMeleeAttack(GameObject victim, Vector2 attackDirection,
                                         BodyPartType damageZone, LayerType layerType)
    {
        if (Cooldowns.IsOnServer(playerScript, CommonCooldowns.Instance.Melee))
        {
            return;
        }
        var weapon = playerScript.playerNetworkActions.GetActiveHandItem();

        var tiles = victim.GetComponent <InteractableTiles>();

        if (tiles)
        {
            //validate based on position of target vector
            if (!Validations.CanApply(playerScript, victim, NetworkSide.Server, targetVector: attackDirection))
            {
                return;
            }
        }
        else
        {
            //validate based on position of target object
            if (!Validations.CanApply(playerScript, victim, NetworkSide.Server))
            {
                return;
            }
        }

        if (!playerMove.allowInput ||
            playerScript.IsGhost ||
            !victim ||
            !playerScript.playerHealth.serverPlayerConscious
            )
        {
            return;
        }

        var isWeapon = weapon != null;
        ItemAttributesV2 weaponAttr = isWeapon ? weapon.GetComponent <ItemAttributesV2>() : null;
        var       damage            = isWeapon ? weaponAttr.ServerHitDamage : fistDamage;
        var       damageType        = isWeapon ? weaponAttr.ServerDamageType : DamageType.Brute;
        var       attackSound       = isWeapon ? weaponAttr.ServerHitSound : null;
        LayerTile attackedTile      = null;
        bool      didHit            = false;

        ItemAttributesV2 weaponStats = null;

        if (isWeapon)
        {
            weaponStats = weapon.GetComponent <ItemAttributesV2>();
        }


        // If Tilemap LayerType is not None then it is a tilemap being attacked
        if (layerType != LayerType.None)
        {
            var tileChangeManager = victim.GetComponent <TileChangeManager>();
            if (tileChangeManager == null)
            {
                return;                                        //Make sure its on a matrix that is destructable
            }
            //Tilemap stuff:
            var tileMapDamage = victim.GetComponentInChildren <MetaTileMap>().Layers[layerType].gameObject
                                .GetComponent <TilemapDamage>();
            if (tileMapDamage != null)
            {
                if (isWeapon && weaponStats != null &&
                    weaponStats.hitSoundSettings == SoundItemSettings.OnlyObject)
                {
                    attackSound = null;
                }
                var worldPos = (Vector2)transform.position + attackDirection;
                attackedTile = tileChangeManager.InteractableTiles.LayerTileAt(worldPos, true);
                tileMapDamage.ApplyDamage((int)damage, AttackType.Melee, worldPos);
                didHit = true;
            }
        }
        else
        {
            //a regular object being attacked

            LivingHealthMasterBase victimHealth = victim.GetComponent <LivingHealthMasterBase>();

            var integrity = victim.GetComponent <Integrity>();
            var meleeable = victim.GetComponent <Meleeable>();
            if (integrity != null)
            {
                if (meleeable.GetMeleeable())
                {                //damaging an object
                    if (isWeapon && weaponStats != null &&
                        weaponStats.hitSoundSettings == SoundItemSettings.Both)
                    {
                        AudioSourceParameters audioSourceParameters = new AudioSourceParameters(pitch: Random.Range(0.9f, 1.1f));
                        SoundManager.PlayNetworkedAtPos(integrity.soundOnHit, gameObject.WorldPosServer(), audioSourceParameters, sourceObj: gameObject);
                    }
                    else if (isWeapon && weaponStats != null &&
                             weaponStats.hitSoundSettings == SoundItemSettings.OnlyObject && integrity.soundOnHit == null)
                    {
                        AudioSourceParameters audioSourceParameters = new AudioSourceParameters(pitch: Random.Range(0.9f, 1.1f));
                        SoundManager.PlayNetworkedAtPos(integrity.soundOnHit, gameObject.WorldPosServer(), audioSourceParameters, sourceObj: gameObject);
                        attackSound = null;
                    }
                    integrity.ApplyDamage((int)damage, AttackType.Melee, damageType);
                    didHit = true;
                }
            }
            else
            {
                //damaging a living thing
                var rng = new System.Random();
                // 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 (isWeapon || 90 >= rng.Next(1, 100))
                {
                    if (victimHealth == null || gameObject == null)
                    {
                        return;
                    }
                    // The attack hit.
                    victimHealth.ApplyDamageToBodyPart(gameObject, (int)damage, AttackType.Melee, damageType, damageZone);
                    didHit = true;
                }
                else
                {
                    // The punch missed.
                    string victimName = victim.Player()?.Name;
                    SoundManager.PlayNetworkedAtPos(SingletonSOSounds.Instance.PunchMiss, transform.position, sourceObj: gameObject);
                    Chat.AddCombatMsgToChat(gameObject, $"You attempted to punch {victimName} but missed!",
                                            $"{gameObject.Player()?.Name} has attempted to punch {victimName}!");
                }
            }
        }

        //common logic to do if we hit something
        if (didHit)
        {
            if (attackSound != null)
            {
                SoundManager.PlayNetworkedAtPos(attackSound, transform.position, sourceObj: gameObject);
            }

            if (damage > 0)
            {
                Chat.AddAttackMsgToChat(gameObject, victim, damageZone, weapon, attackedTile: attackedTile);
            }
            if (victim != gameObject)
            {
                RpcMeleeAttackLerp(attackDirection, weapon);
                //playerMove.allowInput = false;
            }
        }

        Cooldowns.TryStartServer(playerScript, CommonCooldowns.Instance.Melee);
    }