2020-01-01 21:29:24 +01:00
|
|
|
#include "Logic.h"
|
2020-02-10 01:53:01 +01:00
|
|
|
#include "Script.h"
|
2020-01-01 21:29:24 +01:00
|
|
|
#include "Network.h"
|
2020-06-17 09:48:10 +02:00
|
|
|
#include "FileSystemUtils.h"
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2020-04-01 23:48:11 +02:00
|
|
|
void titlelogic()
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
//Misc
|
|
|
|
//map.updatetowerglow();
|
|
|
|
help.updateglow();
|
|
|
|
|
|
|
|
map.bypos -= 2;
|
|
|
|
map.bscroll = -2;
|
|
|
|
|
2020-04-30 00:25:01 +02:00
|
|
|
if (!game.colourblindmode)
|
|
|
|
{
|
|
|
|
graphics.updatetowerbackground();
|
|
|
|
}
|
|
|
|
|
2020-05-02 01:40:35 +02:00
|
|
|
if (!game.menustart)
|
|
|
|
{
|
|
|
|
graphics.col_tr = (int)(164 - (help.glow / 2) - int(fRandom() * 4));
|
|
|
|
graphics.col_tg = 164 - (help.glow / 2) - int(fRandom() * 4);
|
|
|
|
graphics.col_tb = 164 - (help.glow / 2) - int(fRandom() * 4);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
graphics.col_tr = map.r - (help.glow / 4) - int(fRandom() * 4);
|
|
|
|
graphics.col_tg = map.g - (help.glow / 4) - int(fRandom() * 4);
|
|
|
|
graphics.col_tb = map.b - (help.glow / 4) - int(fRandom() * 4);
|
|
|
|
if (graphics.col_tr < 0) graphics.col_tr = 0;
|
|
|
|
if(graphics.col_tr>255) graphics.col_tr=255;
|
|
|
|
if (graphics.col_tg < 0) graphics.col_tg = 0;
|
|
|
|
if(graphics.col_tg>255) graphics.col_tg=255;
|
|
|
|
if (graphics.col_tb < 0) graphics.col_tb = 0;
|
|
|
|
if(graphics.col_tb>255) graphics.col_tb=255;
|
|
|
|
|
|
|
|
graphics.updatetitlecolours();
|
|
|
|
}
|
|
|
|
|
2020-04-30 02:09:51 +02:00
|
|
|
graphics.crewframedelay--;
|
|
|
|
if (graphics.crewframedelay <= 0)
|
|
|
|
{
|
|
|
|
graphics.crewframedelay = 8;
|
|
|
|
graphics.crewframe = (graphics.crewframe + 1) % 2;
|
|
|
|
}
|
|
|
|
|
2020-01-01 21:29:24 +01:00
|
|
|
if (game.menucountdown > 0)
|
|
|
|
{
|
|
|
|
game.menucountdown--;
|
|
|
|
if (game.menucountdown == 0)
|
|
|
|
{
|
2020-04-16 06:53:36 +02:00
|
|
|
if (game.menudest == Menu::mainmenu)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
music.play(6);
|
|
|
|
}
|
2020-04-16 06:53:36 +02:00
|
|
|
else if (game.menudest == Menu::gameover2)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-04-02 01:36:35 +02:00
|
|
|
music.playef(11);
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
2020-04-16 06:53:36 +02:00
|
|
|
else if (game.menudest == Menu::timetrialcomplete3)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-04-02 01:36:35 +02:00
|
|
|
music.playef(3);
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
2020-04-17 06:25:30 +02:00
|
|
|
game.createmenu(game.menudest, true);
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-01 23:48:11 +02:00
|
|
|
void maplogic()
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
//Misc
|
|
|
|
help.updateglow();
|
2020-04-29 03:38:43 +02:00
|
|
|
graphics.updatetextboxes();
|
2020-05-02 01:40:35 +02:00
|
|
|
graphics.updatetitlecolours();
|
2020-04-29 05:28:41 +02:00
|
|
|
|
2020-04-30 02:09:51 +02:00
|
|
|
graphics.crewframedelay--;
|
|
|
|
if (graphics.crewframedelay <= 0)
|
|
|
|
{
|
|
|
|
graphics.crewframedelay = 8;
|
|
|
|
graphics.crewframe = (graphics.crewframe + 1) % 2;
|
|
|
|
}
|
|
|
|
|
2020-04-29 05:46:33 +02:00
|
|
|
graphics.oldmenuoffset = graphics.menuoffset;
|
2020-04-29 05:28:41 +02:00
|
|
|
if (graphics.resumegamemode)
|
|
|
|
{
|
|
|
|
graphics.menuoffset += 25;
|
2020-04-29 05:31:29 +02:00
|
|
|
int threshold = map.extrarow ? 230 : 240;
|
|
|
|
if (graphics.menuoffset >= threshold)
|
2020-04-29 05:28:41 +02:00
|
|
|
{
|
2020-04-29 05:31:29 +02:00
|
|
|
graphics.menuoffset = threshold;
|
|
|
|
//go back to gamemode!
|
|
|
|
game.mapheld = true;
|
|
|
|
game.gamestate = GAMEMODE;
|
2020-04-29 05:28:41 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (graphics.menuoffset > 0)
|
|
|
|
{
|
|
|
|
graphics.menuoffset -= 25;
|
|
|
|
if (graphics.menuoffset < 0)
|
|
|
|
{
|
|
|
|
graphics.menuoffset = 0;
|
|
|
|
}
|
|
|
|
}
|
2020-04-29 06:32:53 +02:00
|
|
|
|
|
|
|
if (map.cursorstate == 0){
|
|
|
|
map.cursordelay++;
|
|
|
|
if (map.cursordelay > 10){
|
|
|
|
map.cursorstate = 1;
|
|
|
|
map.cursordelay = 0;
|
|
|
|
}
|
|
|
|
}else if (map.cursorstate == 1){
|
|
|
|
map.cursordelay++;
|
|
|
|
if (map.cursordelay > 30) map.cursorstate = 2;
|
|
|
|
}else if (map.cursorstate == 2){
|
|
|
|
map.cursordelay++;
|
|
|
|
}
|
2020-05-02 19:31:48 +02:00
|
|
|
|
|
|
|
if (map.finalmode)
|
|
|
|
{
|
|
|
|
map.glitchname = map.getglitchname(game.roomx, game.roomy);
|
|
|
|
}
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-04-01 23:48:11 +02:00
|
|
|
void gamecompletelogic()
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
//Misc
|
|
|
|
map.updatetowerglow();
|
|
|
|
help.updateglow();
|
2020-04-01 23:48:11 +02:00
|
|
|
graphics.crewframe = 0;
|
Don't re-draw credits scroll background every frame
While I was working on my over-30-FPS patch, I found out that the tower
background in the credits scroll was being completely re-drawn every
single frame, which was a bit wasteful and expensive. It's also harder
to interpolate for my over-30-FPS patch. I'm guessing this constant
re-draw was done because the math to get the surface scroll properly
working is a bit subtle, but I've figured the precise math out!
The first changes of this patch is just removing the unconditional
`map.tdrawback = true;`, and having to set `map.scrolldir` everywhere to
get the credits scrolling in the right direction but make sure the title
screen doesn't start scrolling like a descending tower, too.
After that, the first problem is that it looks like the ACTION press to
speed up the credits scrolling doesn't speed up the background, too. No
problem, just shove a `!game.press_action` check in
`gamecompletelogic()`.
However, this introduces a mini-problem, which is that NOW when you hold
down ACTION, the background appears to be slowly getting out of sync
with the credits text by a one-pixel-per-second difference. This is
actually due to the fact that, as a result of me adding the conditional,
`map.bscroll` is no longer always unconditionally getting set to 1,
while `game.creditposition` IS always unconditionally getting
decremented by 1. And when you hold down ACTION, `game.creditposition`
gets decremented by 6.
Thus, I need to set `map.bscroll` when holding down ACTION to be 7,
which is 6 plus 1.
Then we have another problem, which is that the incoming textures desync
when you press ACTION, and when you release ACTION. They desync by
precisely 6 pixels, which should be a familiar number. I (eventually)
tracked this down to `map.bypos` being updated at the same time
`map.bscroll` is, even though `map.bypos` should be updated a frame
later AFTER updating `map.bscroll`.
So I had to change the `map.bypos` update in `gamecompleteinput()` and
`gamecompletelogic()` to be `map.bypos += map.bscroll;` and then place
it before any `map.bscroll` update, thus ensuring that `map.bscroll`
updates exactly one frame before `map.ypos` does. I had to move the
`map.bypos += map.bscroll;` to be in `gamecompleteinput()`, because
`gamecompleteinput()` comes first before `gamecompletelogic()` in the
`main.cpp` game loop, otherwise the `map.bypos` update won't be delayed
by one frame for when you press ACTION to make it go faster, and thus
cause a desync when you press ACTION.
Oh and then after that, I had to make the descending tower background
draw a THIRD row of incoming tiles, otherwise you could see some black
flickering at the bottom of the screen when you held down ACTION.
All of this took me way too long to figure out, but now the credits
scroll works perfectly while being more optimized.
2020-04-30 05:52:33 +02:00
|
|
|
map.scrolldir = 1;
|
2020-05-02 01:40:35 +02:00
|
|
|
graphics.updatetitlecolours();
|
|
|
|
|
|
|
|
graphics.col_tr = map.r - (help.glow / 4) - fRandom() * 4;
|
|
|
|
graphics.col_tg = map.g - (help.glow / 4) - fRandom() * 4;
|
|
|
|
graphics.col_tb = map.b - (help.glow / 4) - fRandom() * 4;
|
|
|
|
if (graphics.col_tr < 0) graphics.col_tr = 0;
|
|
|
|
if(graphics.col_tr>255) graphics.col_tr=255;
|
|
|
|
if (graphics.col_tg < 0) graphics.col_tg = 0;
|
|
|
|
if(graphics.col_tg>255) graphics.col_tg=255;
|
|
|
|
if (graphics.col_tb < 0) graphics.col_tb = 0;
|
|
|
|
if(graphics.col_tb>255) graphics.col_tb=255;
|
2020-01-01 21:29:24 +01:00
|
|
|
|
|
|
|
game.creditposition--;
|
2020-01-17 02:14:56 +01:00
|
|
|
if (game.creditposition <= -game.creditmaxposition)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-01-17 02:14:56 +01:00
|
|
|
game.creditposition = -game.creditmaxposition;
|
2020-01-01 21:29:24 +01:00
|
|
|
map.bscroll = 0;
|
|
|
|
}
|
Don't re-draw credits scroll background every frame
While I was working on my over-30-FPS patch, I found out that the tower
background in the credits scroll was being completely re-drawn every
single frame, which was a bit wasteful and expensive. It's also harder
to interpolate for my over-30-FPS patch. I'm guessing this constant
re-draw was done because the math to get the surface scroll properly
working is a bit subtle, but I've figured the precise math out!
The first changes of this patch is just removing the unconditional
`map.tdrawback = true;`, and having to set `map.scrolldir` everywhere to
get the credits scrolling in the right direction but make sure the title
screen doesn't start scrolling like a descending tower, too.
After that, the first problem is that it looks like the ACTION press to
speed up the credits scrolling doesn't speed up the background, too. No
problem, just shove a `!game.press_action` check in
`gamecompletelogic()`.
However, this introduces a mini-problem, which is that NOW when you hold
down ACTION, the background appears to be slowly getting out of sync
with the credits text by a one-pixel-per-second difference. This is
actually due to the fact that, as a result of me adding the conditional,
`map.bscroll` is no longer always unconditionally getting set to 1,
while `game.creditposition` IS always unconditionally getting
decremented by 1. And when you hold down ACTION, `game.creditposition`
gets decremented by 6.
Thus, I need to set `map.bscroll` when holding down ACTION to be 7,
which is 6 plus 1.
Then we have another problem, which is that the incoming textures desync
when you press ACTION, and when you release ACTION. They desync by
precisely 6 pixels, which should be a familiar number. I (eventually)
tracked this down to `map.bypos` being updated at the same time
`map.bscroll` is, even though `map.bypos` should be updated a frame
later AFTER updating `map.bscroll`.
So I had to change the `map.bypos` update in `gamecompleteinput()` and
`gamecompletelogic()` to be `map.bypos += map.bscroll;` and then place
it before any `map.bscroll` update, thus ensuring that `map.bscroll`
updates exactly one frame before `map.ypos` does. I had to move the
`map.bypos += map.bscroll;` to be in `gamecompleteinput()`, because
`gamecompleteinput()` comes first before `gamecompletelogic()` in the
`main.cpp` game loop, otherwise the `map.bypos` update won't be delayed
by one frame for when you press ACTION to make it go faster, and thus
cause a desync when you press ACTION.
Oh and then after that, I had to make the descending tower background
draw a THIRD row of incoming tiles, otherwise you could see some black
flickering at the bottom of the screen when you held down ACTION.
All of this took me way too long to figure out, but now the credits
scroll works perfectly while being more optimized.
2020-04-30 05:52:33 +02:00
|
|
|
else if (!game.press_action)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
map.bscroll = +1;
|
|
|
|
}
|
|
|
|
|
2020-04-01 23:48:11 +02:00
|
|
|
if (graphics.fademode == 1)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
//Fix some graphical things
|
2020-04-01 23:48:11 +02:00
|
|
|
graphics.showcutscenebars = false;
|
|
|
|
graphics.cutscenebarspos = 0;
|
2020-04-29 02:16:24 +02:00
|
|
|
graphics.oldcutscenebarspos = 0;
|
Don't re-draw credits scroll background every frame
While I was working on my over-30-FPS patch, I found out that the tower
background in the credits scroll was being completely re-drawn every
single frame, which was a bit wasteful and expensive. It's also harder
to interpolate for my over-30-FPS patch. I'm guessing this constant
re-draw was done because the math to get the surface scroll properly
working is a bit subtle, but I've figured the precise math out!
The first changes of this patch is just removing the unconditional
`map.tdrawback = true;`, and having to set `map.scrolldir` everywhere to
get the credits scrolling in the right direction but make sure the title
screen doesn't start scrolling like a descending tower, too.
After that, the first problem is that it looks like the ACTION press to
speed up the credits scrolling doesn't speed up the background, too. No
problem, just shove a `!game.press_action` check in
`gamecompletelogic()`.
However, this introduces a mini-problem, which is that NOW when you hold
down ACTION, the background appears to be slowly getting out of sync
with the credits text by a one-pixel-per-second difference. This is
actually due to the fact that, as a result of me adding the conditional,
`map.bscroll` is no longer always unconditionally getting set to 1,
while `game.creditposition` IS always unconditionally getting
decremented by 1. And when you hold down ACTION, `game.creditposition`
gets decremented by 6.
Thus, I need to set `map.bscroll` when holding down ACTION to be 7,
which is 6 plus 1.
Then we have another problem, which is that the incoming textures desync
when you press ACTION, and when you release ACTION. They desync by
precisely 6 pixels, which should be a familiar number. I (eventually)
tracked this down to `map.bypos` being updated at the same time
`map.bscroll` is, even though `map.bypos` should be updated a frame
later AFTER updating `map.bscroll`.
So I had to change the `map.bypos` update in `gamecompleteinput()` and
`gamecompletelogic()` to be `map.bypos += map.bscroll;` and then place
it before any `map.bscroll` update, thus ensuring that `map.bscroll`
updates exactly one frame before `map.ypos` does. I had to move the
`map.bypos += map.bscroll;` to be in `gamecompleteinput()`, because
`gamecompleteinput()` comes first before `gamecompletelogic()` in the
`main.cpp` game loop, otherwise the `map.bypos` update won't be delayed
by one frame for when you press ACTION to make it go faster, and thus
cause a desync when you press ACTION.
Oh and then after that, I had to make the descending tower background
draw a THIRD row of incoming tiles, otherwise you could see some black
flickering at the bottom of the screen when you held down ACTION.
All of this took me way too long to figure out, but now the credits
scroll works perfectly while being more optimized.
2020-04-30 05:52:33 +02:00
|
|
|
map.scrolldir = 0;
|
|
|
|
map.bypos = 0;
|
2020-01-01 21:29:24 +01:00
|
|
|
//Return to game
|
2020-04-17 05:15:53 +02:00
|
|
|
game.gamestate = GAMECOMPLETE2;
|
2020-04-01 23:48:11 +02:00
|
|
|
graphics.fademode = 4;
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-01 23:48:11 +02:00
|
|
|
void gamecompletelogic2()
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
//Misc
|
|
|
|
map.updatetowerglow();
|
|
|
|
help.updateglow();
|
|
|
|
|
|
|
|
game.creditposdelay--;
|
|
|
|
if (game.creditposdelay <= 0)
|
|
|
|
{
|
|
|
|
game.creditposdelay = 1;
|
|
|
|
game.creditposx++;
|
|
|
|
if (game.creditposx > 40)
|
|
|
|
{
|
|
|
|
game.creditposy++;
|
|
|
|
game.creditposx = 0;
|
|
|
|
if (game.creditposy > 30) game.creditposy = 30;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-01 23:48:11 +02:00
|
|
|
if (graphics.fademode == 1)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
//Fix some graphical things
|
2020-04-01 23:48:11 +02:00
|
|
|
graphics.showcutscenebars = false;
|
|
|
|
graphics.cutscenebarspos = 0;
|
2020-01-01 21:29:24 +01:00
|
|
|
//Fix the save thingy
|
|
|
|
game.deletequick();
|
|
|
|
int tmp=music.currentsong;
|
|
|
|
music.currentsong=4;
|
Fix flag 67 turning on too early
Flag 67 seems to be a general-purpose Game Complete flag. It's used to
replace the CREW option with the SHIP option on the pause screen.
Unfortunately, it gets turned on too early during Game Complete. Right
when Viridian starts to teleport, you can bring up the pause screen and
select the SHIP option.
It will teleport you to the ship coordinates, but still keep you in
finalmode, and since the ship coordinates are at 102,111 (finalmode is
only around 46,54), you'll still be stuck in Outside Dimension VVVVVV,
and you've interrupted the Game Complete gamestate by switching to the
teleporting gamestate. Oh, and your checkpoint is set, too, so you can't
even press R. Oh and since there's no teleporter, and checkpoint setting
doesn't check the sentinel value, this results in Undefined Behavior,
too.
So this results in an in-game softlock. The only option you can do is
quit the game at this point.
To fix this issue, just move turning on flag 67 before the savetele() in
gamecompletelogic2().
2020-05-09 20:41:54 +02:00
|
|
|
obj.flags[67] = true;
|
2020-03-31 02:16:02 +02:00
|
|
|
game.savetele();
|
2020-01-01 21:29:24 +01:00
|
|
|
music.currentsong=tmp;
|
|
|
|
//Return to game
|
|
|
|
map.colstate = 10;
|
2020-04-17 05:15:53 +02:00
|
|
|
game.gamestate = TITLEMODE;
|
2020-04-01 23:48:11 +02:00
|
|
|
graphics.fademode = 4;
|
2020-06-17 09:48:10 +02:00
|
|
|
FILESYSTEM_unmountassets(); // should be before music.playef(18)
|
2020-04-02 01:36:35 +02:00
|
|
|
music.playef(18);
|
2020-05-03 05:38:06 +02:00
|
|
|
game.returntomenu(Menu::play);
|
2020-04-16 06:53:36 +02:00
|
|
|
game.createmenu(Menu::gamecompletecontinue);
|
2020-01-01 21:29:24 +01:00
|
|
|
map.nexttowercolour();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-04-25 06:19:41 +02:00
|
|
|
void gamelogic()
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-04-29 01:25:03 +02:00
|
|
|
if (!game.blackout && !game.completestop)
|
|
|
|
{
|
|
|
|
for (size_t i = 0; i < obj.entities.size(); i++)
|
|
|
|
{
|
|
|
|
//Is this entity on the ground? (needed for jumping)
|
|
|
|
if (obj.entitycollidefloor(i))
|
|
|
|
{
|
|
|
|
obj.entities[i].onground = 2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
obj.entities[i].onground--;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (obj.entitycollideroof(i))
|
|
|
|
{
|
|
|
|
obj.entities[i].onroof = 2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
obj.entities[i].onroof--;
|
|
|
|
}
|
|
|
|
|
|
|
|
//Animate the entities
|
|
|
|
obj.animateentities(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-25 06:19:41 +02:00
|
|
|
//Misc
|
|
|
|
if (map.towermode)
|
|
|
|
{
|
|
|
|
map.updatetowerglow();
|
|
|
|
}
|
2020-01-01 21:29:24 +01:00
|
|
|
help.updateglow();
|
|
|
|
|
2020-04-25 06:19:41 +02:00
|
|
|
if (game.alarmon)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-04-25 06:19:41 +02:00
|
|
|
game.alarmdelay--;
|
|
|
|
if (game.alarmdelay <= 0)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-04-25 06:19:41 +02:00
|
|
|
music.playef(19);
|
|
|
|
game.alarmdelay = 20;
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-25 06:19:41 +02:00
|
|
|
if (obj.nearelephant)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-04-25 06:19:41 +02:00
|
|
|
obj.upset++;
|
|
|
|
if (obj.upset == 300)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-04-25 06:19:41 +02:00
|
|
|
obj.upsetmode = true;
|
|
|
|
//change player to sad
|
|
|
|
int i = obj.getplayer();
|
2020-06-13 05:36:08 +02:00
|
|
|
if (i > -1)
|
|
|
|
{
|
|
|
|
obj.entities[i].tile = 144;
|
|
|
|
}
|
2020-04-25 06:19:41 +02:00
|
|
|
music.playef(2);
|
|
|
|
}
|
|
|
|
if (obj.upset > 301) obj.upset = 301;
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
2020-04-25 06:19:41 +02:00
|
|
|
else if (obj.upsetmode)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-04-25 06:19:41 +02:00
|
|
|
obj.upset--;
|
|
|
|
if (obj.upset <= 0)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-04-25 06:19:41 +02:00
|
|
|
obj.upset = 0;
|
|
|
|
obj.upsetmode = false;
|
|
|
|
//change player to happy
|
|
|
|
int i = obj.getplayer();
|
2020-06-13 05:36:08 +02:00
|
|
|
if (i > -1)
|
|
|
|
{
|
|
|
|
obj.entities[i].tile = 0;
|
|
|
|
}
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
}
|
2020-04-25 06:19:41 +02:00
|
|
|
else
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-04-25 06:19:41 +02:00
|
|
|
obj.upset = 0;
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
|
2020-04-30 01:54:36 +02:00
|
|
|
obj.oldtrophytext = obj.trophytext;
|
|
|
|
|
2020-04-25 06:19:41 +02:00
|
|
|
if (map.towermode)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-04-30 20:52:21 +02:00
|
|
|
map.oldypos = map.ypos;
|
2020-04-30 21:58:08 +02:00
|
|
|
map.oldspikeleveltop = map.spikeleveltop;
|
|
|
|
map.oldspikelevelbottom = map.spikelevelbottom;
|
2020-04-25 06:19:41 +02:00
|
|
|
if(!game.completestop)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-04-25 06:19:41 +02:00
|
|
|
if (map.cameramode == 0)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-04-25 06:19:41 +02:00
|
|
|
//do nothing!
|
|
|
|
//a trigger will set this off in the game
|
|
|
|
map.cameramode = 1;
|
|
|
|
map.bscroll = 0;
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
2020-04-25 06:19:41 +02:00
|
|
|
else if (map.cameramode == 1)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-04-25 06:19:41 +02:00
|
|
|
//move normally
|
|
|
|
if(map.scrolldir==0)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-04-25 06:19:41 +02:00
|
|
|
map.ypos -= 2;
|
|
|
|
map.bypos -= 1;
|
|
|
|
map.bscroll = -1;
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
2020-04-25 06:19:41 +02:00
|
|
|
else
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-04-25 06:19:41 +02:00
|
|
|
map.ypos += 2;
|
|
|
|
map.bypos += 1;
|
|
|
|
map.bscroll = 1;
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
}
|
2020-04-25 06:19:41 +02:00
|
|
|
else if (map.cameramode == 2)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-04-25 06:19:41 +02:00
|
|
|
//do nothing, but cycle colours (for taking damage)
|
|
|
|
map.bscroll = 0;
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
2020-04-25 06:19:41 +02:00
|
|
|
else if (map.cameramode == 4)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-04-25 06:19:41 +02:00
|
|
|
int i = obj.getplayer();
|
2020-06-13 05:36:08 +02:00
|
|
|
if (i > -1)
|
|
|
|
{
|
|
|
|
map.cameraseek = map.ypos - (obj.entities[i].yp - 120);
|
|
|
|
}
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2020-04-25 06:19:41 +02:00
|
|
|
map.cameraseek = map.cameraseek / 10;
|
|
|
|
map.cameraseekframe = 10;
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2020-04-25 06:19:41 +02:00
|
|
|
map.cameramode = 5;
|
|
|
|
|
|
|
|
map.bscroll = map.cameraseek/2;
|
|
|
|
}
|
|
|
|
else if (map.cameramode == 5)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-04-25 06:19:41 +02:00
|
|
|
//actually do it
|
|
|
|
if (map.spikeleveltop > 0) map.spikeleveltop-=2;
|
|
|
|
if (map.spikelevelbottom > 0) map.spikelevelbottom-=2;
|
|
|
|
if (map.cameraseekframe > 0)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-04-25 06:19:41 +02:00
|
|
|
int i = obj.getplayer();
|
|
|
|
map.ypos -= map.cameraseek;
|
2020-06-13 05:36:08 +02:00
|
|
|
if (map.cameraseek > 0 && i > -1)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-04-25 06:19:41 +02:00
|
|
|
if (map.ypos < obj.entities[i].yp - 120)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-04-25 06:19:41 +02:00
|
|
|
map.ypos = obj.entities[i].yp - 120;
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
}
|
2020-06-13 05:36:08 +02:00
|
|
|
else if (i > -1)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-04-25 06:19:41 +02:00
|
|
|
if (map.ypos > obj.entities[i].yp - 120)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-04-25 06:19:41 +02:00
|
|
|
map.ypos = obj.entities[i].yp - 120;
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
}
|
2020-04-25 06:19:41 +02:00
|
|
|
map.cameraseekframe--;
|
|
|
|
map.bypos = map.ypos / 2;
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-04-25 06:19:41 +02:00
|
|
|
int i = obj.getplayer();
|
2020-06-13 05:36:08 +02:00
|
|
|
if (i > -1)
|
|
|
|
{
|
|
|
|
map.ypos = obj.entities[i].yp - 120;
|
|
|
|
}
|
2020-04-25 06:19:41 +02:00
|
|
|
map.bypos = map.ypos / 2;
|
|
|
|
map.cameramode = 0;
|
|
|
|
map.colsuperstate = 0;
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
}
|
2020-04-25 06:19:41 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
map.bscroll = 0;
|
|
|
|
}
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2020-04-25 06:19:41 +02:00
|
|
|
if (map.ypos <= 0)
|
|
|
|
{
|
|
|
|
map.ypos = 0;
|
|
|
|
map.bypos = 0;
|
|
|
|
map.bscroll = 0;
|
|
|
|
}
|
2020-05-05 20:26:26 +02:00
|
|
|
if (map.towermode && map.minitowermode)
|
2020-04-25 06:19:41 +02:00
|
|
|
{
|
|
|
|
if (map.ypos >= 568)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-04-25 06:19:41 +02:00
|
|
|
map.ypos = 568;
|
|
|
|
map.bypos = map.ypos / 2;
|
|
|
|
map.bscroll = 0;
|
|
|
|
} //100-29 * 8 = 568
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (map.ypos >= 5368)
|
|
|
|
{
|
|
|
|
map.ypos = 5368; //700-29 * 8 = 5368
|
|
|
|
map.bypos = map.ypos / 2.0;
|
|
|
|
}
|
|
|
|
}
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2020-04-25 06:19:41 +02:00
|
|
|
if (game.lifeseq > 0)
|
|
|
|
{
|
|
|
|
if (map.cameramode == 2)
|
|
|
|
{
|
|
|
|
map.cameraseekframe = 20;
|
|
|
|
map.cameramode = 4;
|
|
|
|
map.resumedelay = 4;
|
|
|
|
}
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2020-04-25 06:19:41 +02:00
|
|
|
if (map.cameraseekframe <= 0)
|
|
|
|
{
|
|
|
|
if (map.resumedelay <= 0)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-04-25 06:19:41 +02:00
|
|
|
game.lifesequence();
|
|
|
|
if (game.lifeseq == 0) map.cameramode = 1;
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-04-25 06:19:41 +02:00
|
|
|
map.resumedelay--;
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-04-25 06:19:41 +02:00
|
|
|
game.lifesequence();
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
|
2020-05-02 21:06:40 +02:00
|
|
|
graphics.kludgeswnlinewidth = false;
|
2020-01-01 21:29:24 +01:00
|
|
|
|
|
|
|
if (game.deathseq != -1)
|
|
|
|
{
|
2020-04-25 06:19:41 +02:00
|
|
|
if (map.towermode)
|
|
|
|
{
|
|
|
|
map.colsuperstate = 1;
|
|
|
|
map.cameramode = 2;
|
|
|
|
}
|
|
|
|
|
2020-04-03 22:50:16 +02:00
|
|
|
for (size_t i = 0; i < obj.entities.size(); i++)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-02-04 03:53:30 +01:00
|
|
|
if (game.roomx == 111 && game.roomy == 107 && !map.custommode)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
if (obj.entities[i].type == 1)
|
|
|
|
{
|
|
|
|
if (obj.entities[i].xp < 152)
|
|
|
|
{
|
|
|
|
obj.entities[i].xp = 152;
|
|
|
|
obj.entities[i].newxp = 152;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (obj.entities[i].type == 2 && obj.entities[i].state == 3)
|
|
|
|
{
|
|
|
|
//Ok! super magical exception for the room with the intention death for the shiny trinket
|
|
|
|
//fix this when the maps are finalised
|
Fix Prize for the Reckless quicksand fix kludge
If you died in Prize for the Reckless, which is at (11,7), and respawned
in the same room, tile 59 (a solid invisible tile) would be placed at
[18,9] to prevent the moving platform from going back through the
quicksand.
Unfortunately, the way that this kludge was added is poor.
First, the conditional makes it so that it doesn't happen in ONLY
(11,7). Instead of being behind a positive conditional, the tile is
placed in the else-branch of an if-conditional that checks for the
normal case, i.e. if the current room is NOT (11,7), thus being a
negative conditional.
In other words, the positive conditional is "game.roomx == 111 &&
game.roomy == 107". To negate it, all you would have to do is
"!(game.roomx == 111 && game.roomy == 107)".
However, whoever wrote this decided to go one step further, and actually
DISTRIBUTE the negative into both statements. This would be fine, except
if they actually got it right. You see, according to De Morgan's laws,
when you distribute a negative across multiple statements you not only
have to negate the statements themselves, but you have to negate all the
CONJUNCTIONS, too. In other words, you have to change all "and"s into
"or"s and all "or"s into "and"s.
Instead of making the conditional "game.roomx != 111 || game.roomy !=
107", the person who wrote this forgot to replace the "and" with an
"or". Thus, it is "game.roomx != 111 && game.roomy != 107" instead. As a
result, if we re-negate this and take a look at the positive
conditional, i.e. the conditional that results in the else-branch
executing, it turns out to be "game.roomx == 111 || game.roomy == 107".
This ends up forming a cross-shape of rooms where this kludge happens.
As long as your room is either on the line x=11 or on the line y=7, this
kludge will execute.
You can see this if you go to Boldly To Go, since it is (11,13), which
is on the line x=11. Checkpoint in that room, then touch a disappearing
platform, wait for it to fully disappear, then die. Then an invisible
tile will be placed to the left of the spikes on the ceiling.
Anyway, to fix this, it's simple. Just change the "and" in the negative
conditional to an "or".
The second problem was that this kludge was happening in custom levels.
So I've added a map.custommode check to it. I made sure not to make the
same mistake originally made, i.e. I made sure to use an "or" instead of
an "and". Thus, when you re-negate the negative conditional and turn it
into the positive conditional, it reads: "game.roomx == 111 &&
game.roomy == 107 && !map.custommode".
2020-02-02 11:26:49 +01:00
|
|
|
if (game.roomx != 111 || game.roomy != 107 || map.custommode)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
obj.entities[i].state = 4;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
obj.entities[i].state = 4;
|
|
|
|
map.settile(18, 9, 59);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (obj.entities[i].type == 2 && obj.entities[i].state == 2)
|
|
|
|
{
|
|
|
|
//ok, unfortunate case where the disappearing platform hasn't fully disappeared. Accept a little
|
|
|
|
//graphical uglyness to avoid breaking the room!
|
Prevent updating an entity if updateentities() removed it
Otherwise, this would result in the game updating an entity twice, which
isn't good. This is most noticeable in the Gravitron, where many
Gravitron squares are created and destroyed at a time, and it's
especially noticeable during the part near the end of the Gravitron
where the pattern is two Gravitron squares, one at the top and bottom,
and then two Gravitron squares in the middle afterwards. The timing is
just right such that the top one of the two middle ones would be
misaligned with the bottom one of the two when a Gravitron square gets
outside the screen.
To do this, I changed entityclass::updateentities() into a bool, and
made every single caller check its return value. I only needed to do
this for the ones preceding updateentitylogic() and
entitymapcollision(), but I wanted to play it safe and be defensive, so
I did it for the disappearing platform kludge, as well as the
updateentities() within the updateentities() function.
2020-05-05 22:49:12 +02:00
|
|
|
bool entitygone = false;
|
|
|
|
while (obj.entities[i].state == 2)
|
|
|
|
{
|
|
|
|
entitygone = obj.updateentities(i);
|
|
|
|
if (entitygone)
|
|
|
|
{
|
|
|
|
i--;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!entitygone) obj.entities[i].state = 4;
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
else if (map.finalstretch && obj.entities[i].type == 2)
|
|
|
|
{
|
|
|
|
//for the final level. probably something 99% of players won't see.
|
Prevent updating an entity if updateentities() removed it
Otherwise, this would result in the game updating an entity twice, which
isn't good. This is most noticeable in the Gravitron, where many
Gravitron squares are created and destroyed at a time, and it's
especially noticeable during the part near the end of the Gravitron
where the pattern is two Gravitron squares, one at the top and bottom,
and then two Gravitron squares in the middle afterwards. The timing is
just right such that the top one of the two middle ones would be
misaligned with the bottom one of the two when a Gravitron square gets
outside the screen.
To do this, I changed entityclass::updateentities() into a bool, and
made every single caller check its return value. I only needed to do
this for the ones preceding updateentitylogic() and
entitymapcollision(), but I wanted to play it safe and be defensive, so
I did it for the disappearing platform kludge, as well as the
updateentities() within the updateentities() function.
2020-05-05 22:49:12 +02:00
|
|
|
bool entitygone = false;
|
|
|
|
while (obj.entities[i].state == 2)
|
|
|
|
{
|
|
|
|
entitygone = obj.updateentities(i);
|
|
|
|
if (entitygone)
|
|
|
|
{
|
|
|
|
i--;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!entitygone) obj.entities[i].state = 4;
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
else if (obj.entities[i].type == 23 && game.swnmode && game.deathseq<15)
|
|
|
|
{
|
|
|
|
//if playing SWN, get the enemies offscreen.
|
|
|
|
obj.entities[i].xp += obj.entities[i].vx*5;
|
|
|
|
obj.entities[i].yp += obj.entities[i].vy*5;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (game.swnmode)
|
|
|
|
{
|
|
|
|
//if playing SWN game a, push the clock back to the nearest 10 second interval
|
|
|
|
if (game.swngame == 0)
|
|
|
|
{
|
|
|
|
game.swnpenalty();
|
|
|
|
}
|
|
|
|
else if (game.swngame == 1)
|
|
|
|
{
|
|
|
|
game.swnstate = 0;
|
|
|
|
game.swnstate2 = 0;
|
|
|
|
game.swnstate3 = 0;
|
|
|
|
game.swnstate4 = 0;
|
|
|
|
game.swndelay = 0;
|
|
|
|
if (game.swntimer >= game.swnrecord)
|
|
|
|
{
|
2020-04-02 01:36:35 +02:00
|
|
|
if (game.swnmessage == 0) music.playef(25);
|
2020-01-01 21:29:24 +01:00
|
|
|
game.swnmessage = 1;
|
|
|
|
game.swnrecord = game.swntimer;
|
2020-05-09 20:53:41 +02:00
|
|
|
game.savestats();
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-31 02:16:02 +02:00
|
|
|
game.deathsequence();
|
2020-01-01 21:29:24 +01:00
|
|
|
game.deathseq--;
|
|
|
|
if (game.deathseq <= 0)
|
|
|
|
{
|
|
|
|
if (game.nodeathmode)
|
|
|
|
{
|
|
|
|
game.deathseq = 1;
|
2020-03-31 02:16:02 +02:00
|
|
|
game.gethardestroom();
|
2020-01-01 21:29:24 +01:00
|
|
|
//start depressing sequence here...
|
2020-04-01 23:48:11 +02:00
|
|
|
if (game.gameoverdelay <= -10 && graphics.fademode==0) graphics.fademode = 2;
|
|
|
|
if (graphics.fademode == 1) script.resetgametomenu();
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (game.swnmode)
|
|
|
|
{
|
|
|
|
//if playing SWN game b, reset the clock
|
|
|
|
if (game.swngame == 1)
|
|
|
|
{
|
|
|
|
game.swntimer = 0;
|
|
|
|
game.swnmessage = 0;
|
|
|
|
game.swnrank = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-31 02:16:02 +02:00
|
|
|
game.gethardestroom();
|
2020-01-01 21:29:24 +01:00
|
|
|
game.hascontrol = true;
|
|
|
|
|
|
|
|
|
|
|
|
game.gravitycontrol = game.savegc;
|
2020-04-01 23:48:11 +02:00
|
|
|
graphics.textboxremove();
|
2020-03-31 10:09:42 +02:00
|
|
|
map.resetplayer();
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
//Update colour thingy
|
|
|
|
if (map.finalmode)
|
|
|
|
{
|
|
|
|
if (map.final_colormode)
|
|
|
|
{
|
|
|
|
if (map.final_colorframe > 0)
|
|
|
|
{
|
|
|
|
map.final_colorframedelay--;
|
|
|
|
if (map.final_colorframedelay <= 0)
|
|
|
|
{
|
|
|
|
if (map.final_colorframe == 1)
|
|
|
|
{
|
|
|
|
map.final_colorframedelay = 40;
|
2020-04-03 03:50:37 +02:00
|
|
|
int temp = 1+int(fRandom() * 6);
|
2020-01-01 21:29:24 +01:00
|
|
|
if (temp == map.final_mapcol) temp = (temp + 1) % 6;
|
|
|
|
if (temp == 0) temp = 6;
|
2020-03-31 10:09:42 +02:00
|
|
|
map.changefinalcol(temp);
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
else if (map.final_colorframe == 2)
|
|
|
|
{
|
|
|
|
map.final_colorframedelay = 15;
|
2020-04-03 03:50:37 +02:00
|
|
|
int temp = 1+int(fRandom() * 6);
|
2020-01-01 21:29:24 +01:00
|
|
|
if (temp == map.final_mapcol) temp = (temp + 1) % 6;
|
|
|
|
if (temp == 0) temp = 6;
|
2020-03-31 10:09:42 +02:00
|
|
|
map.changefinalcol(temp);
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//State machine for game logic
|
2020-03-31 02:16:02 +02:00
|
|
|
game.updatestate();
|
2020-01-01 21:29:24 +01:00
|
|
|
if (game.startscript)
|
|
|
|
{
|
|
|
|
script.load(game.newscript);
|
|
|
|
game.startscript = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
//Intermission 1 Logic
|
|
|
|
//Player can't walk off a screen with SCM on it until they've left
|
|
|
|
if (game.supercrewmate)
|
|
|
|
{
|
|
|
|
if (game.roomx == 41 + game.scmprogress) //he's in the same room
|
|
|
|
{
|
|
|
|
int i = obj.getplayer();
|
2020-06-13 05:36:08 +02:00
|
|
|
if (i > -1 && obj.entities[i].ax > 0 && obj.entities[i].xp > 280)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
obj.entities[i].ax = 0;
|
|
|
|
obj.entities[i].dir = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//SWN Minigame Logic
|
|
|
|
if (game.swnmode) //which game?
|
|
|
|
{
|
|
|
|
if(game.swngame==0) //intermission, survive 60 seconds game
|
|
|
|
{
|
|
|
|
game.swntimer -= 1;
|
|
|
|
if (game.swntimer <= 0)
|
|
|
|
{
|
|
|
|
music.niceplay(8);
|
|
|
|
game.swngame = 5;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-03-31 02:46:36 +02:00
|
|
|
obj.generateswnwave(0);
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(game.swngame==1) //super gravitron game
|
|
|
|
{
|
|
|
|
game.swntimer += 1;
|
|
|
|
if (game.swntimer > game.swnrecord) game.swnrecord = game.swntimer;
|
|
|
|
|
|
|
|
if (game.swntimer >= 150 && game.swnrank == 0)
|
|
|
|
{
|
|
|
|
game.swnrank = 1;
|
|
|
|
if (game.swnbestrank < 1)
|
|
|
|
{
|
2020-04-02 22:44:45 +02:00
|
|
|
NETWORK_unlockAchievement("vvvvvvsupgrav5");
|
2020-01-01 21:29:24 +01:00
|
|
|
game.swnbestrank = 1;
|
|
|
|
game.swnmessage = 2+30;
|
2020-04-02 01:36:35 +02:00
|
|
|
music.playef(26);
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (game.swntimer >= 300 && game.swnrank == 1)
|
|
|
|
{
|
|
|
|
game.swnrank = 2;
|
|
|
|
if (game.swnbestrank < 2)
|
|
|
|
{
|
2020-04-02 22:44:45 +02:00
|
|
|
NETWORK_unlockAchievement("vvvvvvsupgrav10");
|
2020-01-01 21:29:24 +01:00
|
|
|
game.swnbestrank = 2;
|
|
|
|
game.swnmessage = 2+30;
|
2020-04-02 01:36:35 +02:00
|
|
|
music.playef(26);
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (game.swntimer >= 450 && game.swnrank == 2)
|
|
|
|
{
|
|
|
|
game.swnrank = 3;
|
|
|
|
if (game.swnbestrank < 3)
|
|
|
|
{
|
2020-04-02 22:44:45 +02:00
|
|
|
NETWORK_unlockAchievement("vvvvvvsupgrav15");
|
2020-01-01 21:29:24 +01:00
|
|
|
game.swnbestrank = 3;
|
|
|
|
game.swnmessage = 2+30;
|
2020-04-02 01:36:35 +02:00
|
|
|
music.playef(26);
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (game.swntimer >= 600 && game.swnrank == 3)
|
|
|
|
{
|
|
|
|
game.swnrank = 4;
|
|
|
|
if (game.swnbestrank < 4)
|
|
|
|
{
|
2020-04-02 22:44:45 +02:00
|
|
|
NETWORK_unlockAchievement("vvvvvvsupgrav20");
|
2020-01-01 21:29:24 +01:00
|
|
|
game.swnbestrank = 4;
|
|
|
|
game.swnmessage = 2+30;
|
2020-04-02 01:36:35 +02:00
|
|
|
music.playef(26);
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (game.swntimer >= 900 && game.swnrank == 4)
|
|
|
|
{
|
|
|
|
game.swnrank = 5;
|
|
|
|
if (game.swnbestrank < 5)
|
|
|
|
{
|
2020-04-02 22:44:45 +02:00
|
|
|
NETWORK_unlockAchievement("vvvvvvsupgrav30");
|
2020-01-01 21:29:24 +01:00
|
|
|
game.swnbestrank = 5;
|
|
|
|
game.swnmessage = 2+30;
|
2020-04-02 01:36:35 +02:00
|
|
|
music.playef(26);
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (game.swntimer >= 1800 && game.swnrank == 5)
|
|
|
|
{
|
|
|
|
game.swnrank = 6;
|
|
|
|
if (game.swnbestrank < 6)
|
|
|
|
{
|
2020-04-02 22:44:45 +02:00
|
|
|
NETWORK_unlockAchievement("vvvvvvsupgrav60");
|
2020-01-01 21:29:24 +01:00
|
|
|
game.swnbestrank = 6;
|
|
|
|
game.swnmessage = 2+30;
|
2020-04-02 01:36:35 +02:00
|
|
|
music.playef(26);
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-31 02:46:36 +02:00
|
|
|
obj.generateswnwave(1);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
|
|
|
game.swncoldelay--;
|
|
|
|
if(game.swncoldelay<=0)
|
|
|
|
{
|
|
|
|
game.swncolstate = (game.swncolstate+1)%6;
|
|
|
|
game.swncoldelay = 30;
|
2020-04-01 23:48:11 +02:00
|
|
|
graphics.rcol = game.swncolstate;
|
2020-01-01 21:29:24 +01:00
|
|
|
obj.swnenemiescol(game.swncolstate);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (game.swngame == 2) //introduce game a
|
|
|
|
{
|
|
|
|
game.swndelay--;
|
|
|
|
if (game.swndelay <= 0)
|
|
|
|
{
|
|
|
|
game.swngame = 0;
|
|
|
|
game.swndelay = 0;
|
|
|
|
game.swntimer = (60 * 30) - 1;
|
|
|
|
//game.swntimer = 15;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (game.swngame == 3) //extend line
|
|
|
|
{
|
|
|
|
obj.entities[obj.getlineat(84 - 32)].w += 24;
|
|
|
|
if (obj.entities[obj.getlineat(84 - 32)].w > 332)
|
|
|
|
{
|
|
|
|
obj.entities[obj.getlineat(84 - 32)].w = 332;
|
|
|
|
game.swngame = 2;
|
2020-05-02 21:06:40 +02:00
|
|
|
graphics.kludgeswnlinewidth = true;
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (game.swngame == 4) //create top line
|
|
|
|
{
|
|
|
|
game.swngame = 3;
|
2020-03-31 02:46:36 +02:00
|
|
|
obj.createentity(-8, 84 - 32, 11, 8); // (horizontal gravity line)
|
2020-01-01 21:29:24 +01:00
|
|
|
music.niceplay(2);
|
|
|
|
game.swndeaths = game.deathcounts;
|
|
|
|
}
|
|
|
|
else if (game.swngame == 5) //remove line
|
|
|
|
{
|
|
|
|
obj.entities[obj.getlineat(148 + 32)].xp += 24;
|
|
|
|
if (obj.entities[obj.getlineat(148 + 32)].xp > 320)
|
|
|
|
{
|
2020-04-03 22:50:16 +02:00
|
|
|
obj.removeentity(obj.getlineat(148 + 32));
|
2020-01-01 21:29:24 +01:00
|
|
|
game.swnmode = false;
|
|
|
|
game.swngame = 6;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (game.swngame == 6) //Init the super gravitron
|
|
|
|
{
|
|
|
|
game.swngame = 7;
|
|
|
|
music.niceplay(3);
|
|
|
|
}
|
|
|
|
else if (game.swngame == 7) //introduce game b
|
|
|
|
{
|
|
|
|
game.swndelay--;
|
|
|
|
if (game.swndelay <= 0)
|
|
|
|
{
|
|
|
|
game.swngame = 1;
|
|
|
|
game.swndelay = 0;
|
|
|
|
game.swntimer = 0;
|
|
|
|
game.swncolstate = 3;
|
|
|
|
game.swncoldelay = 30;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//Time trial stuff
|
|
|
|
if (game.intimetrial)
|
|
|
|
{
|
|
|
|
|
|
|
|
if (game.timetrialcountdown > 0)
|
|
|
|
{
|
|
|
|
game.timetrialparlost = false;
|
|
|
|
game.hascontrol = true;
|
|
|
|
game.timetrialcountdown--;
|
|
|
|
if (game.timetrialcountdown > 30)
|
|
|
|
{
|
|
|
|
game.hascontrol = false;
|
|
|
|
}
|
2020-04-02 01:36:35 +02:00
|
|
|
if(game.timetrialcountdown == 120) music.playef(21);
|
|
|
|
if(game.timetrialcountdown == 90) music.playef(21);
|
|
|
|
if(game.timetrialcountdown == 60) music.playef(21);
|
2020-01-01 21:29:24 +01:00
|
|
|
if (game.timetrialcountdown == 30)
|
|
|
|
{
|
|
|
|
switch(game.timetriallevel)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
music.play(1);
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
music.play(3);
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
music.play(2);
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
music.play(1);
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
music.play(12);
|
|
|
|
break;
|
|
|
|
case 5:
|
|
|
|
music.play(15);
|
|
|
|
break;
|
|
|
|
}
|
2020-04-02 01:36:35 +02:00
|
|
|
music.playef(22);
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//Have we lost the par?
|
|
|
|
if (!game.timetrialparlost)
|
|
|
|
{
|
|
|
|
if ((game.minutes * 60) + game.seconds > game.timetrialpar)
|
|
|
|
{
|
|
|
|
game.timetrialparlost = true;
|
|
|
|
int i = obj.getplayer();
|
|
|
|
if (i > -1)
|
|
|
|
{
|
|
|
|
obj.entities[i].tile = 144;
|
|
|
|
}
|
2020-04-02 01:36:35 +02:00
|
|
|
music.playef(2);
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//Update entities
|
|
|
|
//Ok, moving platform fuckers
|
|
|
|
if(!game.completestop)
|
|
|
|
{
|
|
|
|
if(obj.vertplatforms)
|
|
|
|
{
|
2020-04-03 22:50:16 +02:00
|
|
|
for (int i = obj.entities.size() - 1; i >= 0; i--)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
if (obj.entities[i].isplatform)
|
|
|
|
{
|
|
|
|
if(abs(obj.entities[i].vx) < 0.000001f)
|
|
|
|
{
|
|
|
|
obj.removeblockat(obj.entities[i].xp, obj.entities[i].yp);
|
|
|
|
|
Prevent updating an entity if updateentities() removed it
Otherwise, this would result in the game updating an entity twice, which
isn't good. This is most noticeable in the Gravitron, where many
Gravitron squares are created and destroyed at a time, and it's
especially noticeable during the part near the end of the Gravitron
where the pattern is two Gravitron squares, one at the top and bottom,
and then two Gravitron squares in the middle afterwards. The timing is
just right such that the top one of the two middle ones would be
misaligned with the bottom one of the two when a Gravitron square gets
outside the screen.
To do this, I changed entityclass::updateentities() into a bool, and
made every single caller check its return value. I only needed to do
this for the ones preceding updateentitylogic() and
entitymapcollision(), but I wanted to play it safe and be defensive, so
I did it for the disappearing platform kludge, as well as the
updateentities() within the updateentities() function.
2020-05-05 22:49:12 +02:00
|
|
|
bool entitygone = obj.updateentities(i); // Behavioral logic
|
|
|
|
if (entitygone) continue;
|
2020-04-03 02:53:34 +02:00
|
|
|
obj.updateentitylogic(i); // Basic Physics
|
|
|
|
obj.entitymapcollision(i); // Collisions with walls
|
2020-01-01 21:29:24 +01:00
|
|
|
|
|
|
|
obj.createblock(0, obj.entities[i].xp, obj.entities[i].yp, obj.entities[i].w, obj.entities[i].h);
|
|
|
|
if (game.supercrewmate)
|
|
|
|
{
|
2020-03-31 02:46:36 +02:00
|
|
|
obj.movingplatformfix(i);
|
|
|
|
obj.scmmovingplatformfix(i);
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-03-31 02:46:36 +02:00
|
|
|
obj.movingplatformfix(i);
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(obj.horplatforms)
|
|
|
|
{
|
2020-04-03 22:50:16 +02:00
|
|
|
for (int ie = obj.entities.size() - 1; ie >= 0; ie--)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
if (obj.entities[ie].isplatform)
|
|
|
|
{
|
|
|
|
if(abs(obj.entities[ie].vy) < 0.000001f)
|
|
|
|
{
|
|
|
|
obj.removeblockat(obj.entities[ie].xp, obj.entities[ie].yp);
|
|
|
|
|
Prevent updating an entity if updateentities() removed it
Otherwise, this would result in the game updating an entity twice, which
isn't good. This is most noticeable in the Gravitron, where many
Gravitron squares are created and destroyed at a time, and it's
especially noticeable during the part near the end of the Gravitron
where the pattern is two Gravitron squares, one at the top and bottom,
and then two Gravitron squares in the middle afterwards. The timing is
just right such that the top one of the two middle ones would be
misaligned with the bottom one of the two when a Gravitron square gets
outside the screen.
To do this, I changed entityclass::updateentities() into a bool, and
made every single caller check its return value. I only needed to do
this for the ones preceding updateentitylogic() and
entitymapcollision(), but I wanted to play it safe and be defensive, so
I did it for the disappearing platform kludge, as well as the
updateentities() within the updateentities() function.
2020-05-05 22:49:12 +02:00
|
|
|
bool entitygone = obj.updateentities(ie); // Behavioral logic
|
|
|
|
if (entitygone) continue;
|
2020-04-03 02:53:34 +02:00
|
|
|
obj.updateentitylogic(ie); // Basic Physics
|
|
|
|
obj.entitymapcollision(ie); // Collisions with walls
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2020-03-31 02:46:36 +02:00
|
|
|
obj.hormovingplatformfix(ie);
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//is the player standing on a moving platform?
|
|
|
|
int i = obj.getplayer();
|
2020-03-31 02:46:36 +02:00
|
|
|
float j = obj.entitycollideplatformfloor(i);
|
2020-06-13 05:36:08 +02:00
|
|
|
if (i > -1 && j > -1000)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
obj.entities[i].newxp = obj.entities[i].xp + j;
|
2020-03-31 02:46:36 +02:00
|
|
|
obj.entitymapcollision(i);
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-03-31 02:46:36 +02:00
|
|
|
j = obj.entitycollideplatformroof(i);
|
2020-06-13 05:36:08 +02:00
|
|
|
if (i > -1 && j > -1000)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
obj.entities[i].newxp = obj.entities[i].xp + j;
|
2020-03-31 02:46:36 +02:00
|
|
|
obj.entitymapcollision(i);
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-03 22:50:16 +02:00
|
|
|
for (int ie = obj.entities.size() - 1; ie >= 0; ie--)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
if (!obj.entities[ie].isplatform)
|
|
|
|
{
|
Prevent updating an entity if updateentities() removed it
Otherwise, this would result in the game updating an entity twice, which
isn't good. This is most noticeable in the Gravitron, where many
Gravitron squares are created and destroyed at a time, and it's
especially noticeable during the part near the end of the Gravitron
where the pattern is two Gravitron squares, one at the top and bottom,
and then two Gravitron squares in the middle afterwards. The timing is
just right such that the top one of the two middle ones would be
misaligned with the bottom one of the two when a Gravitron square gets
outside the screen.
To do this, I changed entityclass::updateentities() into a bool, and
made every single caller check its return value. I only needed to do
this for the ones preceding updateentitylogic() and
entitymapcollision(), but I wanted to play it safe and be defensive, so
I did it for the disappearing platform kludge, as well as the
updateentities() within the updateentities() function.
2020-05-05 22:49:12 +02:00
|
|
|
bool entitygone = obj.updateentities(ie); // Behavioral logic
|
|
|
|
if (entitygone) continue;
|
2020-04-03 02:53:34 +02:00
|
|
|
obj.updateentitylogic(ie); // Basic Physics
|
|
|
|
obj.entitymapcollision(ie); // Collisions with walls
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-31 02:46:36 +02:00
|
|
|
obj.entitycollisioncheck(); // Check ent v ent collisions, update states
|
2020-04-25 06:19:41 +02:00
|
|
|
|
|
|
|
if (map.towermode)
|
|
|
|
{
|
|
|
|
//special for tower: is the player touching any spike blocks?
|
|
|
|
int player = obj.getplayer();
|
2020-06-13 05:36:08 +02:00
|
|
|
if(player > -1 && obj.checktowerspikes(player) && graphics.fademode==0)
|
2020-04-25 06:19:41 +02:00
|
|
|
{
|
|
|
|
game.deathseq = 30;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(map.towermode && game.lifeseq==0)
|
|
|
|
{
|
|
|
|
int player = obj.getplayer();
|
2020-06-13 05:36:08 +02:00
|
|
|
if(!map.invincibility && player > -1)
|
2020-04-25 06:19:41 +02:00
|
|
|
{
|
|
|
|
if (obj.entities[player].yp-map.ypos <= 0)
|
|
|
|
{
|
|
|
|
game.deathseq = 30;
|
|
|
|
}
|
|
|
|
else if (obj.entities[player].yp-map.ypos >= 208)
|
|
|
|
{
|
|
|
|
game.deathseq = 30;
|
|
|
|
}
|
|
|
|
}
|
2020-06-13 05:36:08 +02:00
|
|
|
else if (player > -1)
|
2020-04-25 06:19:41 +02:00
|
|
|
{
|
|
|
|
if (obj.entities[player].yp-map.ypos <= 0)
|
|
|
|
{
|
|
|
|
map.ypos-=10;
|
|
|
|
map.bypos = map.ypos / 2;
|
|
|
|
map.bscroll = 0;
|
|
|
|
}
|
|
|
|
else if (obj.entities[player].yp-map.ypos >= 208)
|
|
|
|
{
|
|
|
|
map.ypos+=2;
|
|
|
|
map.bypos = map.ypos / 2;
|
|
|
|
map.bscroll = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-13 05:36:08 +02:00
|
|
|
if (player > -1 && obj.entities[player].yp - map.ypos <= 40)
|
2020-04-25 06:19:41 +02:00
|
|
|
{
|
|
|
|
map.spikeleveltop++;
|
|
|
|
if (map.spikeleveltop >= 8) map.spikeleveltop = 8;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (map.spikeleveltop > 0) map.spikeleveltop--;
|
|
|
|
}
|
|
|
|
|
2020-06-13 05:36:08 +02:00
|
|
|
if (player > -1 && obj.entities[player].yp - map.ypos >= 164)
|
2020-04-25 06:19:41 +02:00
|
|
|
{
|
|
|
|
map.spikelevelbottom++;
|
|
|
|
if (map.spikelevelbottom >= 8) map.spikelevelbottom = 8;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (map.spikelevelbottom > 0) map.spikelevelbottom--;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//Using warplines?
|
2020-04-02 22:44:45 +02:00
|
|
|
if (obj.customwarpmode) {
|
|
|
|
//Rewritten system for mobile update: basically, the new logic is to
|
|
|
|
//check if the player is leaving the map, and if so do a special check against
|
|
|
|
//warp lines for collision
|
|
|
|
obj.customwarpmodehon = false;
|
|
|
|
obj.customwarpmodevon = false;
|
|
|
|
|
|
|
|
int i = obj.getplayer();
|
2020-06-13 05:36:08 +02:00
|
|
|
if (i > -1 && ((game.door_down > -2 && obj.entities[i].yp >= 226-16) || (game.door_up > -2 && obj.entities[i].yp < -2+16) || (game.door_left > -2 && obj.entities[i].xp < -14+16) || (game.door_right > -2 && obj.entities[i].xp >= 308-16))){
|
2020-04-02 22:44:45 +02:00
|
|
|
//Player is leaving room
|
|
|
|
obj.customwarplinecheck(i);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(obj.customwarpmodehon){ map.warpy=true;
|
|
|
|
}else{ map.warpy=false; }
|
|
|
|
if(obj.customwarpmodevon){ map.warpx=true;
|
|
|
|
}else{ map.warpx=false; }
|
|
|
|
}
|
2020-01-01 21:29:24 +01:00
|
|
|
|
|
|
|
//Finally: Are we changing room?
|
2020-04-25 06:19:41 +02:00
|
|
|
if (map.warpx && !map.towermode)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-04-03 22:50:16 +02:00
|
|
|
for (size_t i = 0; i < obj.entities.size(); i++)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-04-04 21:16:16 +02:00
|
|
|
if(obj.entities[i].type<50 //Don't warp warp lines
|
|
|
|
&& obj.entities[i].size < 12) //Don't wrap SWN enemies
|
|
|
|
{
|
|
|
|
if (game.roomx == 118 && game.roomy == 102 && obj.entities[i].rule==1 && !map.custommode)
|
2020-04-04 21:13:24 +02:00
|
|
|
{
|
2020-04-04 21:16:16 +02:00
|
|
|
//ascii snakes
|
|
|
|
if (obj.entities[i].xp <= -80)
|
2020-04-04 21:13:24 +02:00
|
|
|
{
|
2020-04-04 21:54:55 +02:00
|
|
|
if (obj.entities[i].isplatform) obj.removeblockat(obj.entities[i].xp, obj.entities[i].yp);
|
2020-04-04 21:16:16 +02:00
|
|
|
obj.entities[i].xp += 400;
|
2020-05-02 02:40:14 +02:00
|
|
|
obj.entities[i].oldxp += 400;
|
2020-04-04 21:13:24 +02:00
|
|
|
}
|
2020-04-04 21:19:18 +02:00
|
|
|
else if (obj.entities[i].xp > 320)
|
2020-04-04 21:13:24 +02:00
|
|
|
{
|
2020-04-04 21:54:55 +02:00
|
|
|
if (obj.entities[i].isplatform) obj.removeblockat(obj.entities[i].xp, obj.entities[i].yp);
|
2020-04-04 21:19:18 +02:00
|
|
|
obj.entities[i].xp -= 400;
|
2020-05-02 02:40:14 +02:00
|
|
|
obj.entities[i].oldxp -= 400;
|
2020-04-04 21:16:16 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (obj.entities[i].xp <= -10)
|
|
|
|
{
|
2020-04-04 21:54:55 +02:00
|
|
|
if (obj.entities[i].isplatform) obj.removeblockat(obj.entities[i].xp, obj.entities[i].yp);
|
2020-04-04 21:16:16 +02:00
|
|
|
obj.entities[i].xp += 320;
|
2020-04-29 01:44:31 +02:00
|
|
|
obj.entities[i].oldxp += 320;
|
2020-04-04 21:16:16 +02:00
|
|
|
}
|
2020-04-04 21:19:18 +02:00
|
|
|
else if (obj.entities[i].xp > 310)
|
2020-04-04 21:16:16 +02:00
|
|
|
{
|
2020-04-04 21:54:55 +02:00
|
|
|
if (obj.entities[i].isplatform) obj.removeblockat(obj.entities[i].xp, obj.entities[i].yp);
|
2020-04-04 21:19:18 +02:00
|
|
|
obj.entities[i].xp -= 320;
|
2020-04-29 01:44:31 +02:00
|
|
|
obj.entities[i].oldxp -= 320;
|
2020-04-04 21:13:24 +02:00
|
|
|
}
|
|
|
|
}
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
De-dupe screen transition / warping logic
I noticed that the code for going to the adjacent room when offscreen
and for warping instead if the room is warping was a bit
copy-and-pasted. To clean up the code a bit, there's now 5 separate
checks in gamelogic():
if (map.warpx)
if (map.warpy)
if (map.warpy && !map.warpx)
if (!map.warpy)
if (!map.warpx)
I made sure to preserve the previous weird horizontal warping behavior
that happens with vertical warping (thus the middle one), and to
preserve the frame ordering just in case there's something dependent on
the frame ordering.
The frame ordering is that first it will warp you horizontally, if
applicable, then it will warp you vertically, if applicable. Then if you
have vertical warping only, that weird horizontal warp. Then it will
screen transition you vertically, if applicable. Then it will screen
transition you horizontally, if applicable.
To explain the weird horizontal warp with the vertical warp: apparently
if an entity is far offscreen enough, and if that entity is not the
player, it will be warped horizontally during a vertical warp. The
points at which it will warp is 30 pixels farther out than normal
horizontal warping.
I think someone ran into this before, but my memory is fuzzy. The best I
can recall is that they were probably createentity()ing a high-speed
horizontally-moving enemy in a vertically warping room, only to discover
that said enemy kept warping horizontally.
2020-04-04 21:39:17 +02:00
|
|
|
|
2020-04-25 06:19:41 +02:00
|
|
|
if (map.warpy && !map.towermode)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-04-03 22:50:16 +02:00
|
|
|
for (size_t i = 0; i < obj.entities.size(); i++)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
if(obj.entities[i].type<50){ //Don't warp warp lines
|
2020-04-04 21:13:24 +02:00
|
|
|
if (obj.entities[i].yp <= -12)
|
|
|
|
{
|
2020-04-04 21:54:55 +02:00
|
|
|
if (obj.entities[i].isplatform) obj.removeblockat(obj.entities[i].xp, obj.entities[i].yp);
|
2020-04-04 21:13:24 +02:00
|
|
|
obj.entities[i].yp += 232;
|
2020-04-29 01:44:31 +02:00
|
|
|
obj.entities[i].oldyp += 232;
|
2020-04-04 21:13:24 +02:00
|
|
|
}
|
2020-04-04 21:19:18 +02:00
|
|
|
else if (obj.entities[i].yp > 226)
|
2020-04-04 21:13:24 +02:00
|
|
|
{
|
2020-04-04 21:54:55 +02:00
|
|
|
if (obj.entities[i].isplatform) obj.removeblockat(obj.entities[i].xp, obj.entities[i].yp);
|
2020-04-04 21:19:18 +02:00
|
|
|
obj.entities[i].yp -= 232;
|
2020-04-29 01:44:31 +02:00
|
|
|
obj.entities[i].oldyp -= 232;
|
2020-04-04 21:13:24 +02:00
|
|
|
}
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
}
|
De-dupe screen transition / warping logic
I noticed that the code for going to the adjacent room when offscreen
and for warping instead if the room is warping was a bit
copy-and-pasted. To clean up the code a bit, there's now 5 separate
checks in gamelogic():
if (map.warpx)
if (map.warpy)
if (map.warpy && !map.warpx)
if (!map.warpy)
if (!map.warpx)
I made sure to preserve the previous weird horizontal warping behavior
that happens with vertical warping (thus the middle one), and to
preserve the frame ordering just in case there's something dependent on
the frame ordering.
The frame ordering is that first it will warp you horizontally, if
applicable, then it will warp you vertically, if applicable. Then if you
have vertical warping only, that weird horizontal warp. Then it will
screen transition you vertically, if applicable. Then it will screen
transition you horizontally, if applicable.
To explain the weird horizontal warp with the vertical warp: apparently
if an entity is far offscreen enough, and if that entity is not the
player, it will be warped horizontally during a vertical warp. The
points at which it will warp is 30 pixels farther out than normal
horizontal warping.
I think someone ran into this before, but my memory is fuzzy. The best I
can recall is that they were probably createentity()ing a high-speed
horizontally-moving enemy in a vertically warping room, only to discover
that said enemy kept warping horizontally.
2020-04-04 21:39:17 +02:00
|
|
|
}
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2020-04-25 06:19:41 +02:00
|
|
|
if (map.warpy && !map.warpx && !map.towermode)
|
De-dupe screen transition / warping logic
I noticed that the code for going to the adjacent room when offscreen
and for warping instead if the room is warping was a bit
copy-and-pasted. To clean up the code a bit, there's now 5 separate
checks in gamelogic():
if (map.warpx)
if (map.warpy)
if (map.warpy && !map.warpx)
if (!map.warpy)
if (!map.warpx)
I made sure to preserve the previous weird horizontal warping behavior
that happens with vertical warping (thus the middle one), and to
preserve the frame ordering just in case there's something dependent on
the frame ordering.
The frame ordering is that first it will warp you horizontally, if
applicable, then it will warp you vertically, if applicable. Then if you
have vertical warping only, that weird horizontal warp. Then it will
screen transition you vertically, if applicable. Then it will screen
transition you horizontally, if applicable.
To explain the weird horizontal warp with the vertical warp: apparently
if an entity is far offscreen enough, and if that entity is not the
player, it will be warped horizontally during a vertical warp. The
points at which it will warp is 30 pixels farther out than normal
horizontal warping.
I think someone ran into this before, but my memory is fuzzy. The best I
can recall is that they were probably createentity()ing a high-speed
horizontally-moving enemy in a vertically warping room, only to discover
that said enemy kept warping horizontally.
2020-04-04 21:39:17 +02:00
|
|
|
{
|
2020-04-03 22:50:16 +02:00
|
|
|
for (size_t i = 0; i < obj.entities.size(); i++)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
|
2020-04-04 21:16:16 +02:00
|
|
|
if(obj.entities[i].type<50 //Don't warp warp lines
|
|
|
|
&&obj.entities[i].rule!=0)
|
|
|
|
{
|
|
|
|
if (obj.entities[i].xp <= -30)
|
2020-04-04 21:13:24 +02:00
|
|
|
{
|
2020-04-04 21:54:55 +02:00
|
|
|
if (obj.entities[i].isplatform) obj.removeblockat(obj.entities[i].xp, obj.entities[i].yp);
|
2020-04-04 21:16:16 +02:00
|
|
|
obj.entities[i].xp += 350;
|
2020-04-29 01:44:31 +02:00
|
|
|
obj.entities[i].oldxp += 350;
|
2020-04-04 21:16:16 +02:00
|
|
|
}
|
2020-04-04 21:19:18 +02:00
|
|
|
else if (obj.entities[i].xp > 320)
|
2020-04-04 21:16:16 +02:00
|
|
|
{
|
2020-04-04 21:54:55 +02:00
|
|
|
if (obj.entities[i].isplatform) obj.removeblockat(obj.entities[i].xp, obj.entities[i].yp);
|
2020-04-04 21:19:18 +02:00
|
|
|
obj.entities[i].xp -= 350;
|
2020-04-29 01:44:31 +02:00
|
|
|
obj.entities[i].oldxp -= 350;
|
2020-04-04 21:13:24 +02:00
|
|
|
}
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
De-dupe screen transition / warping logic
I noticed that the code for going to the adjacent room when offscreen
and for warping instead if the room is warping was a bit
copy-and-pasted. To clean up the code a bit, there's now 5 separate
checks in gamelogic():
if (map.warpx)
if (map.warpy)
if (map.warpy && !map.warpx)
if (!map.warpy)
if (!map.warpx)
I made sure to preserve the previous weird horizontal warping behavior
that happens with vertical warping (thus the middle one), and to
preserve the frame ordering just in case there's something dependent on
the frame ordering.
The frame ordering is that first it will warp you horizontally, if
applicable, then it will warp you vertically, if applicable. Then if you
have vertical warping only, that weird horizontal warp. Then it will
screen transition you vertically, if applicable. Then it will screen
transition you horizontally, if applicable.
To explain the weird horizontal warp with the vertical warp: apparently
if an entity is far offscreen enough, and if that entity is not the
player, it will be warped horizontally during a vertical warp. The
points at which it will warp is 30 pixels farther out than normal
horizontal warping.
I think someone ran into this before, but my memory is fuzzy. The best I
can recall is that they were probably createentity()ing a high-speed
horizontally-moving enemy in a vertically warping room, only to discover
that said enemy kept warping horizontally.
2020-04-04 21:39:17 +02:00
|
|
|
|
2020-04-25 06:19:41 +02:00
|
|
|
if (!map.warpy && !map.towermode)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
//Normal! Just change room
|
|
|
|
int player = obj.getplayer();
|
2020-06-13 05:36:08 +02:00
|
|
|
if (player > -1 && game.door_down > -2 && obj.entities[player].yp >= 238)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
obj.entities[player].yp -= 240;
|
2020-03-31 10:09:42 +02:00
|
|
|
map.gotoroom(game.roomx, game.roomy + 1);
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
2020-06-13 05:36:08 +02:00
|
|
|
if (player > -1 && game.door_up > -2 && obj.entities[player].yp < -2)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
obj.entities[player].yp += 240;
|
2020-03-31 10:09:42 +02:00
|
|
|
map.gotoroom(game.roomx, game.roomy - 1);
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
De-dupe screen transition / warping logic
I noticed that the code for going to the adjacent room when offscreen
and for warping instead if the room is warping was a bit
copy-and-pasted. To clean up the code a bit, there's now 5 separate
checks in gamelogic():
if (map.warpx)
if (map.warpy)
if (map.warpy && !map.warpx)
if (!map.warpy)
if (!map.warpx)
I made sure to preserve the previous weird horizontal warping behavior
that happens with vertical warping (thus the middle one), and to
preserve the frame ordering just in case there's something dependent on
the frame ordering.
The frame ordering is that first it will warp you horizontally, if
applicable, then it will warp you vertically, if applicable. Then if you
have vertical warping only, that weird horizontal warp. Then it will
screen transition you vertically, if applicable. Then it will screen
transition you horizontally, if applicable.
To explain the weird horizontal warp with the vertical warp: apparently
if an entity is far offscreen enough, and if that entity is not the
player, it will be warped horizontally during a vertical warp. The
points at which it will warp is 30 pixels farther out than normal
horizontal warping.
I think someone ran into this before, but my memory is fuzzy. The best I
can recall is that they were probably createentity()ing a high-speed
horizontally-moving enemy in a vertically warping room, only to discover
that said enemy kept warping horizontally.
2020-04-04 21:39:17 +02:00
|
|
|
}
|
|
|
|
|
2020-04-25 06:19:41 +02:00
|
|
|
if (!map.warpx && !map.towermode)
|
De-dupe screen transition / warping logic
I noticed that the code for going to the adjacent room when offscreen
and for warping instead if the room is warping was a bit
copy-and-pasted. To clean up the code a bit, there's now 5 separate
checks in gamelogic():
if (map.warpx)
if (map.warpy)
if (map.warpy && !map.warpx)
if (!map.warpy)
if (!map.warpx)
I made sure to preserve the previous weird horizontal warping behavior
that happens with vertical warping (thus the middle one), and to
preserve the frame ordering just in case there's something dependent on
the frame ordering.
The frame ordering is that first it will warp you horizontally, if
applicable, then it will warp you vertically, if applicable. Then if you
have vertical warping only, that weird horizontal warp. Then it will
screen transition you vertically, if applicable. Then it will screen
transition you horizontally, if applicable.
To explain the weird horizontal warp with the vertical warp: apparently
if an entity is far offscreen enough, and if that entity is not the
player, it will be warped horizontally during a vertical warp. The
points at which it will warp is 30 pixels farther out than normal
horizontal warping.
I think someone ran into this before, but my memory is fuzzy. The best I
can recall is that they were probably createentity()ing a high-speed
horizontally-moving enemy in a vertically warping room, only to discover
that said enemy kept warping horizontally.
2020-04-04 21:39:17 +02:00
|
|
|
{
|
|
|
|
//Normal! Just change room
|
|
|
|
int player = obj.getplayer();
|
2020-06-13 05:36:08 +02:00
|
|
|
if (player > -1 && game.door_left > -2 && obj.entities[player].xp < -14)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
obj.entities[player].xp += 320;
|
2020-03-31 10:09:42 +02:00
|
|
|
map.gotoroom(game.roomx - 1, game.roomy);
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
2020-06-13 05:36:08 +02:00
|
|
|
if (player > -1 && game.door_right > -2 && obj.entities[player].xp >= 308)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
obj.entities[player].xp -= 320;
|
2020-03-31 10:09:42 +02:00
|
|
|
map.gotoroom(game.roomx + 1, game.roomy);
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-25 06:19:41 +02:00
|
|
|
//Right so! Screenwraping for tower:
|
2020-05-05 20:26:26 +02:00
|
|
|
if (map.towermode && map.minitowermode)
|
2020-04-25 06:19:41 +02:00
|
|
|
{
|
|
|
|
if (map.scrolldir == 1)
|
|
|
|
{
|
|
|
|
//This is minitower 1!
|
|
|
|
int player = obj.getplayer();
|
2020-06-13 05:36:08 +02:00
|
|
|
if (player > -1 && game.door_left > -2 && obj.entities[player].xp < -14)
|
2020-04-25 06:19:41 +02:00
|
|
|
{
|
|
|
|
obj.entities[player].xp += 320;
|
|
|
|
map.gotoroom(48, 52);
|
|
|
|
}
|
2020-06-13 05:36:08 +02:00
|
|
|
if (player > -1 && game.door_right > -2 && obj.entities[player].xp >= 308)
|
2020-04-25 06:19:41 +02:00
|
|
|
{
|
|
|
|
obj.entities[player].xp -= 320;
|
|
|
|
obj.entities[player].yp -= (71*8);
|
|
|
|
map.gotoroom(game.roomx + 1, game.roomy+1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
//This is minitower 2!
|
|
|
|
int player = obj.getplayer();
|
2020-06-13 05:36:08 +02:00
|
|
|
if (player > -1 && game.door_left > -2 && obj.entities[player].xp < -14)
|
2020-04-25 06:19:41 +02:00
|
|
|
{
|
|
|
|
if (obj.entities[player].yp > 300)
|
|
|
|
{
|
|
|
|
obj.entities[player].xp += 320;
|
|
|
|
obj.entities[player].yp -= (71 * 8);
|
|
|
|
map.gotoroom(50, 54);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
obj.entities[player].xp += 320;
|
|
|
|
map.gotoroom(50, 53);
|
|
|
|
}
|
|
|
|
}
|
2020-06-13 05:36:08 +02:00
|
|
|
if (player > -1 && game.door_right > -2 && obj.entities[player].xp >= 308)
|
2020-04-25 06:19:41 +02:00
|
|
|
{
|
|
|
|
obj.entities[player].xp -= 320;
|
|
|
|
map.gotoroom(52, 53);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (map.towermode)
|
|
|
|
{
|
|
|
|
//Always wrap except for the very top and very bottom of the tower
|
|
|
|
if(map.ypos>=500 && map.ypos <=5000)
|
|
|
|
{
|
|
|
|
for (size_t i = 0; i < obj.entities.size(); i++)
|
|
|
|
{
|
|
|
|
if (obj.entities[i].xp <= -10)
|
|
|
|
{
|
|
|
|
obj.entities[i].xp += 320;
|
2020-04-29 01:44:31 +02:00
|
|
|
obj.entities[i].oldxp += 320;
|
2020-04-25 06:19:41 +02:00
|
|
|
}
|
2020-04-29 01:45:53 +02:00
|
|
|
else if (obj.entities[i].xp > 310)
|
2020-04-25 06:19:41 +02:00
|
|
|
{
|
2020-04-29 01:45:53 +02:00
|
|
|
obj.entities[i].xp -= 320;
|
|
|
|
obj.entities[i].oldxp -= 320;
|
2020-04-25 06:19:41 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
//Do not wrap! Instead, go to the correct room
|
|
|
|
int player = obj.getplayer();
|
2020-06-13 05:36:08 +02:00
|
|
|
if (player > -1 && game.door_left > -2 && obj.entities[player].xp < -14)
|
2020-04-25 06:19:41 +02:00
|
|
|
{
|
|
|
|
obj.entities[player].xp += 320;
|
|
|
|
obj.entities[player].yp -= (671 * 8);
|
|
|
|
map.gotoroom(108, 109);
|
|
|
|
}
|
2020-06-13 05:36:08 +02:00
|
|
|
if (player > -1 && game.door_right > -2 && obj.entities[player].xp >= 308)
|
2020-04-25 06:19:41 +02:00
|
|
|
{
|
|
|
|
obj.entities[player].xp -= 320;
|
|
|
|
map.gotoroom(110, 104);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-01 21:29:24 +01:00
|
|
|
//Warp tokens
|
|
|
|
if (map.custommode){
|
2020-04-04 21:13:24 +02:00
|
|
|
if (game.teleport)
|
|
|
|
{
|
|
|
|
int edi=obj.entities[game.edteleportent].behave;
|
|
|
|
int edj=obj.entities[game.edteleportent].para;
|
|
|
|
int edi2, edj2;
|
|
|
|
edi2 = (edi-(edi%40))/40;
|
|
|
|
edj2 = (edj-(edj%30))/30;
|
|
|
|
|
|
|
|
map.warpto(100+edi2, 100+edj2, obj.getplayer(), edi%40, (edj%30)+2);
|
|
|
|
game.teleport = false;
|
|
|
|
|
|
|
|
if (game.teleport == false)
|
|
|
|
{
|
|
|
|
game.flashlight = 6;
|
|
|
|
game.screenshake = 25;
|
|
|
|
}
|
|
|
|
}
|
2020-01-01 21:29:24 +01:00
|
|
|
}else{
|
2020-04-04 21:13:24 +02:00
|
|
|
if (game.teleport)
|
|
|
|
{
|
|
|
|
if (game.roomx == 117 && game.roomy == 102)
|
|
|
|
{
|
|
|
|
int i = obj.getplayer();
|
2020-06-13 05:36:08 +02:00
|
|
|
if (i > -1)
|
|
|
|
{
|
|
|
|
obj.entities[i].yp = 225;
|
|
|
|
}
|
2020-04-04 21:13:24 +02:00
|
|
|
map.gotoroom(119, 100);
|
|
|
|
game.teleport = false;
|
|
|
|
}
|
|
|
|
else if (game.roomx == 119 && game.roomy == 100)
|
|
|
|
{
|
|
|
|
int i = obj.getplayer();
|
2020-06-13 05:36:08 +02:00
|
|
|
if (i > -1)
|
|
|
|
{
|
|
|
|
obj.entities[i].yp = 225;
|
|
|
|
}
|
2020-04-04 21:13:24 +02:00
|
|
|
map.gotoroom(119, 103);
|
|
|
|
game.teleport = false;
|
|
|
|
}
|
|
|
|
else if (game.roomx == 119 && game.roomy == 103)
|
|
|
|
{
|
|
|
|
int i = obj.getplayer();
|
2020-06-13 05:36:08 +02:00
|
|
|
if (i > -1)
|
|
|
|
{
|
|
|
|
obj.entities[i].xp = 0;
|
|
|
|
}
|
2020-04-04 21:13:24 +02:00
|
|
|
map.gotoroom(116, 103);
|
|
|
|
game.teleport = false;
|
|
|
|
}
|
|
|
|
else if (game.roomx == 116 && game.roomy == 103)
|
|
|
|
{
|
|
|
|
int i = obj.getplayer();
|
2020-06-13 05:36:08 +02:00
|
|
|
if (i > -1)
|
|
|
|
{
|
|
|
|
obj.entities[i].yp = 225;
|
|
|
|
}
|
2020-04-04 21:13:24 +02:00
|
|
|
map.gotoroom(116, 100);
|
|
|
|
game.teleport = false;
|
|
|
|
}
|
|
|
|
else if (game.roomx == 116 && game.roomy == 100)
|
|
|
|
{
|
|
|
|
int i = obj.getplayer();
|
2020-06-13 05:36:08 +02:00
|
|
|
if (i > -1)
|
|
|
|
{
|
|
|
|
obj.entities[i].xp = 0;
|
|
|
|
}
|
2020-04-04 21:13:24 +02:00
|
|
|
map.gotoroom(114, 102);
|
|
|
|
game.teleport = false;
|
|
|
|
}
|
|
|
|
else if (game.roomx == 114 && game.roomy == 102)
|
|
|
|
{
|
|
|
|
int i = obj.getplayer();
|
2020-06-13 05:36:08 +02:00
|
|
|
if (i > -1)
|
|
|
|
{
|
|
|
|
obj.entities[i].yp = 225;
|
|
|
|
}
|
2020-04-04 21:13:24 +02:00
|
|
|
map.gotoroom(113, 100);
|
|
|
|
game.teleport = false;
|
|
|
|
}
|
|
|
|
else if (game.roomx == 116 && game.roomy == 104)
|
|
|
|
{
|
|
|
|
//pre warp zone here
|
|
|
|
map.warpto(107, 101, obj.getplayer(), 14, 16);
|
|
|
|
}
|
|
|
|
else if (game.roomx == 107 && game.roomy == 101)
|
|
|
|
{
|
|
|
|
map.warpto(105, 119, obj.getplayer(), 5, 26);
|
|
|
|
}
|
|
|
|
else if (game.roomx == 105 && game.roomy == 118)
|
|
|
|
{
|
|
|
|
map.warpto(101, 111, obj.getplayer(), 34, 6);
|
|
|
|
}
|
|
|
|
else if (game.roomx == 101 && game.roomy == 111)
|
|
|
|
{
|
|
|
|
//There are lots of warp tokens in this room, so we have to distinguish!
|
|
|
|
switch(game.teleportxpos)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
map.warpto(108, 108, obj.getplayer(), 4, 27);
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
map.warpto(101, 111, obj.getplayer(), 12, 27);
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
map.warpto(119, 111, obj.getplayer(), 31, 7);
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
map.warpto(114, 117, obj.getplayer(), 19, 16);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (game.roomx == 108 && game.roomy == 106)
|
|
|
|
{
|
|
|
|
map.warpto(119, 111, obj.getplayer(), 4, 27);
|
|
|
|
}
|
|
|
|
else if (game.roomx == 100 && game.roomy == 111)
|
|
|
|
{
|
|
|
|
map.warpto(101, 111, obj.getplayer(), 24, 6);
|
|
|
|
}
|
|
|
|
else if (game.roomx == 119 && game.roomy == 107)
|
|
|
|
{
|
|
|
|
//Secret lab, to super gravitron
|
|
|
|
map.warpto(119, 108, obj.getplayer(), 19, 10);
|
|
|
|
}
|
|
|
|
if (game.teleport == false)
|
|
|
|
{
|
|
|
|
game.flashlight = 6;
|
|
|
|
game.screenshake = 25;
|
|
|
|
}
|
|
|
|
}
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
}
|
2020-04-30 21:32:53 +02:00
|
|
|
|
|
|
|
//Update colour cycling for final level
|
|
|
|
if (map.finalmode && map.final_colormode)
|
|
|
|
{
|
|
|
|
map.final_aniframedelay--;
|
|
|
|
if(map.final_aniframedelay==0)
|
|
|
|
{
|
|
|
|
graphics.foregrounddrawn=false;
|
|
|
|
}
|
|
|
|
if (map.final_aniframedelay <= 0) {
|
|
|
|
map.final_aniframedelay = 2;
|
|
|
|
map.final_aniframe++;
|
|
|
|
if (map.final_aniframe >= 4)
|
|
|
|
map.final_aniframe = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-01 21:29:24 +01:00
|
|
|
int j;
|
|
|
|
if (game.roomchange)
|
|
|
|
{
|
|
|
|
//We've changed room? Let's bring our companion along!
|
|
|
|
game.roomchange = false;
|
2020-06-13 05:36:08 +02:00
|
|
|
int i = obj.getplayer();
|
|
|
|
if (game.companion > 0 && i > -1)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
//ok, we'll presume our companion has been destroyed in the room change. So:
|
|
|
|
switch(game.companion)
|
|
|
|
{
|
|
|
|
case 6:
|
2020-03-31 02:46:36 +02:00
|
|
|
obj.createentity(obj.entities[i].xp, 121.0f, 15.0f,1); //Y=121, the floor in that particular place!
|
2020-04-02 00:32:21 +02:00
|
|
|
j = obj.getcompanion();
|
2020-06-13 05:43:19 +02:00
|
|
|
if (j > -1)
|
|
|
|
{
|
|
|
|
obj.entities[j].vx = obj.entities[i].vx;
|
|
|
|
obj.entities[j].dir = obj.entities[i].dir;
|
|
|
|
}
|
2020-01-01 21:29:24 +01:00
|
|
|
break;
|
|
|
|
case 7:
|
|
|
|
if (game.roomy <= 105) //don't jump after him!
|
|
|
|
{
|
|
|
|
if (game.roomx == 110)
|
|
|
|
{
|
2020-03-31 02:46:36 +02:00
|
|
|
obj.createentity(320, 86, 16, 1); //Y=86, the ROOF in that particular place!
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-03-31 02:46:36 +02:00
|
|
|
obj.createentity(obj.entities[i].xp, 86.0f, 16.0f, 1); //Y=86, the ROOF in that particular place!
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
2020-04-02 00:32:21 +02:00
|
|
|
j = obj.getcompanion();
|
2020-06-13 05:43:19 +02:00
|
|
|
if (j > -1)
|
|
|
|
{
|
|
|
|
obj.entities[j].vx = obj.entities[i].vx;
|
|
|
|
obj.entities[j].dir = obj.entities[i].dir;
|
|
|
|
}
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 8:
|
|
|
|
if (game.roomy >= 104) //don't jump after him!
|
|
|
|
{
|
|
|
|
if (game.roomx == 102)
|
|
|
|
{
|
2020-03-31 02:46:36 +02:00
|
|
|
obj.createentity(310, 177, 17, 1);
|
2020-04-02 00:32:21 +02:00
|
|
|
j = obj.getcompanion();
|
2020-06-13 05:43:19 +02:00
|
|
|
if (j > -1)
|
|
|
|
{
|
|
|
|
obj.entities[j].vx = obj.entities[i].vx;
|
|
|
|
obj.entities[j].dir = obj.entities[i].dir;
|
|
|
|
}
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-03-31 02:46:36 +02:00
|
|
|
obj.createentity(obj.entities[i].xp, 177.0f, 17.0f, 1);
|
2020-04-02 00:32:21 +02:00
|
|
|
j = obj.getcompanion();
|
2020-06-13 05:43:19 +02:00
|
|
|
if (j > -1)
|
|
|
|
{
|
|
|
|
obj.entities[j].vx = obj.entities[i].vx;
|
|
|
|
obj.entities[j].dir = obj.entities[i].dir;
|
|
|
|
}
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 9:
|
|
|
|
if (!map.towermode) //don't go back into the tower!
|
|
|
|
{
|
|
|
|
if (game.roomx == 110 && obj.entities[i].xp<20)
|
|
|
|
{
|
2020-03-31 02:46:36 +02:00
|
|
|
obj.createentity(100, 185, 18, 15, 0, 1);
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-03-31 02:46:36 +02:00
|
|
|
obj.createentity(obj.entities[i].xp, 185.0f, 18.0f, 15, 0, 1);
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
2020-04-02 00:32:21 +02:00
|
|
|
j = obj.getcompanion();
|
2020-06-13 05:43:19 +02:00
|
|
|
if (j > -1)
|
|
|
|
{
|
|
|
|
obj.entities[j].vx = obj.entities[i].vx;
|
|
|
|
obj.entities[j].dir = obj.entities[i].dir;
|
|
|
|
}
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 10:
|
|
|
|
//intermission 2, choose colour based on lastsaved
|
|
|
|
if (game.roomy == 51)
|
|
|
|
{
|
2020-04-09 08:34:26 +02:00
|
|
|
if (!obj.flags[59])
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-04-01 23:48:11 +02:00
|
|
|
obj.createentity(225.0f, 169.0f, 18, graphics.crewcolour(game.lastsaved), 0, 10);
|
2020-04-02 00:32:21 +02:00
|
|
|
j = obj.getcompanion();
|
2020-06-13 05:43:19 +02:00
|
|
|
if (j > -1)
|
|
|
|
{
|
|
|
|
obj.entities[j].vx = obj.entities[i].vx;
|
|
|
|
obj.entities[j].dir = obj.entities[i].dir;
|
|
|
|
}
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (game.roomy >= 52)
|
|
|
|
{
|
2020-04-09 08:34:26 +02:00
|
|
|
if (obj.flags[59])
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-04-01 23:48:11 +02:00
|
|
|
obj.createentity(160.0f, 177.0f, 18, graphics.crewcolour(game.lastsaved), 0, 18, 1);
|
2020-04-02 00:32:21 +02:00
|
|
|
j = obj.getcompanion();
|
2020-06-13 05:43:19 +02:00
|
|
|
if (j > -1)
|
|
|
|
{
|
|
|
|
obj.entities[j].vx = obj.entities[i].vx;
|
|
|
|
obj.entities[j].dir = obj.entities[i].dir;
|
|
|
|
}
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-04-09 08:34:26 +02:00
|
|
|
obj.flags[59] = true;
|
2020-04-01 23:48:11 +02:00
|
|
|
obj.createentity(obj.entities[i].xp, -20.0f, 18.0f, graphics.crewcolour(game.lastsaved), 0, 10, 0);
|
2020-04-02 00:32:21 +02:00
|
|
|
j = obj.getcompanion();
|
2020-06-13 05:43:19 +02:00
|
|
|
if (j > -1)
|
|
|
|
{
|
|
|
|
obj.entities[j].vx = obj.entities[i].vx;
|
|
|
|
obj.entities[j].dir = obj.entities[i].dir;
|
|
|
|
}
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 11:
|
|
|
|
//Intermission 1: We're using the SuperCrewMate instead!
|
|
|
|
if(game.roomx-41==game.scmprogress)
|
|
|
|
{
|
|
|
|
switch(game.scmprogress)
|
|
|
|
{
|
|
|
|
case 0:
|
2020-04-01 23:48:11 +02:00
|
|
|
obj.createentity(76, 161, 24, graphics.crewcolour(game.lastsaved), 2);
|
2020-01-01 21:29:24 +01:00
|
|
|
break;
|
|
|
|
case 1:
|
2020-04-01 23:48:11 +02:00
|
|
|
obj.createentity(10, 169, 24, graphics.crewcolour(game.lastsaved), 2);
|
2020-01-01 21:29:24 +01:00
|
|
|
break;
|
|
|
|
case 2:
|
2020-04-01 23:48:11 +02:00
|
|
|
obj.createentity(10, 177, 24, graphics.crewcolour(game.lastsaved), 2);
|
2020-01-01 21:29:24 +01:00
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
if (game.scmmoveme)
|
|
|
|
{
|
2020-04-01 23:48:11 +02:00
|
|
|
obj.createentity(obj.entities[obj.getplayer()].xp, 185, 24, graphics.crewcolour(game.lastsaved), 2);
|
2020-01-01 21:29:24 +01:00
|
|
|
game.scmmoveme = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-04-01 23:48:11 +02:00
|
|
|
obj.createentity(10, 177, 24, graphics.crewcolour(game.lastsaved), 2);
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 4:
|
2020-04-01 23:48:11 +02:00
|
|
|
obj.createentity(10, 185, 24, graphics.crewcolour(game.lastsaved), 2);
|
2020-01-01 21:29:24 +01:00
|
|
|
break;
|
|
|
|
case 5:
|
2020-04-01 23:48:11 +02:00
|
|
|
obj.createentity(10, 185, 24, graphics.crewcolour(game.lastsaved), 2);
|
2020-01-01 21:29:24 +01:00
|
|
|
break;
|
|
|
|
case 6:
|
2020-04-01 23:48:11 +02:00
|
|
|
obj.createentity(10, 185, 24, graphics.crewcolour(game.lastsaved), 2);
|
2020-01-01 21:29:24 +01:00
|
|
|
break;
|
|
|
|
case 7:
|
2020-04-01 23:48:11 +02:00
|
|
|
obj.createentity(10, 41, 24, graphics.crewcolour(game.lastsaved), 2);
|
2020-01-01 21:29:24 +01:00
|
|
|
break;
|
|
|
|
case 8:
|
2020-04-01 23:48:11 +02:00
|
|
|
obj.createentity(10, 169, 24, graphics.crewcolour(game.lastsaved), 2);
|
2020-01-01 21:29:24 +01:00
|
|
|
break;
|
|
|
|
case 9:
|
2020-04-01 23:48:11 +02:00
|
|
|
obj.createentity(10, 169, 24, graphics.crewcolour(game.lastsaved), 2);
|
2020-01-01 21:29:24 +01:00
|
|
|
break;
|
|
|
|
case 10:
|
2020-04-01 23:48:11 +02:00
|
|
|
obj.createentity(10, 129, 24, graphics.crewcolour(game.lastsaved), 2);
|
2020-01-01 21:29:24 +01:00
|
|
|
break;
|
|
|
|
case 11:
|
2020-04-01 23:48:11 +02:00
|
|
|
obj.createentity(10, 129, 24, graphics.crewcolour(game.lastsaved), 2);
|
2020-01-01 21:29:24 +01:00
|
|
|
break;
|
|
|
|
case 12:
|
2020-04-01 23:48:11 +02:00
|
|
|
obj.createentity(10, 65, 24, graphics.crewcolour(game.lastsaved), 2);
|
2020-01-01 21:29:24 +01:00
|
|
|
break;
|
|
|
|
case 13:
|
2020-04-01 23:48:11 +02:00
|
|
|
obj.createentity(10, 177, 24, graphics.crewcolour(game.lastsaved));
|
2020-01-01 21:29:24 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (game.scmmoveme)
|
|
|
|
{
|
|
|
|
obj.entities[obj.getscm()].xp = obj.entities[obj.getplayer()].xp;
|
|
|
|
game.scmmoveme = false;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
game.activeactivity = obj.checkactivity();
|
|
|
|
|
2020-04-30 02:04:25 +02:00
|
|
|
game.oldreadytotele = game.readytotele;
|
2020-01-01 21:29:24 +01:00
|
|
|
if (game.activetele)
|
|
|
|
{
|
|
|
|
int i = obj.getplayer();
|
2020-06-13 05:36:08 +02:00
|
|
|
if (i > -1)
|
|
|
|
{
|
|
|
|
obj.settemprect(i);
|
|
|
|
}
|
2020-01-01 21:29:24 +01:00
|
|
|
if (help.intersects(game.teleblock, obj.temprect))
|
|
|
|
{
|
|
|
|
game.readytotele += 25;
|
|
|
|
if (game.readytotele >= 255) game.readytotele = 255;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
game.readytotele -= 50;
|
|
|
|
if (game.readytotele < 0) game.readytotele = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (game.readytotele > 0)
|
|
|
|
{
|
|
|
|
game.readytotele -= 50;
|
|
|
|
if (game.readytotele < 0) game.readytotele = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (game.teleport_to_new_area)
|
2020-03-31 21:38:52 +02:00
|
|
|
script.teleport();
|
2020-05-09 21:52:58 +02:00
|
|
|
|
|
|
|
#if !defined(NO_CUSTOM_LEVELS)
|
|
|
|
if (game.shouldreturntoeditor)
|
|
|
|
{
|
|
|
|
game.shouldreturntoeditor = false;
|
|
|
|
game.returntoeditor();
|
|
|
|
}
|
|
|
|
#endif
|
2020-04-29 03:15:26 +02:00
|
|
|
|
2020-04-29 06:58:19 +02:00
|
|
|
game.prev_act_fade = game.act_fade;
|
2020-04-29 03:15:26 +02:00
|
|
|
if (game.activeactivity > -1)
|
|
|
|
{
|
|
|
|
if (game.act_fade < 5)
|
|
|
|
{
|
|
|
|
game.act_fade = 5;
|
|
|
|
}
|
|
|
|
if (game.act_fade < 10)
|
|
|
|
{
|
|
|
|
game.act_fade++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (game.act_fade > 5)
|
|
|
|
{
|
|
|
|
game.act_fade--;
|
|
|
|
}
|
2020-04-29 03:15:56 +02:00
|
|
|
|
|
|
|
if (obj.trophytext > 0)
|
|
|
|
{
|
|
|
|
obj.trophytext--;
|
|
|
|
}
|
2020-04-29 03:38:43 +02:00
|
|
|
|
|
|
|
graphics.updatetextboxes();
|
2020-04-29 04:28:16 +02:00
|
|
|
|
|
|
|
if (!game.colourblindmode)
|
|
|
|
{
|
2020-04-30 00:25:01 +02:00
|
|
|
if (map.towermode)
|
|
|
|
{
|
|
|
|
graphics.updatetowerbackground();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
graphics.updatebackground(map.background);
|
|
|
|
}
|
2020-04-29 04:28:16 +02:00
|
|
|
}
|
2020-04-29 06:17:16 +02:00
|
|
|
|
|
|
|
if (!game.blackout)
|
|
|
|
{
|
|
|
|
//Update line colours!
|
|
|
|
if (graphics.linedelay <= 0)
|
|
|
|
{
|
|
|
|
graphics.linestate++;
|
|
|
|
if (graphics.linestate >= 10) graphics.linestate = 0;
|
|
|
|
graphics.linedelay = 2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
graphics.linedelay--;
|
|
|
|
}
|
|
|
|
}
|
Fix, for in-GAMEMODE sprites, their colors updating too fast
Okay, so the problem here is that Graphics::setcol() is called right
before a sprite is drawn in a render function, but render functions are
done in deltatime, meaning that the color of a sprite keeps being
recalculated every time. This only affects sprites that use fRandom()
(the other thing that can dynamically determine a color is help.glow,
but that's only updated in the fixed-timestep loop), but is especially
noticeable for sprites that flash wildly, like the teleporter, trinket,
and elephant.
To fix this, we need to make the color be recalculated only in the
fixed-timestep loop. However, this means that we MUST store the color of
the sprite SOMEWHERE for the delta-timesteps to render it, otherwise the
color calculation will just be lost or something.
So each entity now has a new attribute, `realcol`, which is the actual
raw color used to render the sprite in render functions. This is not to
be confused with their `colour` attribute, which is more akin to a color
"ID" of sorts, but which isn't an actual color.
At the end of gamelogic(), as well as when an entity is first created,
the `colour` is given to Graphics::setcol() and then `realcol` gets set
to the actual color. Then when it comes time to render the entity,
`realcol` gets used instead.
Gravitron squares are a somewhat tricky case where there's technically
TWO colors for it - one is the actual sprite itself and the other is the
indicator. However, usually the indicator and the square aren't both
onscreen at the same time, so we can simply switch the realcol between
the two as needed.
However, we can't use this system for the sprite colors used on the
title and map screen, so we'll have to do something else for those.
2020-05-01 02:34:37 +02:00
|
|
|
|
|
|
|
graphics.trinketcolset = false;
|
|
|
|
for (int i = obj.entities.size() - 1; i >= 0; i--)
|
|
|
|
{
|
|
|
|
if (obj.entities[i].invis)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
obj.entities[i].updatecolour();
|
|
|
|
}
|
2020-05-02 19:31:48 +02:00
|
|
|
|
|
|
|
if (map.finalmode)
|
|
|
|
{
|
|
|
|
map.glitchname = map.getglitchname(game.roomx, game.roomy);
|
|
|
|
}
|
2020-05-02 19:45:35 +02:00
|
|
|
|
|
|
|
#if !defined(NO_CUSTOM_LEVELS)
|
2020-05-02 19:49:41 +02:00
|
|
|
ed.oldreturneditoralpha = ed.returneditoralpha;
|
2020-05-02 19:45:35 +02:00
|
|
|
if (map.custommode && !map.custommodeforreal && ed.returneditoralpha > 0)
|
|
|
|
{
|
|
|
|
ed.returneditoralpha -= 15;
|
|
|
|
}
|
|
|
|
#endif
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|