Drain
namespace Griff.Modules.PhysicsGames;
public sealed class Drain : Component, IPlaytestReportThe drain at the bottom of a pinball table, with no code: a ball that falls into it is lost, and the next of its Balls is served onto the Plunger``ServeDelay seconds later, until there are none left and the game’s over. A ball lost within BallSave seconds of being shot is given back instead, and shot again by itself (once: shot again, it has no ball save of its own).
Put it on a trigger below the flippers. A ball is any body that falls into it (or one on its Layers); with other balls still on the table (multiball) a ball that drains just goes, and no ball is lost. Its Ball, Balls Left and Game Over outputs are for a Counter (“Ball {0}”) or a panel; its GameOverMessage opens a game-over panel. Its Extra Ball action adds a ball (a target or a Counter’s Reach can award one), and Save Ball starts a ball save. A Tilt covering it is put right as each ball drains.
This is a component: its saved properties are on its component page.
Properties
Section titled “Properties”public int Ball { get; set; }Which ball is being played: 1 for the first.
BallSave
Section titled “BallSave”public float BallSave { get; set; }Seconds after each ball is shot from the plunger that losing it gives it back (served and shot again by itself, with no save of its own this time): a ball save. 0 saves none.
public int Balls { get; set; }How many balls a game has.
BallsLeft
Section titled “BallsLeft”public int BallsLeft { get; }How many balls are left, the one being played too: 0 once the game’s over.
DrainMessage
Section titled “DrainMessage”public string? DrainMessage { get; set; }A message sent as a ball is lost, with the balls left as its data, e.g. “BallLost”.
GameOver
Section titled “GameOver”public bool GameOver { get; set; }True once the last ball has drained.
GameOverMessage
Section titled “GameOverMessage”public string? GameOverMessage { get; set; }A message sent as the last ball drains, e.g. “GameOver”: a panel that says so opens on it.
Layers
Section titled “Layers”public string? Layers { get; set; }The collision layers it drains, e.g. “Ball”. Empty drains any body that falls into it (but flippers).
Plunger
Section titled “Plunger”public string? Plunger { get; set; }The plunger each new ball is served onto, by name. Empty: the nearest plunger.
SaveLeft
Section titled “SaveLeft”public float SaveLeft { get; set; }Seconds the ball save still has; 0 when it’s off. Set by the game.
SaveMessage
Section titled “SaveMessage”public string? SaveMessage { get; set; }A message sent as a lost ball is given back by the ball save, e.g. “BallSaved”.
SaveReady
Section titled “SaveReady”public bool SaveReady { get; set; }True from a ball being served until it’s shot, which starts its ball save (not for a saved ball). Set by the game.
SaveSound
Section titled “SaveSound”public string? SaveSound { get; set; }A sound played as a lost ball is saved.
public bool Saved { get; set; }True if the ball being served was saved, so it’s shot again by itself. Set by the game.
Saving
Section titled “Saving”public bool Saving { get; }True while losing the ball would give it back.
ServeDelay
Section titled “ServeDelay”public float ServeDelay { get; set; }Seconds after a ball drains before the next is served onto the plunger.
ServeIn
Section titled “ServeIn”public float ServeIn { get; set; }Seconds until it’s served. Set by the game.
Serving
Section titled “Serving”public string? Serving { get; set; }The ball waiting to be served, by its entity’s id. Set by the game.
public string? Sound { get; set; }A sound played as a ball drains, e.g. “Sounds/drain.wav”.
Within
Section titled “Within”public string? Within { get; set; }The table it counts balls on, by an entity’s name: the balls inside it or standing in its area. Empty counts every ball in the scene.
Methods
Section titled “Methods”ExtraBall
Section titled “ExtraBall”public void ExtraBall()Adds a ball to the game.
SaveBall
Section titled “SaveBall”public void SaveBall()Starts a ball save of its Ball Save’s seconds (5 if that’s 0): losing the ball soon gives it back.
public override bool Uses(string property)Events
Section titled “Events”Drained
Section titled “Drained”public event Action<Drain, Entity, bool>? DrainedRaised as a ball drains, with the ball and whether it was saved.