1
0
Fork 0
mirror of https://github.com/TerryCavanagh/VVVVVV.git synced 2024-12-23 10:09:43 +01:00

Clean up setting enemy properties

This commit cleans up setting enemy properties. It deduplicates code,
makes custom levels spawn enemies better (doesn't just pretend it's a
certain main game room to set the settings) and makes everything a nice
registry.

This is the basis of a future system which might allow for more enemy
types to be used in the editor, and even custom enemy types...

But it was mostly done for cleanup, since I hated how the code looked.
This commit is contained in:
AllyTally 2023-09-01 21:21:27 -03:00 committed by NyakoFox
parent d4e472db1b
commit 9a17a07ef3
4 changed files with 186 additions and 285 deletions

View file

@ -4017,42 +4017,7 @@ bool editorclass::autotile_connector(int x, int y, TileTypes original_type)
int editorclass::get_enemy_tile(int t) int editorclass::get_enemy_tile(int t)
{ {
switch(t) return (&obj.enemy_types[obj.legacy_id_to_entity(t)])->tile;
{
case 0:
return 78;
break;
case 1:
return 88;
break;
case 2:
return 36;
break;
case 3:
return 164;
break;
case 4:
return 68;
break;
case 5:
return 48;
break;
case 6:
return 176;
break;
case 7:
return 168;
break;
case 8:
return 112;
break;
case 9:
return 114;
break;
default:
return 78;
break;
}
} }
void editorclass::set_tile(int x, int y, int t) void editorclass::set_tile(int x, int y, int t)

View file

