1
0
Fork 0
mirror of https://github.com/TerryCavanagh/VVVVVV.git synced 2024-12-22 17:49: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)
{
switch(t)
{
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;
}
return (&obj.enemy_types[obj.legacy_id_to_entity(t)])->tile;
}
void editorclass::set_tile(int x, int y, int t)

View file

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

View file

@ -1,6 +1,7 @@
#define OBJ_DEFINITION
#include "Entity.h"
#include <map>
#include <SDL.h>
#include "CustomLevels.h"
@ -99,6 +100,117 @@ void entityclass::init(void)
SDL_memset(customcollect, false, sizeof(customcollect));
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)
@ -1371,16 +1483,6 @@ void entityclass::createentity(int xp, int yp, int t, int meta1, int meta2, int
entity.setenemy(1);
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
{
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;
switch(customenemy){
case 0: entity.setenemyroom(4+100, 0+100); break;
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;
}
const char* type = legacy_id_to_entity(customenemy);
set_enemy_type(&entity, type);
//Set colour based on room tile
//Set custom colours

View file

@ -1,6 +1,7 @@
#ifndef ENTITY_H
#define ENTITY_H
#include <map>
#include <SDL.h>
#include <string>
#include <vector>
@ -32,11 +33,25 @@ enum
TELEPORTER = 102
};
struct EnemyType
{
int tile;
int colour;
int animate;
int width;
int height;
};
class entityclass
{
public:
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 fatal_top(void)
@ -200,6 +215,8 @@ public:
std::string customactivitycolour;
std::string customactivitytext;
int customactivitypositiony;
std::map<std::string, EnemyType> enemy_types;
};
#ifndef OBJ_DEFINITION