コード例 #1
0
ファイル: ChatFilter.cs プロジェクト: ktndrnl/unitystation
    /// <summary>
    /// Sends a player message to the server.
    /// The message is omitted if too many messages have been sent recently.
    /// The message is shortened if the player has send too many characters recently.
    /// In either case the player will see a warning in their chat log.
    /// </summary>
    /// <param name="message">The player's message.</param>
    /// <param name="selectedChannels">The selected channels, which are simply passed along.</param>
    public void Send(string message, ChatChannel selectedChannels)
    {
        DecayFiltersOverTime();         // Decrease cpm and messages since last having spoken

        // Limit number of messages
        if (numMessages + 1 > numMessageMax || cpm + 1 > cpmMax)
        {
            if (selectedChannels.HasFlag(ChatChannel.OOC) || selectedChannels.HasFlag(ChatChannel.Ghost))
            {
                Chat.AddExamineMsgToClient(numMessagesWarningOOC);
            }
            else
            {
                Chat.AddExamineMsgToClient(numMessagesWarning);
            }
            return;
        }

        // Users message will (at least partiall) be spoken, so count it.
        numMessages++;
        cpm += message.Length;

        // Limit characters per minute
        int numCharsOverLimit = 0;

        if (cpm > cpmMax)
        {
            // Too many characters, calculate how many need to be removed.
            float cpmOver = cpm - cpmMax;
            cpm = cpmMax;             // Characters will be removed, so cpm must be lowered again.
            numCharsOverLimit = (int)Math.Floor(cpmOver);

            message = message.Remove(message.Length - numCharsOverLimit) + "...";
        }

        // Don't send message if it got shortened below the limit.
        if (0 < numCharsOverLimit && numCharsOverLimit < cpmMinCharacters)
        {
            return;
        }

        // Send message, which might have been shortened because of the character limit per minute.
        PostToChatMessage.Send(message, selectedChannels);

        // Notify player that their message got cut short.
        if (numCharsOverLimit > 0)
        {
            if (selectedChannels.HasFlag(ChatChannel.OOC) || selectedChannels.HasFlag(ChatChannel.Ghost))
            {
                Chat.AddExamineMsgToClient(cpmWarningOOC);
            }
            else
            {
                Chat.AddExamineMsgToClient(cpmWarning);
            }
        }
    }
コード例 #2
0
    public void VendItem(VendorItem item)
    {
        VendorItem itemToSpawn = null;

        foreach (var vendorItem in vendorContent)
        {
            if (vendorItem == item)
            {
                itemToSpawn = item;
                break;
            }
        }

        if (!CanSell(itemToSpawn))
        {
            return;
        }

        Vector3 spawnPos    = vendor.gameObject.RegisterTile().WorldPositionServer;
        var     spawnedItem = PoolManager.PoolNetworkInstantiate(itemToSpawn.Item, spawnPos, vendor.transform.parent);

        itemToSpawn.Stock--;
        PostToChatMessage.Send("Item given", ChatChannel.Examine);

        //Ejecting in direction
        if (vendor.EjectObjects && vendor.EjectDirection != EjectDirection.None)
        {
            Vector3 offset = Vector3.zero;
            switch (vendor.EjectDirection)
            {
            case EjectDirection.Up:
                offset = vendor.transform.rotation * Vector3.up / Random.Range(4, 12);
                break;

            case EjectDirection.Down:
                offset = vendor.transform.rotation * Vector3.down / Random.Range(4, 12);
                break;

            case EjectDirection.Random:
                offset = new Vector3(Random.Range(-0.15f, 0.15f), Random.Range(-0.15f, 0.15f), 0);
                break;
            }
            spawnedItem.GetComponent <CustomNetTransform>()?.Throw(new ThrowInfo
            {
                ThrownBy  = gameObject,
                Aim       = BodyPartType.Chest,
                OriginPos = spawnPos,
                TargetPos = spawnPos + offset,
                SpinMode  = (vendor.EjectDirection == EjectDirection.Random) ? SpinMode.Clockwise : SpinMode.None
            });
        }

        SendToChat(vendMessage);
        UpdateList();
        allowSell = false;
        StartCoroutine(VendorInputCoolDown());
    }
コード例 #3
0
 private void PlayerSendChat()
 {
     PostToChatMessage.Send(InputFieldChat.text, PlayerManager.LocalPlayerScript.SelectedChannels);
     if (InputFieldChat.text != "")
     {
         PlayerManager.LocalPlayerScript.playerNetworkActions.CmdToggleChatIcon(true);
     }
     InputFieldChat.text = "";
 }
