Jump to content

User:MIDIMan/Ringslinger Revolution/PSprites

From SRB2 Wiki

Player Sprites, or PSprites for short, is a system that allows weapon sprites to be drawn to the HUD. It is directly inspired by Doom’s similarly-named system, and has features borrowed from GZDoom’s iteration of the system.

Variables

PSprites contain the following variables:

Name Type Description/Notes
state pspritestate_t The current “state” of the PSprite, defined in PSprites.STATES.
sprite string Determines the sprite prefix to be displayed by the PSprite.
frame string Determines the frame “number” to be displayed by the PSprite; also contains full brightness information.
frameargs boolean Arguments for the current frame (currently only handles fullbright sprites).
animframe integer Current frame index. Used if the frame’s string is longer than one character.
x integer X-coordinate of the PSprite.
y integer Y-coordinate of the PSprite.
tics integer Current value of the PSprite’s state timer, which decreases by 1 until it reaches 0. It will then force the PSprite to go to the next state defined by its current “state” and reset the value to the tics values defined by the next state. If this is set to -1, the state’s duration will be infinite.
processPending boolean If set to false, this PSprite will not decrease its tics timer until all other PSprites have also done the same. This is automatically set to true for all PSprites on the next game tic.

States

All PSprite states are stored in the table PSprites.STATES. To define a new one, simply make a new entry for the table with a string index, using the name you wish to give the state. The state definition can be formatted in one of two ways:

PSprites.STATES["S_YOURSTATENAME"] = {
    sprite = "PSPRNAME",
    frame = "A",
    tics = 12,
    action = "A_StartSound",
    args = {sfx_thok},
    nextstate = "S_YOURSTATENAME"
}

or

PSprites.STATES["S_YOURSTATENAME"] = {"PSPRNAME", "A", 12, "A_StartSound", {sfx_thok}, "S_YOURSTATENAME"}

Ringslinger Revolution provides a couple base states for modders:

Name Description
"S_NONE" This is the default state that the player is set to use when making a new PSprite. It has no sprite, no action, and it lasts forever (unless the PSprite is set to a new state).
"S_NONE_READY" This state uses the action A_RSRWeaponReady constantly to check if the player’s pendingWeapon. If it is not 0, then the player draws the weapon based on the ID given by pendingWeapon.

Actions

Each state in a PSprite can call an action for the player. This can be anything from moving the PSprite’s coordinates to giving the player a shield. Each action has two variables: One for the player (player_t player), and one for the arguments to pass into the action (table args). These are basically the same idea as actions for Object states.

Actions must always be defined in the PSprites.ACTIONS table. To create your own action, just use the following template:

PSprites.ACTIONS.A_ActionNameHere = function(player, args)
    -- Action code goes here.
    -- Arguments should be used as such:
    -- args[1] is the first argument, args[2] is the second argument, etc.
end

Ringslinger Revolution provides a few base actions for modders:

Action Return value(s) Description
A_StartSound() nil Plays a sound from the player. Argument 1 is the sound to play (sfx_* constant).
A_LayerOffset() nil Moves a PSprite layer to the coordinates given. Argument 1 is the ID of the PSprite to move (PSprites.PSPR_* constant), Arguments 2 and 3 are the x and y coordinates, respectively, and Argument 4 makes the PSprite move relative to its previous position.
A_RSRWeaponDraw() nil Raises the player’s current weapon until it’s high enough.
A_RSRWeaponReady() nil Constantly checks if the player is holding the fire or altfire button, then fires the weapon.
A_RSRWeaponRecover() nil Shifts the player’s weapon PSprite’s y-coordinate based on their weaponDelay variable.
A_CheckAmmo() boolean Checks if the player has enough ammo for their currently-held weapon. If not, the player will automatically switch to the highest priority weapon in either the same class, or the next available class.

Functions

Ringslinger Revolution has various functions for adding and cycling through PSprites. Please note that these functions must be called under the PSprites namespace. For example, to run the PSpriteNew() function, it must be written as PSprites.PSpriteNew() for it to actually run.

Function Return value(s) Description
AddPSpriteID(string id) nil Creates a new PSprite ID with the given ID. Every PSprite ID is automatically given a PSPR_* prefix.
PSpriteNew() psprite_t Returns a default PSprite (state set to “S_NONE”; nil sprite; nil frame; animframe, x, and y set to 0; tics set to -1; processPending set to true).
NewPSprite(player_t player, int id) nil Creates a new PSprite in the player’s psprites table with the id given.
PlayerPSpriteInit(player_t player) nil Initializes the player’s psprites table.
GetPSprite(player_t player,int id) psprite_t Gets a PSprite from the player's psprites table given an ID (PSPR_* constants).
SetPSpriteState(player_t player, int id, string newState, boolean pending) nil Sets the player’s PSprite with the given ID to a new state, which can either be a string or an entry from PSprites.STATES. pending determines if processPending should be true or false (Default is false).
PlayerPSpritesReset(player_t player) nil Resets the player’s PSprites to their default settings.
PSpriteTick(player_t player, int id) nil Decrements the player’s PSprite with the given ID by 1. If the PSprite’s tics value is 0, then the PSprite goes to the next state.
TickPSpritesBegin(player_t player) nil Sets processPending to true for all of the player’s PSprites. This function is called in a PlayerThink before PSprites.TickPSprites for every game tic.
TickPSprites(player_t player) nil Runs PSprites.PSpriteTick for all of the player’s PSprites. This function is called in a PlayerThink hook after PSprites.TickPSpritesBegin every game tic.