@ -1,5 +1,6 @@
#include "Ent.h" #include "Ent.h"
#include "Entity.h"
#include "Game.h" #include "Game.h"
#include "Graphics.h" #include "Graphics.h"
@ -106,36 +107,24 @@ void entclass::setenemy( int t )
switch ((int) para) switch ((int) para)
{ {
case 0: case 0:
tile = 60; obj.set_enemy_type(this, "lies_emitter");
animate = 2;
colour = 6;
behave = 10; behave = 10;
w = 32;
h = 32;
x1 = -200; x1 = -200;
break; break;
case 1: case 1:
obj.set_enemy_type(this, "lies");
yp += 10; yp += 10;
lerpoldyp += 10; lerpoldyp += 10;
tile = 63;
animate = 100; //LIES
colour = 6;
behave = 11; behave = 11;
para = 9; // destroyed when outside para = 9; // destroyed when outside
x1 = -200; x1 = -200;
x2 = 400; x2 = 400;
w = 26;
h = 10;
cx = 1; cx = 1;
cy = 1; cy = 1;
break; break;
case 2: case 2:
tile = 62; obj.set_enemy_type(this, "lies_collector");
animate = 100;
colour = 6;
behave = -1; behave = -1;
w = 32;
h = 32;
break; break;
} }
break; break;
@ -144,39 +133,27 @@ void entclass::setenemy( int t )
switch ((int) para) switch ((int) para)
{ {
case 0: case 0:
tile = 72; obj.set_enemy_type(this, "factory_emitter");
animate = 3;
size = 9; size = 9;
colour = 6;
behave = 12; behave = 12;
w = 64;
h = 40;
cx = 0; cx = 0;
cy = 24; cy = 24;
break; break;
case 1: case 1:
obj.set_enemy_type(this, "factory_clouds");
xp += 4; xp += 4;
lerpoldxp += 4; lerpoldxp += 4;
yp -= 4; yp -= 4;
lerpoldyp -= 4; lerpoldyp -= 4;
tile = 76;
animate = 100; // Clouds
colour = 6;
behave = 13; behave = 13;
para = -6; //destroyed when outside para = -6; //destroyed when outside
x2 = 400; x2 = 400;
w = 32;
h = 12;
cx = 0; cx = 0;
cy = 6; cy = 6;
break; break;
case 2: case 2:
tile = 77; obj.set_enemy_type(this, "factory_collector");
animate = 100;
colour = 6;
behave = -1; behave = -1;
w = 32;
h = 16;
break; break;
} }
break; break;
@ -194,47 +171,26 @@ void entclass::setenemyroom( int rx, int ry )
{ {
//Space Station 1 //Space Station 1
case rn(12, 3): //Security Drone case rn(12, 3): //Security Drone
tile = 36; obj.set_enemy_type(this, "disc");
colour = 8;
animate = 1;
break; break;
case rn(13, 3): //Wavelengths case rn(13, 3): //Wavelengths
tile = 32; obj.set_enemy_type(this, "wavelength");
colour = 7;
animate = 1;
w = 32;
break; break;
case rn(15, 3): //Traffic case rn(15, 3): //Traffic
tile = 28; obj.set_enemy_type(this, "stop");
colour = 6;
animate = 1;
w = 22;
h = 32;
break; break;
case rn(12, 5): //The Yes Men case rn(12, 5): //The Yes Men
tile = 40; obj.set_enemy_type(this, "yes");
colour = 9;
animate = 1;
w = 20;
h = 20;
break; break;
case rn(13, 6): //Hunchbacked Guards case rn(13, 6): //Hunchbacked Guards
tile = 44; obj.set_enemy_type(this, "guard");
colour = 8;
animate = 1;
w = 16;
h = 20;
break; break;
case rn(13, 4): //Communication Station case rn(13, 4): //Communication Station
harmful = false; harmful = false;
if (xp == 256) if (xp == 256)
{ {
//transmittor //transmittor
tile = 104; obj.set_enemy_type(this, "transmitter");
colour = 4;
animate = 7;
w = 16;
h = 16;
xp -= 24; xp -= 24;
lerpoldxp -= 24; lerpoldxp -= 24;
yp -= 16; yp -= 16;
@ -243,11 +199,7 @@ void entclass::setenemyroom( int rx, int ry )
else else
{ {
//radar dish //radar dish
tile =124; obj.set_enemy_type(this, "radar");
colour = 4;
animate = 6;
w = 32;
h = 32;
cx = 4; cx = 4;
size = 9; size = 9;
xp -= 4; xp -= 4;
@ -259,18 +211,10 @@ void entclass::setenemyroom( int rx, int ry )
break; break;
//The Lab //The Lab
case rn(4, 0): case rn(4, 0):
tile = 78; obj.set_enemy_type(this, "square");
colour = 7;
animate = 1;
w = 16;
h = 16;
break; break;
case rn(2, 0): case rn(2, 0):
tile = 88; obj.set_enemy_type(this, "circle");
colour = 11;
animate = 1;
w = 16;
h = 16;
break; break;
//Space Station 2 //Space Station 2
case rn(14, 11): case rn(14, 11):
@ -288,237 +232,121 @@ void entclass::setenemyroom( int rx, int ry )
case rn(13, 8): case rn(13, 8):
colour = 8; colour = 8;
break; //Factory break; //Factory
case rn(13,7): // MAVVERRRICK
obj.set_enemy_type(this, "bus");
size = 9;
break;
case rn(11, 13): //Truth case rn(11, 13): //Truth
tile = 64; obj.set_enemy_type(this, "truth");
colour = 7;
animate = 100;
w = 44;
h = 10;
size = 10; size = 10;
break; break;
case rn(17, 7): //Brass sent us under the top case rn(17, 7): //Brass sent us under the top
tile =82; obj.set_enemy_type(this, "solider");
colour = 8;
animate = 5;
w = 28;
h = 32;
cx = 4; cx = 4;
break; break;
case rn(10, 7): // (deception) case rn(10, 7): // (deception)
tile = 92; obj.set_enemy_type(this, "bowtie");
colour = 6;
animate = 1;
w = 16;
h = 16;
break; break;
case rn(14, 13): // (chose poorly) case rn(14, 13): // (chose poorly)
tile = 56; obj.set_enemy_type(this, "skeleton");
colour = 6;
animate = 1;
w = 15;
h = 24;
break; break;
case rn(13, 12): // (backsliders) case rn(13, 12): // (backsliders)
tile = 164; obj.set_enemy_type(this, "glitch");
colour = 7;
animate = 1;
w = 16;
h = 16;
break; break;
case rn(14, 8): // (wheel of fortune room) case rn(14, 8): // (wheel of fortune room)
tile = 116; obj.set_enemy_type(this, "wheel");
colour = 12;
animate = 1;
w = 32;
h = 32;
break; break;
case rn(16, 9): // (seeing dollar signs) case rn(16, 9): // (seeing dollar signs)
tile = 68; obj.set_enemy_type(this, "coin");
colour = 7;
animate = 1;
w = 16;
h = 16;
break; break;
case rn(16, 7): // (tomb of mad carew) case rn(16, 7): // (tomb of mad carew)
tile = 106; obj.set_enemy_type(this, "ghost");
colour = 7;
animate = 2;
w = 24;
h = 25;
break; break;
//Warp Zone //Warp Zone
case rn(15, 2): // (numbers) case rn(15, 2): // (numbers)
tile = 100; obj.set_enemy_type(this, "numbers");
colour = 6;
animate = 1;
w = 32;
h = 14;
yp += 1; yp += 1;
lerpoldyp += 1; lerpoldyp += 1;
break; break;
case rn(16, 2): // (Manequins) case rn(16, 2): // (Manequins)
tile = 52; obj.set_enemy_type(this, "mannequin");
colour = 7;
animate = 5;
w = 16;
h = 25;
yp -= 4; yp -= 4;
lerpoldyp -= 4; lerpoldyp -= 4;
break; break;
case rn(18, 0): // (Obey) case rn(18, 0): // (Obey)
tile = 51; obj.set_enemy_type(this, "obey");
colour = 11;
animate = 100;
w = 30;
h = 14;
break; break;
case rn(19, 1): // Ascending and Descending case rn(19, 1): // Ascending and Descending
tile = 48; obj.set_enemy_type(this, "cross");
colour = 9;
animate = 5;
w = 16;
h = 16;
break; break;
case rn(19, 2): // Shockwave Rider case rn(19, 2): // Shockwave Rider
tile = 176; obj.set_enemy_type(this, "triangle");
colour = 6;
animate = 1;
w = 16;
h = 16;
break; break;
case rn(18, 3): // Mind the gap case rn(18, 3): // Mind the gap
tile = 168; obj.set_enemy_type(this, "ice");
colour = 7;
animate = 1;
w = 16;
h = 16;
break; break;
case rn(17, 3): // Edge Games case rn(17, 3): // Edge Games
if (yp == 96) if (yp == 96)
{ {
tile = 160; obj.set_enemy_type(this, "edgegames_left");
colour = 8;
animate = 1;
w = 16;
h = 16;
} }
else else
{ {
tile = 156; obj.set_enemy_type(this, "edgegames_right");
colour = 8;
animate = 1;
w = 16;
h = 16;
} }
break; break;
case rn(16, 0): // I love you case rn(16, 0): // I love you
tile = 112; obj.set_enemy_type(this, "heart");
colour = 8;
animate = 5;
w = 16;
h = 16;
break; break;
case rn(14, 2): // That's why I have to kill you case rn(14, 2): // That's why I have to kill you
tile = 114; obj.set_enemy_type(this, "broken_heart");
colour = 6;
animate = 5;
w = 16;
h = 16;
break; break;
case rn(18, 2): // Thinking with Portals case rn(18, 2): // Thinking with Portals
//depends on direction //depends on direction
size = 10;
if (xp == 88) if (xp == 88)
{ {
tile = 54+12; obj.set_enemy_type(this, "centipede_right");
colour = 12;
animate = 100;
w = 60;
h = 16;
size = 10;
} }
else else
{ {
tile = 54; obj.set_enemy_type(this, "centipede_left");
colour = 12;
animate = 100;
w = 60;
h = 16;
size = 10;
} }
break; break;
//Final level //Final level
case rn(50-100, 53-100): //The Yes Men case rn(50-100, 53-100): //The Yes Men
tile = 40; obj.set_enemy_type(this, "yes");
colour = 9;
animate = 1;
w = 20;
h = 20;
break; break;
case rn(48-100, 51-100): //Wavelengths case rn(48-100, 51-100): //Wavelengths
tile = 32; obj.set_enemy_type(this, "wavelength");
colour = 7;
animate = 1;
w = 32;
break; break;
case rn(43-100,52-100): // Ascending and Descending case rn(43-100,52-100): // Ascending and Descending
tile = 48; obj.set_enemy_type(this, "cross");
colour = 9;
animate = 5;
w = 16;
h = 16;
break; break;
case rn(46-100,51-100): //kids his age case rn(46-100,51-100): //kids his age
tile = 88; obj.set_enemy_type(this, "circle");
colour = 11;
animate = 1;
w = 16;
h = 16;
break; break;
case rn(43-100,51-100): // Mind the gap case rn(43-100,51-100): // Mind the gap
tile = 168; obj.set_enemy_type(this, "ice");
colour = 7;
animate = 1;
w = 16;
h = 16;
break; break;
case rn(44-100,51-100): // vertigo? case rn(44-100,51-100): // vertigo?
tile = 172; obj.set_enemy_type(this, "vertigo");
colour = 7;
animate = 100;
w = 32;
h = 32;
break; break;
case rn(44-100,52-100): // (backsliders) case rn(44-100,52-100): // (backsliders)
tile = 164; obj.set_enemy_type(this, "glitch");
colour = 7;
animate = 1;
w = 16;
h = 16;
break; break;
case rn(43-100, 56-100): //Intermission 1 case rn(43-100, 56-100): //Intermission 1
tile = 88; obj.set_enemy_type(this, "circle");
colour = 21;
animate = 1;
w = 16;
h = 16;
break; break;
case rn(45-100, 56-100): //Intermission 1 case rn(45-100, 56-100): //Intermission 1
tile = 88; obj.set_enemy_type(this, "circle");
colour = 21;
animate = 1;
w = 16;
h = 16;
break; break;
//The elephant //The elephant
case rn(11, 9): case rn(11, 9):
case rn(12, 9): case rn(12, 9):
case rn(11, 8): case rn(11, 8):
case rn(12, 8): case rn(12, 8):
tile = 0; obj.set_enemy_type(this, "elephant");
colour = 102;
animate = 0;
w = 464;
h = 320;
size = 11; size = 11;
harmful = false; harmful = false;
break; break;

View file

@ -1,6 +1,7 @@
#define OBJ_DEFINITION #define OBJ_DEFINITION
#include "Entity.h" #include "Entity.h"
#include <map>
#include <SDL.h> #include <SDL.h>
#include "CustomLevels.h" #include "CustomLevels.h"
@ -99,6 +100,117 @@ void entityclass::init(void)
SDL_memset(customcollect, false, sizeof(customcollect)); SDL_memset(customcollect, false, sizeof(customcollect));
k = 0; k = 0;
enemy_types.clear();
add_default_types();
}
void entityclass::create_type(const char* type, int tile, int colour, int animate, int width, int height)
{
EnemyType enemy_type;
enemy_type.tile = tile;
enemy_type.colour = colour;
enemy_type.animate = animate;
enemy_type.width = width;
enemy_type.height = height;
enemy_types[type] = enemy_type;
}
void entityclass::add_default_types(void)
{
create_type("square", 78, 7, 1, 16, 16); // Vibrating String Problem
create_type("circle", 88, 11, 1, 16, 16); // Kids His Age Bounce
create_type("disc", 36, 8, 1, 16, 16); // Security Sweep
create_type("glitch", 164, 7, 1, 16, 16); // Backsliders
create_type("coin", 68, 7, 1, 16, 16); // $eeing Dollar $ign$
create_type("cross", 48, 9, 5, 16, 16); // Ascending and Descending
create_type("triangle", 176, 6, 1, 16, 16); // Shockwave Rider
create_type("ice", 168, 7, 1, 16, 16); // Mind The Gap
create_type("heart", 112, 8, 5, 16, 16); // I Love You
create_type("broken_heart", 114, 6, 5, 16, 16); // That's Why I Have To Kill You
create_type("bowtie", 92, 6, 1, 16, 16); // A Deception
create_type("crate", 24, 6, 1, 16, 16); // UNUSED in main game
create_type("wavelength", 32, 7, 1, 32, 16); // Linear Collider
create_type("stop", 28, 6, 1, 22, 32); // Traffic Jam
create_type("yes", 40, 9, 1, 20, 20); // The Yes Men
create_type("bus", 96, 6, 4, 64, 44); // B-B-B-Busted
create_type("vertigo", 172, 7, 100, 32, 32); // Vertigo
create_type("guard", 44, 8, 1, 16, 20); // Trench Warfare
create_type("truth", 64, 7, 100, 44, 10); // Boldly To Go
create_type("obey", 51, 11, 100, 30, 14); // Time to get serious
create_type("mannequin", 52, 7, 5, 16, 25); // Short Circuit
create_type("numbers", 100, 6, 1, 32, 14); // Take the Red Pill
create_type("ghost", 106, 7, 2, 24, 25); // The Tomb of Mad Carew
create_type("wheel", 116, 12, 1, 32, 32); // The Hanged Man, Reversed
create_type("skeleton", 56, 6, 1, 15, 24); // You Chose... Poorly
create_type("solider", 82, 8, 5, 28, 32); // Brass Sent Us Under The Top
create_type("transmitter", 104, 4, 7, 16, 16); // Comms Relay
create_type("radar", 124, 4, 6, 32, 32); // Comms Relay
create_type("edgegames_left", 160, 8, 1, 16, 16); // Edge Games
create_type("edgegames_right", 156, 8, 1, 16, 16); // Edge Games
create_type("centipede_right", 66, 12, 100, 60, 16); // Sweeney's Maze
create_type("centipede_left", 54, 12, 100, 60, 16); // Sweeney's Maze
// LIES
create_type("lies_emitter", 60, 6, 2, 32, 32);
create_type("lies", 63, 6, 100, 26, 10);
create_type("lies_collector", 62, 6, 100, 32, 32);
// Factory
create_type("factory_emitter", 72, 6, 3, 64, 40);
create_type("factory_clouds", 76, 6, 100, 32, 12);
create_type("factory_collector", 77, 6, 100, 32, 16);
// Elephant
create_type("elephant", 0, 102, 0, 464, 320);
}
void entityclass::set_enemy_type(entclass* entity, const char* type)
{
if (enemy_types.count(type) > 0)
{
EnemyType* enemyType = &enemy_types[type];
entity->tile = enemyType->tile;
entity->colour = enemyType->colour;
entity->animate = enemyType->animate;
entity->w = enemyType->width;
entity->h = enemyType->height;
}
}
const char* entityclass::legacy_id_to_entity(const int id)
{
switch (id)
{
case 0:
return "square";
case 1:
return "circle";
case 2:
return "disc";
case 3:
return "glitch";
case 4:
return "coin";
case 5:
return "cross";
case 6:
return "triangle";
case 7:
return "ice";
case 8:
return "heart";
case 9:
return "broken_heart";
default:
return "square";
}
} }
void entityclass::resetallflags(void) void entityclass::resetallflags(void)
@ -1371,16 +1483,6 @@ void entityclass::createentity(int xp, int yp, int t, int meta1, int meta2, int
entity.setenemy(1); entity.setenemy(1);
entity.setenemyroom(game.roomx, game.roomy); //For colour entity.setenemyroom(game.roomx, game.roomy); //For colour
} }
else if (game.roomx == 113 && game.roomy == 107)
{
//MAVVERRRICK
entity.tile = 96;
entity.colour = 6;
entity.size = 9;
entity.w = 64;
entity.h = 44;
entity.animate = 4;
}
else else
{ {
entity.setenemyroom(game.roomx, game.roomy); entity.setenemyroom(game.roomx, game.roomy);
@ -2112,19 +2214,8 @@ void entityclass::createentity(int xp, int yp, int t, int meta1, int meta2, int
entity.harmful = true; entity.harmful = true;
switch(customenemy){ const char* type = legacy_id_to_entity(customenemy);
case 0: entity.setenemyroom(4+100, 0+100); break; set_enemy_type(&entity, type);
case 1: entity.setenemyroom(2+100, 0+100); break;
case 2: entity.setenemyroom(12+100, 3+100); break;
case 3: entity.setenemyroom(13+100, 12+100); break;
case 4: entity.setenemyroom(16+100, 9+100); break;
case 5: entity.setenemyroom(19+100, 1+100); break;
case 6: entity.setenemyroom(19+100, 2+100); break;
case 7: entity.setenemyroom(18+100, 3+100); break;
case 8: entity.setenemyroom(16+100, 0+100); break;
case 9: entity.setenemyroom(14+100, 2+100); break;
default: entity.setenemyroom(4+100, 0+100); break;
}
//Set colour based on room tile //Set colour based on room tile
//Set custom colours //Set custom colours

View file

@ -1,6 +1,7 @@
#ifndef ENTITY_H #ifndef ENTITY_H
#define ENTITY_H #define ENTITY_H
#include <map>
#include <SDL.h> #include <SDL.h>
#include <string> #include <string>
#include <vector> #include <vector>
@ -32,11 +33,25 @@ enum
TELEPORTER = 102 TELEPORTER = 102
}; };
struct EnemyType
{
int tile;
int colour;
int animate;
int width;
int height;
};
class entityclass class entityclass
{ {
public: public:
void init(void); void init(void);
void create_type(const char* type, int tile, int colour, int animate, int width, int height);
void add_default_types(void);
const char* legacy_id_to_entity(int id);
void set_enemy_type(entclass* entity, const char* type);
void resetallflags(void); void resetallflags(void);
void fatal_top(void) void fatal_top(void)
@ -200,6 +215,8 @@ public:
std::string customactivitycolour; std::string customactivitycolour;
std::string customactivitytext; std::string customactivitytext;
int customactivitypositiony; int customactivitypositiony;
std::map<std::string, EnemyType> enemy_types;
}; };
#ifndef OBJ_DEFINITION #ifndef OBJ_DEFINITION