Skip to content

Commit

Permalink
Version 1.1.0 with fixes and LC_API broadcast
Browse files Browse the repository at this point in the history
  • Loading branch information
EliteMasterEric committed Dec 2, 2023
1 parent 532e759 commit b3493a9
Show file tree
Hide file tree
Showing 10 changed files with 387 additions and 122 deletions.
7 changes: 5 additions & 2 deletions Art/manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
{
"name": "Coroner",
"version_number": "1.0.0",
"version_number": "1.1.0",
"website_url": "https://github.com/EliteMasterEric/Coroner",
"description": "Rework the Performance Report with new info, including cause of death.",
"dependencies": []
"dependencies": [
"BepInEx-BepInExPack-5.4.2100",
"2018-LC_API-2.1.1"
]
}
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Changelog

## 1.1.0
## Additions
- Added a custom cause of death for the dropship.
- Added an optional dependency on LC_API and used it to improve accuracy of cause of death reports over multiplayer.
## Bug Fixes
- Fixed a softlock/crash related to checking if the player has a Jetpack.
- Fixed the cause of death not being evaluated properly when being crushed by a ladder.
- Fixed the cause of death not being evaluated properly when drowning in Quicksand.
- Fixed a bug where notes would not start with "Notes:".
- Fixed an issue where BepInEx was not listed as a mandatory dependency.
- Fixed an issue with enemy-related custom deaths not working

## 1.0.0
Initial release.
- Added cause of death to the results screen.
Expand Down
91 changes: 61 additions & 30 deletions Coroner/AdvancedCauseOfDeath.cs
Original file line number Diff line number Diff line change
@@ -1,30 +1,32 @@
using System;
using System.Collections.Generic;
using GameNetcodeStuff;
using Steamworks;

