1
0
mirror of https://github.com/TerryCavanagh/VVVVVV.git synced 2024-06-01 18:43:33 +02:00
Commit Graph

121 Commits

Author SHA1 Message Date
Misa
7703b2c1c2 Ensure that all member attributes are initialized
I ran the game through cppcheck and it spat out a bunch of member
attributes that weren't being initialized. So I initialized them.

In the previous version of this commit, I added constructors to
GraphicsResources, otherlevelclass, labclass, warpclass, and finalclass,
but flibit says this changes the code flow enough that it's risky to
merge before 2.4, so I got rid of those constructors, too.
2020-07-08 19:14:21 -04:00
Misa
3b6867243b Remove useless attribute rcol from finalclass
The rcol of finalclass is always 6, so there's no reason to have an
attribute there as if you could change it or anything.
2020-07-08 19:14:21 -04:00
Misa
ec960b0f95 Remove roomtext from otherlevelclass
Since it's unused, it's better to just delete it because there's no way
to test it to see if it's buggy or not.
2020-07-08 19:14:21 -04:00
Misa
00cb033594 Turn map.specialnames into an array instead of a vector
Easiest de-vectoring I've had to do yet.
2020-07-06 11:19:24 -04:00
Misa
9dcda17978 Turn map.contents into a plain array
map.contents always has 1200 tiles in it, there's no reason it should be
a vector.

This is a big commit because it requires changing all the level classes
to return a pointer to an array instead of returning a vector. Which
took a while for me to figure out, but eventually I did it. I tested to
make sure and there's no problems.
2020-07-06 11:19:24 -04:00
Misa
a1d4523177 Turn areamap into plain array
For this one, I had to make it a static data member and then initialize
it in a certain way in Map.cpp. It's pretty cool that you're able to do
this.
2020-07-06 11:19:24 -04:00
Misa
cb3afa295a Turn map.explored, map.roomdeaths(final) into plain arrays
They're always fixed-size anyways, there's no need for them to be
vectors.

Also used the new INBOUNDS_ARR() macro for the map.explored bounds
checks in Script.cpp, and made map.explored a proper bool array instead
of an int array.
2020-07-06 11:19:24 -04:00
Misa
524a535c62 Move temp and temp2 off of mapclass
There's no reason these temporary variables need to exist on the class
exist.
2020-07-06 11:19:24 -04:00
Misa
d06fadadf2 Fix Map.cpp relying on editor.h to include Script.h
This would mean that NO_CUSTOM_LEVEL builds wouldn't compile.
2020-07-05 10:13:12 -04:00
Misa
d22b895e22 Allow edentity terminals to use any sprite they want
Checkpoints can use any sprite they want, why not terminals, too?
2020-07-02 01:06:50 -04:00
Misa
9e9b1b3c6d Scan for trinkets and put them into shinytrinkets in customs
For showtrinkets() to work, we'll need the correct map data in custom
levels.
2020-06-30 16:30:09 -04:00
Misa
ad27a5c154 Reset width of player in mapclass::resetplayer()
The width of the player can be changed by using the Gravitron OoB
glitch. It will not be reset if the game is in glitchrunner mode.
2020-06-29 19:08:22 -04:00
Misa
66d19d4cf4 Disable two-frame delay fix in glitchrunner mode
The two-frame delay can be utilized to trigger a glitch that spawns
entities in the wrong room.
2020-06-29 19:08:22 -04:00
Misa
ebd381c228 Fix the two-frame-delay when entering a room with an "init" script
This patch is very kludge-y, but at least it fixes a semi-noticeable
visual issue in custom levels that use internal scripts to spawn
entities when loading a room.

Basically, the problem here is that when the game checks for script
boxes and sets newscript, newscript has already been processed for that
frame, and when the game does load a script, script.run() has already
been processed for that frame.

That issue can be fixed, but it turns out that due to my over-30-FPS
game loop changes, there's now ANOTHER visible frame of delay between
room load and entity creation, because the render function gets called
in between the script being loaded at the end of gamelogic() and the
script actually getting run.

So... I have to temporary move script.run() to the end of gamelogic()
(in map.twoframedelayfix()), and make sure it doesn't get run next
frame, because double-evaluations are bad. To do that, I have to
introduce the kludge variable script.dontrunnextframe, which does
exactly as it says.

And with all that work, the two-frame (now three-frame) delay is fixed.
2020-06-29 15:42:51 -04:00
Misa
baf879d9fd Remove unused tmap vars from mapclass
These used to be relevant when the main game tilemaps were stored in
strings, but now they no longer are.
2020-06-29 15:42:51 -04:00
Misa
e1a114d1a5 Un-fix hitbox persistence in map.resetplayer()
It's annoying for casuals to have to close the game if they manage to
get themselves to turn into VVVVVV-Man, but it's amusing enough to
glitchrunners that they mess about with VVVVVV-Man in the main game,
clipping through walls everywhere (well, they call it Big Viridian, but
still).
2020-06-29 15:12:35 -04:00
Misa
387ee4dc79 Un-hardreset certain variables for glitchrunner mode
Ironically enough, resetting more variables in script.hardreset() makes
the glitchy fadeout system even more glitchy. Resetting map.towermode,
for example, makes it so that if you're in towers when you quit to the
menu, script.hardreset() makes it so that the game thinks you're no
longer inbounds (because it no longer thinks you're in a tower and thus
considers coordinates in the space of 40x30 tiles to be inbounds instead
of 40x700 or 40x100 tiles to be inbounds), calls map.gotoroom(), which
resets the gamestate to 0. So if we're using the old system, it's better
to reset only as much as needed.

And furthermore, we shouldn't be relying on script.hardreset() to
initialize variables for us. That should be done at the class
constructor level. So I've gone ahead and initialized the variables in
class constructors, too.
2020-06-29 15:12:35 -04:00
Misa
995f0f126f Fix 1-frame glitch when entering a room with plats in finalmode
Looks like mapclass::changefinalcol() is called whenever you enter a
room in Outside Dimension VVVVVV.

mapclass::changefinalcol() changes the tile, but it doesn't update their
drawframe. So after that function is called, update their drawframe.

If you update their drawframe while inside that function, then when the
platform actually cycles color it'll cycle backwards quickly sometimes,
which is not ideal.
2020-06-19 09:05:48 -04:00
Misa
d88b603019 Fix 1 frame where sad crewmates' drawframes weren't updated
When I loaded the room where Vitellary is in Space Station 2, I saw this
1-frame glitch happen despite my previous efforts to prevent it. So now
it's fixed.
2020-06-19 09:05:48 -04:00
Misa
ad6adcb3c0 Refactor how "hidden names" work
By "hidden names", I'm referring to "Dimension VVVVVV" and "The Ship"
popping up on the quit/pause/teleporter screens, even though those rooms
don't have any roomnames.

Apparently my commit to fix roomname re-draw bleed on the
quit/pause/teleporter screens exposed yet another hardreset()-caused
bug. The issue here is that since hardreset() sets game.roomx and
game.roomy to 0, map.area() will no longer work properly, and since the
hidden roomname check is based on map.area(), it will no longer display
"Dimension VVVVVV" or "The Ship" once you press ACTION to quit. It used
to do this due to the re-draw bleed, but now it doesn't.

I saw that roomnames didn't get reset in hardreset(), so the solution
here is to re-factor hidden names to be an actual variable, instead of
being implicit. map.hiddenname is a variable that's set in
mapclass::loadlevel(), and if isn't empty, it will be drawn on the
quit/pause/teleporter screens. That way it will still display "Dimension
VVVVVV" and "The Ship" when you press ACTION to quit to the menu.

EDIT: Since PR #230 got merged, this commit is no longer strictly
necessary, but it's still good to refactor hidden names like this.
2020-06-19 09:05:48 -04:00
Misa
df2d8e881e Make player not suddenly stop when screen transitioning
This was especially noticeable in slowmode, where after going to an
adjacent room, it would look like they stopped for a split second. This
commit makes it so they smoothly continue their journey after switching
rooms.

The integer cast is to round off any fractional part of the velocity so
that they don't make a difference and result in the oldxp/oldyp being
one pixel off. Especially since the player's y-velocity fluctuates while
standing unflipped on the floor.

