1
0
Fork 0
mirror of https://github.com/TerryCavanagh/VVVVVV.git synced 2024-11-13 22:49:42 +01:00
Commit graph

2691 commits

Author SHA1 Message Date
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
Misa
e6f3dab2e1 Make std::string-using script funcs pass around const references
This makes it so that whenever a string is passed into these functions,
it's no longer needlessly copied.
2020-07-06 11:19:24 -04:00
Misa
d480c1011c Make scriptclass::load(other) rely less on std::string
Instead of comparing against an std::string (which is heavily
templated), just use good ol' SDL_strcmp().
2020-07-06 11:19:24 -04:00
Misa
9398e9f1f0 Remove duplicate talkgreen_2 script and alarmon/alarmoff commands
For some reason, there were just exact duplicates of the talkgreen_2
script and alarmon/alarmoff commands. I have no idea why, but cppcheck
identified them.
2020-07-06 11:19:24 -04:00
Misa
fd0dafc16c De-duplicate Graphics::drawmenu() and Graphics::drawlevelmenu()
Graphics::drawmenu() no longer has copy-pasted code for each individual
case. Instead, the individual cases have their own adding on to common
code, which is far easier to maintain.

Also, the only difference Graphics::drawlevelmenu() does is in some
y-positioning stuff. There's no reason to make it a whole separate
function and duplicate everything AGAIN. So it's been consolidated into
Graphics::drawmenu() as well, and I've added a boolean to draw a menu
this way if it's the level menu.
2020-07-06 11:19:24 -04:00
Misa
fbfeeaccd1 Use SDL_tolower() instead of libc tolower() in compare_nocase()
This is to avoid having to depend on libc as much as possible.
2020-07-06 11:19:24 -04:00
Misa
8366e08fbe Remove usage of std::string from MenuOption
Instead, the string in MenuOption is just a buffer of 161 chars, which
is 40 chars (160 bytes if each were the largest possible UTF-8 character
size) plus a null terminator. This is because the maximum length of a
menu option that can be fit on the screen without going past is 40
chars.
2020-07-06 11:19:24 -04:00
Misa
5fb0b4396a Remove use of std::transform(), use SDL_toupper/lower
There's no need to use a template here. Just manually call SDL_tolower()
or SDL_toupper() as needed.

Oh yeah, and use SDL_tolower() and SDL_toupper() instead of libc
tolower() and toupper().
2020-07-06 11:19:24 -04:00
Misa
36e38027d8 Simplify m_headers init, hardcode 128 less
I don't know how no one realized that the for-loop to (poorly)
initialize m_headers was basically unnecessary, and that the memset()
should've just been used instead. Well, except it should also be
replaced with SDL_memset(), but that's besides the point.

Also, I decided to hardcode the 128 thing less, in case people want to
fork the source code and make a build where it's changed.
2020-07-06 11:19:24 -04:00
Misa
fc03fca838 Turn (super)patrons/githubfriends into arrays & move them to new file
So, originally, I wanted to keep them on Game, but it turns out that if
I initialize it in Game.cpp, the compiler will complain that other files
won't know what's actually inside the array. To do that, I'd have to
initialize it in Game.h. But I don't want to initialize it in Game.h
because that'd mean recompiling a lot of unnecessary files whenever
someone gets added to the credits.

So, I moved all the patrons, superpatrons, and GitHub contributors to a
new file, Credits.h, which only contains the list (and the credits max
position calculation). That way, whenever someone gets added, only the
minimal amount of files need to be recompiled.
2020-07-06 11:19:24 -04:00
Misa
a80502bdc9 Turn ed.contents/vmult into arrays
They're always the same size, so there's no need for them to be vectors.

Also made the number of elements in ed.level/kludgewarpdir controllable
by maxwidth/maxheight.