namespace Coroner {
class AdvancedDeathTracker {
public const int PLAYER_CAUSE_OF_DEATH_DROPSHIP = 300;

private static readonly Dictionary<int, AdvancedCauseOfDeath> PlayerCauseOfDeath = new Dictionary<int, AdvancedCauseOfDeath>();

public static void ClearDeathTracker() {
PlayerCauseOfDeath.Clear();
}

public static void SetCauseOfDeath(int playerIndex, AdvancedCauseOfDeath causeOfDeath) {
public static void SetCauseOfDeath(int playerIndex, AdvancedCauseOfDeath causeOfDeath, bool broadcast = true) {
PlayerCauseOfDeath[playerIndex] = causeOfDeath;
if (broadcast) DeathBroadcaster.BroadcastCauseOfDeath(playerIndex, causeOfDeath);
}

public static void SetCauseOfDeath(int playerIndex, CauseOfDeath causeOfDeath) {
SetCauseOfDeath(playerIndex, ConvertCauseOfDeath(causeOfDeath));
public static void SetCauseOfDeath(int playerIndex, CauseOfDeath causeOfDeath, bool broadcast = true) {
SetCauseOfDeath(playerIndex, ConvertCauseOfDeath(causeOfDeath), broadcast);
}

public static void SetCauseOfDeath(PlayerControllerB playerController, CauseOfDeath causeOfDeath) {
SetCauseOfDeath((int) playerController.playerClientId, ConvertCauseOfDeath(causeOfDeath));
public static void SetCauseOfDeath(PlayerControllerB playerController, CauseOfDeath causeOfDeath, bool broadcast = true) {
SetCauseOfDeath((int) playerController.playerClientId, ConvertCauseOfDeath(causeOfDeath), broadcast);
}

public static void SetCauseOfDeath(PlayerControllerB playerController, AdvancedCauseOfDeath causeOfDeath) {
SetCauseOfDeath((int) playerController.playerClientId, causeOfDeath);
public static void SetCauseOfDeath(PlayerControllerB playerController, AdvancedCauseOfDeath causeOfDeath, bool broadcast = true) {
SetCauseOfDeath((int) playerController.playerClientId, causeOfDeath, broadcast);
}

public static AdvancedCauseOfDeath GetCauseOfDeath(int playerIndex) {
Expand All @@ -35,16 +37,17 @@ public static AdvancedCauseOfDeath GetCauseOfDeath(int playerIndex) {

public static AdvancedCauseOfDeath GetCauseOfDeath(PlayerControllerB playerController) {
if (!PlayerCauseOfDeath.ContainsKey((int) playerController.playerClientId)) {
Plugin.Instance.PluginLogger.LogInfo($"Player {playerController.playerClientId} has no custom cause of death stored! Using fallback...");
return GuessCauseOfDeath(playerController);
} else {
Plugin.Instance.PluginLogger.LogInfo($"Player {playerController.playerClientId} has custom cause of death stored! {PlayerCauseOfDeath[(int) playerController.playerClientId]}");
return PlayerCauseOfDeath[(int) playerController.playerClientId];
}
return PlayerCauseOfDeath[(int) playerController.playerClientId];
}

public static AdvancedCauseOfDeath GuessCauseOfDeath(PlayerControllerB playerController) {
if (playerController.isPlayerDead) {
if (playerController.causeOfDeath == CauseOfDeath.Suffocation && playerController.isSinking) {
return AdvancedCauseOfDeath.Quicksand;
} else if (IsHoldingJetpack(playerController)) {
if (IsHoldingJetpack(playerController)) {
if (playerController.causeOfDeath == CauseOfDeath.Gravity) {
return AdvancedCauseOfDeath.Jetpack_Gravity;
} else if (playerController.causeOfDeath == CauseOfDeath.Blast) {
Expand All @@ -59,10 +62,13 @@ public static AdvancedCauseOfDeath GuessCauseOfDeath(PlayerControllerB playerCon
}

public static bool IsHoldingJetpack(PlayerControllerB playerController) {
var heldObject = playerController.currentlyHeldObjectServer.gameObject.GetComponent<GrabbableObject>();
if (heldObject == null) {
return false;
}
var heldObjectServer = playerController.currentlyHeldObjectServer;
if (heldObjectServer == null) return false;
var heldObjectGameObject = heldObjectServer.gameObject;
if (heldObjectGameObject == null) return false;
var heldObject = heldObjectGameObject.GetComponent<GrabbableObject>();
if (heldObject == null) return false;

if (heldObject is JetpackItem) {
return true;
} else {
Expand Down Expand Up @@ -112,7 +118,7 @@ public static string StringifyCauseOfDeath(AdvancedCauseOfDeath causeOfDeath) {
case AdvancedCauseOfDeath.Gravity:
return "Fell to their death.";
case AdvancedCauseOfDeath.Blast:
return "Exploded.";
return "Went out with a bang.";
case AdvancedCauseOfDeath.Strangulation:
return "Strangled to death.";
case AdvancedCauseOfDeath.Suffocation:
Expand All @@ -130,8 +136,6 @@ public static string StringifyCauseOfDeath(AdvancedCauseOfDeath causeOfDeath) {
case AdvancedCauseOfDeath.Electrocution:
return "Electrocuted to death.";

case AdvancedCauseOfDeath.Enemy_DepositItemsDesk:
return "Received a demotion.";
case AdvancedCauseOfDeath.Enemy_Bracken:
return "Had their neck snapped by a Bracken.";
case AdvancedCauseOfDeath.Enemy_EyelessDog:
Expand All @@ -148,18 +152,36 @@ public static string StringifyCauseOfDeath(AdvancedCauseOfDeath causeOfDeath) {
return "Was eaten by a Baboon Hawk.";
case AdvancedCauseOfDeath.Enemy_Jester:
return "Was the butt of a joke.";
case AdvancedCauseOfDeath.Enemy_SnareFlea:
return "Was suffocated a Snare Flea.";
case AdvancedCauseOfDeath.Enemy_Hygrodere:
return "Was absorbed by a Hygrodere.";
case AdvancedCauseOfDeath.Enemy_HoarderBug:
return "Was hoarded by a Hoarder Bug.";
case AdvancedCauseOfDeath.Enemy_SporeLizard:
return "Was puffed by a Spore Lizard.";
case AdvancedCauseOfDeath.Enemy_SandSpider:
return "Ensnared in the Sand Spider's web.";

case AdvancedCauseOfDeath.Quicksand:
return "Got stuck in quicksand.";
case AdvancedCauseOfDeath.Jetpack_Gravity:
return "Flew too close to the sun.";
case AdvancedCauseOfDeath.Jetpack_Blast:
return "Went up in a fiery blaze.";
return "Turned into a firework.";
case AdvancedCauseOfDeath.Player_Murder:
return "Was the victim of a murder.";
case AdvancedCauseOfDeath.Player_Quicksand:
return "Got stuck in quicksand.";
case AdvancedCauseOfDeath.Player_DepositItemsDesk:
return "Received a demotion.";
case AdvancedCauseOfDeath.Player_Dropship:
return "Couldn't wait for their items.";
case AdvancedCauseOfDeath.Player_StunGrenade:
return "Was the victim of a murder.";

case AdvancedCauseOfDeath.Unknown:
return "Died somehow.";
return "Most sincerely dead.";
default:
return "Died somehow.";
return "Most sincerely dead.";
}
}

Expand All @@ -185,19 +207,28 @@ enum AdvancedCauseOfDeath {
Electrocution,

// Custom causes (enemies)
Enemy_DepositItemsDesk,
Enemy_BaboonHawk, // Also known as BaboonBird
Enemy_Bracken, // Also known as Flowerman
Enemy_CircuitBees, // Also known as RedLocustBees
Enemy_EarthLeviathan, // Also known as SandWorm
Enemy_EyelessDog, // Also known as MouthDog
Enemy_ForestGiant,
Enemy_CircuitBees, // Also known as RedLocustBees
Enemy_GhostGirl, // Also known as DressGirl
Enemy_EarthLeviathan, // Also known as SandWorm
Enemy_BaboonHawk, // Also known as BaboonBird
Enemy_Jester,
Enemy_SnareFlea, // Also known as Centipede
Enemy_SporeLizard, // Also known as Puffer TODO: Implement this.
Enemy_Hygrodere, // Also known as Blob TODO: Implement this.
Enemy_SandSpider, // TODO: Implement this.
Enemy_Thumper, // Also known as Crawler TODO: Implement this.
Enemy_HoarderBug, // TODO: Implement this.

// Custom causes (other)
Quicksand,
Enemy_Jester,
Jetpack_Gravity,
Jetpack_Blast,
Player_Quicksand,
Player_Murder,
Player_DepositItemsDesk,
Player_Dropship,
Player_StunGrenade, // TODO: Implement this.
}
}
11 changes: 11 additions & 0 deletions Coroner/Coroner.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@
<Private>false</Private>
<HintPath>..\include\UnityEngine.UI.dll</HintPath>
</Reference>

<Reference Include="LC_API">
<Private>false</Private>
<HintPath>..\include\LC_API.dll</HintPath>
</Reference>
</ItemGroup>

<ItemGroup>
Expand All @@ -87,6 +92,12 @@
</ItemGroup>

<!-- Fuck you. -->
<ItemGroup>
<Compile Remove="build\obj\**" />
<Content Remove="build\obj\**" />
<EmbeddedResource Remove="build\obj\**" />
<None Remove="build\obj\**" />
</ItemGroup>
<Target Name="PostBuild" BeforeTargets="PostBuildEvent">
<Exec Command="del %22$(TargetDir)$(TargetName).deps.json%22" />
<Exec Command="del %22$(TargetDir)$(TargetName).pdb%22" />
Expand Down
44 changes: 44 additions & 0 deletions Coroner/DeathBroadcaster.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
namespace Coroner {
class DeathBroadcaster {
const string SIGNATURE_DEATH = PluginInfo.PLUGIN_GUID + ".death";

public static void Initialize() {
Plugin.Instance.PluginLogger.LogInfo("Initializing DeathBroadcaster...");
if (Plugin.Instance.IsLC_APIPresent) {
Plugin.Instance.PluginLogger.LogInfo("LC_API is present! Registering signature...");
LC_API.ServerAPI.Networking.GetString += OnBroadcastString;
} else {
Plugin.Instance.PluginLogger.LogInfo("LC_API is not present! Skipping registration...");
}
}

static void OnBroadcastString(string data, string signature) {
if (signature == SIGNATURE_DEATH) {
Plugin.Instance.PluginLogger.LogInfo("Broadcast has been received from LC_API!");
string[] split = data.Split('|');
int playerId = int.Parse(split[0]);
int causeOfDeathInt = int.Parse(split[1]);
AdvancedCauseOfDeath causeOfDeath = (AdvancedCauseOfDeath) causeOfDeathInt;
Plugin.Instance.PluginLogger.LogInfo("Player " + playerId + " died of " + AdvancedDeathTracker.StringifyCauseOfDeath(causeOfDeath));
AdvancedDeathTracker.SetCauseOfDeath(playerId, causeOfDeath, false);
}
}

public static void BroadcastCauseOfDeath(int playerId, AdvancedCauseOfDeath causeOfDeath) {
AttemptBroadcast(BuildData(playerId, causeOfDeath), SIGNATURE_DEATH);
}

static string BuildData(int playerId, AdvancedCauseOfDeath causeOfDeath) {
return playerId + "|" + ((int) causeOfDeath);
}

static void AttemptBroadcast(string data, string signature) {
if (Plugin.Instance.IsLC_APIPresent) {
Plugin.Instance.PluginLogger.LogInfo("LC_API is present! Broadcasting...");
LC_API.ServerAPI.Networking.Broadcast(data, signature);
} else {
Plugin.Instance.PluginLogger.LogInfo("LC_API is not present! Skipping broadcast...");
}
}
}
}
Loading

0 comments on commit b3493a9

Please sign in to comment.