Damage and breakdown intercepts
An intercept lets your mod look at damage before the player takes it, and change it or cancel it. A breakdown is the game’s mental-health breakdown, where the player may harm themselves, drink or take mushrooms. These calls are on Survival, and they are described here because they work on the player.
Survival damage intercepts and the breakdown event
Use InterceptDamage to change or cancel damage before the player takes it, and subscribe to Breakdown to change or cancel a breakdown action the game is about to try.
public static partial class Survival
{
public static bool InterceptDamage(string modId, Action<DamageArgs> handler);
public static bool RemoveDamage(string modId, Action<DamageArgs> handler);
public static event Action<BreakdownArgs> Breakdown;
}
| Method | Returns | What it does |
|---|---|---|
InterceptDamage(modId, handler) | bool | Adds your handler. Returns false when IsAvailable is false. |
RemoveDamage(modId, handler) | bool | Removes your handler. Returns true when it was removed. |
| Event | Gives you | When it fires |
|---|---|---|
Breakdown | BreakdownArgs | The game is about to try a breakdown action. |
DamageArgs the damage the player is about to take
InterceptDamage handlers get one of these. Set Amount to change the damage, or Cancel to apply none.
public sealed class DamageArgs
{
public DamageTypeNames Reason { get; }
public bool Silent { get; }
public float Original { get; }
public float Amount { get; set; }
public bool Cancel { get; set; }
}
| Property | Type | What it means |
|---|---|---|
Reason | DamageTypeNames | Why the damage happens, for example DamageTypeNames.Fall. |
Silent | bool | true when the game asked for no sound, shake or message. |
Original | float | The damage the game passed in. |
Amount | float | The damage that will be applied. It starts as Original. |
Cancel | bool | Set to true to apply no damage. |
BreakdownArgs a breakdown action the game is about to try
Survival.Breakdown hands you one of these for each action the game tries. Kind says which action is starting, and setting Cancel stops that action.
public sealed class BreakdownArgs
{
public BreakdownKind Kind { get; }
public bool Cancel { get; set; }
}
| Property | Type | What it means |
|---|---|---|
Kind | BreakdownKind | The breakdown step that is starting. |
Cancel | bool | Set to true to stop this action. |
BreakdownKind the breakdown actions
These are the values of BreakdownArgs.Kind. The game’s roll decides which of them it tries and in what order, as the Breakdowns notes below say.
public enum BreakdownKind
{
Suicide,
SelfHarm,
Mushrooms,
Alcohol
}
| Value | Meaning |
|---|---|
Suicide | The player takes their own life. |
SelfHarm | The player hurts themselves. |
Mushrooms | The player eats mushrooms. |
Alcohol | The player drinks. |
Things to know
Damage intercepts
InterceptDamageruns your handler before the player takes the damage. (It runs before the game’sPlayerStatsHealth.Damageapplies the amount.)- Handlers run in the order they were added and share one
DamageArgs, so a later handler sees theAmountthat the earlier ones set. - A handler that throws an error is logged to its mod’s log, and the other handlers still run.
RemoveDamage(modId, handler)removes one handler of that mod, andRemoveAll(modId)removes all of them. Wrong arguments throw errors, the same as for the otherSurvivalcalls.- Adding the same handler again for the same mod does nothing and returns
true. The handler keeps its first place and still runs once. - Handlers match by the delegate itself, so a new lambda that captures variables counts as a new handler. Keep the delegate in a field, so you can add it once and remove it later.
Survival.OnCrossed(same mod, stat, threshold and callback;RemoveCrossed(modId, callback)removes it) andSurvival.Consumables.Intercept(Consumables.Remove(modId, handler)removes it) follow the same rules.- With several mods, handlers run in the order they were added, across mods. Any
Cancelwins: once a handler sets it, the later handlers still run and seeCancelastrue, and setting it back tofalsehas no effect.Amountis the value the last handler wrote, and it is ignored when the damage is cancelled.Consumables.Intercepthandlers run the same way. Cancelmeans the player takes no damage. There is then no sound, shake, death orDamagedevent. AnAmountthat is not a real number, is infinite or is below 0 is treated as 0. (The game returns at once for zero damage.)- Only damage above 0 is intercepted. Damage of 0 or less passes through untouched. Handlers do not run while a save is loading or being written. A
PlayerState.Damagecall that you make from inside a handler is not intercepted again. Survival.Damagedreports the loss after your change. A damage amount you made smaller or larger is reported at that new size.- The game’s mushroom and gas protection runs after your change. So a mushroom or gas amount you scaled still meets that protection.
Breakdowns
Breakdownfires each time the game tries a breakdown action, not once per breakdown. The game rolls a number, and the roll decides what it tries and in which order.- If the roll is above 99, it tries Suicide, then Alcohol, then SelfHarm. Above 60 and up to 99 it raises SelfHarm once, and cancelling it does nothing. Above 30 and up to 60 it tries Mushrooms, then Alcohol, then SelfHarm. At 30 or less it tries Alcohol, then SelfHarm. (It is raised from
PlayerStatsMentalHealth.UpdateStats.) - Each cancel moves the game on to its next option, and the mood drop after the breakdown still applies.
- A cancelled
Suicidemeans noSurvival.PlayerDied, because the death is skipped. Consumables.Consumedstill fires for mushroom and alcohol uses that are not cancelled.- With several
Breakdownhandlers, anyCancelwins, the same as for damage.Breakdownhas nomodId, so you remove your handler with-=. - The survival changes are split into six feature groups. Their names are
obenseuer.moddingframework.survival.consumables,.needs,.death,.damage,.breakdownand.depression. A missing change turns off only its group.Survival.IsAvailableisfalsewhile any group is missing, but each member and event needs only the groups it uses, andGetandSetneed none.
Limits
- Some damage can’t be intercepted, because the game does not use its normal damage call for it. These are the bleed tick and the negative regeneration branch, the direct death calls in the health code, the suicide from depression, the SMV death in the mushroom code, and the direct write in the mushroom code. (The game does not call
PlayerStatsHealth.Damagefor them. They are inPlayerStatsHealth,Depression.SuicideandPlayerStatsMushrooms.) MushroomsandAlcoholfire even when the player has none. The game makes this check before it looks in the inventory, so your handler can’t tell an attempt from a real use. Cancelling returnsfalse, the same as an empty inventory.Breakdowndoes not fire while a save is loading or being written, or when the game’s breakdown or depression part is missing.