public void SetBodyPart(BodyPartType bodyPartType, Element element) {
		switch (bodyPartType) {
		case BodyPartType.Head:
			Head.gameObject.GetComponent<SpriteRenderer> ().sprite = BodyPartCollections [(int)element].Head;
			break;
		case BodyPartType.Body:
			Body.gameObject.GetComponent<SpriteRenderer> ().sprite = BodyPartCollections [(int)element].Body;
			LeftWing.gameObject.SetActive(BodyPartCollections[(int)element].UseSecondaryWings == false);
			RightWing.gameObject.SetActive(BodyPartCollections[(int)element].UseSecondaryWings == false);
			SecondLeftWing.gameObject.SetActive(BodyPartCollections[(int)element].UseSecondaryWings);
			SecondRightWing.gameObject.SetActive(BodyPartCollections[(int)element].UseSecondaryWings);
			break;
		case BodyPartType.Wings:
			SecondLeftWing.gameObject.GetComponent<SpriteRenderer> ().sprite = BodyPartCollections [(int)element].LeftWing;
			SecondRightWing.gameObject.GetComponent<SpriteRenderer> ().sprite = BodyPartCollections [(int)element].RightWing;

			LeftWing.gameObject.GetComponent<SpriteRenderer> ().sprite = BodyPartCollections [(int)element].LeftWing;
			RightWing.gameObject.GetComponent<SpriteRenderer> ().sprite = BodyPartCollections [(int)element].RightWing;

			break;
		}
	}
Ejemplo n.º 2
0
 public override void Shoot(Vector2 direction, GameObject controlledByPlayer, Gun fromWeapon, BodyPartType targetZone = BodyPartType.Chest)
 {
     WillHurtShooter = false;
     StartShoot(direction, controlledByPlayer, fromWeapon, targetZone);
 }
Ejemplo n.º 3
0
 public BodyPartSlot(string id, BodyPartType partType, IEnumerable <BodyPartSlot> connections)
 {
     Id          = id;
     PartType    = partType;
     Connections = new HashSet <BodyPartSlot>(connections);
 }
Ejemplo n.º 4
0
 public BodyPart[] GetAllParts(BodyPartType type)
 {
     return(allParts[(int)type].parts);
 }
Ejemplo n.º 5
0
 public abstract void Suicide(GameObject controlledByPlayer, Gun fromWeapon, BodyPartType targetZone = BodyPartType.Chest);
Ejemplo n.º 6
0
    /// <summary>
    /// Sends a message to all players about an attack that took place
    /// </summary>
    /// <param name="attacker">GameObject of the player that attacked</param>
    /// <param name="victim">GameObject of the player hat was the victim</param>
    /// <param name="damage">damage done</param>
    /// <param name="hitZone">zone that was damaged</param>
    /// <param name="item">optional gameobject with an itemattributes, representing the item the attack was made with</param>
    /// <param name="customAttackVerb">If you want to override the attack verb then pass the verb here</param>
    /// <param name="attackedTile">If attacking a particular tile, the layer tile being attacked</param>
    public static void AddAttackMsgToChat(GameObject attacker, GameObject victim,
                                          BodyPartType hitZone = BodyPartType.None, GameObject item = null, string customAttackVerb = "", LayerTile attackedTile = null)
    {
        string attackVerb;
        string attack;

        if (item)
        {
            var itemAttributes = item.GetComponent <ItemAttributesV2>();
            attackVerb = itemAttributes.ServerAttackVerbs.PickRandom() ?? "attacked";
            attack     = $" with {itemAttributes.ArticleName}";
        }
        else
        {
            // Punch attack as there is no item.
            attackVerb = "punched";
            attack     = "";
        }

        if (!string.IsNullOrEmpty(customAttackVerb))
        {
            attackVerb = customAttackVerb;
        }

        var player = victim.Player();

        if (player == null)
        {
            hitZone = BodyPartType.None;
        }

        string victimName;
        string victimNameOthers = "";

        if (attacker == victim)
        {
            victimName = "yourself";
            if (player != null)
            {
                if (player.Script.characterSettings.Gender == Gender.Female)
                {
                    victimNameOthers = "herself";
                }

                if (player.Script.characterSettings.Gender == Gender.Male)
                {
                    victimNameOthers = "himself";
                }

                if (player.Script.characterSettings.Gender == Gender.Neuter)
                {
                    victimNameOthers = "itself";
                }
            }
            else
            {
                victimNameOthers = "itself";
            }
        }
        else if (attackedTile != null)
        {
            victimName       = attackedTile.DisplayName;
            victimNameOthers = victimName;
        }
        else
        {
            victimName       = victim.ExpensiveName();
            victimNameOthers = victimName;
        }

        var attackerName = attacker.Player()?.Name;

        if (string.IsNullOrEmpty(attackerName))
        {
            var mobAi = attacker.GetComponent <MobAI>();
            if (mobAi != null)
            {
                attackerName = mobAi.mobName;
            }
            else
            {
                attackerName = "Unknown";
            }
        }

        var messageOthers = $"{attackerName} has {attackVerb} {victimNameOthers}{InTheZone(hitZone)}{attack}!";
        var message       = $"You {attackVerb} {victimName}{InTheZone(hitZone)}{attack}!";

        Instance.addChatLogServer.Invoke(new ChatEvent
        {
            channels      = ChatChannel.Combat,
            message       = message,
            messageOthers = messageOthers,
            position      = attacker.WorldPosServer(),
            speaker       = attacker.name,
            originator    = attacker
        });
    }
