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
|
//Start SDL
|
||||||
|
|
||||||
//Init
|
//Init
|
||||||
commands.resize(500);
|
|
||||||
words.resize(40);
|
words.resize(40);
|
||||||
txt.resize(40);
|
txt.resize(40);
|
||||||
|
|
||||||
position = 0;
|
position = 0;
|
||||||
scriptlength = 0;
|
|
||||||
scriptdelay = 0;
|
scriptdelay = 0;
|
||||||
running = false;
|
running = false;
|
||||||
|
|
||||||
|
@ -72,7 +70,7 @@ void scriptclass::run( KeyPoll& key, Graphics& dwgfx, Game& game, mapclass& map,
|
||||||
{
|
{
|
||||||
while(running && scriptdelay<=0 && !game.pausescript)
|
while(running && scriptdelay<=0 && !game.pausescript)
|
||||||
{
|
{
|
||||||
if (position < scriptlength)
|
if (position < (int) commands.size())
|
||||||
{
|
{
|
||||||
//Let's split or command in an array of words
|
//Let's split or command in an array of words
|
||||||
tokenize(commands[position]);
|
tokenize(commands[position]);
|
||||||
|
@ -3596,7 +3594,7 @@ void scriptclass::hardreset( KeyPoll& key, Graphics& dwgfx, Game& game,mapclass&
|
||||||
|
|
||||||
//Script Stuff
|
//Script Stuff
|
||||||
position = 0;
|
position = 0;
|
||||||
scriptlength = 0;
|
commands.clear();
|
||||||
scriptdelay = 0;
|
scriptdelay = 0;
|
||||||
scriptname = "null";
|
scriptname = "null";
|
||||||
running = false;
|
running = false;
|
||||||
|
|
|
@ -23,8 +23,7 @@ public:
|
||||||
|
|
||||||
void inline add(std::string t)
|
void inline add(std::string t)
|
||||||
{
|
{
|
||||||
commands[scriptlength] = t;
|
commands.push_back(t);
|
||||||
scriptlength++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearcustom();
|
void clearcustom();
|
||||||
|
@ -51,7 +50,7 @@ public:
|
||||||
std::vector<std::string> words;
|
std::vector<std::string> words;
|
||||||
std::vector<std::string> txt;
|
std::vector<std::string> txt;
|
||||||
std::string scriptname;
|
std::string scriptname;
|
||||||
int position, scriptlength;
|
int position;
|
||||||
int looppoint, loopcount;
|
int looppoint, loopcount;
|
||||||
|
|
||||||
int scriptdelay;
|
int scriptdelay;
|
||||||
|
|
|
@ -11,7 +11,7 @@ void scriptclass::load(std::string t)
|
||||||
{
|
{
|
||||||
//loads script name t into the array
|
//loads script name t into the array
|
||||||
position = 0;
|
position = 0;
|
||||||
scriptlength=0;
|
commands.clear();
|
||||||
running = true;
|
running = true;
|
||||||
|
|
||||||
int maxlength = (std::min(int(t.length()),7));
|
int maxlength = (std::min(int(t.length()),7));
|
||||||
|
|
|
@ -324,25 +324,11 @@ void editorclass::reset()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(numhooks>0)
|
hooklist.clear();
|
||||||
{
|
|
||||||
for(int i=0; i<numhooks; i++)
|
|
||||||
{
|
|
||||||
removehook(hooklist[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < 500; i++)
|
sb.clear();
|
||||||
{
|
|
||||||
sb[i]="";
|
|
||||||
}
|
|
||||||
for (int i = 0; i < 500; i++)
|
|
||||||
{
|
|
||||||
hooklist[i]="";
|
|
||||||
}
|
|
||||||
|
|
||||||
clearscriptbuffer();
|
clearscriptbuffer();
|
||||||
sblength=1;
|
|
||||||
sbx=0;
|
sbx=0;
|
||||||
sby=0;
|
sby=0;
|
||||||
pagey=0;
|
pagey=0;
|
||||||
|
@ -353,7 +339,6 @@ void editorclass::reset()
|
||||||
|
|
||||||
hookmenupage=0;
|
hookmenupage=0;
|
||||||
hookmenu=0;
|
hookmenu=0;
|
||||||
numhooks=0;
|
|
||||||
script.customscript.clear();
|
script.customscript.clear();
|
||||||
|
|
||||||
returneditoralpha = 0;
|
returneditoralpha = 0;
|
||||||
|
@ -370,7 +355,7 @@ void editorclass::weirdloadthing(std::string t)
|
||||||
void editorclass::gethooks()
|
void editorclass::gethooks()
|
||||||
{
|
{
|
||||||
//Scan through the script and create a hooks list based on it
|
//Scan through the script and create a hooks list based on it
|
||||||
numhooks=0;
|
hooklist.clear();
|
||||||
std::string tstring;
|
std::string tstring;
|
||||||
std::string tstring2;
|
std::string tstring2;
|
||||||
for(size_t i=0; i<script.customscript.size(); i++)
|
for(size_t i=0; i<script.customscript.size(); i++)
|
||||||
|
@ -392,8 +377,7 @@ void editorclass::gethooks()
|
||||||
{
|
{
|
||||||
tstring2+=tstring[j];
|
tstring2+=tstring[j];
|
||||||
}
|
}
|
||||||
hooklist[numhooks]=tstring2;
|
hooklist.push_back(tstring2);
|
||||||
numhooks++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -427,12 +411,15 @@ void editorclass::loadhookineditor(std::string t)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//load in this line
|
//load in this line
|
||||||
sb[sblength-1]=script.customscript[i];
|
sb.push_back(script.customscript[i]);
|
||||||
sblength++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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)
|
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
|
//Adds hook+the scriptbuffer to the end of the scriptclass
|
||||||
removehookfromscript(t);
|
removehookfromscript(t);
|
||||||
script.customscript.push_back(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)
|
void editorclass::removehook(std::string t)
|
||||||
{
|
{
|
||||||
//Check the hooklist for the hook t. If it's there, remove it from here and the script
|
//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++)
|
removehookfromscript(t);
|
||||||
{
|
hooklist.erase(std::remove(hooklist.begin(), hooklist.end(), t), hooklist.end());
|
||||||
if(hooklist[i]==t)
|
|
||||||
{
|
|
||||||
removehookfromscript(t);
|
|
||||||
for(int j=i; j<numhooks; j++)
|
|
||||||
{
|
|
||||||
hooklist[j]=hooklist[j+1];
|
|
||||||
}
|
|
||||||
hooklist[numhooks]="";
|
|
||||||
numhooks--;
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void editorclass::addhook(std::string t)
|
void editorclass::addhook(std::string t)
|
||||||
{
|
{
|
||||||
//Add an empty function to the list in both editor and script
|
//Add an empty function to the list in both editor and script
|
||||||
removehook(t);
|
removehook(t);
|
||||||
hooklist[numhooks]=t;
|
hooklist.push_back(t);
|
||||||
numhooks++;
|
|
||||||
addhooktoscript(t);
|
addhooktoscript(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool editorclass::checkhook(std::string t)
|
bool editorclass::checkhook(std::string t)
|
||||||
{
|
{
|
||||||
//returns true if hook t already is in the list
|
//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;
|
if(hooklist[i]==t) return true;
|
||||||
}
|
}
|
||||||
|
@ -538,43 +509,22 @@ bool editorclass::checkhook(std::string t)
|
||||||
|
|
||||||
void editorclass::clearscriptbuffer()
|
void editorclass::clearscriptbuffer()
|
||||||
{
|
{
|
||||||
for(int i=0; i<sblength+1; i++)
|
sb.clear();
|
||||||
{
|
|
||||||
sb[i]="";
|
|
||||||
}
|
|
||||||
sblength=1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void editorclass::removeline(int t)
|
void editorclass::removeline(int t)
|
||||||
{
|
{
|
||||||
//Remove line t from the script
|
//Remove line t from the script
|
||||||
if(sblength>1)
|
if((int)sb.size()>1)
|
||||||
{
|
{
|
||||||
if(sblength==t)
|
sb.erase(sb.begin() + t);
|
||||||
{
|
|
||||||
sblength--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for(int i=t; i<sblength; i++)
|
|
||||||
{
|
|
||||||
sb[i]=sb[i+1];
|
|
||||||
}
|
|
||||||
sb[sblength]="";
|
|
||||||
sblength--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void editorclass::insertline(int t)
|
void editorclass::insertline(int t)
|
||||||
{
|
{
|
||||||
//insert a blank line into script at line t
|
//insert a blank line into script at line t
|
||||||
for(int i=sblength; i>=t; i--)
|
sb.insert(sb.begin() + t, "");
|
||||||
{
|
|
||||||
sb[i+1]=sb[i];
|
|
||||||
}
|
|
||||||
sb[t]="";
|
|
||||||
sblength++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void editorclass::loadlevel( int rxi, int ryi )
|
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,44,"PRESS ESC TO RETURN TO MENU", 123, 111, 218, true);
|
||||||
//dwgfx.Print(16,60,"READY.", 123, 111, 218, false);
|
//dwgfx.Print(16,60,"READY.", 123, 111, 218, false);
|
||||||
|
|
||||||
if(ed.numhooks>0)
|
if(!ed.hooklist.empty())
|
||||||
{
|
{
|
||||||
for(int i=0; i<9; i++)
|
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)
|
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);
|
std::transform(tstring.begin(), tstring.end(),tstring.begin(), ::toupper);
|
||||||
dwgfx.Print(16,68+(i*16),tstring,123, 111, 218, true);
|
dwgfx.Print(16,68+(i*16),tstring,123, 111, 218, true);
|
||||||
}
|
}
|
||||||
else
|
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
|
//Draw text
|
||||||
for(int i=0; i<25; i++)
|
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);
|
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,i*8,script.customscript[i],255,255,255);
|
||||||
}
|
}
|
||||||
dwgfx.Print(0,8*script.customscript.size(),help.String(script.customscript.size()),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,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)
|
if(ed.notedelay>0)
|
||||||
|
@ -3718,9 +3668,9 @@ void editorinput( KeyPoll& key, Graphics& dwgfx, Game& game, mapclass& map, enti
|
||||||
ed.hookmenu++;
|
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;
|
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;
|
ed.deletekeyheld=1;
|
||||||
music.playef(2);
|
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
|
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;
|
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;
|
game.mapheld=true;
|
||||||
ed.scripthelppage=1;
|
ed.scripthelppage=1;
|
||||||
key.keybuffer="";
|
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.loadhookineditor(ed.sbscript);
|
||||||
|
|
||||||
ed.sby=ed.sblength-1;
|
ed.sby=ed.sb.size()-1;
|
||||||
ed.pagey=0;
|
ed.pagey=0;
|
||||||
while(ed.sby>=20)
|
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)
|
if(key.keymap[SDLK_DOWN] && ed.keydelay<=0)
|
||||||
{
|
{
|
||||||
ed.keydelay=6;
|
ed.keydelay=6;
|
||||||
if(ed.sby+ed.pagey<ed.sblength-1)
|
if(ed.sby+ed.pagey<(int)ed.sb.size()-1)
|
||||||
{
|
{
|
||||||
ed.sby++;
|
ed.sby++;
|
||||||
if(ed.sby>=20)
|
if(ed.sby>=20)
|
||||||
|
@ -3862,7 +3812,7 @@ void editorinput( KeyPoll& key, Graphics& dwgfx, Game& game, mapclass& map, enti
|
||||||
{
|
{
|
||||||
game.mapheld=true;
|
game.mapheld=true;
|
||||||
//Continue to next line
|
//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++;
|
ed.sby++;
|
||||||
if(ed.sby>=20)
|
if(ed.sby>=20)
|
||||||
|
@ -3870,7 +3820,6 @@ void editorinput( KeyPoll& key, Graphics& dwgfx, Game& game, mapclass& map, enti
|
||||||
ed.pagey++;
|
ed.pagey++;
|
||||||
ed.sby--;
|
ed.sby--;
|
||||||
}
|
}
|
||||||
if(ed.sby+ed.pagey>=ed.sblength) ed.sblength=ed.sby+ed.pagey;
|
|
||||||
key.keybuffer=ed.sb[ed.pagey+ed.sby];
|
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());
|
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;
|
bool scripteditmod;
|
||||||
int scripthelppage, scripthelppagedelay;
|
int scripthelppage, scripthelppagedelay;
|
||||||
std::string sb[500];
|
std::vector<std::string> sb;
|
||||||
std::string sbscript;
|
std::string sbscript;
|
||||||
int sblength;
|
|
||||||
int sbx, sby;
|
int sbx, sby;
|
||||||
int pagey;
|
int pagey;
|
||||||
|
|
||||||
|
@ -226,8 +225,7 @@ class editorclass{
|
||||||
void clearscriptbuffer();
|
void clearscriptbuffer();
|
||||||
void gethooks();
|
void gethooks();
|
||||||
bool checkhook(std::string t);
|
bool checkhook(std::string t);
|
||||||
std::string hooklist[500];
|
std::vector<std::string> hooklist;
|
||||||
int numhooks;
|
|
||||||
|
|
||||||
int hookmenupage, hookmenu;
|
int hookmenupage, hookmenu;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue