1
0
Fork 0
mirror of https://github.com/TerryCavanagh/VVVVVV.git synced 2024-12-23 10:09:43 +01:00
VVVVVV/desktop_version/src
Misa 3927bb9713 Fix entity and block indices after destroying them
This patch restores some 2.2 behavior, fixing a regression caused by the
refactor of properly using std::vectors.

In 2.2, the game allocated 200 items in obj.entities, but used a system
where each entity had an `active` attribute to signify if the entity
actually existed or not. When dealing with entities, you would have to
check this `active` flag, or else you'd be dealing with an entity that
didn't actually exist. (By the way, what I'm saying applies to blocks
and obj.blocks as well, except for some small differing details like the
game allocating 500 block slots versus obj.entities's 200.)

As a consequence, the game had to use a separate tracking variable,
obj.nentity, because obj.entities.size() would just report 200, instead
of the actual amount of entities. Needless to say, having to check for
`active` and use `obj.nentity` is a bit error-prone, and it's messier
than simply using the std::vector the way it was intended. Also, this
resulted in a hard limit of 200 entities, which custom level makers ran
into surprisingly quite often.

2.3 comes along, and removes the whole system. Now, std::vectors are
properly being used, and obj.entities.size() reports the actual number
of entities in the vector; you no longer have to check for `active` when
dealing with entities of any sort.

But there was one previous behavior of 2.2 that this system kind of
forgets about - namely, the ability to have holes in between entities.
You see, when an entity got disabled in 2.2 (which just meant turning
its `active` off), the indices of all other entities stayed the same;
the indice of the entity that got disabled stays there as a hole in the
array. But when an entity gets removed in 2.3 (previous to this patch),
the indices of every entity afterwards in the array get shifted down by
one. std::vector isn't really meant to be able to contain holes.

Do the indices of entities and blocks matter? Yes; they determine the
order in which entities and blocks get evaluated (the highest indice
gets evaluated first), and I had to fix some block evaluation order
stuff in previous PRs.

And in the case of entities, they matter hugely when using the
recently-discovered Arbitrary Entity Manipulation glitch (where crewmate
script commands are used on arbitrary entities by setting the `i`
attribute of `scriptclass` and passing invalid crewmate identifiers to
the commands). If you use Arbitrary Entity Manipulation after destroying
some entities, there is a chance that your script won't work between 2.2
and 2.3.

