VVVVVV/desktop_version/src/Entity.h

215 lines
4.3 KiB
C
Raw Normal View History

2020-01-01 21:29:24 +01:00
#ifndef ENTITY_H
#define ENTITY_H
#include <SDL.h>
#include <string>
#include <vector>
2020-01-01 21:29:24 +01:00
#include "Maths.h"
#include "Ent.h"
#include "BlockV.h"
#include "Game.h"
2020-01-01 21:29:24 +01:00
#define removeentity_iter(index) \
do \
{ \
extern entityclass obj; \
if (obj.removeentity(index)) \
{ \
index--; \
} \
} while (false)
#define removeblock_iter(index) \
do \
{ \
extern entityclass obj; \
obj.removeblock(index); \
index--; \
} while (false)
2020-01-01 21:29:24 +01:00
enum
{
BLOCK = 0,
TRIGGER = 1,
DAMAGE = 2,
DIRECTIONAL = 3,
SAFE = 4,
ACTIVITY = 5
};
class entityclass
{
public:
void init();
void resetallflags();
void fatal_top()
{
createblock(DAMAGE, -8, -8, 384, 16);
}
void fatal_bottom()
{
createblock(DAMAGE, -8, 224, 384, 16);
}
void fatal_left()
{
createblock(DAMAGE, -8, -8, 16, 260);
}
void fatal_right()
{
createblock(DAMAGE, 312, -8, 16, 260);
}
int swncolour(int t );
void swnenemiescol(int t);
void gravcreate(int ypos, int dir, int xoff = 0, int yoff = 0);
2020-01-01 21:29:24 +01:00
void generateswnwave(int t);
2020-01-01 21:29:24 +01:00
void createblock(int t, int xp, int yp, int w, int h, int trig = 0, const std::string& script = "");
2020-01-01 21:29:24 +01:00
Prevent removing the player entity Removing the player entity has all sorts of nasty effects, such as softlocking the game because many inputs require there to be a player present, such as opening the quit menu. The most infamous glitch to remove the player entity is the Gravitron Fling, where the game doesn't see a gravity line at a specific y-position in the current room, and when it moves the bottom gravity line it moves the player instead. When the gravity line gets outside the room, it gets destroyed, so if the player gets dragged outside the room, they get destroyed, too. (Don't misinterpret this as saying anytime the player gets dragged outside the room, they get destroyed - it's only the Gravitron logic that destroys them.) Also, there are many places in the code that use entity-getting functions that have a fallback value of 0. If it was possible to remove the player, then it's possible for this fallback value of 0 to index obj.entities out-of-bounds, which is not good. To fix this, entityclass::removeentity() is now a bool that signifies if the entity was successfully removed or not. If the entity given is the player (meaning it first checks if it's rule 0, just so in 99% of cases it'll short-circuit and won't do the next check, which is if entityclass::getplayer() says the indice to be removed is the player), then it'll refuse to remove the entity, and return false. This is a change in behavior where callers might expect entityclass::removeentity() to always succeed, so I changed the removeentity_iter() macro to only decrement if removing the entity succeeded. I also changed entityclass::updateentities() from 'removeentity(i); return true;' to 'return removeentity(i);'.
2020-06-13 21:00:04 +02:00
bool removeentity(int t);
2020-01-01 21:29:24 +01:00
void removeallblocks();
void removeblock(int t);
void removeblockat(int x, int y);
void moveblockto(int x1, int y1, int x2, int y2, int w, int h);
void nocollisionat(int x, int y);
2020-01-01 21:29:24 +01:00
void removetrigger(int t);
void copylinecross(int t);
void revertlinecross(int t, int s);
bool gridmatch(int p1, int p2, int p3, int p4, int p11, int p21, int p31, int p41);
int crewcolour(int t);
void createentity(float xp, float yp, int t, float vx = 0, float vy = 0,
2020-01-01 21:29:24 +01:00
int p1 = 0, int p2 = 0, int p3 = 320, int p4 = 240 );
bool updateentities(int i);
2020-01-01 21:29:24 +01:00
void animateentities(int i);
2020-01-01 21:29:24 +01:00
int getcompanion();
2020-01-01 21:29:24 +01:00
int getplayer();
int getscm();
int getlineat(int t);
int getcrewman(int t);
int getcustomcrewman(int t);
int getteleporter();
bool entitycollide(int a, int b);
bool checkdamage(bool scm = false);
2020-01-01 21:29:24 +01:00
int checktrigger(int* block_idx);
2020-01-01 21:29:24 +01:00
int checkactivity();
int getgridpoint(int t);
bool checkplatform(const SDL_Rect& temprect, int* px, int* py);
2020-01-01 21:29:24 +01:00
bool checkblocks(const SDL_Rect& temprect, const float dx, const float dy, const float dr, const bool skipdirblocks);
2020-01-01 21:29:24 +01:00
bool checktowerspikes(int t);
2020-01-01 21:29:24 +01:00
bool checkwall(const SDL_Rect& temprect, const float dx, const float dy, const float dr, const bool skipblocks, const bool skipdirblocks);
bool checkwall(const SDL_Rect& temprect);
2020-01-01 21:29:24 +01:00
float hplatformat(const int px, const int py);
2020-01-01 21:29:24 +01:00
int yline(int a, int b);
bool entityhlinecollide(int t, int l);
bool entityvlinecollide(int t, int l);
bool entitywarphlinecollide(int t, int l);
bool entitywarpvlinecollide(int t, int l);
2020-01-01 21:29:24 +01:00
void customwarplinecheck(int i);
2020-01-01 21:29:24 +01:00
float entitycollideplatformroof(int t);
2020-01-01 21:29:24 +01:00
float entitycollideplatformfloor(int t);
2020-01-01 21:29:24 +01:00
bool entitycollidefloor(int t);
2020-01-01 21:29:24 +01:00
bool entitycollideroof(int t);
2020-01-01 21:29:24 +01:00
bool testwallsx(int t, int tx, int ty, const bool skipdirblocks);
2020-01-01 21:29:24 +01:00
bool testwallsy(int t, float tx, float ty);
2020-01-01 21:29:24 +01:00
void applyfriction(int t, float xrate, float yrate);
void updateentitylogic(int t);
2020-01-01 21:29:24 +01:00
void entitymapcollision(int t);
2020-01-01 21:29:24 +01:00
void movingplatformfix(int t, int j);
2020-01-01 21:29:24 +01:00
void entitycollisioncheck();
2020-01-01 21:29:24 +01:00
void collisioncheck(int i, int j, bool scm = false);
void stuckprevention(int t);
2020-01-01 21:29:24 +01:00
std::vector<entclass> entities;
std::vector<entclass> linecrosskludge;
int k;
2020-01-01 21:29:24 +01:00
std::vector<blockclass> blocks;
bool flags[100];
bool collect[100];
bool customcollect[100];
2020-01-01 21:29:24 +01:00
int platformtile;
bool vertplatforms, horplatforms;
// :(
bool nearelephant, upsetmode;
int upset;
//Trophy Text
int trophytext, trophytype;
int oldtrophytext;
2020-01-01 21:29:24 +01:00
//Secret lab scripts
int altstates;
//Custom stuff
int customenemy;
int customplatformtile;
bool customwarpmode, customwarpmodevon, customwarpmodehon;
std::string customscript;
bool customcrewmoods[Game::numcrew];
2020-01-01 21:29:24 +01:00
};
#ifndef OBJ_DEFINITION
extern entityclass obj;
#endif
2020-01-01 21:29:24 +01:00
#endif /* ENTITY_H */