コード例 #4
0
	//We want ChatEvent to be created on the server, so we're only passing the individual variables
	public static PostToChatMessage Send(string message, ChatChannel channels)
	{
		PostToChatMessage msg = new PostToChatMessage
		{
			Channels = channels,
			ChatMessageText = message
		};
		msg.Send();

		return msg;
	}
コード例 #5
0
    public void ReportKills()
    {
        if (syndicateKills != 0)
        {
            PostToChatMessage.Send("Syndicate managed to kill " + syndicateKills + " crew members.", ChatChannel.System);
        }

        if (crewKills != 0)
        {
            PostToChatMessage.Send("Crew managed to kill " + crewKills + " Syndicate operators.", ChatChannel.System);
        }
    }
コード例 #6
0
    private void PlayerSendChat()
    {
        // Selected channels already masks all unavailable channels in it's get method
        PostToChatMessage.Send(InputFieldChat.text, SelectedChannels);

        if (PlayerChatShown())
        {
            PlayerManager.LocalPlayerScript.playerNetworkActions.CmdToggleChatIcon(true, InputFieldChat.text,
                                                                                   SelectedChannels);
        }

        InputFieldChat.text = "";
    }
コード例 #7
0
 public static void Kick(ConnectedPlayer player, string raisins = "4 no raisins")
 {
     if (!player.Connection.isConnected)
     {
         Logger.Log($"Not kicking, already disconnected: {player}", Category.Connections);
         return;
     }
     Logger.Log($"Kicking {player} : {raisins}", Category.Connections);
     InfoWindowMessage.Send(player.GameObject, $"Kicked: {raisins}", "Kicked");
     PostToChatMessage.Send($"Player '{player.Name}' got kicked: {raisins}", ChatChannel.System);
     player.Connection.Disconnect();
     player.Connection.Dispose();
 }
コード例 #8
0
    /// <summary>
    /// Called after MatrixManager is initialized
    /// </summary>
    private void InitEscapeStuff()
    {
        //Primary escape shuttle lookup
        if (!PrimaryEscapeShuttle)
        {
            var shuttles = FindObjectsOfType <EscapeShuttle>();
            if (shuttles.Length != 1)
            {
                Logger.LogError("Primary escape shuttle is missing from GameManager!", Category.Round);
                return;
            }
            Logger.LogWarning("Primary escape shuttle is missing from GameManager, but one was found on scene");
            primaryEscapeShuttle = shuttles[0];
        }

        //later, maybe: keep a list of all computers and call the shuttle automatically with a 25 min timer if they are deleted

        //Starting up at Centcom coordinates
        PrimaryEscapeShuttle.MatrixInfo.MatrixMove.SetPosition(PrimaryEscapeShuttle.CentcomDest.Position);

        bool beenToStation = false;

        PrimaryEscapeShuttle.OnShuttleUpdate?.AddListener(status =>
        {
            //status display ETA tracking
            if (status == ShuttleStatus.OnRouteStation)
            {
                PrimaryEscapeShuttle.OnTimerUpdate.AddListener(TrackETA);
            }
            else
            {
                PrimaryEscapeShuttle.OnTimerUpdate.RemoveListener(TrackETA);
                CentComm.OnStatusDisplayUpdate.Invoke(StatusDisplayChannel.EscapeShuttle, string.Empty);
            }

            if (status == ShuttleStatus.DockedCentcom && beenToStation)
            {
                RoundEnd();
                Logger.Log("Shuttle arrived to Centcom, Round should end here", Category.Round);
            }

            if (status == ShuttleStatus.DockedStation)
            {
                beenToStation = true;
                SoundManager.PlayNetworked("Disembark");
                PostToChatMessage.Send("Escape shuttle has arrived! Crew has 1 minute to get on it.", ChatChannel.System);
                //should be changed to manual send later
                StartCoroutine(SendEscapeShuttle(60));
            }
        });
    }