I removed editorclass::saveconvertor() because I didn't want to convert
it to treat ed.contents like an array, because it's unused so I'd have
no way of testing it, plus it's also unused so it doesn't matter. Might
as well get rid of it.
2020-07-06 11:19:24 -04:00
Misa
067fbc75f0 Turn fadebars into an array
There's always 15 of them, it doesn't need to be a vector.
2020-07-06 11:19:24 -04:00
Misa
78181bc676 Statically allocate strings in UtilityClass::number()
It slightly bothered me that these weren't statically allocated, so they
are now.
2020-07-06 11:19:24 -04:00
Misa
5f91bdd073 Turn splitseconds into an array
It's always 30, there's no need for it to be a vector.
2020-07-06 11:19:24 -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
450cf1a31e Turn star and backbox vectors into arrays
There's always 50 stars and always 18 backboxes, there's no reason to
have them be vectors.
2020-07-06 11:19:24 -04:00
Misa
4c6ab6e6b7 Remove unused vars from Graphics/GraphicsResources
These unused vars are:
 - Graphics::bfontmask_rect
 - Graphics::backgrounds
 - Graphics::bfontmask
 - GraphicsResources::im_bfontmask

While it seems that Graphics::backgrounds was indexed in
Graphics::drawbackground(), in reality there was never anything in that
vector and thus actually using it would cause a segfault.
2020-07-06 11:19:24 -04:00
Misa
adca6a122a Turn tower vectors into plain arrays
Also, the arrays are statically allocated. I forgot to do this when we
were statically allocating things earlier, but better late than never.
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
118008d824 Move temp/temp2 off of UtilityClass, remove globaltemp
There's no reason for the temp variables to be on the class itself.
2020-07-06 11:19:24 -04:00
Misa
6b23244366 Move temp variable off of editorclass
Again, basically no reason for it to exist on the class itself.

The usage of the variable was replaced with temp2 instead of temp
because there was already a temp variable in the function it was used
in.
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
0664eac7fc Turn obj.collect and obj.customcollect into plain arrays
Since they're always fixed-size, there's no need for them to be vectors.

Also added an INBOUNDS_ARR() macro to do bounds checks with plain
arrays.
2020-07-06 11:19:24 -04:00
Misa
62203efb2c Turn obj.flags into an array instead of a vector
Since it's always fixed-size, there's no reason for it to be a vector.
2020-07-06 11:19:24 -04:00
Misa
1258eb7bf4 Turn crew rescued/mood vectors into arrays
Since they're always fixed-size, they don't need to be dynamically-sized
vectors.

entityclass::customcrewmoods is now a proper bool instead of an int now,
and I replaced the hardcoded constant 6 with a static const int Game
attribute to make it easier to change.
2020-07-06 11:19:24 -04:00
Misa
cd3869f974 Turn time trial stat vectors into plain arrays
These are the besttimes, besttrinkets, bestlives, and bestrank
attributes of Game. bestframes was already a plain array.

As these are always fixed-sized, there's no reason for them to be
vectors. Also, I put their size in a static const int so it's easy to
change how many of them there are.
2020-07-06 11:19:24 -04:00
Misa
56f06bd853 De-duplicate and use a macro for loading things into plain arrays
Since it's basically the same code each time, I might as well just have
a macro instead.
2020-07-06 11:19:24 -04:00
Misa
3f448ce439 Turn unlock/unlocknotify into plain arrays
They're always fixed-size, so there's no need to them to be a dynamic
vector.

I changed their type to `bool` too because they don't need to be `int`s.

Also, I replaced the hardcoded 25 constant with at least a name, in case
people want to change it in the future.
2020-07-06 11:19:24 -04:00
Misa
c3e7ddca9c Add bounds checks to scriptclass::tokenize()
It could index the `words` array out-of-bounds if there were more than
40 arguments in a command. Not like that would ever happen, but it's
still good to be sure.
2020-07-06 11:19:24 -04:00
Misa
c7774a3eb9 Turn words into an array instead of an std::vector
It never changes its size, so it doesn't need to be a dynamically-sized
vector.
2020-07-06 11:19:24 -04:00
Misa
689af99220 Make currentletter a char instead of an std::string
It's only one character... why does it have to be a fully-fledged
std::string?
2020-07-06 11:19:24 -04:00
Misa
56b2f43ff8 Move tempword and currentletter off of scriptclass
There's no reason for these temporary variables to be a permanent part
of the class itself.
2020-07-06 11:19:24 -04:00
Misa
f28fcd78e8 Fix softlock from interrupted completestop
In summary, if you got to gamestate 1002 or 1012 without an advancetext,
and you had completestop on, you were basically softlocked. So just add
those gamestates there and advance the gamestate if advancetext is off.
2020-07-05 10:14:26 -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
1dfc536b0f Fix infinite loop pressing left/right in tele menu w/ no teles unlocked
This infinite loop would occur because once you pressed left or right,
the game keeps searching through all the list of teleporters until it
finds one that is unlocked. But if there's none that are unlocked, then
the game goes into an infinite loop, which brings up the Not Responding
dialog on Windows so you can kill it.