Ejemplo n.º 7
0
    private Bounds LoadObject(BodyPartType bodyPart, int id)
    {
        Bounds objectBounds = new Bounds(skeleton.transform.position, Vector3.zero);
        ZSC zsc = rm.getZSC(charModel.gender, bodyPart);

        for (int i = 0; i < zsc.Objects[id].Models.Count; i++)
        {
            int ModelID = zsc.Objects[id].Models[i].ModelID;
            int TextureID = zsc.Objects[id].Models[i].TextureID;

            Bounds partBounds = LoadPart(bodyPart, zsc.Objects[id].Models[i].DummyIndex, zsc.Models[ModelID], zsc.Textures[TextureID].Path);
            objectBounds.Encapsulate(partBounds);
        }
        return objectBounds;
    }
Ejemplo n.º 8
0
    /// <summary>
    /// Sends a message to all players about an attack that took place
    /// </summary>
    /// <param name="item">gameobject with an itemattributes, representing the item the attack was made with</param>
    /// <param name="attacker">GameObject of the player that attacked</param>
    /// <param name="victim">GameObject of the player hat was the victim</param>
    /// <param name="damage">damage done</param>
    /// <param name="hitZone">zone that was damaged</param>
    public static void SendItemAttackMessage(GameObject item, GameObject attacker, GameObject victim, float damage, BodyPartType hitZone = BodyPartType.None)
    {
        var itemAttributes = item.GetComponent <ItemAttributes>();

        var player = victim.Player();

        if (player == null)
        {
            hitZone = BodyPartType.None;
        }

        string victimName;

        if (attacker == victim)
        {
            victimName = "self";
        }
        else
        {
            victimName = victim.ExpensiveName();
        }

        var attackVerb = itemAttributes.attackVerb.GetRandom() ?? "attacked";

        var message = $"{attacker.Player()?.Name} has {attackVerb} {victimName}{InTheZone( hitZone )} with {itemAttributes.itemName}!";

//		var message = $"{victim.Name} has been {attackVerb}{zone} with {itemAttributes.itemName}!";
        ChatRelay.Instance.AddToChatLogServer(new ChatEvent {
            channels = ChatChannel.Combat,
            message  = message,
            position = victim.transform.position,
            radius   = 9f,
            sizeMod  = Mathf.Clamp(damage / 15, 1, 3)
        });
    }
Ejemplo n.º 9
0
 public BodyPart(BodyPartType type)
 {
     Type = type;
     MaxStacks = 1;
 }
Ejemplo n.º 10
0
 /// <summary>
 /// Get the ZSC object associated with the given gender and bodyPart
 /// </summary>
 /// <param name="gender"></param>
 /// <param name="bodyPart"></param>
 /// <returns></returns>
 public ZSC getZSC( GenderType gender, BodyPartType bodyPart)
 {
     bool male = gender == GenderType.MALE;
     switch(bodyPart)
     {
         case BodyPartType.BODY:
             return male ? zsc_body_male : zsc_body_female;
         case BodyPartType.ARMS:
             return male ? zsc_arms_male : zsc_arms_female;
         case BodyPartType.FOOT:
             return male ? zsc_foot_male : zsc_foot_female;
         case BodyPartType.FACE:
             return male ? zsc_face_male : zsc_face_female;
         case BodyPartType.HAIR:
             return male ? zsc_hair_male : zsc_hair_female;
         case BodyPartType.CAP:
             return male ? zsc_cap_male : zsc_cap_female;
         case BodyPartType.BACK:
             return zsc_back;
         case BodyPartType.FACEITEM:
             return zsc_faceItem;
         case BodyPartType.WEAPON:
             return zsc_weapon;
         case BodyPartType.SUBWEAPON:
             return zsc_subweapon;
         default:
             return null;
     }
 }
    /*
    void Spawn()
    {
        m_PuppetParts = new BodyPart[m_BodyParts.Length];
        for (int i = 0; i < m_BodyParts.Length; i++)
        {
            if (m_BodyParts[i].m_Parts == null || m_BodyParts[i].m_Parts.Length == 0 )
                continue;

            BodyPart part = Instantiate(m_BodyParts[i].m_Parts[0]) as BodyPart;            
            m_PuppetParts[i] = part;    
        }
    }
    */
    
    BodyPart[] GetBodyParts( BodyPartType type )
    {
        for (int i = 0; i < m_BodyParts.Length; i++)
        {
            if (m_BodyParts[i].m_Type == type)
                return m_BodyParts[i].m_Parts;
        }

        return null;
    }