Incidentally enough, this seems to only have been a problem with screen
transitions for some reason. No other uses of gotoroom() (such as the
one where gotoroom() is called every other frame, or every frame) seem
to have resulted in this "pausing" behavior, or at least a reversion
back to 30 FPS movement. I don't know why.
2020-06-19 09:05:48 -04:00
Misa
2e17e872e4 Interpolate spikeleveltop and spikelevelbottom
This doesn't have much effect, except for when the spikes quickly move,
because the spikes only usually move at 1 pixel per frame anyway.
2020-06-19 09:05:48 -04:00
Misa
5ff4a09acc Reset spikeleveltop and spikelevelbottom in mapclass::loadlevel()
Just a small thing, but if you teleported out of a tower with the
top/bottom screen spikes being onscreen (by dying, for example), they
would retract once you went back in to a tower. Small little thing, but
it's a good thing to polish.
2020-06-19 09:05:48 -04:00
Misa
0e54aa2f51 Set map.ypos when entering tower
To prevent the camera "zipping" when entering a tower.
2020-06-19 09:05:48 -04:00
Misa
fe1045b515 Interpolate tower scrolling
Now tower scrolling will look smooth ayy-eff.
2020-06-19 09:05:48 -04:00
Misa
27fe7ff8f9 Fix crewmates facing wrong way or not being flipped for <1 frame
By "frame" here I'm referring to the fixed-timestep, not a visual
delta-timestep.

Anyway, the problem is because crewmates' drawframes wait for
entityclass::animateentities() to be called in gamelogic(). In the
old, 30-FPS-only system, this entityclass::animateentities() would be
called in gamerender(), before any actual rendering would take place.
However, I've had to move it out of gamerender() because otherwise
entities would animate too fast. As a result, since gamerender() could
be called in between the entity creation and gamelogic(), a
less-than-1-frame visual glitch could happen.

The solution is to set the entity's drawframe as well when fixing facing
the player in Map.cpp.
2020-06-19 09:05:48 -04:00
Misa
9a8dc4b6ff Only remove duplicate player entities in scriptclass::hardreset()
Looks like duplicate player entities persisting across rooms is a
semi-useful feature used by some levels. Still, though, it's a bit of a
nuisance to have duplicate player entities persisting across game
sessions. And levels can't rely on this persistence anyway, anyone could
just close the game and re-open it to get rid of the duplicate entities
regardless.
2020-06-15 21:30:39 -04:00
Misa
b53d2ae53f Remove i/j/k attributes from classes that don't need them
The only class that actually needs its i/j/k kept is scriptclass,
because some custom levels rely on it for creating custom activity
zones. So I haven't touched that.

Other than that, there's no chance that anything important relies on
i/j/k in any other class. For that to be the case, it would have to use
i/j/k without initializing it beforehand, and that can simply be
detected by removing the attribute from the header file and seeing where
the compiler complains. And the compiler complains only about cases
where it's initialized first. (Note that due to this check, I *haven't*
removed Graphics's `m` as it precisely does exactly this, using it
without initializing it first.)

Interestingly enough, otherlevelclass and towerclass have unused i/k
variables for whatever reason.
2020-06-14 14:37:29 -04:00
Misa
beab344267 Guard all cases obj.getplayer() is used unchecked
obj.getplayer() can return -1, which can cause out-of-bounds indexing of
obj.entities, which is really bad. This was by far the most changes, as
obj.getplayer() is the most used entity-getting function that returns
-1, as well as the most-used function whose sentinel value goes
unchecked.

To deal with the usage of obj.getplayer() in mapclass::warpto(), I just
added general bounds checks inside that function instead of changing all
the callers.
2020-06-12 23:55:48 -04:00
Misa
9205421090 Clean up editorclass externs into one location
Again, like the previous commit, it should just be put in the header
file of its respective class instead of being a mess everywhere.
2020-05-22 09:46:12 -04:00
Misa
4301a70f2d Remove unnecessary middleman ed.swapmap
When the game loads a room in a custom level, previously it would load
the tilemap of that room into ed.swapmap, and then mapclass::loadlevel()
would manually go through each element in ed.swapmap to set each tile in
`contents`. Why do that, when you can just return the vector from
editorclass::loadlevel() and set it directly? ed.swapmap is really
unnecessary.
2020-05-21 23:28:15 -04:00
Misa
e795fbb511 Simplify inits/resets in entityclass/mapclass
Instead of using somewhat-obtuse for-loops to initialize or reset these
vectors, it takes up less lines of code and is clearer if we use
std::vector::resize() and std::vector::clear() instead.
2020-05-19 20:41:56 -04:00
Misa
664bf8ca6c Remove now-unused function mapclass::fillareamap()
This is no longer needed since we load the areamap directly, instead of
having strings as unnecessary middlemen for our tilemap.
2020-05-17 22:03:29 -04:00
Misa
e938bfdb57 Refactor areamap initialization to not use strings
Instead, the data is held in a const int array, which is directly loaded
into areamap.
2020-05-17 22:03:29 -04:00
Misa
aed7b220c7 Remove now-unused function mapclass::fillcontent()
Previously, it was used to parse 30 strings whenever loading a room. But
now it's no longer used since we just assign the tilemap to the vector
directly.
2020-05-17 22:03:29 -04:00
Misa
ec72031cfd Refactor Otherlevel.cpp to not use strings for tilemaps
Instead, they're all held in a constant int array instead.
2020-05-17 22:03:29 -04:00
Misa
8a573af273 Refactor Spacestation2.cpp to not use strings for tilemaps
They are now stored in const int arrays instead. Except for the Prize
for the Reckless room, which I made sure had its spikes removed in No
Death Mode and the Time Trial.
2020-05-17 22:03:29 -04:00
Misa
781aa38e1f Refactor Finalclass.cpp to not use strings for tilemaps
Instead, they're all stored in a constant int array.