Normally, you're not supposed to have no teleporters unlocked while
being able to access a teleporter, but you can achieve this by going to
Class Dismissed from a custom level (while making sure you don't start
in 0,0, because there's a teleporter there that you would unlock).

The solution is to make sure at least one teleporter is unlocked before
doing any searching.
2020-07-04 22:48:16 -04:00
Misa
aa873ce172 Use proper do-while for teleporter searching loop
A do-while is just a while-loop, but the inner block will always run
once before the conditional is checked.

It looks like in order to achieve this desired behavior (always run the
block once before checking the conditional), instead of using a do-while
loop, Terry just used a normal while-loop and copy-pasted the inner
block on the outside.

So I'm de-duplicating the code.
2020-07-04 22:48:16 -04:00
Misa
7f61147973 Fix still being able to unlock things in custommode
This was caused by the fact that not all unlocks were done through the
Game::unlocknum() function. Some just set the unlock number directly.
But it's fixed now.
2020-07-02 23:59:42 -04:00
Ethan Lee
c4853688b4 Separate mkdirs from path string generation 2020-07-02 15:57:40 -04:00
Misa
029cc9d4b9 Fix wrong function being used to set color of coins
It should be setcolreal(), and not setcol().

Fixes #347.
2020-07-02 15:33:27 -04:00
Ethan Lee
c3e4e8589d Check saves dir in addition to levels dir for migration 2020-07-02 14:58:04 -04:00
Ethan Lee
d057c6a348 PHYSFS_mkdir uses the mount location when a system is mounted 2020-07-02 14:56:59 -04:00
Ethan Lee
ee610238b5 Try to preserve the script args for createentity when using default args 2020-07-02 14:34:21 -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
450663594f Add G keybind to go to room
Ved has this useful feature where instead of having to manually travel
to a room whose coordinates you know, you can just press G and type in
coordinates to go there.

VCE added this, but I changed the text to be "x,y" instead of "(x,y)"
because otherwise it could confuse someone into thinking they need to
type parentheses when in reality they don't need to and typing them will
just make it not work.

Also I made sure to add an error message if the user types in an invalid
format. Failing silently would just confuse people, and maybe they'll
start thinking the feature doesn't work or something like that. VCE
doesn't have this helpful error message.

Lastly, VCE has a bug where if you use the shortcut to go from one
horizontally/vertically warping room to another, the background of the
previous room will still be there and scroll off with the background of
the room you went to, instead of just having the new background only.
This is because they forgot a 'graphics.backgrounddrawn = false;'. But
don't worry, *I* didn't forget about it.
2020-07-02 01:06:50 -04:00
Misa
76d8dc5bf2 Refactor/de-duplicate entity text input
This is basically FIQ's patch from VCE, except he never upstreamed it
because he said something along the lines of it seeming to not fit the
purpose of upstream.

But anyway, it basically just de-duplicates all the text input and text
finishing handling code and cuts down on the large amount of copy-paste
in the editor functions. It makes things way more maintainable.

Interesting note, it seems like FIQ had the intent to refactor the text
input in editor settings (i.e. the level metadata details), but never
got around to it in VCE. Maybe we'll finish that job for him later.
2020-07-02 01:06:50 -04:00
Ethan Lee
0f450f3e39 Move the VSync work to Screen.
The problem we're running into is entirely contained in the Screen - we need to
either decouple graphics context init from Screen::init or we need to take out
the screenbuffer interaction from loadstats (which I'm more in favor of since we
can just pull the config values and pass them to Screen::init later).
2020-07-02 00:19:40 -04:00
Misa
d854c61960 Add Shift+F1/F2/F3 hotkeys
Allowing users to reverse cycle tilesets/tilecols/enemies prevents them
from having to press the hotkey a zillion times in order to get to the
one they want if the one they want just happens to be behind the current
one they're on.
2020-07-01 23:49:23 -04:00