Ejemplo n.º 12
0
 public void changeID(BodyPartType bodyPart, int id)
 {
     switch (bodyPart) {
         case BodyPartType.ARMS:
             equip.handID = id; break;
         case BodyPartType.BACK:
             equip.backID = id; break;
         case BodyPartType.BODY:
             equip.chestID = id; break;
         case BodyPartType.CAP:
             equip.capID = id; break;
         case BodyPartType.FACE:
             equip.faceID = id; break;
         case BodyPartType.FACEITEM:
             equip.maskID = id; break;
         case BodyPartType.FOOT:
             equip.footID = id; break;
         case BodyPartType.HAIR:
             equip.hairID = id; break;
         case BodyPartType.SUBWEAPON:
             equip.shieldID = id; break;
         case BodyPartType.WEAPON:
             equip.weaponID = id; break;
         default:
             break;
     }
 }
Ejemplo n.º 13
0
 public void OnChangeEquip(BodyPartType bodyPart, int id)
 {
     rosePlayer.equip (bodyPart, id);
 }
Ejemplo n.º 14
0
    public void equip(BodyPartType bodyPart, int id, bool changeId = true)
    {
        if (bodyPart == BodyPartType.WEAPON) {
            WeaponType weapType = rm.getWeaponType (id);
            charModel.equip.weaponID = id;

            // if this weapon is two-handed and a subweapon is equipped, unequip the subweapon first
            if ( !Utils.isOneHanded(weapType) && charModel.equip.shieldID > 0)
                equip(BodyPartType.SUBWEAPON, 0);

            // Change skeleton if weapon type is different
            if (weapType != charModel.weapon) {
                charModel.weapon = weapType;
                LoadPlayerSkeleton ( charModel );
                return;
            }
        }

        // If equipping subweapon and a two-hand weapon is equipped, first unequip the 2-hand
        if (( bodyPart == BodyPartType.SUBWEAPON) && id > 0 && !Utils.isOneHanded(charModel.weapon))
                equip(BodyPartType.WEAPON, 0);

        // If equipping cap, first make sure the hair is changed to the right type
        if(bodyPart == BodyPartType.CAP)
        {
            String hairOffsetStr = rm.stb_cap_list.Cells[id][34];
            int hairOffset = (hairOffsetStr == "") ? 0 : int.Parse(hairOffsetStr);
            equip(BodyPartType.HAIR, charModel.equip.hairID - (charModel.equip.hairID)%5 + hairOffset, false);
        }

        if( changeId)
            charModel.changeID(bodyPart, id);

        List<Transform> partTransforms = Utils.findChildren (player, bodyPart.ToString());

        foreach (Transform partTransform in partTransforms)
            Utils.Destroy(partTransform.gameObject);

        LoadObject(bodyPart, id);
    }
Ejemplo n.º 15
0
    private Bounds LoadPart(BodyPartType bodyPart, ZSC.DummyType dummy, string zmsPath, string texPath)
    {
        zmsPath = Utils.FixPath(zmsPath);
        texPath = Utils.FixPath (texPath).Replace ("dds", "png");

        // Cached load of ZMS and texture
        ResourceManager rm = ResourceManager.Instance;
        ZMS zms = (ZMS)rm.cachedLoad(zmsPath);
        Texture2D tex = (Texture2D)rm.cachedLoad(texPath);

        // Create material
        string shader = "VertexLit";
        if (bodyPart == BodyPartType.BACK)
            shader = "Transparent/Cutout/VertexLit";

        Material mat = new Material(Shader.Find(shader));

        mat.SetTexture("_MainTex", tex);
        mat.SetColor("_Emission", new Color(0.15f, 0.15f, 0.15f));

        GameObject modelObject = new GameObject();

        switch ( bodyPart )
        {
            case BodyPartType.FACE:
            case BodyPartType.HAIR:
                modelObject.transform.parent = Utils.findChild(skeleton, "b1_head");
                break;
            case BodyPartType.CAP:  // TODO: figure out how to fix issue of hair coming out of cap
                modelObject.transform.parent = Utils.findChild(skeleton, "p_06");
                break;
            case BodyPartType.BACK:
                modelObject.transform.parent = Utils.findChild(skeleton, "p_03");
                break;
            case BodyPartType.WEAPON:
                if(charModel.weapon == WeaponType.DSW || charModel.weapon == WeaponType.KATAR )
                    modelObject.transform.parent = Utils.findChild(skeleton, dummy == ZSC.DummyType.RightHand? "p_00" : "p_01");
                else
                    modelObject.transform.parent = Utils.findChild(skeleton, "p_00");
                break;
            case BodyPartType.SUBWEAPON:
                modelObject.transform.parent = Utils.findChild(skeleton, "p_02");
                break;
            default:
                modelObject.transform.parent = skeleton.transform.parent.transform;
                break;
        }

        modelObject.transform.localPosition = Vector3.zero;
        modelObject.transform.localRotation = Quaternion.identity;
        modelObject.transform.localScale = Vector3.one;
        modelObject.name = bodyPart.ToString ();
        Mesh mesh = zms.getMesh();
        if (zms.support.bones)
        {
            SkinnedMeshRenderer renderer = modelObject.AddComponent<SkinnedMeshRenderer>();

            mesh.bindposes = bindPoses.bindPoses;
            renderer.sharedMesh = mesh;
            renderer.material = mat;
            renderer.bones = bindPoses.boneTransforms;
        }
        else
        {
            modelObject.AddComponent<MeshFilter>().mesh = mesh;
            MeshRenderer renderer = modelObject.AddComponent<MeshRenderer>();
            renderer.material = mat;
        }

        return mesh.bounds;
    }
