Esempio n. 1
0
 private ClientMemory GetClientMemory(Client client)
 {
     if (!clientMemories.ContainsKey(client))
     {
         clientMemories[client] = new ClientMemory()
         {
             PreviousNotifiedKarma = client.Karma
         };
     }
     return(clientMemories[client]);
 }
Esempio n. 2
0
        public void OnWireDisconnected(Character character, Wire wire)
        {
            if (character == null || wire == null)
            {
                return;
            }
            Client client = GameMain.Server.ConnectedClients.Find(c => c.Character == character);

            if (client == null)
            {
                return;
            }

            if (!clientMemories.ContainsKey(client))
            {
                clientMemories[client] = new ClientMemory();
            }

            clientMemories[client].WireDisconnectTime.RemoveAll(w => w.First == wire);
            clientMemories[client].WireDisconnectTime.Add(new Pair <Wire, float>(wire, (float)Timing.TotalTime));
        }
Esempio n. 3
0
        public void OnCharacterHealthChanged(Character target, Character attacker, float damage, float stun, IEnumerable <Affliction> appliedAfflictions = null)
        {
            if (target == null || attacker == null)
            {
                return;
            }
            if (target == attacker)
            {
                return;
            }

            //damaging dead characters doesn't affect karma
            if (target.IsDead || target.Removed)
            {
                return;
            }

            bool isEnemy = target.AIController is EnemyAIController || target.TeamID != attacker.TeamID;

            if (GameMain.Server.TraitorManager?.Traitors != null)
            {
                if (GameMain.Server.TraitorManager.Traitors.Any(t => t.Character == target))
                {
                    //traitors always count as enemies
                    isEnemy = true;
                }
                if (GameMain.Server.TraitorManager.Traitors.Any(t =>
                                                                t.Character == attacker &&
                                                                t.CurrentObjective != null &&
                                                                t.CurrentObjective.IsEnemy(target)))
                {
                    //target counts as an enemy to the traitor
                    isEnemy = true;
                }
            }

            bool targetIsHusk   = target.CharacterHealth?.GetAffliction <AfflictionHusk>("huskinfection")?.State == AfflictionHusk.InfectionState.Active;
            bool attackerIsHusk = attacker.CharacterHealth?.GetAffliction <AfflictionHusk>("huskinfection")?.State == AfflictionHusk.InfectionState.Active;

            //huskified characters count as enemies to healthy characters and vice versa
            if (targetIsHusk != attackerIsHusk)
            {
                isEnemy = true;
            }

            if (appliedAfflictions != null)
            {
                foreach (Affliction affliction in appliedAfflictions)
                {
                    if (MathUtils.NearlyEqual(affliction.Prefab.KarmaChangeOnApplied, 0.0f))
                    {
                        continue;
                    }
                    damage -= affliction.Prefab.KarmaChangeOnApplied * affliction.Strength;
                }
            }

            Client targetClient = GameMain.Server.ConnectedClients.Find(c => c.Character == target);

            if (damage > 0 && targetClient != null)
            {
                var targetMemory = GetClientMemory(targetClient);
                targetMemory.LastAttackTime[attacker] = Timing.TotalTime;
            }

            Client       attackerClient = GameMain.Server.ConnectedClients.Find(c => c.Character == attacker);
            ClientMemory attackerMemory = GetClientMemory(attackerClient);

            if (attackerMemory != null)
            {
                //if the attacker has been attacked by the target within the last x seconds, ignore the damage
                //(= no karma penalty from retaliating against someone who attacked you)
                if (attackerMemory.LastAttackTime.ContainsKey(target) &&
                    attackerMemory.LastAttackTime[target] > Timing.TotalTime - AllowedRetaliationTime)
                {
                    damage = Math.Min(damage, 0);
                    stun   = 0.0f;
                }
            }

            //attacking/healing clowns has a smaller effect on karma
            if (target.HasEquippedItem("clownmask") &&
                target.HasEquippedItem("clowncostume"))
            {
                damage *= 0.5f;
                stun   *= 0.5f;
            }

            //smaller karma penalty for attacking someone who's aiming with a weapon
            if (damage > 0.0f &&
                target.IsKeyDown(InputType.Aim) &&
                target.SelectedItems.Any(it => it != null && (it.GetComponent <MeleeWeapon>() != null || it.GetComponent <RangedWeapon>() != null)))
            {
                damage *= 0.5f;
                stun   *= 0.5f;
            }

            //damage scales according to the karma of the target
            //(= smaller karma penalty from attacking someone who has a low karma)
            if (damage > 0 && targetClient != null)
            {
                damage *= MathUtils.InverseLerp(0.0f, 50.0f, targetClient.Karma);
            }

            if (isEnemy)
            {
                if (damage > 0)
                {
                    float karmaIncrease = damage * DamageEnemyKarmaIncrease;
                    if (attacker?.Info?.Job.Prefab.Identifier == "securityofficer")
                    {
                        karmaIncrease *= 2.0f;
                    }
                    AdjustKarma(attacker, karmaIncrease, "Damaged enemy");
                }
            }
            else
            {
                if (stun > 0 && attackerMemory != null)
                {
                    //GameServer.Log(GameServer.CharacterLogName(attacker) + " stunned " + GameServer.CharacterLogName(target) + $" ({stun})", ServerLog.MessageType.Karma);
                    attackerMemory.StunsInPastMinute.Add(new ClientMemory.TimeAmount()
                    {
                        Time = Timing.TotalTime, Amount = stun
                    });

                    if (attackerMemory.StunsInPastMinute.Count > 1)
                    {
                        float avgStunsInflicted = attackerMemory.StunsInPastMinute[0].Amount / (float)(attackerMemory.StunsInPastMinute[1].Time - attackerMemory.StunsInPastMinute[0].Time);
                        for (int i = 1; i < attackerMemory.StunsInPastMinute.Count; i++)
                        {
                            avgStunsInflicted += attackerMemory.StunsInPastMinute[i].Amount / (float)(attackerMemory.StunsInPastMinute[i].Time - attackerMemory.StunsInPastMinute[i - 1].Time);
                        }

                        //GameServer.Log(avgStunsInflicted.ToString(), ServerLog.MessageType.Karma);

                        if (avgStunsInflicted > StunFriendlyKarmaDecreaseThreshold ||
                            attackerMemory.StunKarmaDecreaseMultiplier > 1.0f)
                        {
                            AdjustKarma(attacker, -StunFriendlyKarmaDecrease * attackerMemory.StunKarmaDecreaseMultiplier, "Stunned friendly");
                            attackerMemory.StunKarmaDecreaseMultiplier *= 2.0f;
                        }
                    }
                }

                if (damage > 0)
                {
                    AdjustKarma(attacker, -damage * DamageFriendlyKarmaDecrease, "Damaged friendly");
                }
                else
                {
                    float karmaIncrease = -damage * HealFriendlyKarmaIncrease;
                    if (attacker?.Info?.Job.Prefab.Identifier == "medicaldoctor")
                    {
                        karmaIncrease *= 2.0f;
                    }
                    AdjustKarma(attacker, karmaIncrease, "Healed friendly");
                }
            }
        }