The indices also still determine the rendering order of entities
(highest indice gets drawn first, which means lowest indice gets drawn
in front of other entities). As an example: let's say we have the player
at 0, a gravity line at 1, and a checkpoint at 2; then we destroy the
gravity line and create a crewmate (let's do Violet).

If we're able to have holes, then after removing the gravity line, none
of the other indices shift. Then Violet will be created at indice 1, and
will be drawn in front of the checkpoint.

But if we can't have holes, then removing the gravity line results in
the indice of the checkpoint shifting down to indice 1. Then Violet is
created at indice 2, and gets drawn behind the checkpoint! This is a
clear illustration of changing the behavior that existed in 2.2.

However, I also don't want to go back to the `active` system of having
to check an attribute before operating on an entity. So... what do we
do to restore the holes?

Well, we don't need to have an `active` attribute, or modify any
existing code that operates on entities. Instead, we can just set the
attributes of the entities so that they naturally get ignored by
everything that comes into contact with it. For entities, we set their
invis to true, and their size, type, and rule to -1 (the game never uses
a size, type, or rule of -1 anywhere); for blocks, we set their type to
-1, and their width and height to 0.

obj.entities.size() will no longer necessarily equal the amount of
entities in the room; rather, it will be the amount of entity SLOTS that
have been allocated. But nothing that uses obj.entities.size() needs to
actually know the amount of entities; it's mostly used for iterating
over every entity in the vector.

Excess entity slots get cleaned up upon every call of
mapclass::gotoroom(), which will now deallocate entity slots starting
from the end until it hits a player, at which point it will switch to
disabling entity slots instead of removing them entirely.

The entclass::clear() and blockclass::clear() functions have been
restored because we need to call their initialization functions when
reusing a block/entity slot; it's possible to create an entity with an
invalid type number (it creates a glitchy Viridian), and without calling
the initialization function again, it would simply not create anything.

After this patch is applied, entity and block indices will be restored
to how they behaved in 2.2.
2021-02-16 19:31:23 -05:00
..
BinaryBlob.cpp Bail for all SDL_malloc() failures 2021-02-15 23:07:35 -05:00
BinaryBlob.h Refactor TRACK_NAMES to take in a blob parameter 2021-02-15 23:07:35 -05:00
BlockV.cpp Fix entity and block indices after destroying them 2021-02-16 19:31:23 -05:00
BlockV.h Fix entity and block indices after destroying them 2021-02-16 19:31:23 -05:00
Credits.h Fix entities in the Warp Zone's gray tileset not being gray in the editor (#480) 2020-09-25 13:35:03 -04:00
editor.cpp Fix using ii instead of i in script serialization 2021-02-16 00:13:39 -05:00
editor.h Clean up unnecessary exports and add static keywords 2021-01-10 12:23:59 -05:00
Ent.cpp Fix entity and block indices after destroying them 2021-02-16 19:31:23 -05:00
Ent.h Fix entity and block indices after destroying them 2021-02-16 19:31:23 -05:00
Entity.cpp Fix entity and block indices after destroying them 2021-02-16 19:31:23 -05:00
Entity.h Fix entity and block indices after destroying them 2021-02-16 19:31:23 -05:00
Enums.h Hello WWWWWWorld! 2020-01-08 10:37:50 -05:00
Exit.h Add VVV_exit() 2021-02-15 23:07:35 -05:00
FileSystemUtils.cpp Bail for all SDL_malloc() failures 2021-02-15 23:07:35 -05:00
FileSystemUtils.h Only re-color one-ways if assets are not mounted 2020-06-30 18:06:14 -04:00
Finalclass.cpp Separate includes into sections and alphabetize them 2020-07-19 21:37:40 -04:00
Finalclass.h Remove unnecessary includes from header files 2020-07-19 21:37:40 -04:00
Game.cpp Fix entity and block indices after destroying them 2021-02-16 19:31:23 -05:00
Game.h Fix No Death Mode results being reset before being shown 2021-01-18 13:06:15 -05:00
GOGNetwork.c Ifdef out network code for M&P 2020-08-02 23:43:55 -04:00
Graphics.cpp Clean up all program close paths to use VVV_exit() 2021-02-15 23:07:35 -05:00
Graphics.h Move Graphics buffer creation to new func create_buffers() 2021-02-15 23:07:35 -05:00
GraphicsResources.cpp Free data upon failure in LoadImage() 2021-01-18 13:06:43 -05:00
GraphicsResources.h Consistently use angle brackets for SDL.h includes 2020-07-19 21:37:40 -04:00
GraphicsUtil.cpp Reduce dependency on libc functions 2021-01-12 14:02:31 -05:00
GraphicsUtil.h Clean up unnecessary exports and add static keywords 2021-01-10 12:23:59 -05:00
Input.cpp Fix entity and block indices after destroying them 2021-02-16 19:31:23 -05:00
Input.h Remove unnecessary includes from header files 2020-07-19 21:37:40 -04:00
KeyPoll.cpp Ignore resize events for unfocused windows 2021-02-14 22:51:07 -05:00
KeyPoll.h Remove unused function KeyPoll::isUp() 2021-01-02 09:06:42 -05:00
Labclass.cpp Separate includes into sections and alphabetize them 2020-07-19 21:37:40 -04:00
Labclass.h Remove unnecessary includes from header files 2020-07-19 21:37:40 -04:00
Logic.cpp Fix entity and block indices after destroying them 2021-02-16 19:31:23 -05:00
Logic.h Move all fixed-timestep render updates to new file RenderFixed.cpp 2020-12-18 12:01:02 -05:00
main.cpp Clean up all program close paths to use VVV_exit() 2021-02-15 23:07:35 -05:00
MakeAndPlay.h Re-comment out #define MAKEANDPLAY 2020-02-09 10:42:03 -05:00
Map.cpp Fix entity and block indices after destroying them 2021-02-16 19:31:23 -05:00
Map.h Remove map.finalx/y and map.customx/y 2021-01-11 00:24:59 -05:00
Maths.h Reduce dependency on libc functions 2021-01-12 14:02:31 -05:00
Music.cpp Clear musicWriteBlob after writing BinaryMusic.vvv 2021-02-15 23:07:35 -05:00
Music.h Separate musicReadBlob into mmmmmm_blob and pppppp_blob 2021-02-15 23:07:35 -05:00
Network.c Remove unnecessary externs from network func forward decls 2020-08-02 23:43:55 -04:00
Network.h Add support for multiple Network backends, stub in GOGNetwork 2020-01-13 11:15:22 -05:00
Otherlevel.cpp Bounds check all entity getters that can return 0 2020-09-25 13:51:47 -04:00
Otherlevel.h Remove unnecessary includes from header files 2020-07-19 21:37:40 -04:00
preloader.cpp Clean up unnecessary exports and add static keywords 2021-01-10 12:23:59 -05:00
preloader.h Allow pressing ACTION to skip fake loading screen 2020-12-20 15:19:22 -08:00
Render.cpp Fix No Death Mode results being reset before being shown 2021-01-18 13:06:15 -05:00
Render.h Remove unnecessary includes from header files 2020-07-19 21:37:40 -04:00
RenderFixed.cpp Move mapclass r/g/b variables off onto TowerBG 2021-01-07 21:15:34 -05:00
RenderFixed.h Move all fixed-timestep render updates to new file RenderFixed.cpp 2020-12-18 12:01:02 -05:00
Screen.cpp Fix FIXME comments with outdated referents in Screen.cpp 2021-02-15 23:07:35 -05:00
Screen.h Add Screen::destroy() 2021-02-15 23:07:35 -05:00
ScreenSettings.h Factor out screen settings to ScreenSettings struct 2020-12-18 10:02:18 -05:00
Script.cpp Fix entity and block indices after destroying them 2021-02-16 19:31:23 -05:00
Script.h Clean up and prevent unnecessary qualifiers to self 2020-09-28 01:34:40 -04:00
Scripts.cpp Make 'custom_' check more readable 2020-09-27 16:31:40 -04:00
SoundSystem.cpp Pass 1 to Mix_LoadMUS_RW() in MusicTrack::MusicTrack() 2021-02-15 23:07:35 -05:00
SoundSystem.h Remove unused function SoundSystem::playMusic() 2021-01-02 09:06:42 -05:00
Spacestation2.cpp Separate includes into sections and alphabetize them 2020-07-19 21:37:40 -04:00
Spacestation2.h Remove unnecessary includes from header files 2020-07-19 21:37:40 -04:00
SteamNetwork.c Ifdef out network code for M&P 2020-08-02 23:43:55 -04:00
TerminalScripts.cpp Separate includes into sections and alphabetize them 2020-07-19 21:37:40 -04:00
Textbox.cpp Remove allowspecial, replace with opaqueness check 2020-08-06 22:12:15 -04:00
Textbox.h Remove allowspecial, replace with opaqueness check 2020-08-06 22:12:15 -04:00
ThirdPartyDeps.c Reduce dependency on libc functions 2021-01-12 14:02:31 -05:00
Tower.cpp Remove zeroed arrays from tower functions in M&P 2020-08-03 00:29:15 -04:00
Tower.h Change all tilemaps to be short[1200] instead of int[1200] 2020-07-19 16:25:53 -04:00
TowerBG.h Move mapclass r/g/b variables off onto TowerBG 2021-01-07 21:15:34 -05:00
UtilityClass.cpp Fix VVV_isxdigit() accepting A-Za-z instead of A-Fa-f 2021-02-15 23:50:08 -05:00
UtilityClass.h Refactor is_positive_num() to use C-strings 2021-02-15 23:50:08 -05:00
Version.h Don't recompile all files when the commit hash is changed 2020-12-25 20:17:01 -05:00
Version.h.in Don't recompile all files when the commit hash is changed 2020-12-25 20:17:01 -05:00
WarpClass.cpp Separate includes into sections and alphabetize them 2020-07-19 21:37:40 -04:00
WarpClass.h Remove unnecessary includes from header files 2020-07-19 21:37:40 -04:00
XMLUtils.cpp Move all settings to settings.vvv 2020-11-04 12:06:57 -05:00
XMLUtils.h Move all settings to settings.vvv 2020-11-04 12:06:57 -05:00