mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-02-26 13:51:09 +00:00
Added two new sub-blocks for Choice blocks
Added two new sub-blocks for Choice blocks: Require and Exclude. The syntax for both is the same as Cost blocks. Require defines what item must be present in your inventory in order to show this choice/reply. Exclude defines what item must not be present in your inventory in order to show this choice/reply. If any Require/Exclude blocks are defined then this choice/reply will be hidden until all blocks of both types are satisfied.
This commit is contained in:
parent
87ea75169e
commit
b1880964fa
4 changed files with 75 additions and 9 deletions
|
@ -585,6 +585,8 @@ xx(Ifitem)
|
||||||
xx(Choice)
|
xx(Choice)
|
||||||
xx(Link)
|
xx(Link)
|
||||||
xx(Goodbye)
|
xx(Goodbye)
|
||||||
|
xx(Require)
|
||||||
|
xx(Exclude)
|
||||||
|
|
||||||
// Special menus
|
// Special menus
|
||||||
xx(Mainmenu)
|
xx(Mainmenu)
|
||||||
|
|
|
@ -516,6 +516,8 @@ static void ParseReplies (FStrifeDialogueReply **replyptr, Response *responses)
|
||||||
reply->ItemCheck[k].Item = dyn_cast<PClassInventory>(GetStrifeType(rsp->Item[k]));
|
reply->ItemCheck[k].Item = dyn_cast<PClassInventory>(GetStrifeType(rsp->Item[k]));
|
||||||
reply->ItemCheck[k].Amount = rsp->Count[k];
|
reply->ItemCheck[k].Amount = rsp->Count[k];
|
||||||
}
|
}
|
||||||
|
reply->ItemCheckRequire.Clear();
|
||||||
|
reply->ItemCheckExclude.Clear();
|
||||||
|
|
||||||
// If the first item check has a positive amount required, then
|
// If the first item check has a positive amount required, then
|
||||||
// add that to the reply string. Otherwise, use the reply as-is.
|
// add that to the reply string. Otherwise, use the reply as-is.
|
||||||
|
@ -656,6 +658,38 @@ CUSTOM_CVAR(Float, dlg_musicvolume, 1.0f, CVAR_ARCHIVE)
|
||||||
else if (self > 1.f) self = 1.f;
|
else if (self > 1.f) self = 1.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// ShouldSkipReply
|
||||||
|
//
|
||||||
|
// Determines whether this reply should be skipped or not.
|
||||||
|
//
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
static bool ShouldSkipReply(FStrifeDialogueReply *reply, player_t *player)
|
||||||
|
{
|
||||||
|
if (reply->Reply == nullptr)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < (int)reply->ItemCheckRequire.Size(); ++i)
|
||||||
|
{
|
||||||
|
if (!CheckStrifeItem(player, reply->ItemCheckRequire[i].Item, reply->ItemCheckRequire[i].Amount))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < (int)reply->ItemCheckExclude.Size(); ++i)
|
||||||
|
{
|
||||||
|
if (CheckStrifeItem(player, reply->ItemCheckExclude[i].Item, reply->ItemCheckExclude[i].Amount))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
//
|
//
|
||||||
// The conversation menu
|
// The conversation menu
|
||||||
|
@ -673,6 +707,7 @@ class DConversationMenu : public DMenu
|
||||||
bool mShowGold;
|
bool mShowGold;
|
||||||
FStrifeDialogueNode *mCurNode;
|
FStrifeDialogueNode *mCurNode;
|
||||||
int mYpos;
|
int mYpos;
|
||||||
|
player_t *mPlayer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static int mSelection;
|
static int mSelection;
|
||||||
|
@ -683,9 +718,10 @@ public:
|
||||||
//
|
//
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
DConversationMenu(FStrifeDialogueNode *CurNode)
|
DConversationMenu(FStrifeDialogueNode *CurNode, player_t *player)
|
||||||
{
|
{
|
||||||
mCurNode = CurNode;
|
mCurNode = CurNode;
|
||||||
|
mPlayer = player;
|
||||||
mDialogueLines = NULL;
|
mDialogueLines = NULL;
|
||||||
mShowGold = false;
|
mShowGold = false;
|
||||||
|
|
||||||
|
@ -720,7 +756,7 @@ public:
|
||||||
int i,j;
|
int i,j;
|
||||||
for (reply = CurNode->Children, i = 1; reply != NULL; reply = reply->Next)
|
for (reply = CurNode->Children, i = 1; reply != NULL; reply = reply->Next)
|
||||||
{
|
{
|
||||||
if (reply->Reply == NULL)
|
if (ShouldSkipReply(reply, mPlayer))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -778,6 +814,13 @@ public:
|
||||||
}
|
}
|
||||||
ConversationMenuY = mYpos;
|
ConversationMenuY = mYpos;
|
||||||
//ConversationMenu.indent = 50;
|
//ConversationMenu.indent = 50;
|
||||||
|
|
||||||
|
// Because replies can be selectively hidden mResponses.Size() won't be consistent.
|
||||||
|
// So make sure mSelection doesn't exceed mResponses.Size(). [FishyClockwork]
|
||||||
|
if (mSelection >= (int)mResponses.Size())
|
||||||
|
{
|
||||||
|
mSelection = mResponses.Size() - 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
@ -839,12 +882,24 @@ public:
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Send dialogue and reply numbers across the wire.
|
|
||||||
assert((unsigned)mCurNode->ThisNodeNum < StrifeDialogues.Size());
|
assert((unsigned)mCurNode->ThisNodeNum < StrifeDialogues.Size());
|
||||||
assert(StrifeDialogues[mCurNode->ThisNodeNum] == mCurNode);
|
assert(StrifeDialogues[mCurNode->ThisNodeNum] == mCurNode);
|
||||||
|
|
||||||
|
// This is needed because mSelection represents the replies currently being displayed which will
|
||||||
|
// not match up with what's supposed to be selected if there are any hidden/skipped replies. [FishyClockwork]
|
||||||
|
FStrifeDialogueReply *reply = mCurNode->Children;
|
||||||
|
int replynum = mSelection;
|
||||||
|
for (int i = 0; i <= mSelection && reply != nullptr; reply = reply->Next)
|
||||||
|
{
|
||||||
|
if (ShouldSkipReply(reply, mPlayer))
|
||||||
|
replynum++;
|
||||||
|
else
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
// Send dialogue and reply numbers across the wire.
|
||||||
Net_WriteByte(DEM_CONVREPLY);
|
Net_WriteByte(DEM_CONVREPLY);
|
||||||
Net_WriteWord(mCurNode->ThisNodeNum);
|
Net_WriteWord(mCurNode->ThisNodeNum);
|
||||||
Net_WriteByte(mSelection);
|
Net_WriteByte(replynum);
|
||||||
}
|
}
|
||||||
Close();
|
Close();
|
||||||
return true;
|
return true;
|
||||||
|
@ -1169,7 +1224,7 @@ void P_StartConversation (AActor *npc, AActor *pc, bool facetalker, bool saveang
|
||||||
S_Sound (npc, CHAN_VOICE|CHAN_NOPAUSE, CurNode->SpeakerVoice, 1, ATTN_NORM);
|
S_Sound (npc, CHAN_VOICE|CHAN_NOPAUSE, CurNode->SpeakerVoice, 1, ATTN_NORM);
|
||||||
}
|
}
|
||||||
|
|
||||||
DConversationMenu *cmenu = new DConversationMenu(CurNode);
|
DConversationMenu *cmenu = new DConversationMenu(CurNode, pc->player);
|
||||||
|
|
||||||
|
|
||||||
if (CurNode != PrevNode)
|
if (CurNode != PrevNode)
|
||||||
|
|
|
@ -45,6 +45,8 @@ struct FStrifeDialogueReply
|
||||||
int ActionSpecial;
|
int ActionSpecial;
|
||||||
int Args[5];
|
int Args[5];
|
||||||
TArray<FStrifeDialogueItemCheck> ItemCheck;
|
TArray<FStrifeDialogueItemCheck> ItemCheck;
|
||||||
|
TArray<FStrifeDialogueItemCheck> ItemCheckRequire;
|
||||||
|
TArray<FStrifeDialogueItemCheck> ItemCheckExclude;
|
||||||
char *Reply;
|
char *Reply;
|
||||||
char *QuickYes;
|
char *QuickYes;
|
||||||
int NextNode; // index into StrifeDialogues
|
int NextNode; // index into StrifeDialogues
|
||||||
|
|
|
@ -76,11 +76,11 @@ class USDFParser : public UDMFParserBase
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
// Parse a cost block
|
// Parse a cost/require/exclude block
|
||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
bool ParseCost(FStrifeDialogueReply *response)
|
bool ParseCostRequireExclude(FStrifeDialogueReply *response, FName type)
|
||||||
{
|
{
|
||||||
FStrifeDialogueItemCheck check;
|
FStrifeDialogueItemCheck check;
|
||||||
check.Item = NULL;
|
check.Item = NULL;
|
||||||
|
@ -101,7 +101,12 @@ class USDFParser : public UDMFParserBase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
response->ItemCheck.Push(check);
|
switch (type)
|
||||||
|
{
|
||||||
|
case NAME_Cost: response->ItemCheck.Push(check); break;
|
||||||
|
case NAME_Require: response->ItemCheckRequire.Push(check); break;
|
||||||
|
case NAME_Exclude: response->ItemCheckExclude.Push(check); break;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,7 +211,9 @@ class USDFParser : public UDMFParserBase
|
||||||
switch(key)
|
switch(key)
|
||||||
{
|
{
|
||||||
case NAME_Cost:
|
case NAME_Cost:
|
||||||
ParseCost(reply);
|
case NAME_Require:
|
||||||
|
case NAME_Exclude:
|
||||||
|
ParseCostRequireExclude(reply, key);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Reference in a new issue