Exemplo n.º 1
0
    public void CmdKnifeHarvestMob(GameObject npcObj, Vector2 stabDirection)
    {
        if (!playerMove.allowInput || playerMove.isGhost)
        {
            return;
        }

        SimpleAnimal attackTarget = npcObj.GetComponent <SimpleAnimal>();

        RpcKnifeAttackLerp(stabDirection);
        attackTarget.Harvest();
        soundNetworkActions.RpcPlayNetworkSound("BladeSlice", transform.position);
    }
    [Command] //TODO fixme ghetto proof-of-concept
    public void CmdKnifeAttackMob(GameObject npcObj, GameObject weapon, Vector2 stabDirection, BodyPartType damageZone)
    {
        HealthBehaviour healthBehaviour = npcObj.GetComponent <HealthBehaviour>();

        if (healthBehaviour.IsDead == false)
        {
            if (!playerMove.allowInput || !allowAttack || playerMove.isGhost)
            {
                return;
            }

            if (npcObj != gameObject)
            {
                RpcMeleAttackLerp(stabDirection, weapon);
            }

            healthBehaviour
            .ApplyDamage(gameObject.name, 20, DamageType.BRUTE, damageZone);

            //this crap will remain here until moved to netmessages
            healthBehaviour.RpcApplyDamage(gameObject.name, 20, DamageType.BRUTE, damageZone);

            soundNetworkActions.RpcPlayNetworkSound("BladeSlice", transform.position);
            StartCoroutine(AttackCoolDown());
        }
        else
        {
            if (!playerMove.allowInput || playerMove.isGhost)
            {
                return;
            }
            if (npcObj.GetComponent <SimpleAnimal>())
            {
                SimpleAnimal attackTarget = npcObj.GetComponent <SimpleAnimal>();
                RpcMeleAttackLerp(stabDirection, weapon);
                attackTarget.Harvest();
                soundNetworkActions.RpcPlayNetworkSound("BladeSlice", transform.position);
            }
            else
            {
                PlayerHealth attackTarget = npcObj.GetComponent <PlayerHealth>();
                RpcMeleAttackLerp(stabDirection, weapon);
                attackTarget.Harvest();
                soundNetworkActions.RpcPlayNetworkSound("BladeSlice", transform.position);
            }
        }
    }
    public void CmdRequestMeleeAttack(GameObject victim, Vector2 attackDirection,
                                      BodyPartType damageZone, LayerType layerType)
    {
        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;
        }

        if (!allowAttack)
        {
            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       attackSoundName   = isWeapon ? weaponAttr.ServerHitSound : "Punch#";
        LayerTile attackedTile      = null;

        bool didHit = false;


        // 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)
            {
                var worldPos = (Vector2)transform.position + attackDirection;
                attackedTile = tileChangeManager.InteractableTiles.LayerTileAt(worldPos);
                tileMapDamage.DoMeleeDamage(worldPos,
                                            gameObject, (int)damage);
                didHit = true;
            }
        }
        else
        {
            //a regular object being attacked

            //butchering
            //TODO: Move butchering logic to IF2, it should be a progress action done on corpses (make a Corpse component probably)
            LivingHealthBehaviour victimHealth = victim.GetComponent <LivingHealthBehaviour>();
            if (victimHealth != null && victimHealth.IsDead && isWeapon && weaponAttr.HasTrait(KnifeTrait))
            {
                if (victim.GetComponent <SimpleAnimal>())
                {
                    SimpleAnimal attackTarget = victim.GetComponent <SimpleAnimal>();
                    RpcMeleeAttackLerp(attackDirection, weapon);
                    playerMove.allowInput = false;
                    attackTarget.Harvest();
                    SoundManager.PlayNetworkedAtPos("BladeSlice", transform.position);
                }
                else
                {
                    PlayerHealth attackTarget = victim.GetComponent <PlayerHealth>();
                    RpcMeleeAttackLerp(attackDirection, weapon);
                    playerMove.allowInput = false;
                    attackTarget.Harvest();
                    SoundManager.PlayNetworkedAtPos("BladeSlice", transform.position);
                }
            }

            var integrity = victim.GetComponent <Integrity>();
            if (integrity != null)
            {
                //damaging an object
                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))
                {
                    // 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("PunchMiss", transform.position);
                    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)
        {
            SoundManager.PlayNetworkedAtPos(attackSoundName, transform.position);
            if (damage > 0)
            {
                Chat.AddAttackMsgToChat(gameObject, victim, damageZone, weapon, attackedTile: attackedTile);
            }
            if (victim != gameObject)
            {
                RpcMeleeAttackLerp(attackDirection, weapon);
                playerMove.allowInput = false;
            }
        }

        //no matter what, start a cooldown for attacking again so they can't spam attack requests
        StartCoroutine(AttackCoolDown());
    }