コード例 #9
0
    protected override void OnDeathActions()
    {
        if (CustomNetworkManager.Instance._isServer)
        {
            PlayerNetworkActions pna = gameObject.GetComponent <PlayerNetworkActions>();
            PlayerMove           pm  = gameObject.GetComponent <PlayerMove>();

            ConnectedPlayer player = PlayerList.Instance.Get(gameObject);

            string killerName = "Stressful work";
            if (LastDamagedBy != null)
            {
                killerName = PlayerList.Instance.Get(LastDamagedBy).Name;
            }

            string playerName = player.Name ?? "dummy";
            if (killerName == playerName)
            {
                PostToChatMessage.Send(playerName + " commited suicide", ChatChannel.System);                 //Killfeed
            }
            else if (killerName.EndsWith(playerName))
            {
                // chain reactions
                PostToChatMessage.Send(
                    playerName + " screwed himself up with some help (" + killerName + ")",
                    ChatChannel.System);                     //Killfeed
            }
            else
            {
                PlayerList.Instance.UpdateKillScore(LastDamagedBy, gameObject);
            }
            pna.DropItem("rightHand");
            pna.DropItem("leftHand");

            if (isServer)
            {
                EffectsFactory.Instance.BloodSplat(transform.position, BloodSplatSize.large);
            }

            PlayerDeathMessage.Send(gameObject);
            //syncvars for everyone
            pm.isGhost    = true;
            pm.allowInput = true;
            //consider moving into PlayerDeathMessage.Process()
            pna.RpcSpawnGhost();
            RpcPassBullets(gameObject);

            //FIXME Remove for next demo
            pna.RespawnPlayer(10);
        }
    }
コード例 #10
0
    private bool ValidateFloating(Vector3 origin, Vector3 goal)
    {
//		Logger.Log( $"{gameObject.name} check {origin}->{goal}. Speed={serverState.Speed}" );
        Vector3Int             intOrigin = Vector3Int.RoundToInt(origin);
        Vector3Int             intGoal   = Vector3Int.RoundToInt(goal);
        var                    info      = serverState.ActiveThrow;
        List <HealthBehaviour> hitDamageables;

        if (CanDriftTo(intOrigin, intGoal) & !HittingSomething(intGoal, info.ThrownBy, out hitDamageables))
        {
            //if object is solid, check if player is nearby to make it stop
            return(registerTile.IsPassable() ? true : !IsPlayerNearby(serverState));
        }
        else
        {
            //Can't drift to goal for some reason:
            //Check Tile damage from throw
            var hit2D = Physics2D.RaycastAll(origin, info.Trajectory.normalized, 1.5f, tileDmgMask);

            for (int i = 0; i < hit2D.Length; i++)
            {
                //Debug.Log("THROW HIT: " + hit2D[i].collider.gameObject.name);

                //TilemapDamage automatically detects if a layer is below another damageable layer and won't affect it
                var tileDmg = hit2D[i].collider.gameObject.GetComponent <TilemapDamage>();
                if (tileDmg != null)
                {
                    var damage = ( int )(ItemAttributes.throwDamage * 2);
                    tileDmg.DoThrowDamage(intGoal, info, damage);
                }
            }
        }

        //Hurting what we can
        if (hitDamageables != null && hitDamageables.Count > 0 && !Equals(info, ThrowInfo.NoThrow))
        {
            for (var i = 0; i < hitDamageables.Count; i++)
            {
                //Remove cast to int when moving health values to float
                var damage = ( int )(ItemAttributes.throwDamage * 2);
                hitDamageables[i].ApplyDamage(info.ThrownBy, damage, DamageType.BRUTE, info.Aim);
                PostToChatMessage.SendThrowHitMessage(gameObject, hitDamageables[i].gameObject, damage, info.Aim);
            }
            //hit sound
            PlaySoundMessage.SendToAll("GenericHit", transform.position, 1f);
        }

        return(false);
    }
コード例 #11
0
    private void Update()
    {
        if (!isProcessingSpaceBody && PendingSpaceBodies.Count > 0)
        {
            isProcessingSpaceBody = true;
            StartCoroutine(ProcessSpaceBody(PendingSpaceBodies.Dequeue()));
        }

        if (waitForRestart)
        {
            restartTime -= Time.deltaTime;
            if (restartTime <= 0f)
            {
                waitForRestart = false;
                RestartRound();
            }
        }

        else if (counting)
        {
            GetRoundTime   -= Time.deltaTime;
            roundTimer.text = Mathf.Floor(GetRoundTime / 60).ToString("00") + ":" +
                              (GetRoundTime % 60).ToString("00");
            if (GetRoundTime <= 0f)
            {
                counting        = false;
                roundTimer.text = "GameOver";

                // Prevents annoying sound duplicate when testing
                if (SystemInfo.graphicsDeviceType != GraphicsDeviceType.Null && !GameData.Instance.testServer)
                {
                    SoundManager.Play("ApcDestroyed", 0.3f, 1f, 0f);
                }

                if (CustomNetworkManager.Instance._isServer)
                {
                    waitForRestart = true;
                    PlayerList.Instance.ReportScores();
                }
            }
            //Nuke ops shuttle arrival
            if (shuttleArrived == true && shuttleArrivalBroadcasted == false)
            {
                PostToChatMessage.Send("Escape shuttle has arrived! Crew has 1 minute to get on it.", ChatChannel.System);
                shuttleArrivalBroadcasted = true;
            }
        }
    }
