mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-12-20 06:53:00 +00:00
Goner setup: cook
- Build list of incoming text
- First pass of very first section of dialogue
- Use srb2::Dialogue::Typewriter class to handle ticking through dialogue
- Store history log as incoming text is processed (possible todo: scrolling?)
This commit is contained in:
parent
1cf14f29dc
commit
ffb34204f5
3 changed files with 241 additions and 2 deletions
|
|
@ -53,6 +53,7 @@ void Dialogue::Typewriter::NewText(std::string newText)
|
|||
textTimer = kTextPunctPause;
|
||||
textSpeed = kTextSpeedDefault;
|
||||
textDone = false;
|
||||
textLines = 1;
|
||||
|
||||
syllable = true;
|
||||
}
|
||||
|
|
@ -79,6 +80,9 @@ void Dialogue::Typewriter::WriteText(void)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (c == '\n')
|
||||
textLines++;
|
||||
|
||||
if (!textDest.empty())
|
||||
nextc = textDest.back();
|
||||
|
||||
|
|
@ -115,7 +119,12 @@ void Dialogue::Typewriter::CompleteText(void)
|
|||
{
|
||||
while (!textDest.empty())
|
||||
{
|
||||
text.push_back( textDest.back() );
|
||||
char c = textDest.back();
|
||||
|
||||
if (c == '\n')
|
||||
textLines++;
|
||||
|
||||
text.push_back( c );
|
||||
textDest.pop_back();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ public:
|
|||
fixed_t textTimer;
|
||||
fixed_t textSpeed;
|
||||
bool textDone;
|
||||
int textLines;
|
||||
|
||||
sfxenum_t voiceSfx;
|
||||
bool syllable;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,12 @@
|
|||
/// \brief The Goner Setup.
|
||||
|
||||
#include "../k_menu.h"
|
||||
#include "../r_skins.h"
|
||||
#include "../st_stuff.h" // faceprefix
|
||||
#include "../v_draw.hpp"
|
||||
#include "../k_dialogue.hpp"
|
||||
|
||||
#include <forward_list>
|
||||
|
||||
menuitem_t MAIN_Goner[] =
|
||||
{
|
||||
|
|
@ -31,6 +37,7 @@ menuitem_t MAIN_Goner[] =
|
|||
};
|
||||
|
||||
static boolean M_GonerInputs(INT32 ch);
|
||||
static void M_GonerDrawer(void);
|
||||
|
||||
menu_t MAIN_GonerDef = {
|
||||
sizeof (MAIN_Goner) / sizeof (menuitem_t),
|
||||
|
|
@ -42,15 +49,156 @@ menu_t MAIN_GonerDef = {
|
|||
MBF_UD_LR_FLIPPED,
|
||||
"_GONER",
|
||||
0, 0,
|
||||
M_DrawHorizontalMenu,
|
||||
M_GonerDrawer,
|
||||
M_GonerTick,
|
||||
NULL,
|
||||
NULL,
|
||||
M_GonerInputs,
|
||||
};
|
||||
|
||||
// ---
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GONERSPEAKER_EGGMAN = 0,
|
||||
GONERSPEAKER_TAILS,
|
||||
MAXGONERSPEAKERS
|
||||
} gonerspeakers_t;
|
||||
|
||||
class GonerSpeaker
|
||||
{
|
||||
public:
|
||||
float offset;
|
||||
|
||||
GonerSpeaker(std::string skinName, float offset)
|
||||
{
|
||||
if (!skinName.empty())
|
||||
{
|
||||
this->skinID = R_SkinAvailable(skinName.c_str());
|
||||
}
|
||||
|
||||
this->offset = offset;
|
||||
};
|
||||
|
||||
sfxenum_t TalkSound(void)
|
||||
{
|
||||
if (!ValidID())
|
||||
return sfx_ktalk;
|
||||
|
||||
return skins[ skinID ]
|
||||
.soundsid[ S_sfx[sfx_ktalk].skinsound ];
|
||||
};
|
||||
|
||||
int GetSkinID(void)
|
||||
{
|
||||
if (!ValidID())
|
||||
return -1;
|
||||
|
||||
return skinID;
|
||||
};
|
||||
|
||||
private:
|
||||
int skinID = -1;
|
||||
bool ValidID(void)
|
||||
{
|
||||
return (skinID >= 0 && skinID < numskins);
|
||||
};
|
||||
};
|
||||
|
||||
std::array<std::optional<GonerSpeaker>, MAXGONERSPEAKERS> goner_speakers = {};
|
||||
|
||||
srb2::Dialogue::Typewriter goner_typewriter;
|
||||
|
||||
int goner_delay;
|
||||
|
||||
class GonerChatLine
|
||||
{
|
||||
public:
|
||||
gonerspeakers_t speaker;
|
||||
std::string dialogue;
|
||||
int value; // Mutlipurpose.
|
||||
|
||||
GonerChatLine(gonerspeakers_t speaker, int delay, std::string dialogue)
|
||||
{
|
||||
this->speaker = speaker;
|
||||
this->dialogue = V_ScaledWordWrap(
|
||||
(BASEVIDWIDTH/2 + 12) << FRACBITS,
|
||||
FRACUNIT, FRACUNIT, FRACUNIT,
|
||||
0, TINY_FONT,
|
||||
dialogue.c_str()
|
||||
);
|
||||
this->value = delay;
|
||||
};
|
||||
|
||||
// Returns true if line is text
|
||||
bool Handle(void)
|
||||
{
|
||||
if (speaker >= MAXGONERSPEAKERS)
|
||||
return false;
|
||||
|
||||
goner_typewriter.voiceSfx = sfx_ktalk;
|
||||
if (goner_speakers[speaker])
|
||||
{
|
||||
goner_typewriter.voiceSfx = (*goner_speakers[speaker]).TalkSound();
|
||||
}
|
||||
|
||||
goner_typewriter.NewText(dialogue);
|
||||
|
||||
goner_delay = value;
|
||||
|
||||
value = 1; // this is now repurposed as the number of lines visible
|
||||
|
||||
return true;
|
||||
};
|
||||
};
|
||||
|
||||
std::forward_list<GonerChatLine> LinesToDigest;
|
||||
std::forward_list<GonerChatLine> LinesOutput;
|
||||
|
||||
// ---
|
||||
|
||||
void M_GonerTick(void)
|
||||
{
|
||||
static bool speakersinit = false;
|
||||
if (!speakersinit)
|
||||
{
|
||||
goner_delay = TICRATE;
|
||||
|
||||
goner_speakers[GONERSPEAKER_EGGMAN] = GonerSpeaker("eggman", 0);
|
||||
goner_speakers[GONERSPEAKER_TAILS] = GonerSpeaker("tails", 12);
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, TICRATE,
|
||||
"Metal Sonic. Are you online?");
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, TICRATE/2,
|
||||
"Take a close look, Miles. Moments ago he was at my throat!\
|
||||
Now he's docile as can be on that operating table.");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, 0,
|
||||
"I don't feel very safe!");
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, TICRATE/4,
|
||||
"But its programming is definitely locked down...");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, 0,
|
||||
"You've given me quite the headache, Metal.\
|
||||
Thankfully, Tails caught you in the act.");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, TICRATE/5,
|
||||
"Wait, I'm getting weird readings over the network.");
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, 0,
|
||||
"Metal Sonic is the unit labeled \"MS1\", right?");
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_TAILS, TICRATE,
|
||||
"The ""\x87""viewport""\x80"" and ""\x87""audio""\x80"" config looks like it got messed up.");
|
||||
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, 0,
|
||||
"So you're right. I wonder if it has anything to do with that outburst.");
|
||||
LinesToDigest.emplace_front(GONERSPEAKER_EGGMAN, 0,
|
||||
"Alright, Metal! I don't remember your specifications offhand. First things first, go ahead and set up your ""\x87""Video Options""\x80"" yourself.");
|
||||
|
||||
LinesToDigest.reverse();
|
||||
|
||||
speakersinit = true;
|
||||
}
|
||||
|
||||
if (menutyping.active == false && cv_dummyextraspassword.string[0] != '\0')
|
||||
{
|
||||
// Challenges are not interpreted at this stage.
|
||||
|
|
@ -59,7 +207,88 @@ void M_GonerTick(void)
|
|||
cht_Interpret(cv_dummyextraspassword.string);
|
||||
CV_StealthSet(&cv_dummyextraspassword, "");
|
||||
}
|
||||
|
||||
goner_typewriter.WriteText();
|
||||
|
||||
if (goner_typewriter.textDone)
|
||||
{
|
||||
if (goner_delay > 0)
|
||||
goner_delay--;
|
||||
else if (!LinesToDigest.empty())
|
||||
{
|
||||
if (!LinesOutput.empty())
|
||||
LinesOutput.front().value = goner_typewriter.textLines;
|
||||
|
||||
auto line = LinesToDigest.front();
|
||||
if (line.Handle())
|
||||
LinesOutput.push_front(line);
|
||||
LinesToDigest.pop_front();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void M_GonerDrawer(void)
|
||||
{
|
||||
srb2::Draw drawer = srb2::Draw();
|
||||
|
||||
drawer
|
||||
.width(BASEVIDWIDTH)
|
||||
.height(BASEVIDHEIGHT)
|
||||
.fill(31);
|
||||
|
||||
drawer = drawer.x(BASEVIDWIDTH/4);
|
||||
|
||||
float newy = BASEVIDHEIGHT/2 + (3*12);
|
||||
boolean first = true;
|
||||
|
||||
for (auto & element : LinesOutput)
|
||||
{
|
||||
INT32 flags = V_TRANSLUCENT;
|
||||
std::string text;
|
||||
if (first)
|
||||
{
|
||||
text = goner_typewriter.text;
|
||||
newy -= goner_typewriter.textLines*12;
|
||||
flags = 0;
|
||||
first = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
text = element.dialogue;
|
||||
newy -= element.value*12;
|
||||
}
|
||||
|
||||
if (newy < 0) break;
|
||||
|
||||
//if (newy > BASEVIDHEIGHT) continue; -- not needed yet
|
||||
|
||||
if (!goner_speakers[element.speaker])
|
||||
continue;
|
||||
|
||||
auto speaker = *goner_speakers[element.speaker];
|
||||
|
||||
srb2::Draw line = drawer
|
||||
.xy(speaker.offset, newy)
|
||||
.flags(flags);
|
||||
|
||||
int skinID = speaker.GetSkinID();
|
||||
if (skinID != -1)
|
||||
{
|
||||
line
|
||||
.xy(-16, -2)
|
||||
.colormap(skinID, static_cast<skincolornum_t>(skins[skinID].prefcolor))
|
||||
.patch(faceprefix[skinID][FACE_MINIMAP]);
|
||||
}
|
||||
|
||||
line
|
||||
.font(srb2::Draw::Font::kThin)
|
||||
.text( text.c_str() );
|
||||
}
|
||||
|
||||
M_DrawHorizontalMenu();
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
void M_GonerProfile(INT32 choice)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue