- merged menu branch back into trunk.
SVN r2768 (trunk)
This commit is contained in:
parent
ec0b07b5e2
commit
579502ab74
86 changed files with 13610 additions and 9229 deletions
|
|
@ -41,7 +41,6 @@
|
|||
#include "w_wad.h"
|
||||
#include "cmdlib.h"
|
||||
#include "s_sound.h"
|
||||
#include "m_menu.h"
|
||||
#include "v_text.h"
|
||||
#include "v_video.h"
|
||||
#include "m_random.h"
|
||||
|
|
@ -56,11 +55,13 @@
|
|||
#include "d_net.h"
|
||||
#include "g_level.h"
|
||||
#include "d_event.h"
|
||||
#include "d_gui.h"
|
||||
#include "doomstat.h"
|
||||
#include "c_console.h"
|
||||
#include "sbar.h"
|
||||
#include "farchive.h"
|
||||
#include "p_lnspec.h"
|
||||
#include "menu/menu.h"
|
||||
|
||||
// The conversations as they exist inside a SCRIPTxx lump.
|
||||
struct Response
|
||||
|
|
@ -112,9 +113,8 @@ typedef TMap<FName, int> FDialogueMap; // maps actor class names to dialogue
|
|||
static FStrifeTypeMap StrifeTypes;
|
||||
static FDialogueIDMap DialogueRoots;
|
||||
static FDialogueMap ClassRoots;
|
||||
static int ConversationMenuY;
|
||||
|
||||
static menu_t ConversationMenu;
|
||||
static TArray<menuitem_t> ConversationItems;
|
||||
static int ConversationPauseTic;
|
||||
static bool ShowGold;
|
||||
|
||||
|
|
@ -123,13 +123,11 @@ static FStrifeDialogueNode *ReadRetailNode (FileReader *lump, DWORD &prevSpeaker
|
|||
static FStrifeDialogueNode *ReadTeaserNode (FileReader *lump, DWORD &prevSpeakerType);
|
||||
static void ParseReplies (FStrifeDialogueReply **replyptr, Response *responses);
|
||||
static bool DrawConversationMenu ();
|
||||
static void PickConversationReply ();
|
||||
static void PickConversationReply (int replyindex);
|
||||
static void CleanupConversationMenu ();
|
||||
static void ConversationMenuEscaped ();
|
||||
static void TerminalResponse (const char *str);
|
||||
|
||||
static FStrifeDialogueNode *CurNode, *PrevNode;
|
||||
static FBrokenLines *DialogueLines;
|
||||
static FStrifeDialogueNode *PrevNode;
|
||||
|
||||
#define NUM_RANDOM_LINES 10
|
||||
#define NUM_RANDOM_GOODBYES 3
|
||||
|
|
@ -233,7 +231,6 @@ void P_FreeStrifeConversations ()
|
|||
DialogueRoots.Clear();
|
||||
ClassRoots.Clear();
|
||||
|
||||
CurNode = NULL;
|
||||
PrevNode = NULL;
|
||||
}
|
||||
|
||||
|
|
@ -541,10 +538,6 @@ static void ParseReplies (FStrifeDialogueReply **replyptr, Response *responses)
|
|||
reply->ItemCheck[k].Amount = rsp->Count[k];
|
||||
}
|
||||
|
||||
// ReplyLines is calculated when the menu is shown. It is just Reply
|
||||
// with word wrap turned on.
|
||||
reply->ReplyLines = NULL;
|
||||
|
||||
// If the first item check has a positive amount required, then
|
||||
// add that to the reply string. Otherwise, use the reply as-is.
|
||||
if (rsp->Count[0] > 0)
|
||||
|
|
@ -615,7 +608,6 @@ FStrifeDialogueReply::~FStrifeDialogueReply ()
|
|||
if (Reply != NULL) delete[] Reply;
|
||||
if (QuickYes != NULL) delete[] QuickYes;
|
||||
if (QuickNo != NULL) delete[] QuickNo;
|
||||
if (ReplyLines != NULL) V_FreeBrokenLines (ReplyLines);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
|
@ -703,6 +695,372 @@ CUSTOM_CVAR(Float, dlg_musicvolume, 1.0f, CVAR_ARCHIVE)
|
|||
else if (self > 1.f) self = 1.f;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// The conversation menu
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
class DConversationMenu : public DMenu
|
||||
{
|
||||
DECLARE_CLASS(DConversationMenu, DMenu)
|
||||
|
||||
FString mSpeaker;
|
||||
FBrokenLines *mDialogueLines;
|
||||
TArray<FString> mResponseLines;
|
||||
TArray<unsigned int> mResponses;
|
||||
bool mShowGold;
|
||||
FStrifeDialogueNode *mCurNode;
|
||||
int mYpos;
|
||||
|
||||
public:
|
||||
static int mSelection;
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
DConversationMenu(FStrifeDialogueNode *CurNode)
|
||||
{
|
||||
menuactive = MENU_OnNoPause;
|
||||
mCurNode = CurNode;
|
||||
mDialogueLines = NULL;
|
||||
mShowGold = false;
|
||||
|
||||
// Format the speaker's message.
|
||||
const char * toSay = CurNode->Dialogue;
|
||||
if (strncmp (toSay, "RANDOM_", 7) == 0)
|
||||
{
|
||||
FString dlgtext;
|
||||
|
||||
dlgtext.Format("TXT_%s_%02d", toSay, 1+(pr_randomspeech() % NUM_RANDOM_LINES));
|
||||
toSay = GStrings[dlgtext];
|
||||
if (toSay == NULL)
|
||||
{
|
||||
toSay = "Go away!"; // Ok, it's lame - but it doesn't look like an error to the player. ;)
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// handle string table replacement
|
||||
if (toSay[0] == '$')
|
||||
{
|
||||
toSay = GStrings(toSay + 1);
|
||||
}
|
||||
}
|
||||
if (toSay == NULL)
|
||||
{
|
||||
toSay = ".";
|
||||
}
|
||||
mDialogueLines = V_BreakLines (SmallFont, screen->GetWidth()/CleanXfac - 24*2, toSay);
|
||||
|
||||
FStrifeDialogueReply *reply;
|
||||
int i,j;
|
||||
for (reply = CurNode->Children, i = 1; reply != NULL; reply = reply->Next)
|
||||
{
|
||||
if (reply->Reply == NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
mShowGold |= reply->NeedsGold;
|
||||
|
||||
const char *ReplyText = reply->Reply;
|
||||
if (ReplyText[0] == '$')
|
||||
{
|
||||
ReplyText = GStrings(ReplyText + 1);
|
||||
}
|
||||
FBrokenLines *ReplyLines = V_BreakLines (SmallFont, 320-50-10, ReplyText);
|
||||
|
||||
mResponses.Push(mResponseLines.Size());
|
||||
for (j = 0; ReplyLines[j].Width >= 0; ++j)
|
||||
{
|
||||
mResponseLines.Push(ReplyLines[j].Text);
|
||||
}
|
||||
++i;
|
||||
V_FreeBrokenLines (ReplyLines);
|
||||
}
|
||||
char goodbye[25];
|
||||
mysnprintf(goodbye, countof(goodbye), "TXT_RANDOMGOODBYE_%d", 1+(pr_randomspeech() % NUM_RANDOM_GOODBYES));
|
||||
const char *goodbyestr = GStrings[goodbye];
|
||||
if (goodbyestr == NULL) goodbyestr = "Bye.";
|
||||
mResponses.Push(mResponseLines.Size());
|
||||
mResponseLines.Push(FString(goodbyestr));
|
||||
|
||||
// Determine where the top of the reply list should be positioned.
|
||||
i = OptionSettings.mLinespacing;
|
||||
mYpos = MIN<int> (140, 192 - mResponseLines.Size() * i);
|
||||
for (i = 0; mDialogueLines[i].Width >= 0; ++i)
|
||||
{ }
|
||||
i = 44 + i * 10;
|
||||
if (mYpos - 100 < i - screen->GetHeight() / CleanYfac / 2)
|
||||
{
|
||||
mYpos = i - screen->GetHeight() / CleanYfac / 2 + 100;
|
||||
}
|
||||
ConversationMenuY = mYpos;
|
||||
//ConversationMenu.indent = 50;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
void Destroy()
|
||||
{
|
||||
V_FreeBrokenLines(mDialogueLines);
|
||||
mDialogueLines = NULL;
|
||||
I_SetMusicVolume (1.f);
|
||||
}
|
||||
|
||||
bool DimAllowed()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
bool MenuEvent(int mkey, bool fromcontroller)
|
||||
{
|
||||
if (mkey == MKEY_Up)
|
||||
{
|
||||
if (--mSelection < 0) mSelection = mResponses.Size() - 1;
|
||||
return true;
|
||||
}
|
||||
else if (mkey == MKEY_Down)
|
||||
{
|
||||
if (++mSelection >= (int)mResponses.Size()) mSelection = 0;
|
||||
return true;
|
||||
}
|
||||
else if (mkey == MKEY_Back)
|
||||
{
|
||||
Close();
|
||||
return true;
|
||||
}
|
||||
else if (mkey == MKEY_Enter)
|
||||
{
|
||||
if ((unsigned)mSelection >= mResponses.Size())
|
||||
{
|
||||
Net_WriteByte(DEM_CONVCLOSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Send dialogue and reply numbers across the wire.
|
||||
assert((unsigned)mCurNode->ThisNodeNum < StrifeDialogues.Size());
|
||||
assert(StrifeDialogues[mCurNode->ThisNodeNum] == mCurNode);
|
||||
Net_WriteByte(DEM_CONVREPLY);
|
||||
Net_WriteWord(mCurNode->ThisNodeNum);
|
||||
Net_WriteByte(mSelection);
|
||||
}
|
||||
Close();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
bool MouseEvent(int type, int x, int y)
|
||||
{
|
||||
int sel = -1;
|
||||
int fh = SmallFont->GetHeight();
|
||||
|
||||
// convert x/y from screen to virtual coordinates, according to CleanX/Yfac use in DrawTexture
|
||||
x = ((x - (screen->GetWidth() / 2)) / CleanXfac) + 160;
|
||||
y = ((y - (screen->GetHeight() / 2)) / CleanYfac) + 100;
|
||||
|
||||
if (x >= 24 && x <= 320-24 && y >= mYpos && y < mYpos + fh * (int)mResponseLines.Size())
|
||||
{
|
||||
sel = (y - mYpos) / fh;
|
||||
for(unsigned i=0;i<mResponses.Size(); i++)
|
||||
{
|
||||
if ((int)mResponses[i] > sel)
|
||||
{
|
||||
sel = i-1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sel != -1 && sel != mSelection)
|
||||
{
|
||||
//S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE);
|
||||
}
|
||||
mSelection = sel;
|
||||
if (type == MOUSE_Release)
|
||||
{
|
||||
return MenuEvent(MKEY_Enter, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
bool Responder(event_t *ev)
|
||||
{
|
||||
if (ev->type == EV_GUI_Event && ev->subtype == EV_GUI_Char && ev->data1 >= '0' && ev->data1 <= '9')
|
||||
{ // Activate an item of type numberedmore (dialogue only)
|
||||
mSelection = ev->data1 == '0' ? 10 : ev->data1 - '0';
|
||||
return MenuEvent(MKEY_Enter, false);
|
||||
}
|
||||
return Super::Responder(ev);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// DrawConversationMenu
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
void Drawer()
|
||||
{
|
||||
const char *speakerName;
|
||||
int i, x, y, linesize;
|
||||
int width, fontheight;
|
||||
int labelofs;
|
||||
|
||||
player_t *cp = &players[consoleplayer];
|
||||
|
||||
assert (mDialogueLines != NULL);
|
||||
assert (mCurNode != NULL);
|
||||
|
||||
FStrifeDialogueNode *CurNode = mCurNode;
|
||||
|
||||
if (CurNode == NULL)
|
||||
{
|
||||
Close ();
|
||||
return;
|
||||
}
|
||||
|
||||
// [CW] Freeze the game depending on MAPINFO options.
|
||||
if (ConversationPauseTic < gametic && !multiplayer && !(level.flags2 & LEVEL2_CONV_SINGLE_UNFREEZE))
|
||||
{
|
||||
menuactive = MENU_On;
|
||||
}
|
||||
|
||||
if (CurNode->Backdrop.isValid())
|
||||
{
|
||||
screen->DrawTexture (TexMan(CurNode->Backdrop), 0, 0, DTA_320x200, true, TAG_DONE);
|
||||
}
|
||||
x = 16 * screen->GetWidth() / 320;
|
||||
y = 16 * screen->GetHeight() / 200;
|
||||
linesize = 10 * CleanYfac;
|
||||
|
||||
// Who is talking to you?
|
||||
if (CurNode->SpeakerName != NULL)
|
||||
{
|
||||
speakerName = CurNode->SpeakerName;
|
||||
}
|
||||
else
|
||||
{
|
||||
speakerName = cp->ConversationNPC->GetTag("Person");
|
||||
}
|
||||
|
||||
// Dim the screen behind the dialogue (but only if there is no backdrop).
|
||||
if (!CurNode->Backdrop.isValid())
|
||||
{
|
||||
for (i = 0; mDialogueLines[i].Width >= 0; ++i)
|
||||
{ }
|
||||
screen->Dim (0, 0.45f, 14 * screen->GetWidth() / 320, 13 * screen->GetHeight() / 200,
|
||||
308 * screen->GetWidth() / 320 - 14 * screen->GetWidth () / 320,
|
||||
speakerName == NULL ? linesize * i + 6 * CleanYfac
|
||||
: linesize * i + 6 * CleanYfac + linesize * 3/2);
|
||||
}
|
||||
|
||||
// Dim the screen behind the PC's choices.
|
||||
|
||||
screen->Dim (0, 0.45f, (24-160) * CleanXfac + screen->GetWidth()/2,
|
||||
(mYpos - 2 - 100) * CleanYfac + screen->GetHeight()/2,
|
||||
272 * CleanXfac,
|
||||
MIN<int>(mResponseLines.Size() * OptionSettings.mLinespacing + 4, 200 - mYpos) * CleanYfac);
|
||||
|
||||
if (speakerName != NULL)
|
||||
{
|
||||
screen->DrawText (SmallFont, CR_WHITE, x, y, speakerName,
|
||||
DTA_CleanNoMove, true, TAG_DONE);
|
||||
y += linesize * 3 / 2;
|
||||
}
|
||||
x = 24 * screen->GetWidth() / 320;
|
||||
for (i = 0; mDialogueLines[i].Width >= 0; ++i)
|
||||
{
|
||||
screen->DrawText (SmallFont, CR_UNTRANSLATED, x, y, mDialogueLines[i].Text,
|
||||
DTA_CleanNoMove, true, TAG_DONE);
|
||||
y += linesize;
|
||||
}
|
||||
|
||||
if (ShowGold)
|
||||
{
|
||||
AInventory *coin = cp->ConversationPC->FindInventory (RUNTIME_CLASS(ACoin));
|
||||
char goldstr[32];
|
||||
|
||||
mysnprintf (goldstr, countof(goldstr), "%d", coin != NULL ? coin->Amount : 0);
|
||||
screen->DrawText (SmallFont, CR_GRAY, 21, 191, goldstr, DTA_320x200, true,
|
||||
DTA_FillColor, 0, DTA_Alpha, HR_SHADOW, TAG_DONE);
|
||||
screen->DrawTexture (TexMan(((AInventory *)GetDefaultByType (RUNTIME_CLASS(ACoin)))->Icon),
|
||||
3, 190, DTA_320x200, true,
|
||||
DTA_FillColor, 0, DTA_Alpha, HR_SHADOW, TAG_DONE);
|
||||
screen->DrawText (SmallFont, CR_GRAY, 20, 190, goldstr, DTA_320x200, true, TAG_DONE);
|
||||
screen->DrawTexture (TexMan(((AInventory *)GetDefaultByType (RUNTIME_CLASS(ACoin)))->Icon),
|
||||
2, 189, DTA_320x200, true, TAG_DONE);
|
||||
}
|
||||
|
||||
y = mYpos;
|
||||
labelofs = OptionSettings.mLabelOffset;
|
||||
y -= labelofs;
|
||||
fontheight = OptionSettings.mLinespacing;
|
||||
|
||||
int response = 0;
|
||||
for (i = 0; i < (int)mResponseLines.Size(); i++, y += fontheight)
|
||||
{
|
||||
width = SmallFont->StringWidth(mResponseLines[i]);
|
||||
x = 64;
|
||||
|
||||
screen->DrawText (SmallFont, CR_GREEN, x, y, mResponseLines[i], DTA_Clean, true, TAG_DONE);
|
||||
|
||||
if (i == mResponses[response])
|
||||
{
|
||||
char tbuf[16];
|
||||
|
||||
response++;
|
||||
mysnprintf (tbuf, countof(tbuf), "%d.", response);
|
||||
x = 50 - SmallFont->StringWidth (tbuf);
|
||||
screen->DrawText (SmallFont, CR_GREY, x, y, tbuf, DTA_Clean, true, TAG_DONE);
|
||||
|
||||
if (response == mSelection+1)
|
||||
{
|
||||
int color = ((DMenu::MenuTime%8) < 4) || DMenu::CurrentMenu != this ? CR_RED:CR_GREY;
|
||||
|
||||
x = (50 + 3 - 160) * CleanXfac + screen->GetWidth() / 2;
|
||||
int yy = (y-1+labelofs - 100) * CleanYfac + screen->GetHeight() / 2;
|
||||
screen->DrawText (ConFont, color, x, yy, "\xd",
|
||||
DTA_CellX, 8 * CleanXfac,
|
||||
DTA_CellY, 8 * CleanYfac,
|
||||
TAG_DONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
IMPLEMENT_ABSTRACT_CLASS(DConversationMenu)
|
||||
int DConversationMenu::mSelection; // needs to be preserved if the same dialogue is restarted
|
||||
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// P_StartConversation
|
||||
|
|
@ -714,10 +1072,7 @@ CUSTOM_CVAR(Float, dlg_musicvolume, 1.0f, CVAR_ARCHIVE)
|
|||
void P_StartConversation (AActor *npc, AActor *pc, bool facetalker, bool saveangle)
|
||||
{
|
||||
AActor *oldtarget;
|
||||
FStrifeDialogueReply *reply;
|
||||
menuitem_t item;
|
||||
const char *toSay;
|
||||
int i, j;
|
||||
int i;
|
||||
|
||||
// Make sure this is actually a player.
|
||||
if (pc->player == NULL) return;
|
||||
|
|
@ -798,102 +1153,19 @@ void P_StartConversation (AActor *npc, AActor *pc, bool facetalker, bool saveang
|
|||
S_Sound (npc, CHAN_VOICE|CHAN_NOPAUSE, CurNode->SpeakerVoice, 1, ATTN_NORM);
|
||||
}
|
||||
|
||||
// Set up the menu
|
||||
::CurNode = CurNode; // only set the global variable for the consoleplayer
|
||||
ConversationMenu.PreDraw = DrawConversationMenu;
|
||||
ConversationMenu.EscapeHandler = ConversationMenuEscaped;
|
||||
DConversationMenu *cmenu = new DConversationMenu(CurNode);
|
||||
|
||||
// Format the speaker's message.
|
||||
toSay = CurNode->Dialogue;
|
||||
if (strncmp (toSay, "RANDOM_", 7) == 0)
|
||||
{
|
||||
FString dlgtext;
|
||||
|
||||
dlgtext.Format("TXT_%s_%02d", toSay, 1+(pr_randomspeech() % NUM_RANDOM_LINES));
|
||||
toSay = GStrings[dlgtext];
|
||||
if (toSay == NULL)
|
||||
{
|
||||
toSay = "Go away!"; // Ok, it's lame - but it doesn't look like an error to the player. ;)
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// handle string table replacement
|
||||
if (toSay[0] == '$')
|
||||
{
|
||||
toSay = GStrings(toSay + 1);
|
||||
}
|
||||
}
|
||||
if (toSay == NULL)
|
||||
{
|
||||
toSay = ".";
|
||||
}
|
||||
DialogueLines = V_BreakLines (SmallFont, screen->GetWidth()/CleanXfac - 24*2, toSay);
|
||||
|
||||
// Fill out the possible choices
|
||||
ShowGold = false;
|
||||
item.type = numberedmore;
|
||||
item.e.mfunc = PickConversationReply;
|
||||
for (reply = CurNode->Children, i = 1; reply != NULL; reply = reply->Next)
|
||||
{
|
||||
if (reply->Reply == NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
ShowGold |= reply->NeedsGold;
|
||||
reply->ReplyLines = V_BreakLines (SmallFont, 320-50-10, reply->Reply);
|
||||
for (j = 0; reply->ReplyLines[j].Width >= 0; ++j)
|
||||
{
|
||||
item.label = reply->ReplyLines[j].Text.LockBuffer();
|
||||
// handle string table replacement
|
||||
if (item.label[0] == '$')
|
||||
{
|
||||
item.label = GStrings(item.label + 1);
|
||||
}
|
||||
|
||||
item.b.position = j == 0 ? i : 0;
|
||||
item.c.extra = reply;
|
||||
ConversationItems.Push (item);
|
||||
}
|
||||
++i;
|
||||
}
|
||||
char goodbye[25];
|
||||
mysnprintf(goodbye, countof(goodbye), "TXT_RANDOMGOODBYE_%d", 1+(pr_randomspeech() % NUM_RANDOM_GOODBYES));
|
||||
item.label = (char*)GStrings[goodbye];
|
||||
if (item.label == NULL) item.label = "Bye.";
|
||||
item.b.position = i;
|
||||
item.c.extra = NULL;
|
||||
ConversationItems.Push (item);
|
||||
|
||||
// Determine where the top of the reply list should be positioned.
|
||||
i = (gameinfo.gametype & GAME_Raven) ? 9 : 8;
|
||||
ConversationMenu.y = MIN<int> (140, 192 - ConversationItems.Size() * i);
|
||||
for (i = 0; DialogueLines[i].Width >= 0; ++i)
|
||||
{ }
|
||||
i = 44 + i * 10;
|
||||
if (ConversationMenu.y - 100 < i - screen->GetHeight() / CleanYfac / 2)
|
||||
{
|
||||
ConversationMenu.y = i - screen->GetHeight() / CleanYfac / 2 + 100;
|
||||
}
|
||||
ConversationMenu.indent = 50;
|
||||
|
||||
// Finish setting up the menu
|
||||
ConversationMenu.items = &ConversationItems[0];
|
||||
ConversationMenu.numitems = ConversationItems.Size();
|
||||
if (CurNode != PrevNode)
|
||||
{ // Only reset the selection if showing a different menu.
|
||||
ConversationMenu.lastOn = 0;
|
||||
DConversationMenu::mSelection = 0;
|
||||
PrevNode = CurNode;
|
||||
}
|
||||
ConversationMenu.DontDim = true;
|
||||
|
||||
// And open the menu
|
||||
M_StartControlPanel (false);
|
||||
OptionsActive = true;
|
||||
menuactive = MENU_OnNoPause;
|
||||
M_ActivateMenu(cmenu);
|
||||
ConversationPauseTic = gametic + 20;
|
||||
|
||||
M_SwitchMenu (&ConversationMenu);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -921,193 +1193,6 @@ void P_ResumeConversation ()
|
|||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// DrawConversationMenu
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
static bool DrawConversationMenu ()
|
||||
{
|
||||
const char *speakerName;
|
||||
int i, x, y, linesize;
|
||||
int width, fontheight;
|
||||
menuitem_t *item;
|
||||
int labelofs;
|
||||
|
||||
player_t *cp = &players[consoleplayer];
|
||||
|
||||
assert (DialogueLines != NULL);
|
||||
assert (CurNode != NULL);
|
||||
|
||||
if (CurNode == NULL)
|
||||
{
|
||||
M_ClearMenus ();
|
||||
return true;
|
||||
}
|
||||
|
||||
// [CW] Freeze the game depending on MAPINFO options.
|
||||
if (ConversationPauseTic < gametic && !multiplayer && !(level.flags2 & LEVEL2_CONV_SINGLE_UNFREEZE))
|
||||
{
|
||||
menuactive = MENU_On;
|
||||
}
|
||||
|
||||
if (CurNode->Backdrop.isValid())
|
||||
{
|
||||
screen->DrawTexture (TexMan(CurNode->Backdrop), 0, 0, DTA_320x200, true, TAG_DONE);
|
||||
}
|
||||
x = 16 * screen->GetWidth() / 320;
|
||||
y = 16 * screen->GetHeight() / 200;
|
||||
linesize = 10 * CleanYfac;
|
||||
|
||||
// Who is talking to you?
|
||||
if (CurNode->SpeakerName != NULL)
|
||||
{
|
||||
speakerName = CurNode->SpeakerName;
|
||||
}
|
||||
else
|
||||
{
|
||||
speakerName = cp->ConversationNPC->GetTag("Person");
|
||||
}
|
||||
|
||||
// Dim the screen behind the dialogue (but only if there is no backdrop).
|
||||
if (!CurNode->Backdrop.isValid())
|
||||
{
|
||||
for (i = 0; DialogueLines[i].Width >= 0; ++i)
|
||||
{ }
|
||||
screen->Dim (0, 0.45f, 14 * screen->GetWidth() / 320, 13 * screen->GetHeight() / 200,
|
||||
308 * screen->GetWidth() / 320 - 14 * screen->GetWidth () / 320,
|
||||
speakerName == NULL ? linesize * i + 6 * CleanYfac
|
||||
: linesize * i + 6 * CleanYfac + linesize * 3/2);
|
||||
}
|
||||
|
||||
// Dim the screen behind the PC's choices.
|
||||
screen->Dim (0, 0.45f, (24-160) * CleanXfac + screen->GetWidth()/2,
|
||||
(ConversationMenu.y - 2 - 100) * CleanYfac + screen->GetHeight()/2,
|
||||
272 * CleanXfac,
|
||||
MIN(ConversationMenu.numitems * (gameinfo.gametype & GAME_Raven ? 9 : 8) + 4,
|
||||
200 - ConversationMenu.y) * CleanYfac);
|
||||
|
||||
if (speakerName != NULL)
|
||||
{
|
||||
screen->DrawText (SmallFont, CR_WHITE, x, y, speakerName,
|
||||
DTA_CleanNoMove, true, TAG_DONE);
|
||||
y += linesize * 3 / 2;
|
||||
}
|
||||
x = 24 * screen->GetWidth() / 320;
|
||||
for (i = 0; DialogueLines[i].Width >= 0; ++i)
|
||||
{
|
||||
screen->DrawText (SmallFont, CR_UNTRANSLATED, x, y, DialogueLines[i].Text,
|
||||
DTA_CleanNoMove, true, TAG_DONE);
|
||||
y += linesize;
|
||||
}
|
||||
|
||||
if (ShowGold)
|
||||
{
|
||||
AInventory *coin = cp->ConversationPC->FindInventory (RUNTIME_CLASS(ACoin));
|
||||
char goldstr[32];
|
||||
|
||||
mysnprintf (goldstr, countof(goldstr), "%d", coin != NULL ? coin->Amount : 0);
|
||||
screen->DrawText (SmallFont, CR_GRAY, 21, 191, goldstr, DTA_320x200, true,
|
||||
DTA_FillColor, 0, DTA_Alpha, HR_SHADOW, TAG_DONE);
|
||||
screen->DrawTexture (TexMan(((AInventory *)GetDefaultByType (RUNTIME_CLASS(ACoin)))->Icon),
|
||||
3, 190, DTA_320x200, true,
|
||||
DTA_FillColor, 0, DTA_Alpha, HR_SHADOW, TAG_DONE);
|
||||
screen->DrawText (SmallFont, CR_GRAY, 20, 190, goldstr, DTA_320x200, true, TAG_DONE);
|
||||
screen->DrawTexture (TexMan(((AInventory *)GetDefaultByType (RUNTIME_CLASS(ACoin)))->Icon),
|
||||
2, 189, DTA_320x200, true, TAG_DONE);
|
||||
}
|
||||
|
||||
y = CurrentMenu->y;
|
||||
|
||||
if (gameinfo.gametype & GAME_Raven)
|
||||
{
|
||||
labelofs = 2;
|
||||
y -= 2;
|
||||
fontheight = 9;
|
||||
}
|
||||
else
|
||||
{
|
||||
labelofs = 0;
|
||||
fontheight = 8;
|
||||
}
|
||||
for (i = 0; i < CurrentMenu->numitems; i++, y += fontheight)
|
||||
{
|
||||
item = CurrentMenu->items + i;
|
||||
|
||||
width = SmallFont->StringWidth(item->label);
|
||||
x = CurrentMenu->indent + 14;
|
||||
|
||||
screen->DrawText (SmallFont, CR_GREEN, x, y, item->label, DTA_Clean, true, TAG_DONE);
|
||||
|
||||
if (item->b.position != 0)
|
||||
{
|
||||
char tbuf[16];
|
||||
|
||||
mysnprintf (tbuf, countof(tbuf), "%d.", item->b.position);
|
||||
x = CurrentMenu->indent - SmallFont->StringWidth (tbuf);
|
||||
screen->DrawText (SmallFont, CR_GREY, x, y, tbuf, DTA_Clean, true, TAG_DONE);
|
||||
}
|
||||
|
||||
if (i == CurrentItem &&
|
||||
(skullAnimCounter < 6 || menuactive == MENU_WaitKey))
|
||||
{
|
||||
int x = (CurrentMenu->indent + 3 - 160) * CleanXfac + screen->GetWidth() / 2;
|
||||
int yy = (y-1+labelofs - 100) * CleanYfac + screen->GetHeight() / 2;
|
||||
screen->DrawText (ConFont, CR_RED, x, yy, "\xd",
|
||||
DTA_CellX, 8 * CleanXfac,
|
||||
DTA_CellY, 8 * CleanYfac,
|
||||
TAG_DONE);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// PickConversationReply
|
||||
//
|
||||
// Run only on the local machine with the conversation menu up.
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
static void PickConversationReply ()
|
||||
{
|
||||
FStrifeDialogueReply *reply = (FStrifeDialogueReply *)ConversationItems[ConversationMenu.lastOn].c.extra;
|
||||
FStrifeDialogueReply *replyscan;
|
||||
int replynum = 0;
|
||||
|
||||
assert(CurNode->ThisNodeNum >= 0 && CurNode->ThisNodeNum < 65536);
|
||||
assert(StrifeDialogues[CurNode->ThisNodeNum] == CurNode);
|
||||
|
||||
// Determine reply number for netcode.
|
||||
if (reply == NULL)
|
||||
{
|
||||
replyscan = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (replyscan = CurNode->Children; replyscan != NULL && replyscan != reply; ++replynum, replyscan = replyscan->Next)
|
||||
{ }
|
||||
}
|
||||
|
||||
M_ClearMenus ();
|
||||
if (replyscan == NULL)
|
||||
{
|
||||
Net_WriteByte(DEM_CONVCLOSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Send dialogue and reply numbers across the wire.
|
||||
assert(replynum < 256);
|
||||
Net_WriteByte(DEM_CONVREPLY);
|
||||
Net_WriteWord(CurNode->ThisNodeNum);
|
||||
Net_WriteByte(replynum);
|
||||
}
|
||||
CleanupConversationMenu ();
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// HandleReply
|
||||
|
|
@ -1307,27 +1392,6 @@ static void HandleReply(player_t *player, bool isconsole, int nodenum, int reply
|
|||
|
||||
void CleanupConversationMenu ()
|
||||
{
|
||||
FStrifeDialogueReply *reply;
|
||||
|
||||
if (CurNode != NULL)
|
||||
{
|
||||
for (reply = CurNode->Children; reply != NULL; reply = reply->Next)
|
||||
{
|
||||
if (reply->ReplyLines != NULL)
|
||||
{
|
||||
V_FreeBrokenLines (reply->ReplyLines);
|
||||
reply->ReplyLines = NULL;
|
||||
}
|
||||
}
|
||||
CurNode = NULL;
|
||||
}
|
||||
if (DialogueLines != NULL)
|
||||
{
|
||||
V_FreeBrokenLines (DialogueLines);
|
||||
DialogueLines = NULL;
|
||||
}
|
||||
ConversationItems.Clear ();
|
||||
I_SetMusicVolume (1.f);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
|
@ -1408,7 +1472,7 @@ static void TerminalResponse (const char *str)
|
|||
// their dialogue screen. I think most other conversations use this
|
||||
// only as a response for terminating the dialogue.
|
||||
StatusBar->AttachMessage(new DHUDMessageFadeOut(SmallFont, str,
|
||||
float(CleanWidth/2) + 0.4f, float(ConversationMenu.y - 110 + CleanHeight/2), CleanWidth, -CleanHeight,
|
||||
float(CleanWidth/2) + 0.4f, float(ConversationMenuY - 110 + CleanHeight/2), CleanWidth, -CleanHeight,
|
||||
CR_UNTRANSLATED, 3, 1), MAKE_ID('T','A','L','K'));
|
||||
}
|
||||
else
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue