Add textbox indexes, update trinket/crew textboxes

This adds an attribute to textboxclass to allow a text box to keep an
index that references another text box inside the graphics.textboxes
std::vector.

This is needed because the second text box of a "You have found a
shiny trinket!" or "You have found a lost crewmate!" pair of text boxes
explicitly relies on the height of the first text box. With this, I have
moved those text boxes over to the new text box translation system.

Since the update order now matters, I added a comment to
recomputetextboxes() that clarifies that the text boxes must be updated
in linear order, starting from 0.
This commit is contained in:
Misa 2024-01-21 12:39:15 -08:00 committed by Misa Elizabeth Kai
parent 668d0c744d
commit 7088858957
7 changed files with 124 additions and 79 deletions

View File

@ -1000,6 +1000,86 @@ static void im1_instructions_textbox3(textboxclass* THIS)
THIS->padtowidth(36*8);
}
/* Also used in foundtrinket() script command. */
void foundtrinket_textbox1(textboxclass* THIS)
{
THIS->lines.clear();
THIS->lines.push_back(loc::gettext("Congratulations!\n\nYou have found a shiny trinket!"));
THIS->wrap(2);
THIS->centertext();
THIS->pad(1, 1);
}
/* Also used in foundtrinket() script command. */
void foundtrinket_textbox2(textboxclass* THIS)
{
extern Game game;
THIS->lines.clear();
const int max_trinkets = map.custommode ? cl.numtrinkets() : 20;
char buffer[SCREEN_WIDTH_CHARS + 1];
vformat_buf(
buffer, sizeof(buffer),
loc::gettext("{n_trinkets|wordy} out of {max_trinkets|wordy}"),
"n_trinkets:int, max_trinkets:int",
game.trinkets(), max_trinkets
);
THIS->lines.push_back(buffer);
if (INBOUNDS_VEC(THIS->other_textbox_index, graphics.textboxes)
&& &graphics.textboxes[THIS->other_textbox_index] != THIS)
{
THIS->yp = 95 + graphics.textboxes[THIS->other_textbox_index].h;
}
THIS->wrap(2);
THIS->centertext();
THIS->pad(1, 1);
}
static void foundcrewmate_textbox1(textboxclass* THIS)
{
THIS->lines.clear();
THIS->lines.push_back(loc::gettext("Congratulations!\n\nYou have found a lost crewmate!"));
THIS->wrap(2);
THIS->centertext();
THIS->pad(1, 1);
}
static void foundcrewmate_textbox2(textboxclass* THIS)
{
extern Game game;
THIS->lines.clear();
const int num_remaining = cl.numcrewmates() - game.crewmates();
if (num_remaining == 0)
{
THIS->lines.push_back(loc::gettext("All crewmates rescued!"));
}
else
{
char buffer[SCREEN_WIDTH_CHARS + 1];
loc::gettext_plural_fill(
buffer, sizeof(buffer),
"{n_crew|wordy} remain", "{n_crew|wordy} remains",
"n_crew:int",
num_remaining
);
THIS->lines.push_back(buffer);
}
if (INBOUNDS_VEC(THIS->other_textbox_index, graphics.textboxes)
&& &graphics.textboxes[THIS->other_textbox_index] != THIS)
{
THIS->yp = 95 + graphics.textboxes[THIS->other_textbox_index].h;
}
THIS->wrap(4);
THIS->centertext();
THIS->pad(2, 2);
}
void Game::setstate(const int gamestate)
{
if (!statelocked || GlitchrunnerMode_less_than_or_equal(Glitchrunner2_2))
@ -2189,43 +2269,22 @@ void Game::updatestate(void)
setstatedelay(15);
break;
case 1001:
{
//Found a trinket!
advancetext = true;
incstate();
graphics.createtextboxflipme(loc::gettext("Congratulations!\n\nYou have found a shiny trinket!"), 50, 85, TEXT_COLOUR("gray"));
graphics.createtextboxflipme("", 50, 85, TEXT_COLOUR("gray"));
graphics.textboxprintflags(PR_FONT_INTERFACE);
int h = graphics.textboxwrap(2);
graphics.textboxcentertext();
graphics.textboxpad(1, 1);
graphics.textboxcenterx();
graphics.textboxtranslate(TEXTTRANSLATE_FUNCTION, foundtrinket_textbox1);
graphics.textboxapplyposition();
int max_trinkets;
if(map.custommode)
{
max_trinkets = cl.numtrinkets();
}
else
{
max_trinkets = 20;
}
char buffer[SCREEN_WIDTH_CHARS + 1];
vformat_buf(
buffer, sizeof(buffer),
loc::gettext("{n_trinkets|wordy} out of {max_trinkets|wordy}"),
"n_trinkets:int, max_trinkets:int",
trinkets(), max_trinkets
);
graphics.createtextboxflipme(buffer, 50, 95+h, TEXT_COLOUR("gray"));
graphics.createtextboxflipme("", 50, 95, TEXT_COLOUR("gray"));
graphics.textboxprintflags(PR_FONT_INTERFACE);
graphics.textboxwrap(2);
graphics.textboxcentertext();
graphics.textboxpad(1, 1);
graphics.textboxcenterx();
graphics.textboxindex(graphics.textboxes.size() - 2);
graphics.textboxtranslate(TEXTTRANSLATE_FUNCTION, foundtrinket_textbox2);
graphics.textboxapplyposition();
break;
}
case 1002:
if (!advancetext)
{
@ -2254,39 +2313,22 @@ void Game::updatestate(void)
setstatedelay(15);
break;
case 1011:
{
//Found a crewmate!
advancetext = true;
incstate();
graphics.createtextboxflipme(loc::gettext("Congratulations!\n\nYou have found a lost crewmate!"), 50, 85, TEXT_COLOUR("gray"));
graphics.createtextboxflipme("", 50, 85, TEXT_COLOUR("gray"));
graphics.textboxprintflags(PR_FONT_INTERFACE);
int h = graphics.textboxwrap(2);
graphics.textboxcentertext();
graphics.textboxpad(1, 1);
graphics.textboxcenterx();
graphics.textboxtranslate(TEXTTRANSLATE_FUNCTION, foundcrewmate_textbox1);
graphics.textboxapplyposition();
if(cl.numcrewmates()-crewmates()==0)
{
graphics.createtextboxflipme(loc::gettext("All crewmates rescued!"), 50, 95+h, TEXT_COLOUR("gray"));
}
else
{
char buffer[SCREEN_WIDTH_CHARS + 1];
loc::gettext_plural_fill(
buffer, sizeof(buffer),
"{n_crew|wordy} remain", "{n_crew|wordy} remains",
"n_crew:int",
cl.numcrewmates()-crewmates()
);
graphics.createtextboxflipme(buffer, 50, 95+h, TEXT_COLOUR("gray"));
}
graphics.createtextboxflipme("", 50, 95, TEXT_COLOUR("gray"));
graphics.textboxprintflags(PR_FONT_INTERFACE);
graphics.textboxwrap(4);
graphics.textboxcentertext();
graphics.textboxpad(2, 2);
graphics.textboxcenterx();
graphics.textboxindex(graphics.textboxes.size() - 2);
graphics.textboxtranslate(TEXTTRANSLATE_FUNCTION, foundcrewmate_textbox2);
graphics.textboxapplyposition();
break;
}
case 1012:
if (!advancetext)
{

View File

@ -1525,6 +1525,17 @@ int Graphics::getlinegap(void)
return 1;
}
void Graphics::textboxindex(const int index)
{
if (!INBOUNDS_VEC(m, textboxes))
{
vlog_error("textboxindex() out-of-bounds!");
return;
}
textboxes[m].other_textbox_index = index;
}
void Graphics::createtextboxreal(
const std::string& t,
int xp, int yp,

View File

@ -137,6 +137,8 @@ public:
void setimage(TextboxImage image);
void textboxindex(int index);
void textboxremove(void);
void textboxremovefast(void);

View File

@ -271,7 +271,8 @@ static void updatebuttonmappings(int bind)
static void recomputetextboxes(void)
{
/* Retranslate and reposition all text boxes. */
/* Retranslate and reposition all text boxes.
* WARNING: Needs to update in linear order, starting from 0. */
for (size_t i = 0; i < graphics.textboxes.size(); i++)
{
graphics.textboxes[i].updatetext();

View File

@ -158,6 +158,10 @@ static int getcrewmanfromname(std::string name)
}
/* Also used in gamestate 1001. */
void foundtrinket_textbox1(textboxclass* THIS);
void foundtrinket_textbox2(textboxclass* THIS);
void scriptclass::run(void)
{
if (!running)
@ -1783,37 +1787,18 @@ void scriptclass::run(void)
graphics.textboxremovefast();
graphics.createtextboxflipme(loc::gettext("Congratulations!\n\nYou have found a shiny trinket!"), 50, 85, TEXT_COLOUR("gray"));
graphics.createtextboxflipme("", 50, 85, TEXT_COLOUR("gray"));
graphics.textboxprintflags(PR_FONT_INTERFACE);
int h = graphics.textboxwrap(2);
graphics.textboxcentertext();
graphics.textboxpad(1, 1);
graphics.textboxcenterx();
graphics.textboxtranslate(TEXTTRANSLATE_FUNCTION, foundtrinket_textbox1);
graphics.textboxapplyposition();
int max_trinkets;
if (map.custommode)
{
max_trinkets = cl.numtrinkets();
}
else
{
max_trinkets = 20;
}
char buffer[SCREEN_WIDTH_CHARS + 1];
vformat_buf(
buffer, sizeof(buffer),
loc::gettext("{n_trinkets|wordy} out of {max_trinkets|wordy}"),
"n_trinkets:int, max_trinkets:int",
game.trinkets(), max_trinkets
);
graphics.createtextboxflipme(buffer, 50, 95+h, TEXT_COLOUR("gray"));
graphics.createtextboxflipme("", 50, 95, TEXT_COLOUR("gray"));
graphics.textboxprintflags(PR_FONT_INTERFACE);
graphics.textboxwrap(2);
graphics.textboxcentertext();
graphics.textboxpad(1, 1);
graphics.textboxcenterx();
graphics.textboxindex(graphics.textboxes.size() - 2);
graphics.textboxtranslate(TEXTTRANSLATE_FUNCTION, foundtrinket_textbox2);
graphics.textboxapplyposition();
if (!game.backgroundtext)
{

View File

@ -45,6 +45,8 @@ textboxclass::textboxclass(int gap)
original = TextboxOriginalContext();
original.text_case = 1;
spacing = TextboxSpacing();
other_textbox_index = -1;
}
void textboxclass::addsprite(int x, int y, int tile, int col)

View File

@ -137,6 +137,8 @@ public:
TextboxOriginalContext original;
TextboxSpacing spacing;
TextboxFunction function;
int other_textbox_index;
};
#endif /* TEXTBOX_H */