I made sure The Gravitron still has 30 rows just like Outer Space,
though I don't think it matters.
2020-05-17 22:03:29 -04:00
Misa
5126c4dbc4 Refactor WarpClass.cpp to not use strings for tilemaps
They now use a constant int array instead.
2020-05-17 22:03:29 -04:00
Misa
cc0d5d1d79 Refactor Labclass.cpp to not use strings for tilemaps
They now use a const int array instead.
2020-05-17 22:03:29 -04:00
Misa
915100b370 Reset vvvvvvman size in mapclass::resetplayer()
It's a bit annoying how vvvvvvman status is preserved between in-game
sessions, and the only thing reset is the color. This is annoying
because it means you have to close the game to reset vvvvvvman.

But now it'll be reset properly. I chose to put this reset code in
mapclass::resetplayer() instead of scriptclass::hardreset() because it
seemed like the more appropriate place. It's where all other properties
of the player are reset, after all.
2020-05-09 15:16:11 -04:00
Misa
85074c1402 Prevent spawning crewmates/activity zones in custommode
Looks like there wasn't a custommode check for the spawning of crewmates
based on which crewmates were rescued, but now there is.

This has gone undiscovered for a long time, mostly because people don't
use the rescued() internal command.
2020-04-30 05:05:04 -04:00
Misa
bf62233b60 Fix compile failure if both MAKEANDPLAY and NO_CUSTOM_LEVELS are defined
I don't know why you would have to have both defined simultaneously, but
now you can.

The compile fail was caused by the fact that if both were defined, then
there would be an expression like this in Map.cpp:

    switch (t)
    {
    case 0:
    }

which is an invalid expression.

The solution is to put 'case 0:' into the MAKEANDPLAY ifdef-guard as
well.
2020-04-17 15:41:48 -04:00
Misa
76e3b3ede4 Remove map.numshinytrinkets
This removes map.numshinytrinkets in favor of using
map.shinytrinkets.size(). Having automatic length tracking is much less
error-prone and less tedious.
2020-04-14 22:54:16 -04:00
Misa
4f7290440b Remove now-unused parameter 't' from mapclass::settrinket()
This parameter used to be used to set the trinket based on indice, but
now that we push_back it's no longer used.
2020-04-14 22:54:16 -04:00
Misa
d43daa5fae Dynamically add shinytrinkets instead of using indices
That is, instead of doing shinytrinkets[t] = ..., do
shinytrinkets.push_back(...).
2020-04-14 22:54:16 -04:00
Misa
d63ba761d5 Remove map.numteleporters
This removes the separate length-tracking variable map.numteleporters,
in favor of using map.teleporters.size().
2020-04-14 22:54:16 -04:00
Misa
5b9c6a9680 Remove now-unused parameter 't' from mapclass::setteleporter()
This was previously used to set the indice of the teleporter, but now
that we do push_back() it's no longer necessary and is now unused.
2020-04-14 22:54:16 -04:00
Misa
fd7d6076e0 Dynamically add teleporters instead of using indices
That is, instead of doing the following:

    teleporters[0] = ...;
    teleporters[1] = ...;
    teleporters[2] = ...;
    ...

Instead do:

    teleporters.push_back(...);
    teleporters.push_back(...);
    teleporters.push_back(...);
    ...