Ejemplo n.º 16
0
    public void CmdShootBullet(GameObject weapon, GameObject magazine, Vector2 direction, string bulletName, BodyPartType damageZone)
    {
        if (!playerMove.allowInput || playerMove.isGhost)
        {
            return;
        }

        //get componants
        Weapon            wepBehavior  = weapon.GetComponent <Weapon>();
        MagazineBehaviour magBehaviour = magazine.GetComponent <MagazineBehaviour>();

        //reduce ammo for shooting
        magBehaviour.ammoRemains--;         //TODO: remove more bullets if burst

        //get the bullet prefab being shot
        GameObject bullet = PoolManager.PoolClientInstantiate(Resources.Load(bulletName) as GameObject, transform.position, Quaternion.identity);
        var        angle  = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;

        //if we have recoil variance add it, and get the new attack angle
        if (wepBehavior != null && wepBehavior.CurrentRecoilVariance > 0)
        {
            direction = GetRecoilOffset(wepBehavior, angle);
        }

        BulletBehaviour b = bullet.GetComponent <BulletBehaviour>();

        b.Shoot(direction, angle, gameObject.name, damageZone);

        //add additional recoil after shooting for the next round
        AppendRecoil(wepBehavior, angle);

        //This is used to determine where bullet shot should head towards on client
        Ray2D ray = new Ray2D(transform.position, direction);

        RpcShootBullet(weapon, ray.GetPoint(30f), bulletName, damageZone);

        //TODO add a check to see if bullet or energy weapon
        SpawnBulletCaseing();
        if (!isFlashing)
        {
            isFlashing = true;
            StartCoroutine(ShowMuzzleFlash());
        }
    }
Ejemplo n.º 17
0
 private static string InTheZone(BodyPartType hitZone)
 {
     return(hitZone == BodyPartType.None ? "" : $" in the {hitZone.ToString().ToLower().Replace( "_", " " )}");
 }
Ejemplo n.º 18
0
 public void ChangeBodySprite(Sprite partSprite, BodyPartType bodyPart, int spriteID)
 {
     imageLookup[(int)bodyPart].sprite          = partSprite;
     characterData.partSelection[(int)bodyPart] = spriteID;
     Debug.Log("Part: " + partSprite.ToString() + "Sprite ID: " + spriteID.ToString());
 }
Ejemplo n.º 19
0
 /// <summary>
 /// Shoot the controlledByPlayer
 /// </summary>
 /// <param name="controlledByPlayer">player doing the shooting</param>
 /// <param name="targetZone">body part being targeted</param>
 /// <param name="fromWeapon">Weapon the shot is being fired from</param>
 public void Suicide(GameObject controlledByPlayer, Gun fromWeapon, BodyPartType targetZone = BodyPartType.Chest)
 {
     isSuicide = true;
     StartShoot(Vector2.zero, controlledByPlayer, fromWeapon, targetZone);
 }
Ejemplo n.º 20
0
 public void ChangePartColor(Color partColor, BodyPartType bodyPart, int colourID)
 {
     imageLookup[(int)bodyPart].color             = partColor;
     characterData.colourSelection[(int)bodyPart] = colourID;
 }
Ejemplo n.º 21
0
 private BodyPart FindBodyPart(BodyPartType bodyPartType)
 {
     return(bodyParts.FirstOrDefault(bodyParts => bodyParts.BodyPartType == bodyPartType));
 }
 /// <summary>
 ///     Grabs the <see cref="BodyPartType"/> of the given slotName if there is one. Returns true if the slot is found, false otherwise. If false, result will be null.
 /// </summary>
 public bool TryGetSlotType(string slotName, out BodyPartType result)
 {
     return(_template.Slots.TryGetValue(slotName, out result));
 }
Ejemplo n.º 23
0
 public BodyManagerHealthChangeParams(BodyPartType part)
 {
     Part = part;
 }
