1
0
Fork 0
mirror of https://github.com/TerryCavanagh/VVVVVV.git synced 2024-12-25 02:59:44 +01:00
Commit graph

2939 commits

Author SHA1 Message Date
Misa
71a989707e De-duplicate and add safety check to ed.level reference
Instead of repeating 'ed.level[curlevel]' (or even worse, you type in
that giant expression inside the brackets instead of reusing
'curlevel'), why not just type 'room'? As an added bonus, I added bounds
checks so 'room' is always guaranteed to point to an existing object.

There are some levels that index 'ed.level' out of bounds, and I'd like
to make their behavior properly defined instead of being undefined. One
of the things usually true about out-of-bounds rooms is that they're
always tiles2.png (that means an edlevelclass tileset that isn't 0),
because the chance of the memory location being exactly 0 is smaller
than it being nonzero. So the out-of-bounds room has tileset 1.
2020-07-15 12:21:12 -04:00
Misa
729f24d732 De-duplicate reference to edentity
'edentity[edi]' is a bit long-winded when you really just want to access
the attributes of the edentity. How about just 'ent'?
2020-07-15 12:21:12 -04:00
Misa
4b6406d08e Unindent case labels in entity creation
Everyone knows that best practice is to put case labels on the same line
as the switch statement...
2020-07-15 12:21:12 -04:00
Misa
fd2ee96c49 Clean up tsx/tsy initialization
Again, it used this severely overcomplicated expression for god knows
what reason. I've replaced it with a simpler one. Also it's const just
to indicate intent.
2020-07-15 12:21:12 -04:00
Misa
d591c77088 De-duplicate expressions of actual coordinates for edentities
Previously it copy-pasted this god-awful overcomplicated expression
(possibly for cursed ActionScript legacy reasons?) everywhere, instead
of putting it in a variable, or even just using a simpler one like the
one I replaced it with.

Now the obj.createentity() and obj.createblock() calls are much nicer.
2020-07-15 12:21:12 -04:00
Misa
34b0e2c812 Unindent ending for-loop brace
It's rather unnecessary to have it be on the same level as the ending
brace for the case-switch.
2020-07-15 12:21:12 -04:00
Misa
8b8f9b3389 Negate edentity room check and use a continue
This reduces the brace level by one, meaning the indentation level is no
longer semi-misleading.
2020-07-15 12:21:12 -04:00
Ethan Lee
264279d17a Warning fix for uninitialized prefix 2020-07-15 12:11:23 -04:00
Ethan Lee
b302e4dbbb Valgrind warning fix 2020-07-15 12:09:24 -04:00
Ethan Lee
5ff5ae7294 mmmmmm is initialized earlier in init() 2020-07-15 11:58:00 -04:00
Misa
f8190439a9 Reset ed.roomnamehide to 0 when exiting playtesting
Now if your cursor was at the bottom of the screen when you entered
playtesting but then was moved to the top during playtesting, when you
exit, the roomname won't instantly disappear and then sheepishly rise
back up again.

And if your cursor was at the bottom of the screen when you entered
playtesting, and exited still being that way, the roomname will rise
back down again and won't instantly disappear.

Both of these behaviors make the roomname movement much more continuous
than it was previously, and it feels smoother and less janky.
2020-07-15 11:45:29 -04:00
Misa
def540d184 Reset ed.notedelay when exiting playtesting
It's not very useful to show a message that was relevant only when you
started playtesting.
2020-07-15 11:45:29 -04:00
Misa
22d556f4be Disable "Game Saved" text box in custommode
Also, use inspecial() instead of writing out each part of the
conditional separately. This just basically adds the insecretlab
conditional to the if-statement, which shouldn't be a big deal.
2020-07-15 11:45:29 -04:00
Misa
13e260bf50 Fix pressing Esc in teleporter menu going to quit screen
When I added the new pause menu, I forgot to make pressing Esc in the
teleporter menu go to the new pause menu instead. But it's fixed now.
2020-07-15 11:45:29 -04:00
Misa
5f131b426b Allow pressing Enter on teleporters during playtesting
There's no reason you shouldn't be allowed to press Enter on teleporters
during playtesting.

Well, except that you can press Esc in the teleporter menu in order to
go to the pause menu, which isn't intended in playtesting. But I can
just add a check there so that pressing Esc closes the teleporter menu
instead, it's fine.
2020-07-15 11:45:28 -04:00
Misa
846c6f61d4 Use .clear() when removing text boxes in reset functions
graphics.textbox.clear() should be used instead of
graphics.textboxremove() or graphics.textboxremovefast(), because even
with graphics.textboxremovefast(), you'll still have to process at least
one frame of GAMEMODE logic before the text boxes are actually properly
removed, and this caused a 1-frame glitch when exiting playtesting with
text boxes on-screen and then re-entering playtesting.

Technically I could've only fixed it in Game::returntoeditor(), but I
wanted to be safe, so I also fixed it in scriptclass::hardreset(), too.
2020-07-15 11:45:28 -04:00
Misa
7fada0548b Set ed.settingskey to true when returning to editor
This fixes a bug where the settings menu would immediately be brought up
if you used Esc to exit playtesting, unless you were an incredible ninja
and only pressed it for exactly one frame.
2020-07-15 11:45:28 -04:00
Misa
6c52b79ddf Set ed.keydelay to 6 when returning to editor
This fixes an annoying bug where if you use Up or Down to press ACTION
on the "All crewmates rescued!" dialogue whenever you rescue the last
crewmate during playtesting, it'll move you to the room above or below
you. This is because ed.keydelay isn't set to 6 (which is the standard
value that it gets set to whenever you press most keys in the editor),
but now it is.
2020-07-15 11:45:28 -04:00
Misa
1caabe374b Fix return to editor via crewmate rescue not using shouldreturntoeditor
The shouldreturntoeditor variable is supposed to be used because it
fixes the warp background not being reset if you exit into a
horizontally/vertically warping room with a different background. It
also properly resets other variables, which is good, too.
2020-07-15 11:45:28 -04:00
Misa
2506127a17 Directly execute scripts if script boxes have a non-empty script field
Instead of using gamestates, just directly use the 'script' attribute of
a script box if it is non-empty.