Exemplo n.º 4
0
    public void CmdRequestMeleeAttack(GameObject victim, string slot, Vector2 stabDirection, BodyPartType damageZone)
    {
        if (!playerMove.allowInput ||
            playerMove.isGhost ||
            !victim ||
            !playerScript.playerNetworkActions.SlotNotEmpty(slot) ||
            !PlayerManager.PlayerInReach(victim.transform)
            )
        {
            return;
        }
        var             weapon       = playerScript.playerNetworkActions.Inventory[slot];
        ItemAttributes  weaponAttr   = weapon.GetComponent <ItemAttributes>();
        HealthBehaviour victimHealth = victim.GetComponent <HealthBehaviour>();


        // checks object and component existence before defining healthBehaviour variable.
        if (victimHealth.IsDead == false)
        {
            if (!allowAttack)
            {
                return;
            }

            if (victim != gameObject)
            {
                RpcMeleeAttackLerp(stabDirection, weapon);
            }

            victimHealth.ApplyDamage(gameObject, ( int )weaponAttr.hitDamage, DamageType.BRUTE, damageZone);
            if (weaponAttr.hitDamage > 0)
            {
                PostToChatMessage.SendItemAttackMessage(weapon, gameObject, victim, (int)weaponAttr.hitDamage, damageZone);
            }

            soundNetworkActions.RpcPlayNetworkSound(weaponAttr.hitSound, transform.position);
            StartCoroutine(AttackCoolDown());
        }
        else
        {
            //Butchering if we can
            if (weaponAttr.type != ItemType.Knife)
            {
                return;
            }
            if (victim.GetComponent <SimpleAnimal>())
            {
                SimpleAnimal attackTarget = victim.GetComponent <SimpleAnimal>();
                RpcMeleeAttackLerp(stabDirection, weapon);
                attackTarget.Harvest();
                soundNetworkActions.RpcPlayNetworkSound("BladeSlice", transform.position);
            }
            else
            {
                PlayerHealth attackTarget = victim.GetComponent <PlayerHealth>();
                RpcMeleeAttackLerp(stabDirection, weapon);
                attackTarget.Harvest();
                soundNetworkActions.RpcPlayNetworkSound("BladeSlice", transform.position);
            }
        }
    }
    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)
        {
            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)
            {
                //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)
        {
            Chat.AddAttackMsgToChat(gameObject, victim, damageZone, weapon);
        }


        StartCoroutine(AttackCoolDown());
    }
Exemplo n.º 6
0
    public void CmdRequestMeleeAttack(GameObject victim, string slot, Vector2 stabDirection,
                                      BodyPartType damageZone, LayerType layerType)
    {
        if (!playerMove.allowInput ||
            playerMove.isGhost ||
            !victim ||
            !playerScript.playerNetworkActions.SlotNotEmpty(slot) ||
            !playerScript.playerHealth.serverPlayerConscious
            )
        {
            return;
        }
        if (!allowAttack)
        {
            return;
        }

        var            weapon     = playerScript.playerNetworkActions.Inventory[slot].Item;
        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))
        {
            return;
        }

        //Meaty bodies:
        LivingHealthBehaviour victimHealth = victim.GetComponent <LivingHealthBehaviour>();

        if (victimHealth.IsDead && weaponAttr.type == 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);
            }
            return;
        }

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

        victimHealth.ApplyDamage(gameObject, (int)weaponAttr.hitDamage, DamageType.Brute, damageZone);
        if (weaponAttr.hitDamage > 0)
        {
            PostToChatMessage.SendItemAttackMessage(weapon, gameObject, victim, (int)weaponAttr.hitDamage, damageZone);
        }

        SoundManager.PlayNetworkedAtPos(weaponAttr.hitSound, transform.position);
        StartCoroutine(AttackCoolDown());
    }