Ejemplo n.º 24
0
    public void ServerPerformMeleeAttack(GameObject victim, Vector2 attackDirection, BodyPartType damageZone, LayerType layerType)
    {
        if (victim == null)
        {
            return;
        }
        if (Cooldowns.IsOnServer(playerScript, CommonCooldowns.Instance.Melee))
        {
            return;
        }
        if (playerMove.allowInput == false)
        {
            return;
        }
        if (playerScript.IsGhost)
        {
            return;
        }
        if (playerScript.playerHealth.serverPlayerConscious == false)
        {
            return;
        }

        if (victim.TryGetComponent <InteractableTiles>(out var tiles))
        {
            // validate based on position of target vector
            if (Validations.CanApply(playerScript, victim, NetworkSide.Server, targetVector: attackDirection) == false)
            {
                return;
            }
        }
        else
        {
            // validate based on position of target object
            if (Validations.CanApply(playerScript, victim, NetworkSide.Server) == false)
            {
                return;
            }
        }

        float                  damage           = fistDamage;
        DamageType             damageType       = DamageType.Brute;
        AddressableAudioSource weaponSound      = meleeSounds.PickRandom();
        GameObject             weapon           = playerScript.playerNetworkActions.GetActiveHandItem();
        ItemAttributesV2       weaponAttributes = weapon == null ? null : weapon.GetComponent <ItemAttributesV2>();

        if (weaponAttributes != null)
        {
            damage       = weaponAttributes.ServerHitDamage;
            damageType   = weaponAttributes.ServerDamageType;
            weaponSound  = weaponAttributes.hitSoundSettings == SoundItemSettings.OnlyObject ? null : weaponAttributes.ServerHitSound;
            slashChance  = weaponAttributes.SlashChance;
            slashDamage  = weaponAttributes.SlashDamage;
            pierceChance = weaponAttributes.PierceChance;
            pierceDamage = weaponAttributes.PierceDamage;
            burnDamage   = weaponAttributes.BurnDamage;
        }

        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)
            {
                return;
            }

            var worldPos = (Vector2)transform.position + attackDirection;
            attackedTile = tileChangeManager.InteractableTiles.LayerTileAt(worldPos, true);

            // Tile itself is responsible for playing victim damage sound
            tileMapDamage.ApplyDamage(damage, AttackType.Melee, worldPos);
            didHit = true;
        }
        // Damaging an object
        else if (victim.TryGetComponent <Integrity>(out var integrity) &&
                 victim.TryGetComponent <Meleeable>(out var meleeable) && meleeable.IsMeleeable)
        {
            if (weaponAttributes != null && weaponAttributes.hitSoundSettings != SoundItemSettings.OnlyItem)
            {
                AudioSourceParameters audioSourceParameters = new AudioSourceParameters(pitch: Random.Range(0.9f, 1.1f));
                SoundManager.PlayNetworkedAtPos(integrity.soundOnHit, gameObject.WorldPosServer(), audioSourceParameters, sourceObj: gameObject);
            }

            integrity.ApplyDamage(damage, AttackType.Melee, damageType);
            didHit = true;
        }