2020-04-14 22:54:16 -04:00
Misa
abfae6b4d7 Declare obj.flags a vector of bools instead of ints
It's treated like a bool anyway, so might as well make it one.

This also necessitates updating every single instance where it or an
element inside it is used, too.
2020-04-09 19:20:31 -04:00
Misa
6b317c5ab9 Remove map.customcrewmates
Same as the previous commit, except for the amount of custom crewmates.
2020-04-09 19:20:31 -04:00
Misa
85bd7d9a2d Remove map.customtrinkets
This variable's sole purpose is to copy ed.numtrinkets, even though ed
has always been a name that's been accessible globally. So let's not
dupe cope.
2020-04-09 19:20:31 -04:00
Misa
744c685614 Remove entityclass::cleanup()
This function's sole purpose was to make sure obj.nentity was in sync,
and that obj.nentity-1 pointed to the last 'active' entity in
obj.entities. But now that obj.nentity is removed and we use
obj.entities.size() instead, it is no longer necessary.
2020-04-03 23:28:47 -04:00
Misa
fd417d6a8c Remove remnants of entity 'active' conditionals
In the previous commit, if an if-statement consisted solely of checking
the active attribute of an entity, I temporarily changed it to 'true'
and put a comment to remove it later, because it would add too much
noise to unindent everything in the same commit.
2020-04-03 23:28:47 -04:00
Misa
b1b1474b7b Refactor entities and linecrosskludge to not use the 'active' system
This removes the variables obj.nentity and obj.nlinecrosskludge, as well
as removing the 'active' attribute from the entity class object. Now
every entity you access is guaranteed to be real and you don't have to
check the 'active' variable.

The biggest part of this is changing createentity() to modify a
newly-created entity object and push it back instead of already
modifying an indice in obj.entities.

As well, removing an entity now uses the new obj.removeentity() function
and removeentity_iter() macro.
2020-04-03 23:28:47 -04:00
Misa
9817e19150 Remove outdated comments from Map.cpp
Surprisingly not that many. It looks like at one point in development,
damage blocks were created for every single spike in the Tower, before
it was too laggy so they switched to directly checking collision with
the tile instead.
2020-04-03 10:40:50 -04:00
Misa
5ba1cf7571 Fix mixed indentation in Map.h and Map.cpp
Again, not that much. These files more-or-less consistently use their
respective indentation.
2020-04-03 10:40:50 -04:00
Misa
d910800423 Remove global args from main game loadlevel() functions
This removes global args from Finalclass.cpp, Labclass.cpp,
Otherlevel.cpp, Spacestation2.cpp, and WarpClass.cpp.
2020-04-03 10:40:50 -04:00
Misa
35d9bcce05 Remove global args from mapclass
This commit removes the global args being passed around from the
function args on the mapclass object, as well as updating all callers in
other files to not have those args. Furthermore, 'dwgfx' has been
renamed to 'graphics' in Map.cpp.
2020-04-03 10:40:50 -04:00
Misa
cac1a9e3ab Remove global args from entityclass
This commit removes all global args from functions on the entityclass
object, and updates the callers of those functions in other files
accordingly (most significantly, the game level files Finalclass.cpp,
Labclass.cpp, Otherlevel.cpp, Spacestation2.cpp, WarpClass.cpp, due to
them using createentity()), as well as renaming all instances of 'dwgfx'
in Entity.cpp to 'graphics'.
2020-04-03 10:40:50 -04:00
Misa
8d44d9387b Refactor edentities to not use separate length-trackers
This turns the array 'edentity' into a proper vector, and removes the need to
use a separate length-tracking variable and manually keep track of the actual
amount of edentities in the level by using the long-winded
'EditorData::GetInstance().numedentities'. This manual tracking was more
error-prone and much less maintainable.

editorclass::naddedentity() has been removed due to now functionally being the
same as editorclass::addedentity() (there's no more
'EditorData::GetInstance().numedentities' to not increment) and for also being
unused in the first place.

editorclass::copyedentity() has been removed because it was only used to shift
the rest of the edentities up manually, but now that we let C++ do all the
hard work it's no longer necessary.
2020-03-01 15:47:01 -05:00
Misa
a4d7fc017c Refactor roomtext to not use ad-hoc objects / separate length trackers
This refactors the roomtext code to (1) not use ad-hoc objects and (2)
not use a separate length-tracking variable to keep track of the actual
amount of roomtext in a room.