This is accomplished by having to return the index of the block that the
player collides with, so callers can inspect the 'script' attribute of
the block themselves, and do their logic accordingly.
2020-07-15 11:24:25 -04:00
Misa
ca9e4c8f6e Only set game.customscript if index is inbounds
game.customscript is an unnecessary middleman, but it will be kept
around for compatibility reasons. However, it's still possible to crash
the game, so I'm adding this bounds check.
2020-07-15 11:24:25 -04:00
Misa
8c42f82317 Set script attribute of custom level script boxes
To avoid going through gamestates, we'll need to carry the name of the
script on the script box itself. And to do that, we'll need to set the
'script' attribute of script boxes when translating edentities into real
entities in custom levels.
2020-07-15 11:24:25 -04:00
Misa
5e94239967 Optimize 30-mode FPS loop to use SDL_Delay()
This patch optimizes the loop used to limit the framerate in 30-FPS-only
mode so that it uses SDL_Delay() instead of an accumulator. This means
that the game will take up less CPU power in 30-FPS-only mode. This also
means that the game loop code has been simplified, so there's only two
while-loops, and only two places where game.over30mode is checked, thus
leading to easier-to-understand logic.

Using an accumulator here would essentially mean busywaiting until the
34 millisecond timer was up. (The following is just what leo60228 told
me.) Busywaiting is bad because it's inefficient. The operating system
assumes that if you're busywaiting, you're performing a complex
calculation and handles your process accordingly. And this is why
sleeping was invented, so you could busywait without taking up
unnecessary CPU time.
2020-07-14 00:44:42 -04:00
Ethan Lee
11312976fc Fall back to default settings when screenbuffer is not present 2020-07-13 16:09:48 -04:00
Misa
47eba09edb Fix missing newline on printf for customsavequick() failure
A missing newline in a printf() is annoying, it means the next line of
output is concatenated to the previous one.
2020-07-11 17:52:26 -04:00
Misa
582aaa587e Don't remove non-player entities in scriptclass::hardreset()
When I moved duplicate player entity removal to
scriptclass::hardreset(), I also inadvertently made it so all non-player
entities got removed as well, even though this wasn't my intent. And
thus, pressing Enter to restart a time trial removes every entity except
the player, since it calls script.hardreset().

