mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-28 15:02:01 +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(Link)
|
||||
xx(Goodbye)
|
||||
xx(Require)
|
||||
xx(Exclude)
|
||||
|
||||
// Special menus
|
||||
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].Amount = rsp->Count[k];
|
||||
}
|
||||
reply->ItemCheckRequire.Clear();
|
||||
reply->ItemCheckExclude.Clear();
|
||||
|
||||
// If the first item check has a positive amount required, then
|
||||
// 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;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// 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
|
||||
|
@ -673,6 +707,7 @@ class DConversationMenu : public DMenu
|
|||
bool mShowGold;
|
||||
FStrifeDialogueNode *mCurNode;
|
||||
int mYpos;
|
||||
player_t *mPlayer;
|
||||
|
||||
public:
|
||||
static int mSelection;
|
||||
|
@ -683,9 +718,10 @@ public:
|
|||
//
|
||||
//=============================================================================
|
||||
|
||||
DConversationMenu(FStrifeDialogueNode *CurNode)
|
||||
DConversationMenu(FStrifeDialogueNode *CurNode, player_t *player)
|
||||
{
|
||||
mCurNode = CurNode;
|
||||
mPlayer = player;
|
||||
mDialogueLines = NULL;
|
||||
mShowGold = false;
|
||||
|
||||
|
@ -720,7 +756,7 @@ public:
|
|||
int i,j;
|
||||
for (reply = CurNode->Children, i = 1; reply != NULL; reply = reply->Next)
|
||||
{
|
||||
if (reply->Reply == NULL)
|
||||
if (ShouldSkipReply(reply, mPlayer))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -778,6 +814,13 @@ public:
|
|||
}
|
||||
ConversationMenuY = mYpos;
|
||||
//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
|
||||
{
|
||||
// Send dialogue and reply numbers across the wire.
|
||||
assert((unsigned)mCurNode->ThisNodeNum < StrifeDialogues.Size());
|
||||
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_WriteWord(mCurNode->ThisNodeNum);
|
||||
Net_WriteByte(mSelection);
|
||||
Net_WriteByte(replynum);
|
||||
}
|
||||
Close();
|
||||
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);
|
||||
}
|
||||
|
||||
DConversationMenu *cmenu = new DConversationMenu(CurNode);
|
||||
DConversationMenu *cmenu = new DConversationMenu(CurNode, pc->player);
|
||||
|
||||
|
||||
if (CurNode != PrevNode)
|
||||
|
|
|
@ -45,6 +45,8 @@ struct FStrifeDialogueReply
|
|||
int ActionSpecial;
|
||||
int Args[5];
|
||||
TArray<FStrifeDialogueItemCheck> ItemCheck;
|
||||
TArray<FStrifeDialogueItemCheck> ItemCheckRequire;
|
||||
TArray<FStrifeDialogueItemCheck> ItemCheckExclude;
|
||||
char *Reply;
|
||||
char *QuickYes;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -206,7 +211,9 @@ class USDFParser : public UDMFParserBase
|
|||
switch(key)
|
||||
{
|
||||
case NAME_Cost:
|
||||
ParseCost(reply);
|
||||
case NAME_Require:
|
||||
case NAME_Exclude:
|
||||
ParseCostRequireExclude(reply, key);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
Loading…
Reference in a new issue