mirror of
https://github.com/TerryCavanagh/VVVVVV.git
synced 2024-12-22 17:49:43 +01:00
Make commands
, sb
, and hooklist
not use separate length-trackers
This is a refactor that turns the script-related arrays `ed.sb`, and `ed.hooklist` into C++ vectors (`script.commands` was already a vector, it was just misused). The code handling these vectors now looks more like idiomatic C++ than sloppily-pasted pseudo-ActionScript. This removes the variables `script.scriptlength`, `ed.sblength`, and `ed.numhooks`, too. This reduces the amount of code needed to e.g. simply remove something from any of these vectors. Previously the code had to manually shift the rest of the elements down one-by-one, and doing it manually is definitely error-prone and tedious. But now we can just use fancy functions like `std::vector::erase()` and `std::remove()` to do it all in one line! Don't worry, I checked and `std::remove()` is in the C++ standard since at least 1998. This patch makes it so the `commands` vector gets cleared when `scriptclass::load()` is ran. Previously, the `commands` vector never actually properly got cleared, so there could potentially be glitches that rely on the game indexing past the bounds set by `scriptlength` but still in-bounds in the eyes of C++, and people could potentially rely on such an exploit... However, I checked, and I'm pretty sure that no such glitch previously existed at all, because the only times the vector gets indexed are when `scriptlength` is either being incremented after starting from 0 (`add()`) or when it's underneath a `position < scriptlength` conditional. Furthermore, I'm unaware of anyone who has actually found or used such an exploit, and I've been in the custom level community for 6 years. So I think it's fine.
This commit is contained in:
parent
58fc42b638
commit
1be398319c
5 changed files with 43 additions and 99 deletions
|
@ -11,12 +11,10 @@ scriptclass::scriptclass()
|
|||
//Start SDL
|
||||
|
||||
//Init
|
||||
commands.resize(500);
|
||||
words.resize(40);
|
||||
txt.resize(40);
|
||||
|
||||
position = 0;
|
||||
scriptlength = 0;
|
||||
scriptdelay = 0;
|
||||
running = false;
|
||||
|
||||
|
@ -72,7 +70,7 @@ void scriptclass::run( KeyPoll& key, Graphics& dwgfx, Game& game, mapclass& map,
|
|||
{
|
||||
while(running && scriptdelay<=0 && !game.pausescript)
|
||||
{
|
||||
if (position < scriptlength)
|
||||
if (position < (int) commands.size())
|
||||
{
|
||||
//Let's split or command in an array of words
|
||||
tokenize(commands[position]);
|
||||
|
@ -3596,7 +3594,7 @@ void scriptclass::hardreset( KeyPoll& key, Graphics& dwgfx, Game& game,mapclass&
|
|||
|
||||
//Script Stuff
|
||||
position = 0;
|
||||
scriptlength = 0;
|
||||
commands.clear();
|
||||
scriptdelay = 0;
|
||||
scriptname = "null";
|
||||
running = false;
|
||||
|
|
|
@ -23,8 +23,7 @@ public:
|
|||
|
||||
void inline add(std::string t)
|
||||
{
|
||||
commands[scriptlength] = t;
|
||||
scriptlength++;
|
||||
commands.push_back(t);
|
||||
}
|
||||
|
||||
void clearcustom();
|
||||
|
@ -51,7 +50,7 @@ public:
|
|||
std::vector<std::string> words;
|
||||
std::vector<std::string> txt;
|
||||
std::string scriptname;
|
||||
int position, scriptlength;
|
||||
int position;
|
||||
int looppoint, loopcount;
|
||||
|
||||
int scriptdelay;
|
||||
|
|
|
@ -11,7 +11,7 @@ void scriptclass::load(std::string t)
|
|||
{
|
||||
//loads script name t into the array
|
||||
position = 0;
|
||||
scriptlength=0;
|
||||
commands.clear();
|
||||
running = true;
|
||||
|
||||
int maxlength = (std::min(int(t.length()),7));
|
||||
|
|
|
@ -324,25 +324,11 @@ void editorclass::reset()
|
|||
}
|
||||
}
|
||||
|
||||
if(numhooks>0)
|
||||
{
|
||||
for(int i=0; i<numhooks; i++)
|
||||
{
|
||||
removehook(hooklist[i]);
|
||||
}
|
||||
}
|
||||
hooklist.clear();
|
||||
|
||||
for (int i = 0; i < 500; i++)
|
||||
{
|
||||
sb[i]="";
|
||||
}
|
||||
for (int i = 0; i < 500; i++)
|
||||
{
|
||||
hooklist[i]="";
|
||||
}
|
||||
sb.clear();
|
||||
|
||||
clearscriptbuffer();
|
||||
sblength=1;
|
||||
sbx=0;
|
||||
sby=0;
|
||||
pagey=0;
|
||||
|
@ -353,7 +339,6 @@ void editorclass::reset()
|
|||
|
||||
hookmenupage=0;
|
||||
hookmenu=0;
|
||||
numhooks=0;
|
||||
script.customscript.clear();
|
||||
|
||||
returneditoralpha = 0;
|
||||
|
@ -370,7 +355,7 @@ void editorclass::weirdloadthing(std::string t)
|
|||
void editorclass::gethooks()
|
||||
{
|
||||
//Scan through the script and create a hooks list based on it
|
||||
numhooks=0;
|
||||
hooklist.clear();
|
||||
std::string tstring;
|
||||
std::string tstring2;
|
||||
for(size_t i=0; i<script.customscript.size(); i++)
|
||||
|
@ -392,8 +377,7 @@ void editorclass::gethooks()
|
|||
{
|
||||
tstring2+=tstring[j];
|
||||
}
|
||||
hooklist[numhooks]=tstring2;
|
||||
numhooks++;
|
||||
hooklist.push_back(tstring2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -427,12 +411,15 @@ void editorclass::loadhookineditor(std::string t)
|
|||
else
|
||||
{
|
||||
//load in this line
|
||||
sb[sblength-1]=script.customscript[i];
|
||||
sblength++;
|
||||
sb.push_back(script.customscript[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(sblength>1) sblength--;
|
||||
if(sb.empty())
|
||||
{
|
||||
//Always have one line or we'll have problems
|
||||
sb.resize(1);
|
||||
}
|
||||
}
|
||||
|
||||
void editorclass::addhooktoscript(std::string t)
|
||||
|
@ -440,12 +427,9 @@ void editorclass::addhooktoscript(std::string t)
|
|||
//Adds hook+the scriptbuffer to the end of the scriptclass
|
||||
removehookfromscript(t);
|
||||
script.customscript.push_back(t+":");
|
||||
if(sblength>=1)
|
||||
for(size_t i=0; i<sb.size(); i++)
|
||||
{
|
||||
for(int i=0; i<sblength; i++)
|
||||
{
|
||||
script.customscript.push_back(sb[i]);
|
||||
}
|
||||
script.customscript.push_back(sb[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -500,35 +484,22 @@ void editorclass::removehookfromscript(std::string t)
|
|||
void editorclass::removehook(std::string t)
|
||||
{
|
||||
//Check the hooklist for the hook t. If it's there, remove it from here and the script
|
||||
for(int i=0; i<numhooks; i++)
|
||||
{
|
||||
if(hooklist[i]==t)
|
||||
{
|
||||
removehookfromscript(t);
|
||||
for(int j=i; j<numhooks; j++)
|
||||
{
|
||||
hooklist[j]=hooklist[j+1];
|
||||
}
|
||||
hooklist[numhooks]="";
|
||||
numhooks--;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
removehookfromscript(t);
|
||||
hooklist.erase(std::remove(hooklist.begin(), hooklist.end(), t), hooklist.end());
|
||||
}
|
||||
|
||||
void editorclass::addhook(std::string t)
|
||||
{
|
||||
//Add an empty function to the list in both editor and script
|
||||
removehook(t);
|
||||
hooklist[numhooks]=t;
|
||||
numhooks++;
|
||||
hooklist.push_back(t);
|
||||
addhooktoscript(t);
|
||||
}
|
||||
|
||||
bool editorclass::checkhook(std::string t)
|
||||
{
|
||||
//returns true if hook t already is in the list
|
||||
for(int i=0; i<numhooks; i++)
|
||||
for(size_t i=0; i<hooklist.size(); i++)
|
||||
{
|
||||
if(hooklist[i]==t) return true;
|
||||
}
|
||||
|
@ -538,43 +509,22 @@ bool editorclass::checkhook(std::string t)
|
|||
|
||||
void editorclass::clearscriptbuffer()
|
||||
{
|
||||
for(int i=0; i<sblength+1; i++)
|
||||
{
|
||||
sb[i]="";
|
||||
}
|
||||
sblength=1;
|
||||
sb.clear();
|
||||
}
|
||||
|
||||
void editorclass::removeline(int t)
|
||||
{
|
||||
//Remove line t from the script
|
||||
if(sblength>1)
|
||||
if((int)sb.size()>1)
|
||||
{
|
||||
if(sblength==t)
|
||||
{
|
||||
sblength--;
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int i=t; i<sblength; i++)
|
||||
{
|
||||
sb[i]=sb[i+1];
|
||||
}
|
||||
sb[sblength]="";
|
||||
sblength--;
|
||||
}
|
||||
sb.erase(sb.begin() + t);
|
||||
}
|
||||
}
|
||||
|
||||
void editorclass::insertline(int t)
|
||||
{
|
||||
//insert a blank line into script at line t
|
||||
for(int i=sblength; i>=t; i--)
|
||||
{
|
||||
sb[i+1]=sb[i];
|
||||
}
|
||||
sb[t]="";
|
||||
sblength++;
|
||||
sb.insert(sb.begin() + t, "");
|
||||
}
|
||||
|
||||
void editorclass::loadlevel( int rxi, int ryi )
|
||||
|
@ -2912,21 +2862,21 @@ void editorrender( KeyPoll& key, Graphics& dwgfx, Game& game, mapclass& map, ent
|
|||
dwgfx.Print(16,44,"PRESS ESC TO RETURN TO MENU", 123, 111, 218, true);
|
||||
//dwgfx.Print(16,60,"READY.", 123, 111, 218, false);
|
||||
|
||||
if(ed.numhooks>0)
|
||||
if(!ed.hooklist.empty())
|
||||
{
|
||||
for(int i=0; i<9; i++)
|
||||
{
|
||||
if(ed.hookmenupage+i<ed.numhooks)
|
||||
if(ed.hookmenupage+i<(int)ed.hooklist.size())
|
||||
{
|
||||
if(ed.hookmenupage+i==ed.hookmenu)
|
||||
{
|
||||
std::string tstring="> " + ed.hooklist[(ed.numhooks-1)-(ed.hookmenupage+i)] + " <";
|
||||
std::string tstring="> " + ed.hooklist[(ed.hooklist.size()-1)-(ed.hookmenupage+i)] + " <";
|
||||
std::transform(tstring.begin(), tstring.end(),tstring.begin(), ::toupper);
|
||||
dwgfx.Print(16,68+(i*16),tstring,123, 111, 218, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
dwgfx.Print(16,68+(i*16),ed.hooklist[(ed.numhooks-1)-(ed.hookmenupage+i)],123, 111, 218, true);
|
||||
dwgfx.Print(16,68+(i*16),ed.hooklist[(ed.hooklist.size()-1)-(ed.hookmenupage+i)],123, 111, 218, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2945,7 +2895,7 @@ void editorrender( KeyPoll& key, Graphics& dwgfx, Game& game, mapclass& map, ent
|
|||
//Draw text
|
||||
for(int i=0; i<25; i++)
|
||||
{
|
||||
if(i+ed.pagey<500)
|
||||
if(i+ed.pagey<(int)ed.sb.size())
|
||||
{
|
||||
dwgfx.Print(16,20+(i*8),ed.sb[i+ed.pagey], 123, 111, 218, false);
|
||||
}
|
||||
|
@ -3526,15 +3476,15 @@ void editorrender( KeyPoll& key, Graphics& dwgfx, Game& game, mapclass& map, ent
|
|||
}
|
||||
|
||||
/*
|
||||
for(int i=0; i<script.customscript.size(); i++){
|
||||
for(size_t i=0; i<script.customscript.size(); i++){
|
||||
dwgfx.Print(0,i*8,script.customscript[i],255,255,255);
|
||||
}
|
||||
dwgfx.Print(0,8*script.customscript.size(),help.String(script.customscript.size()),255,255,255);
|
||||
|
||||
for(int i=0; i<ed.numhooks; i++){
|
||||
for(size_t i=0; i<ed.hooklist.size(); i++){
|
||||
dwgfx.Print(260,i*8,ed.hooklist[i],255,255,255);
|
||||
}
|
||||
dwgfx.Print(260,8*ed.numhooks,help.String(ed.numhooks),255,255,255);
|
||||
dwgfx.Print(260,8*ed.hooklist.size(),help.String(ed.hooklist.size()),255,255,255);
|
||||
*/
|
||||
|
||||
if(ed.notedelay>0)
|
||||
|
@ -3718,9 +3668,9 @@ void editorinput( KeyPoll& key, Graphics& dwgfx, Game& game, mapclass& map, enti
|
|||
ed.hookmenu++;
|
||||
}
|
||||
|
||||
if(ed.hookmenu>=ed.numhooks)
|
||||
if(ed.hookmenu>=(int)ed.hooklist.size())
|
||||
{
|
||||
ed.hookmenu=ed.numhooks-1;
|
||||
ed.hookmenu=ed.hooklist.size()-1;
|
||||
}
|
||||
if(ed.hookmenu<0) ed.hookmenu=0;
|
||||
|
||||
|
@ -3740,7 +3690,7 @@ void editorinput( KeyPoll& key, Graphics& dwgfx, Game& game, mapclass& map, enti
|
|||
{
|
||||
ed.deletekeyheld=1;
|
||||
music.playef(2);
|
||||
ed.removehook(ed.hooklist[(ed.numhooks-1)-ed.hookmenu]);
|
||||
ed.removehook(ed.hooklist[(ed.hooklist.size()-1)-ed.hookmenu]);
|
||||
}
|
||||
|
||||
if (!game.press_action && !game.press_left && !game.press_right
|
||||
|
@ -3752,15 +3702,15 @@ void editorinput( KeyPoll& key, Graphics& dwgfx, Game& game, mapclass& map, enti
|
|||
{
|
||||
game.jumpheld = true;
|
||||
}
|
||||
if ((game.press_action || game.press_map) && ed.numhooks>0)
|
||||
if ((game.press_action || game.press_map) && !ed.hooklist.empty())
|
||||
{
|
||||
game.mapheld=true;
|
||||
ed.scripthelppage=1;
|
||||
key.keybuffer="";
|
||||
ed.sbscript=ed.hooklist[(ed.numhooks-1)-ed.hookmenu];
|
||||
ed.sbscript=ed.hooklist[(ed.hooklist.size()-1)-ed.hookmenu];
|
||||
ed.loadhookineditor(ed.sbscript);
|
||||
|
||||
ed.sby=ed.sblength-1;
|
||||
ed.sby=ed.sb.size()-1;
|
||||
ed.pagey=0;
|
||||
while(ed.sby>=20)
|
||||
{
|
||||
|
@ -3813,7 +3763,7 @@ void editorinput( KeyPoll& key, Graphics& dwgfx, Game& game, mapclass& map, enti
|
|||
if(key.keymap[SDLK_DOWN] && ed.keydelay<=0)
|
||||
{
|
||||
ed.keydelay=6;
|
||||
if(ed.sby+ed.pagey<ed.sblength-1)
|
||||
if(ed.sby+ed.pagey<(int)ed.sb.size()-1)
|
||||
{
|
||||
ed.sby++;
|
||||
if(ed.sby>=20)
|
||||
|
@ -3862,7 +3812,7 @@ void editorinput( KeyPoll& key, Graphics& dwgfx, Game& game, mapclass& map, enti
|
|||
{
|
||||
game.mapheld=true;
|
||||
//Continue to next line
|
||||
if(ed.sby+ed.pagey>=ed.sblength) //we're on the last line
|
||||
if(ed.sby+ed.pagey>=(int)ed.sb.size()) //we're on the last line
|
||||
{
|
||||
ed.sby++;
|
||||
if(ed.sby>=20)
|
||||
|
@ -3870,7 +3820,6 @@ void editorinput( KeyPoll& key, Graphics& dwgfx, Game& game, mapclass& map, enti
|
|||
ed.pagey++;
|
||||
ed.sby--;
|
||||
}
|
||||
if(ed.sby+ed.pagey>=ed.sblength) ed.sblength=ed.sby+ed.pagey;
|
||||
key.keybuffer=ed.sb[ed.pagey+ed.sby];
|
||||
ed.sbx = utf8::unchecked::distance(ed.sb[ed.pagey+ed.sby].begin(), ed.sb[ed.pagey+ed.sby].end());
|
||||
}
|
||||
|
|
|
@ -207,9 +207,8 @@ class editorclass{
|
|||
|
||||
bool scripteditmod;
|
||||
int scripthelppage, scripthelppagedelay;
|
||||
std::string sb[500];
|
||||
std::vector<std::string> sb;
|
||||
std::string sbscript;
|
||||
int sblength;
|
||||
int sbx, sby;
|
||||
int pagey;
|
||||
|
||||
|
@ -226,8 +225,7 @@ class editorclass{
|
|||
void clearscriptbuffer();
|
||||
void gethooks();
|
||||
bool checkhook(std::string t);
|
||||
std::string hooklist[500];
|
||||
int numhooks;
|
||||
std::vector<std::string> hooklist;
|
||||
|
||||
int hookmenupage, hookmenu;
|
||||
|
||||
|
|
Loading…
Reference in a new issue