The time trial script.hardreset() is bad for other reasons (see #367),
however it's still a good idea to reset only what's needed in
script.hardreset().
2020-07-11 15:29:33 -04:00
Misa
199a8f45d6 Fix -playmusic command line option not working
There's a bug where playtesting from Ved doesn't properly play the music
of the level, due to no fault with Ved.

This was because the music was being faded out by
scriptclass::startgamemode() case 23 after main() called music.play().
To fix this, just call music.play() when all the other variables are
being set in Game::customloadquick().
2020-07-11 15:03:37 -04:00
Misa
15319b9ed0 Fix being able to circumvent not-in-Flip-Mode detection
So you get a trophy and achievement for completing the game in Flip
Mode. Which begs the question, how does the game know that you've played
through the game in Flip Mode the entire way, and haven't switched it
off at any point? It looks like if you play normally all the way up
until the checkpoint in V, and then turn on Flip Mode, the game won't
give you the trophy. What gives?

Well, actually, what happens is that every time you press Enter on a
teleporter, the game will set flag 73 to true if you're NOT in Flip
Mode. Then when Game Complete runs, the game will check if flag 73 is
off, and then give you the achievement and trophy accordingly.

However, what this means is that you could just save your game before
pressing Enter on a teleporter, then quit and go into options, turn on
Flip Mode, use the teleporter, then save your game (it's automatically
saved since you just used a teleporter), quit and go into options, and
turn it off. Then you'd get the Flip Mode trophy even though you haven't
actually played the entire game in Flip Mode.

Furthermore, in 2.3 you can bring up the pause menu to toggle Flip Mode,
so you don't even have to quit to circumvent this detection.

To fix both of these exploits, I moved the turning on of flag 73 to
starting a new game, loading a quicksave, and loading a telesave (cases
0, 1, and 2 respectively in scriptclass::startgamemode()). I also added
a Flip Mode check to the routine that runs whenever you exit an options
menu back to the pause menu, so you can't circumvent the detection that
way, either.
2020-07-10 21:35:47 -04:00
Misa
90929d80ea Fix wrong Tower music when toggling Flip Mode from in-game options
The music for the Tower is supposed to be ecroF evitisoP in Flip Mode,
and Positive Force when not in Flip Mode. However, if you go to the
options from the pause menu and toggle Flip Mode, the music isn't
changed.

Fixing this is pretty simple, just check the current area if not in a
custom level and play the correct track accordingly when toggling Flip
Mode from in-game.
2020-07-10 21:33:52 -04:00
Misa
b419601b41 De-duplicate gamestates 300..336
Gamestates 300..336 are used to start scripts in custom levels. However,
it looks like instead of having the cases have common code, each
individual case was copy-pasted numerous times, which is pretty
wasteful.
2020-07-09 21:55:35 -04:00
Ethan Lee
82666a1875 Set both filter and vsync hints with override priority 2020-07-08 21:43:05 -04:00
Misa
3932c75acc Remove unnecessary stub destructors
It's a bit misleading to have these stub destructors when they don't do
anything special.
2020-07-08 19:14:21 -04:00
Misa
307cdefb8e Remove duplicate advancetext/fullScreenEffect_badSignal initializations
They're already initialized in the constructor above, I have no idea why
they're here.
2020-07-08 19:14:21 -04:00
Misa
6b0b86d434 Remove unused attribute advanced_mode from Game
This attribute does absolutely nothing. In fact, it does so much nothing
I can safely remove reading and writing it!
2020-07-08 19:14:21 -04:00
Misa
7128e9c3ac Remove unnecessary string initializations from constructors
std::string is one of those special types that has a constructor that
just initializes itself to a blank state automatically. This means all
`std::string`s are by default already `""`, so there's no need to set
them. And in fact, cppcheck throws out warnings about performance due to
initializing `std::string`s this way.
2020-07-08 19:14:21 -04:00
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
876c120ed8 Remove unused coin attributes from finalclass and warpclass
Looks like coins were basically a scrapped mechanic, although I'm not
sure what these attributes were for. I guess counting the number of
coins in each room? But why, when you can just make a function to count
them automatically? Whatever.
2020-07-08 19:14:21 -04:00
Misa
63f6784cfe Remove unused <vector> include from Otherlevel.h
I forgot to do this earlier in my previous pull request de-vectoring
everything.
2020-07-08 19:14:21 -04:00
Misa
420bc38dff Move Roomtext struct to Map.h
This is a more appropriate place for it, because it's never used in
Otherlevel.cpp.
2020-07-08 19:14:21 -04:00
Misa
5e8ca20d02 Remove block type enum from Otherlevel.h
I have no idea why this is here. It should already be included from
Entity.h, anyway. There's no reason to copy-paste it.
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
a698d3a6f8 Remove unused vars relating to esc/keybuffer from KeyPoll
These attributes were escapeWasPressedPreviously, keyentered, and
keybufferlen.

Don't know why they were here or what they were intended to be for.
2020-07-08 19:14:21 -04:00
Misa
5eab43a655 Initialize saveDir and levelDir in FileSystemUtils.cpp
This is just in case these values happen to be used without being
initialized or anything. I vaguely recall someone reporting an issue
where they didn't have a "Documents" folder on Windows and their level
folder ended up being a garbage path, so it's good to do this.
2020-07-08 19:14:21 -04:00
Ethan Lee
2716296a10 Haiku: Keep the option visible, but note the bug 2020-07-08 14:43:04 -04:00
Ethan Lee
86fde7bf99 More VSync Haiku hackery 2020-07-08 14:38:55 -04:00
Ethan Lee
d3f9a36941 Refactor startup to load config before calling Screen::init 2020-07-08 14:30:57 -04:00
Ethan Lee
f8bb8cde32 HACK: Disable VSync option for Haiku 2020-07-08 14:06:45 -04:00
Misa
09e15db878 Fix Vitellary looking left for one frame in "Now Stay Close To Me..."
There's a bug in the cutscene that plays if your companion is Vitellary
in the room "Now Stay Close To Me...". The relevant gamestate is
gamestate 43, which for Vitellary calls the script `int1yellow_4`.

When Vitellary says the text box "That big... C thing! I wonder what it
does?", Terry intended for Vitellary to change his facing direction to
the left, as you can see with the command `changedir(yellow,0)` in the
original scripting. `changedir()` just changes the `dir` attribute of an
entity, and a `dir` of 0 means face left and a `dir` of 1 means face
right.

Then when Vitellary says "Maybe we should take it back to the ship to
study it?", Terry intended for him to face rightwards once again, as
indicated by the `changedir(yellow,1)` command.

Unfortunately, what happens instead is that when Vitellary says the
first text box ("That big... C thing! I wonder what it does?"), he turns
left for precisely one frame, and then afterwards goes back to facing
right. Then the second text box comes around, but he's already facing
right. How come?

Well, the problem here is that Vitellary's AI for "follow Viridian" is
overriding his `dir` attribute. Vitellary's AI says "get close to
Viridian", but Vitellary is already close enough to them that he stays
put. However, he still turns to face them as part of that AI.

To fix that, we need to put him in the AI mode that specifically says to
face left, with the command `changeai(yellow,faceleft)`. That way, he no
longer has the AI mode of following Viridian, and he will actually look
left for the intended duration instead of only looking left for one
frame.

But then we have another problem. When the cutscene ends, Vitellary no
longer follows Viridian. I mean it makes sense - we just placed him in
"only face left" mode, not "follow Viridian" mode! And this is not
merely a visual problem, because Vitellary is a supercrewmate and the
game won't let the player walk off the screen if Vitellary isn't
offscreen yet.

To fix THAT issue, we'll need to put Vitellary back in "follow Viridian"
mode. It turns out that the `changeai()` command was more intended for
scripting crewmates (entity type 12), NOT supercrewmates (entity type
14). As such, the command assumes that you'll want state numbers that
apply to entity type 12, such as 10, 11, 12, 13, and 14, even though the
only one that applies to entity type 14 is state 0, and every other
state number just makes it so that the entity doesn't move an inch. And
specifying faceleft/faceright is just state number 17.

Luckily, we can still pass the raw state number to `changeai()`, we
don't have to use its intended names. So I do a `changeai(yellow,0)` to
set Vitellary's state number back to 0 when it comes time to make him
face right again.

As a bonus, I added comments to the changed lines. This is a semi-obtuse
method of scripting, so it's always good to clarify.
2020-07-08 07:18:04 -04:00
Matt Penny
5ce2c04ea4 Fix 'Prize for the Reckless' spikes when switching game modes
The spikes are removed if the game is in no death or time trial mode,
however the removal is accomplished by modifying a static array. So if
the player switches to no death or time trial mode and switches back to
regular play, the spikes will no longer be present until the game is
restarted.

This simple fix writes the spikes back to the static array if the game
is not in no death or time trial mode. Another option is to maintain 2
static arrays - one with the spikes and one without - but that is
needlessly wasteful and prone to mistakes (one array updated but not the
other).
2020-07-06 22:04:04 -04:00