What I mean by ad-hoc object is, instead of formally creating a
fully-fledged struct or class and storing one vector containing that
object, this game instead hacks together an object by storing each
attribute of an object in different vectors.

In the case of roomtext, instead of making a Roomtext object that has
attributes 'x', 'y', and 'text', the 'text' attribute of each is stored
in the vector 'roomtext', the 'x' attribute of each is stored in the
vector 'roomtextx', and the 'y' attribute of each is stored in the
vector 'roomtexty'. It's only an object in the sense that you can grab
the attributes of each roomtext by using the same index across all three
vectors.

This makes it somewhat annoying to maintain and deal with, like when I
wanted add sub-tile positions to roomtext in VVVVVV: Community Edition.
Instead of being able to add attributes to an already-existing
formalized Roomtext object, I would instead have to add two more
vectors, which is inelegant. Or I could refactor the whole system, which
is what I decided to do instead.

Furthermore, this removes the separate length-tracking variable
'roomtextnumlines', which makes the code much more easy to maintain and
deal with, as the amount of roomtext is naturally tracked by C++ instead
of us having to keep track of the actual amount of roomtext manually.
2020-02-29 23:02:52 -05:00
Matt Penny
1b00d12600 Add option to allow custom levels when the editor is disabled 2020-02-09 23:31:44 -05:00
Matt Penny
7d35c5ce4e Add option to compile without the level editor 2020-02-09 23:31:44 -05:00
Fredrik Ljungdahl
1062113f73 Make tiles in tower mode behave consistently with tower tileset elsewhere
Previously, in tower mode, being inside walls would just kill you, unlike
being inside walls outside tower mode, which was somewhat confusing.

Also, spikes behaved differently with regards to invincibility, being
unsolid in towers but solid outside them.

This does not change the behaviour of the "edge" spikes in towers.
2020-02-05 22:08:48 +01:00
Info Teddy
1e460721bb Fix hardcoded (19,8) all-sides warp happening in custom levels
(19,8) is hardcoded to warp on all-sides no matter what. This is fine,
except for the fact that it was doing this in custom levels, too, even
despite the fact that the warp background and color would be overridden
anyway. The only workaround was to add a warp line to the room in custom
levels. I've added a check for custommode so that this won't happen.
2020-02-02 08:43:28 -05:00
Info Teddy
47ebbf15ab Don't redraw H/V warp BG if gotorooming to same room in customs
This has two benefits:
 (1) The game uses less resources when it is asked to gotoroom to the
     same room because it is no longer redrawing the warp background
     every single frame, which is very wasteful.
 (2) The warp background no longer freezes or flickers if the player is
     standing inside a gotoroom script box (which calls gotoroom every
     frame or every other frame, because every time the gotoroom happens
     the script box gets reloaded).
2020-01-27 14:46:11 -08:00
Fredrik Ljungdahl
3697487f47 Fix minor issue with respawning into a tower
When the game enter towermode, it adjusts player amd camera x/y depending
on what screen the player entered it from (The Tower) or the loadlevel
mode ("minitowers"; Panic Room and The Final Challenge). This code didn't
account for respawning to checkpoints. This is unlikely to matter in most
circumstances, but can cause problems in some corner cases, or with R abuse.
This could cause a player to die, respawn outside camera edges and then
immediately die again due to the edge spikes, repositioning the camera
properly. Invincibility would cause further issues, but that's Invincibility
Mode for you -- if this was the only problem I wouldn't bother.

I added a check that repositions the tower camera appropriately if a player
enter a tower as part of the respawn process.
2020-01-25 23:30:29 -05:00
Info Teddy
921e288ebe Correct Warp Zone's area name from "Warpzone" to "Warp Zone"
This is the name that gets displayed in your save file.
2020-01-15 20:29:30 -05:00
Info Teddy
b8e611a3bf Destroy duplicate player entities during gotoroom
The game makes sure that the player entity is never destroyed, but in
doing so, it doesn't destroy any duplicate player entities that might
have been created via strange means e.g. a custom level doing a
createentity with t=0.

Duplicate player entities are, in a sense, not the "real" player entity.
For one, they can take damage and die, but when they do they'll still be
stuck inside the hazard, which can result in a softlock. For another,
their position isn't updated when going between rooms. It's better to
just destroy them when we can.
2020-01-13 18:18:44 -05:00
Ethan Lee
f7c0321b71 Hello WWWWWWorld! 2020-01-08 10:37:50 -05:00