private async void KillHandler(object?sender, Ps2EventArgs <KillEvent> args) { if (_State != MatchState.RUNNING) { return; } KillEvent ev = args.Payload; string sourceFactionID = Loadout.GetFaction(ev.LoadoutID); string targetFactionID = Loadout.GetFaction(ev.TargetLoadoutID); foreach (KeyValuePair <int, TrackedPlayer> entry in _Players) { int index = entry.Key; TrackedPlayer player = entry.Value; bool emit = false; foreach (Character c in player.Characters) { if (ev.SourceID == c.ID && ev.TargetID == c.ID) { _Logger.LogInformation($"Player {index} committed suicide"); _MatchMessages.Log($"Team {index}:{player.RunnerName} @{c.Name} SUICIDE"); if (player.Streak > 1) { player.Streaks.Add(player.Streak); player.Streak = 0; } player.Deaths.Add(ev); emit = true; } else if (c.ID == ev.SourceID) { if (sourceFactionID == targetFactionID) { _Logger.LogInformation($"Player {index}:{player.RunnerName} on {c.Name} TK"); _MatchMessages.Log($"Team {index}:{player.RunnerName} @{c.Name} got a TK"); } else { //_Logger.LogInformation($"Player {index}:{player.RunnerName} kill"); player.Kills.Add(ev); PsItem?weapon = await _ItemCollection.GetByID(ev.WeaponID); if (weapon != null) { if (ItemCategory.IsValidSpeedrunnerWeapon(weapon) == true) { player.Streak += 1; player.ValidKills.Add(ev); int score = 1; List <IndexedChallenge> runningChallenges = _Challenges.GetRunning(); foreach (IndexedChallenge challenge in runningChallenges) { bool met = await challenge.Challenge.WasMet(ev, weapon); if (_Challenges.GetMode() == ChallengeMode.MEAN) { if (met == false) { _Logger.LogTrace($"Team {index}:{player.RunnerName} @{c.Name} failed challenge {challenge.Challenge.ID}/{challenge.Challenge.Name}"); score = 0; } else { challenge.KillCount += 1; _ChallengeEvents.EmitChallengeUpdate(challenge); } } else if (_Challenges.GetMode() == ChallengeMode.NICE) { if (met == true) { challenge.KillCount += 1; _ChallengeEvents.EmitChallengeUpdate(challenge); _Logger.LogTrace($"Team {index}:{player.RunnerName} @{c.Name} met challenge {challenge.Challenge.ID}/{challenge.Challenge.Name}, score mult {challenge.Challenge.Multiplier}"); score *= challenge.Challenge.Multiplier; } } else { _Logger.LogError($"Unknown challenge mode {_Challenges.GetMode()}"); } if (challenge.Challenge.DurationType == Code.Challenge.ChallengeDurationType.KILLS && challenge.KillCount >= challenge.Challenge.Duration) { _Logger.LogDebug($"Team {index}:{player.RunnerName} @{c.Name} finished challenge {challenge.Challenge.ID}/{challenge.Challenge.Name}"); _Challenges.End(challenge.Index); } } if (score != 0) { player.Scores.Add(new ScoreEvent() { Timestamp = ev.Timestamp, ScoreChange = score, TotalScore = player.Score + score }); } player.Score += score; _Logger.LogInformation($"Player {index}:{player.RunnerName} on {c.Name} valid weapon {score} points, {weapon.Name}/{weapon.CategoryID}"); _MatchMessages.Log($"Team {index}:{player.RunnerName} @{c.Name} VALID kill {score} points, {weapon.Name}/{weapon.CategoryID}, faction {targetFactionID}"); if (player.Score >= _Settings.KillGoal) { _Logger.LogInformation($"Player {index}:{player.RunnerName} reached goal {_Settings.KillGoal}, ending match"); _MatchMessages.Log($"Team {index}:{player.RunnerName} reached goal {_Settings.KillGoal}, ending match"); StopRound(player.Index); } } else { _Logger.LogInformation($"Player {index}:{player.RunnerName} on {c.Name} invalid weapon, {weapon.Name}/{weapon.CategoryID}"); _MatchMessages.Log($"Team {index}:{player.RunnerName} @{c.Name} INVALID kill, {weapon.Name}/{weapon.CategoryID}, faction {targetFactionID}"); } } else { _MatchMessages.Log($"Team {index}:{player.RunnerName} @{c.Name} UNKNOWN WEAPON {ev.WeaponID}, faction {targetFactionID}"); _Logger.LogInformation($"Null weapon {ev.WeaponID}"); } emit = true; } } else if (c.ID == ev.TargetID) { if (player.Streak > 1) { player.Streaks.Add(player.Streak); } player.Streak = 0; player.Deaths.Add(ev); _Logger.LogInformation($"Player {index}:{player.RunnerName} on {c.Name} death"); _MatchMessages.Log($"Team {index}:{player.RunnerName} @{c.Name} DEATH, faction {sourceFactionID}"); emit = true; } else { //_Logger.LogInformation($"Kill source:{ev.SourceID}, target:{ev.TargetID} was not {player.ID}"); } } if (emit == true) { _MatchEvents.EmitPlayerUpdateEvent(index, player); } } }