Ejemplo n.º 25
0
 public abstract void Shoot(Vector2 direction, GameObject controlledByPlayer, Gun fromWeapon, BodyPartType targetZone = BodyPartType.Chest);
    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       attackSoundName   = isWeapon ? weaponAttr.ServerHitSound : "Punch#";
        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)
                {
                    attackSoundName = "";
                }
                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

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

            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)
                    {
                        SoundManager.PlayNetworkedAtPos(integrity.soundOnHit, gameObject.WorldPosServer(), Random.Range(0.9f, 1.1f), sourceObj: gameObject);
                    }
                    else if (isWeapon && weaponStats != null &&
                             weaponStats.hitSoundSettings == SoundItemSettings.OnlyObject && integrity.soundOnHit != "")
                    {
                        SoundManager.PlayNetworkedAtPos(integrity.soundOnHit, gameObject.WorldPosServer(), Random.Range(0.9f, 1.1f), sourceObj: gameObject);
                        attackSoundName = "";
                    }
                    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("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 (!string.IsNullOrEmpty(attackSoundName))
            {
                SoundManager.PlayNetworkedAtPos(attackSoundName, 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);
    }
Ejemplo n.º 27
0
 public BodyPartSlot(string id, BodyPartType partType)
 {
     Id          = id;
     PartType    = partType;
     Connections = new HashSet <BodyPartSlot>();
 }
 public void OnShoot(Vector2 direction, GameObject shooter, Gun weapon, BodyPartType targetZone = BodyPartType.Chest)
 {
     this.shooter    = shooter;
     this.targetZone = targetZone;
 }
Ejemplo n.º 29
0
 protected void ApplyDamageToPartyType(LivingHealthMasterBase health, BodyPartType type)
 {
     health.ApplyDamageToBodyPart(gameObject, damageToGive, attackType, damageType, type, armorPentration, traumaChance, traumaType);
 }
 public RuleSolution(ToolBox.Tool t, BodyPartType b)
 {
     tool = t;
     isBodyPartSpecific = true;
     bodyPart           = b;
 }
Ejemplo n.º 31
0
        private void StartShoot(Vector2 direction, GameObject controlledByPlayer, Gun fromWeapon, BodyPartType targetZone)
        {
            shooter = controlledByPlayer;

            var startPosition = new Vector3(direction.x, direction.y, thisTransform.position.z) * 0.2f;

            thisTransform.position += startPosition;

            if (overrideVelocity == false && fromWeapon != null)
            {
                projectileVelocity = fromWeapon.ProjectileVelocity;
            }

            movingProjectile.SetUpBulletTransform(direction, projectileVelocity);

            foreach (var behaviour in behavioursOnShoot)
            {
                behaviour.OnShoot(direction, controlledByPlayer, fromWeapon, targetZone);
            }
        }
    // Eval a rule: given the current body state, the tool applied and to what body part, we apply our rules
    // Returns true if we did something right (even if the rule isn't resolved) and false on a mistake
    public static bool EvaluateCure(BodyPart[] bodyParts, ToolBox.Tool playersTool, BodyPartType playersTargetBodyPart, BodyPartColor bodyColor, ref int bodyHeartbeat, out bool fixesColor)
    {
        fixesColor = false;
        // Count number of each symptom we have
        int kSymptomCount = System.Enum.GetNames(typeof(Symptom)).Length;

        int[] symptomCount = new int[kSymptomCount];

        // How many of each symptom do we have?
        for (int i = 1; i < kSymptomCount; i++)
        {
            symptomCount[i] = CountSymptom(bodyParts, (Symptom)i);
        }


        int  lastGroupId  = -1;
        bool groupDidFail = false;

        // For each rule, see which is applicable!
        foreach (Rule rule in rules)
        {
            bool ruleDoesApply = false;

            // What was the last rule's group and did it get applied but failed? If so, stop applying this group's rules..
            if (lastGroupId != rule.GroupID)
            {
                groupDidFail = false;
                lastGroupId  = rule.GroupID;
            }
            else if (groupDidFail)
            {
                continue;
            }

            // ExactCount: Checks if there is X number of Y symptoms on fixesBodyPartType.
            if (rule.ruleType == RuleType.ExactCount)
            {
                // Check count of this symptom, followed by if the symptom matches
                if (symptomCount [(int)rule.countSymptom] == rule.count && bodyParts [(int)rule.fixesBodyPartType].symptom == rule.countSymptom)
                {
                    ruleDoesApply = true;
                }
            }

            // MinCount: Checks if there is 1 number of Y sumptom on fixesBodyPartType and at least X (inclusive) number overall.
            else if (rule.ruleType == RuleType.MinCount)
            {
                if (symptomCount [(int)rule.countSymptom] >= rule.count && bodyParts [(int)rule.fixesBodyPartType].symptom == rule.countSymptom)
                {
                    ruleDoesApply = true;
                }
            }

            // ExactMatch: Rule is applied if the matching pattern (color, body part, symptom) i.
            else if (rule.ruleType == RuleType.ExactMatch)
            {
                // Does the target body part have this symptom?
                bool symptomMatches = (rule.exactSymptom == bodyParts [(int)rule.fixesBodyPartType].symptom);

                bool colorMatches = true;
                if (rule.exactColorIsSpecific && rule.exactColorNegate == false)
                {
                    colorMatches = (rule.exactColor == bodyColor);
                }
                else if (rule.exactColorNegate)
                {
                    colorMatches = (rule.exactColor != bodyColor);
                }

                if (symptomMatches && colorMatches)
                {
                    ruleDoesApply = true;
                }
            }

            // ColorMatch: Check if there is a color match. Simple.
            else if (rule.ruleType == RuleType.ColorMatch)
            {
                ruleDoesApply = (bodyColor == rule.exactColor);
            }

            // Heartbeat: Check if heartbeat is below or above.
            else if (rule.ruleType == RuleType.Heartbeat)
            {
                if (rule.heartbeatGreater == true)
                {
                    ruleDoesApply = (bodyHeartbeat > rule.heartbeatValue);
                }
            }


            // If rule applies...
            if (ruleDoesApply)
            {
                // Did it succeed? If so we're done!
                if (EvaluateRuleSolutions(rule, playersTool, playersTargetBodyPart))
                {
                    BodyPart fixedBodyPart = bodyParts [(int)rule.fixesBodyPartType];

                    fixedBodyPart.symptom = Symptom.None;
                    fixesColor            = (rule.fixesColor && rule.ruleSolutions.Count <= 0);            // Color is fixed if all requirements met

                    if (fixedBodyPart.BloodSpurt != null)
                    {
                        Object.Destroy(fixedBodyPart.BloodSpurt);
                        fixedBodyPart.BloodSpurt = null;
                    }

                    if (fixedBodyPart.PainEffect != null)
                    {
                        Object.Destroy(fixedBodyPart.PainEffect);
                        fixedBodyPart.PainEffect = null;
                    }

                    // Hack: if it's a heart rule that passes, we assume heartrate is fixed
                    if (rule.ruleType == RuleType.Heartbeat)
                    {
                        bodyHeartbeat = BodyController.kTargetHeartbeat;
                    }

                    return(true);

                    // No, so we can't apply any other rules in this group
                }
                else
                {
                    groupDidFail = true;
                }
            }
        }

        // No success..
        return(false);
    }
Ejemplo n.º 33
0
    public override int ReceiveAndCalculateDamage(string damagedBy, int damage, DamageType damageType, BodyPartType bodyPartAim)
    {
        base.ReceiveAndCalculateDamage(damagedBy, damage, damageType, bodyPartAim);

        //if this living is on the server:
//            if (b != null && b.shooterName != gameObject.name && mobStat != MobConsciousStat.DEAD) {
        var simpleAnimal = GetComponent <SimpleAnimal>();

        if (simpleAnimal != null &&
            simpleAnimal.mobStat != MobConsciousStat.DEAD &&
            CustomNetworkManager.Instance._isServer)
        {
            //delegated to Living atm
            GetComponent <Living>().ReceiveDamage(damagedBy, damage, damageType, bodyPartAim);
        }
        return(damage);
    }
Ejemplo n.º 34
0
 /// <summary>
 /// Applies burn damage to the specified victim's bodyparts.
 /// Attack type is internal, so as to avoid needing to add electrical resistances to Armor class.
 /// </summary>
 /// <param name="damage">The amount of damage to apply to the bodypart</param>
 /// <param name="bodypart">The BodyPartType to damage.</param>
 private void DealElectrocutionDamage(float damage, BodyPartType bodypart)
 {
     ApplyDamageToBodyPart(null, damage, AttackType.Internal, DamageType.Burn, bodypart);
 }
Ejemplo n.º 35
0
    public static void SendThrowHitMessage(GameObject item, GameObject victim, int damage, BodyPartType hitZone = BodyPartType.None)
    {
        var player = victim.Player();

        if (player == null)
        {
            hitZone = BodyPartType.None;
        }

        var message = $"{victim.ExpensiveName()} has been hit by {item.Item()?.itemName ?? item.name}{InTheZone( hitZone )}";

        ChatRelay.Instance.AddToChatLogServer(new ChatEvent {
            channels = ChatChannel.Combat,
            message  = message,
            position = victim.transform.position,
            radius   = 9f,
            sizeMod  = Mathf.Clamp(damage / 15, 1, 3)
        });
    }
Ejemplo n.º 36
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];
        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;
            }

            //Tilemap stuff:
            var tileMapDamage = tileChangeManager.GetTilemap(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.transform.position))
        {
            return;
        }

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

        if (victimHealth.IsDead && weaponAttr.type == ItemType.Knife)
        {
            if (victim.GetComponent <SimpleAnimal>())
            {
                SimpleAnimal attackTarget = victim.GetComponent <SimpleAnimal>();
                RpcMeleeAttackLerp(stabDirection, weapon);
                playerMove.allowInput = false;
                attackTarget.Harvest();
                soundNetworkActions.RpcPlayNetworkSound("BladeSlice", transform.position);
            }
            else
            {
                PlayerHealth attackTarget = victim.GetComponent <PlayerHealth>();
                RpcMeleeAttackLerp(stabDirection, weapon);
                playerMove.allowInput = false;
                attackTarget.Harvest();
                soundNetworkActions.RpcPlayNetworkSound("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);
        }

        soundNetworkActions.RpcPlayNetworkSound(weaponAttr.hitSound, transform.position);
        StartCoroutine(AttackCoolDown());
    }
Ejemplo n.º 37
0
 /// <summary>
 /// Inventory move in which the object in the slot is thrown into the world from the location of its root storage
 /// </summary>
 /// <param name="fromSlot"></param>
 /// <param name="worldTargetVector">world space vector pointing from origin to targeted position to throw</param>
 /// <param name="spinMode"></param>
 /// <param name="aim">body part to target</param>
 /// <returns>true if successful</returns>
 public static bool ServerThrow(ItemSlot fromSlot, Vector2 worldTargetVector, SpinMode spinMode = SpinMode.CounterClockwise, BodyPartType aim = BodyPartType.Chest)
 {
     return(ServerPerform(InventoryMove.Throw(fromSlot, worldTargetVector, spinMode, aim)));
 }
Ejemplo n.º 38
0
        /// <summary>
        /// Perform and display the shot locally (i.e. only on this instance of the game). Does not
        /// communicate anything to other players (unless this is the server, in which case the server
        /// will determine the effects of the bullet). Does not do any validation. This should only be invoked
        /// when displaying the results of a shot (i.e. after receiving a ShootMessage or after this client performs a shot)
        /// or when server is determining the outcome of the shot.
        /// </summary>
        /// <param name="shooter">gameobject of the shooter</param>
        /// <param name="finalDirection">direction the shot should travel (accuracy deviation should already be factored into this)</param>
        /// <param name="damageZone">targeted damage zone</param>
        /// <param name="isSuicideShot">if this is a suicide shot (aimed at shooter)</param>
        public void DisplayShot(GameObject shooter, Vector2 finalDirection,
                                BodyPartType damageZone, bool isSuicideShot)
        {
            if (!MatrixManager.IsInitialized)
            {
                return;
            }

            //if this is our gun (or server), last check to ensure we really can shoot
            if ((isServer || PlayerManager.LocalPlayer == shooter) &&
                CurrentMagazine.ClientAmmoRemains <= 0)
            {
                if (isServer)
                {
                    Logger.LogTrace("Server rejected shot - out of ammo", Category.Firearms);
                }

                return;
            }
            //TODO: If this is not our gun, simply display the shot, don't run any other logic
            if (shooter == PlayerManager.LocalPlayer)
            {
                //this is our gun so we need to update our predictions
                FireCountDown += 1.0 / FireRate;
                //add additional recoil after shooting for the next round
                AppendRecoil();

                //Default camera recoil params until each gun is configured separately
                if (CameraRecoilConfig == null || CameraRecoilConfig.Distance == 0f)
                {
                    CameraRecoilConfig = new CameraRecoilConfig
                    {
                        Distance         = 0.2f,
                        RecoilDuration   = 0.05f,
                        RecoveryDuration = 0.6f
                    };
                }
                Camera2DFollow.followControl.Recoil(-finalDirection, CameraRecoilConfig);
            }

            if (CurrentMagazine == null)
            {
                Logger.Log("Why is CurrentMagazine null on this client?");
            }
            else
            {
                //call ExpendAmmo outside of previous check, or it won't run serverside and state will desync.
                CurrentMagazine.ExpendAmmo();
            }

            //display the effects of the shot

            //get the bullet prefab being shot

            if (isSuicideShot)
            {
                GameObject bullet = Spawn.ClientPrefab(Projectile.name,
                                                       shooter.transform.position, parent: shooter.transform.parent).GameObject;
                var b = bullet.GetComponent <Projectile>();
                b.Suicide(shooter, this, damageZone);
            }
            else
            {
                for (int n = 0; n < ProjectilesFired; n++)
                {
                    GameObject Abullet = Spawn.ClientPrefab(Projectile.name,
                                                            shooter.transform.position, parent: shooter.transform.parent).GameObject;
                    var A = Abullet.GetComponent <Projectile>();
                    var finalDirectionOverride = CalcDirection(finalDirection, n);
                    A.Shoot(finalDirectionOverride, shooter, this, damageZone);
                }
            }
            SoundManager.PlayAtPosition(FiringSound, shooter.transform.position, shooter);
            shooter.GetComponent <PlayerSprites>().ShowMuzzleFlash();
        }
Ejemplo n.º 39
0
 public BodyPart(Texture2D texture, BodyPartType type)
 {
     _texture = texture;
     Type = type;
     MaxStacks = 1;
 }
Ejemplo n.º 40
0
    public override void Deserialize(NetworkReader reader)
    {
        base.Deserialize(reader);
        var componentID = reader.ReadUInt16();

        if (componentID == UNKNOWN_COMPONENT_TYPE_ID)
        {
            //client didn't know which to trigger, leave ComponentType null
            ComponentType = null;
        }
        else
        {
            //client requested a specific component.
            ComponentType = componentIDToComponentType[componentID];
        }

        InteractionType = interactionIDToInteractionType[reader.ReadByte()];
        if (componentID != UNKNOWN_COMPONENT_TYPE_ID)
        {
            // client specified exact component
            ProcessorObject = reader.ReadUInt32();
        }
        else
        {
            // client requested server to check the interaction
            ProcessorObject = NetId.Invalid;
        }
        Intent = (Intent)reader.ReadByte();

        if (InteractionType == typeof(PositionalHandApply))
        {
            TargetObject   = reader.ReadUInt32();
            TargetVector   = reader.ReadVector2();
            TargetBodyPart = (BodyPartType)reader.ReadUInt32();
        }
        else if (InteractionType == typeof(HandApply))
        {
            TargetObject   = reader.ReadUInt32();
            TargetBodyPart = (BodyPartType)reader.ReadUInt32();
            IsAltUsed      = reader.ReadBoolean();
        }
        else if (InteractionType == typeof(AimApply))
        {
            TargetVector     = reader.ReadVector2();
            MouseButtonState = reader.ReadBoolean() ? MouseButtonState.PRESS : MouseButtonState.HOLD;
        }
        else if (InteractionType == typeof(MouseDrop))
        {
            TargetObject = reader.ReadUInt32();
            UsedObject   = reader.ReadUInt32();
        }
        else if (InteractionType == typeof(InventoryApply))
        {
            UsedObject = reader.ReadUInt32();
            Storage    = reader.ReadUInt32();
            SlotIndex  = reader.ReadInt32();
            NamedSlot  = (NamedSlot)reader.ReadInt32();
            IsAltUsed  = reader.ReadBoolean();
        }
        else if (InteractionType == typeof(TileApply))
        {
            TargetVector = reader.ReadVector2();
        }
        else if (InteractionType == typeof(TileMouseDrop))
        {
            UsedObject   = reader.ReadUInt32();
            TargetVector = reader.ReadVector2();
        }
    }