Addition of the SF_KARTLESS flag to S_SKIN lumps in character WADs to prevent kart & related gibs from spawning upon death
Hey guys, a few things before we get started.
First of all, I've only ever programmed in a team in a work environment where merge requests are not a thing, we just have the right to merge into the master branch as employees. As such, I've never done a merge request before, so please tell me if any of this is incorrect or odd. I'm looking to merge commit de767fef in specifically if something gets lost in translation which as of writing this is the latest commit on the new-skin-flags
branch.
Second of all, I accidentally authored my first commit with my real name and email, and from there I just kept doing it since I already flubbed it up and it was on-record as such. I'd prefer to go by my screen-name wherever possible, so just keep that in mind.
Anyway, all that said, here's what I did:
I added the SF_KARTLESS
flag for S_SKIN
lumps in character WADs. When the bit for this flag is set, upon a player dying, no kart husk will spawn and no kart gib particles will spew. The kart mobj WILL still spawn such that the logic of the kart husk can remain relatively untouched, it will just be invisible and intangible with respects to certain checks for the S_INVISIBLE
state.
Below, you can see a clip of what happens when a skin with the SF_KARTLESS
bit is set as of the commit listed above:
To get this to work as non-destructively as possible, I had to add a new state named S_KART_LEFTOVER_KARTLESS
to statenum_t
that acts the same as S_INVISIBLE
in info.c
but is distinct from that state. I did this because the destroy()
method in destroyed-kart.cpp
is conditioned to not run past the first frame in think()
where that method can run by checking if the state of the kart is S_INVISIBLE
or not, and so if I were to re-use S_INVISIBLE
for this new SF_KARTLESS
flag then it'd fail that condition (although I think the checks at the start of destroy()
would result in a no-op anyway). My first thought to prevent the creation of a fairly pointless state like S_KART_LEFTOVER_KARTLESS
was to add an extravalue3
to mobj_t
, however that wasn't going to work because certain enum
s related to those variables are used in bitwise operations that cap out at 32
entires for the data type in which they are stored which the enum
s in question had already reached.
Lastly, the only important thing to bring up is that in order to prevent a kartless instance of the kart mobj from animating its particles as though it were NOT kartless on the condition that the player changes skin between the kartless instance spawning and being deleted, I had to have some way to cache the state of SF_KARTLESS
upon the kartless instance spawning without using the aforementioned extravalue3
. I did this by creating a new enum
value for the mobjeflag_t
enum
called MFE_KARTLESS
. You may already be thinking that the eflags
variable of mobj_t
is a UINT16
type and is not designed to do bitwise operations with values of that mobjeflag_t
enum
if there are more than 16
entries which this update would push the number of entires to 17
, but I changed the data type of eflags
to UINT32
for up to 32
flags and saw no adverse effects in-game from this as little testing as I did to prove this all the same.
So, TL;DR:
-
S_SKIN
lumps can set theSF_KARTLESS
flag to prevent a kart husk from spawning upon death - This required me to make a new state identical to
S_VISIBLE
but distinct from it all the same to maintain the integrity of certain existingif
statements - The particle update system of
destroyed-kart.cpp
required me to cache theSF_KARTLESS
bit in advance through a newmobjeflag_t
value that has been adjusted ineflags
to accomodate>16
enum
values for thisenum
with no adverse effects observed for this change.