コード例 #12
0
    public void ReportScores()
    {
        //TODO: Add server announcement messages

        /*
         * var scoreSort = playerScores.OrderByDescending(pair => pair.Value)
         *  .ToDictionary(pair => pair.Key, pair => pair.Value);
         *
         * foreach (KeyValuePair<string, int> ps in scoreSort)
         * {
         *  UIManager.Chat.ReportToChannel("<b>" + ps.Key + "</b>  total kills:  <b>" + ps.Value + "</b>");
         * }
         */

        PostToChatMessage.Send("Game Restarting in 10 seconds...", ChatChannel.System);
    }
コード例 #13
0
    public void ReportScores()
    {
        if (!reportDone)
        {
            //if (!nukeSetOff && syndicateKills == 0 && crewKills == 0)
            //{
            //	PostToChatMessage.Send("Nobody killed anybody. F*****g hippies.", ChatChannel.System);
            //}

            if (nukeSetOff)
            {
                PostToChatMessage.Send("Nuke has been detonated, <b>Syndicate wins.</b>", ChatChannel.System);
                ReportKills();
            }
            else
            {
                int alivePlayers     = GetAlivePlayers().Count;
                int crewCountOnboard = GetAliveShuttleCrew().Count;
                if (alivePlayers > 0 && crewCountOnboard == 0)
                {
                    PostToChatMessage.Send("Station crew failed to escape, <b>Syndicate wins.</b>", ChatChannel.System);
                    ReportKills();
                }
                else if (alivePlayers == 0)
                {
                    PostToChatMessage.Send("All crew members are dead, <b>Syndicate wins.</b>", ChatChannel.System);
                    ReportKills();
                }
                else if (alivePlayers > 0 && crewCountOnboard > 0)
                {
                    PostToChatMessage.Send(crewCountOnboard + " Crew member(s) have managed to escape the station. <b>Syndicate lost.</b>", ChatChannel.System);
                    ReportKills();
                }
            }

            PostToChatMessage.Send("Game Restarting in 30 seconds...", ChatChannel.System);
            reportDone = true;
        }

        List <ConnectedPlayer> GetAliveShuttleCrew()
        {
            var playersOnMatrix = GetPlayersOnMatrix(GameManager.Instance.PrimaryEscapeShuttle.MatrixInfo);

            return(GetAlivePlayers(playersOnMatrix).FindAll(p => p.Job != JobType.SYNDICATE));
        }
    }
コード例 #14
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}!"
            });
        }
    }
コード例 #15
0
    /// <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();
    }
コード例 #16
0
    protected override void OnDeathActions()
    {
        if (CustomNetworkManager.Instance._isServer)
        {
            PlayerNetworkActions pna = gameObject.GetComponent <PlayerNetworkActions>();
            PlayerMove           pm  = gameObject.GetComponent <PlayerMove>();

            ConnectedPlayer player = PlayerList.Instance.Get(gameObject);

            string killerName = "Stressful work";
            if (LastDamagedBy != null)
            {
                killerName = PlayerList.Instance.Get(LastDamagedBy).Name;
            }

            string playerName = player.Name ?? "dummy";
            if (killerName == playerName)
            {
                PostToChatMessage.Send(playerName + " commited suicide", ChatChannel.System);                 //Killfeed
            }
            else if (killerName.EndsWith(playerName))
            {
                // chain reactions
                PostToChatMessage.Send(
                    playerName + " screwed himself up with some help (" + killerName + ")",
                    ChatChannel.System);                     //Killfeed
            }
            else
            {
                PlayerList.Instance.UpdateKillScore(LastDamagedBy, gameObject);
            }
            pna.DropItem(EquipSlot.rightHand);
            pna.DropItem(EquipSlot.leftHand);

            if (isServer)
            {
                EffectsFactory.Instance.BloodSplat(transform.position, BloodSplatSize.large);
            }

            PlayerDeathMessage.Send(gameObject);
        }
    }
コード例 #17
0
        protected override void OnDeathActions()
        {
            if (CustomNetworkManager.Instance._isServer)
            {
                if (LastDamagedBy == gameObject.name)
                {
                    PostToChatMessage.Send(gameObject.name + " commited suicide", ChatChannel.System); //Killfeed
                }
                else if (LastDamagedBy.EndsWith(gameObject.name))
                {
                    // chain reactions
                    PostToChatMessage.Send(
                        gameObject.name + " screwed himself up with some help (" + LastDamagedBy + ")",
                        ChatChannel.System); //Killfeed
                }
                else
                {
                    PlayerList.Instance.UpdateKillScore(LastDamagedBy);
                    PostToChatMessage.Send(LastDamagedBy + " has killed " + gameObject.name,
                                           ChatChannel.System); //Killfeed
                }
                playerNetworkActions.ValidateDropItem("rightHand", true);
                playerNetworkActions.ValidateDropItem("leftHand", true);

                if (isServer)
                {
                    EffectsFactory.Instance.BloodSplat(transform.position, BloodSplatSize.large);
                }

                playerNetworkActions.RpcSpawnGhost();
                playerMove.isGhost    = true;
                playerMove.allowInput = true;

                //FIXME Remove for next demo
                playerNetworkActions.RespawnPlayer(10);
            }
        }
コード例 #18
0
 private void PlayerSendChat(string sendMessage)
 {
     // Selected channels already masks all unavailable channels in it's get method
     PostToChatMessage.Send(sendMessage, SelectedChannels);
     InputFieldChat.text = "";
 }
コード例 #19
0
        protected override void OnDeathActions()
        {
            if (CustomNetworkManager.Instance._isServer)
            {
                PlayerNetworkActions pna = gameObject.GetComponent <PlayerNetworkActions>();
                PlayerMove           pm  = gameObject.GetComponent <PlayerMove>();

                ConnectedPlayer player = PlayerList.Instance.Get(gameObject);

                string killerName = "stressfull work";
                if (LastDamagedBy != null)
                {
                    killerName = PlayerList.Instance.Get(LastDamagedBy).Name;
                }

                if (killerName == player.Name)
                {
                    PostToChatMessage.Send(player.Name + " commited suicide", ChatChannel.System);                     //Killfeed
                }
                else if (killerName.EndsWith(player.Name))
                {
                    // chain reactions
                    PostToChatMessage.Send(
                        player.Name + " screwed himself up with some help (" + killerName + ")",
                        ChatChannel.System);                         //Killfeed
                }
                else
                {
                    PlayerList.Instance.UpdateKillScore(LastDamagedBy, gameObject);

                    string departmentKillText = "";
                    if (LastDamagedBy != null)
                    {
                        JobDepartment killerDepartment =
                            SpawnPoint.GetJobDepartment(LastDamagedBy.GetComponent <PlayerScript>().JobType);
                        JobDepartment victimDepartment =
                            SpawnPoint.GetJobDepartment(gameObject.GetComponent <PlayerScript>().JobType);

                        if (killerDepartment == victimDepartment)
                        {
                            departmentKillText = ", losing " + killerDepartment.GetDescription() +
                                                 " 1 point for team killing!";
                        }
                        else
                        {
                            departmentKillText = ", 1 point to " + killerDepartment.GetDescription() + "!";
                        }
                    }

                    //TDM demo killfeed
                    PostToChatMessage.Send(killerName + " has killed " + player.Name + departmentKillText,
                                           ChatChannel.System);

                    //Combat demo killfeed
                    //PostToChatMessage.Send(killerName + " has killed " + gameObject.name, ChatChannel.System);
                }
                pna.ValidateDropItem("rightHand", true, transform.position);
                pna.ValidateDropItem("leftHand", true, transform.position);

                if (isServer)
                {
                    EffectsFactory.Instance.BloodSplat(transform.position, BloodSplatSize.large);
                }

                pna.RpcSpawnGhost();
                pm.isGhost    = true;
                pm.allowInput = true;
                RpcPassBullets(gameObject);
                PlayerDeathMessage.Send(gameObject);

                //FIXME Remove for next demo
                pna.RespawnPlayer(10);
            }
        }
コード例 #20
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);
            }
        }
    }
コード例 #21
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());
    }