mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-02-17 17:51:11 +00:00
[USDF branch]
- Removed limits on the number of item checks that can be made with ifitem and cost blocks. SVN r2551 (usdf)
This commit is contained in:
parent
320dce2494
commit
3c884e2c16
4 changed files with 60 additions and 47 deletions
|
@ -628,6 +628,7 @@ add_executable( zdoom WIN32
|
|||
p_tick.cpp
|
||||
p_trace.cpp
|
||||
p_udmf.cpp
|
||||
p_usdf.cpp
|
||||
p_user.cpp
|
||||
p_writemap.cpp
|
||||
p_xlat.cpp
|
||||
|
|
|
@ -387,10 +387,11 @@ static FStrifeDialogueNode *ReadRetailNode (FileReader *lump, DWORD &prevSpeaker
|
|||
node->DropType = GetStrifeType (speech.DropType);
|
||||
|
||||
// Items you need to have to make the speaker use a different node.
|
||||
node->ItemCheck.Resize(3);
|
||||
for (j = 0; j < 3; ++j)
|
||||
{
|
||||
node->ItemCheck[j] = GetStrifeType (speech.ItemCheck[j]);
|
||||
node->ItemCheckCount[j] = -1;
|
||||
node->ItemCheck[j].Item = GetStrifeType (speech.ItemCheck[j]);
|
||||
node->ItemCheck[j].Amount = -1;
|
||||
}
|
||||
node->ItemCheckNode = speech.Link;
|
||||
node->Children = NULL;
|
||||
|
@ -464,9 +465,11 @@ static FStrifeDialogueNode *ReadTeaserNode (FileReader *lump, DWORD &prevSpeaker
|
|||
node->DropType = GetStrifeType (speech.DropType);
|
||||
|
||||
// Items you need to have to make the speaker use a different node.
|
||||
node->ItemCheck.Resize(3);
|
||||
for (j = 0; j < 3; ++j)
|
||||
{
|
||||
node->ItemCheck[j] = NULL;
|
||||
node->ItemCheck[j].Item = NULL;
|
||||
node->ItemCheck[j].Amount = -1;
|
||||
}
|
||||
node->ItemCheckNode = 0;
|
||||
node->Children = NULL;
|
||||
|
@ -528,10 +531,11 @@ static void ParseReplies (FStrifeDialogueReply **replyptr, Response *responses)
|
|||
reply->ActionSpecial = 0;
|
||||
|
||||
// Do you need anything special for this reply to succeed?
|
||||
reply->ItemCheck.Resize(3);
|
||||
for (k = 0; k < 3; ++k)
|
||||
{
|
||||
reply->ItemCheck[k] = GetStrifeType (rsp->Item[k]);
|
||||
reply->ItemCheckAmount[k] = rsp->Count[k];
|
||||
reply->ItemCheck[k].Item = GetStrifeType (rsp->Item[k]);
|
||||
reply->ItemCheck[k].Amount = rsp->Count[k];
|
||||
}
|
||||
|
||||
// ReplyLines is calculated when the menu is shown. It is just Reply
|
||||
|
@ -564,7 +568,7 @@ static void ParseReplies (FStrifeDialogueReply **replyptr, Response *responses)
|
|||
{
|
||||
reply->QuickYes = ncopystring (rsp->Yes);
|
||||
}
|
||||
if (reply->ItemCheck[0] != 0)
|
||||
if (reply->ItemCheck[0].Item != 0)
|
||||
{
|
||||
reply->QuickNo = ncopystring (rsp->No);
|
||||
}
|
||||
|
@ -760,11 +764,18 @@ void P_StartConversation (AActor *npc, AActor *pc, bool facetalker, bool saveang
|
|||
}
|
||||
|
||||
// Check if we should jump to another node
|
||||
while (CurNode->ItemCheck[0] != NULL)
|
||||
while (CurNode->ItemCheck.Size() > 0 && CurNode->ItemCheck[0].Item != NULL)
|
||||
{
|
||||
if (CheckStrifeItem (pc->player, CurNode->ItemCheck[0], CurNode->ItemCheckCount[0]) &&
|
||||
CheckStrifeItem (pc->player, CurNode->ItemCheck[1], CurNode->ItemCheckCount[1]) &&
|
||||
CheckStrifeItem (pc->player, CurNode->ItemCheck[2], CurNode->ItemCheckCount[2]))
|
||||
bool jump = true;
|
||||
for (i = 0; i < (int)CurNode->ItemCheck.Size(); ++i)
|
||||
{
|
||||
if(!CheckStrifeItem (pc->player, CurNode->ItemCheck[i].Item, CurNode->ItemCheck[i].Amount))
|
||||
{
|
||||
jump = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (jump)
|
||||
{
|
||||
int root = pc->player->ConversationNPC->ConversationRoot;
|
||||
CurNode = StrifeDialogues[root + CurNode->ItemCheckNode - 1];
|
||||
|
@ -1110,9 +1121,9 @@ static void HandleReply(player_t *player, bool isconsole, int nodenum, int reply
|
|||
npc = player->ConversationNPC;
|
||||
|
||||
// Check if you have the requisite items for this choice
|
||||
for (i = 0; i < 3; ++i)
|
||||
for (i = 0; i < (int)reply->ItemCheck.Size(); ++i)
|
||||
{
|
||||
if (!CheckStrifeItem(player, reply->ItemCheck[i], reply->ItemCheckAmount[i]))
|
||||
if (!CheckStrifeItem(player, reply->ItemCheck[i].Item, reply->ItemCheck[i].Amount))
|
||||
{
|
||||
// No, you don't. Say so and let the NPC animate negatively.
|
||||
if (reply->QuickNo && isconsole)
|
||||
|
@ -1188,9 +1199,9 @@ static void HandleReply(player_t *player, bool isconsole, int nodenum, int reply
|
|||
// Take away required items if the give was successful or none was needed.
|
||||
if (takestuff)
|
||||
{
|
||||
for (i = 0; i < 3; ++i)
|
||||
for (i = 0; i < (int)reply->ItemCheck.Size(); ++i)
|
||||
{
|
||||
TakeStrifeItem (player, reply->ItemCheck[i], reply->ItemCheckAmount[i]);
|
||||
TakeStrifeItem (player, reply->ItemCheck[i].Item, reply->ItemCheck[i].Amount);
|
||||
}
|
||||
replyText = reply->QuickYes;
|
||||
}
|
||||
|
|
|
@ -7,13 +7,18 @@ struct FStrifeDialogueReply;
|
|||
class FTexture;
|
||||
struct FBrokenLines;
|
||||
|
||||
struct FStrifeDialogueItemCheck
|
||||
{
|
||||
const PClass *Item;
|
||||
int Amount;
|
||||
};
|
||||
|
||||
// FStrifeDialogueNode holds text an NPC says to the player
|
||||
struct FStrifeDialogueNode
|
||||
{
|
||||
~FStrifeDialogueNode ();
|
||||
const PClass *DropType;
|
||||
const PClass *ItemCheck[3];
|
||||
int ItemCheckCount[3];
|
||||
TArray<FStrifeDialogueItemCheck> ItemCheck;
|
||||
int ThisNodeNum; // location of this node in StrifeDialogues
|
||||
int ItemCheckNode; // index into StrifeDialogues
|
||||
|
||||
|
@ -35,8 +40,7 @@ struct FStrifeDialogueReply
|
|||
const PClass *GiveType;
|
||||
int ActionSpecial;
|
||||
int Args[5];
|
||||
const PClass *ItemCheck[3];
|
||||
int ItemCheckAmount[3];
|
||||
TArray<FStrifeDialogueItemCheck> ItemCheck;
|
||||
char *Reply;
|
||||
char *QuickYes;
|
||||
int NextNode; // index into StrifeDialogues
|
||||
|
|
|
@ -81,22 +81,28 @@ class USDFParser : public UDMFParserBase
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
bool ParseCost(FStrifeDialogueReply *response, int index)
|
||||
bool ParseCost(FStrifeDialogueReply *response)
|
||||
{
|
||||
FStrifeDialogueItemCheck check;
|
||||
check.Item = NULL;
|
||||
check.Amount = -1;
|
||||
|
||||
while (!sc.CheckToken('}'))
|
||||
{
|
||||
FName key = ParseKey();
|
||||
switch(key)
|
||||
{
|
||||
case NAME_Item:
|
||||
response->ItemCheck[index] = CheckActorType(key);
|
||||
check.Item = CheckActorType(key);
|
||||
break;
|
||||
|
||||
case NAME_Amount:
|
||||
response->ItemCheckAmount[index] = CheckInt(key);
|
||||
check.Amount = CheckInt(key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
response->ItemCheck.Push(check);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -119,7 +125,6 @@ class USDFParser : public UDMFParserBase
|
|||
FString QuickYes;
|
||||
FString QuickNo;
|
||||
FString LogString;
|
||||
unsigned int costs = 0;
|
||||
bool closeDialog = false;
|
||||
|
||||
|
||||
|
@ -203,17 +208,7 @@ class USDFParser : public UDMFParserBase
|
|||
switch(key)
|
||||
{
|
||||
case NAME_Cost:
|
||||
if(costs > 2)
|
||||
{
|
||||
sc.ScriptMessage ("Too many cost blocks, ignoring.");
|
||||
sc.UnGet();
|
||||
Skip();
|
||||
}
|
||||
else
|
||||
{
|
||||
ParseCost(reply, costs);
|
||||
costs++;
|
||||
}
|
||||
ParseCost(reply);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -223,12 +218,15 @@ class USDFParser : public UDMFParserBase
|
|||
}
|
||||
}
|
||||
// Todo: Finalize
|
||||
if (reply->ItemCheckAmount[0] <= 0) reply->NeedsGold = false;
|
||||
if (reply->NeedsGold) ReplyString.AppendFormat(" for %u", reply->ItemCheckAmount[0]);
|
||||
if (reply->ItemCheck.Size() > 0)
|
||||
{
|
||||
if (reply->ItemCheck[0].Amount <= 0) reply->NeedsGold = false;
|
||||
if (reply->NeedsGold) ReplyString.AppendFormat(" for %u", reply->ItemCheck[0].Amount);
|
||||
}
|
||||
|
||||
reply->Reply = ncopystring(ReplyString);
|
||||
reply->QuickYes = ncopystring(QuickYes);
|
||||
if (reply->ItemCheck[0] != NULL)
|
||||
if (reply->ItemCheck.Size() > 0 && reply->ItemCheck[0].Item != NULL)
|
||||
{
|
||||
reply->QuickNo = ncopystring(QuickNo);
|
||||
}
|
||||
|
@ -247,23 +245,29 @@ class USDFParser : public UDMFParserBase
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
bool ParseIfItem(FStrifeDialogueNode *node, int index)
|
||||
bool ParseIfItem(FStrifeDialogueNode *node)
|
||||
{
|
||||
FStrifeDialogueItemCheck check;
|
||||
check.Item = NULL;
|
||||
check.Amount = -1;
|
||||
|
||||
while (!sc.CheckToken('}'))
|
||||
{
|
||||
FName key = ParseKey();
|
||||
switch(key)
|
||||
{
|
||||
case NAME_Item:
|
||||
node->ItemCheck[index] = CheckActorType(key);
|
||||
check.Item = CheckActorType(key);
|
||||
break;
|
||||
|
||||
case NAME_Count:
|
||||
// Not yet implemented in the engine. Todo later
|
||||
node->ItemCheckCount[index] = CheckInt(key);
|
||||
check.Amount = CheckInt(key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
node->ItemCheck.Push(check);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -275,7 +279,6 @@ class USDFParser : public UDMFParserBase
|
|||
|
||||
bool ParsePage()
|
||||
{
|
||||
int ifitemcount = 0;
|
||||
FStrifeDialogueNode *node = new FStrifeDialogueNode;
|
||||
FStrifeDialogueReply **replyptr = &node->Children;
|
||||
memset(node, 0, sizeof(*node));
|
||||
|
@ -334,13 +337,7 @@ class USDFParser : public UDMFParserBase
|
|||
switch(key)
|
||||
{
|
||||
case NAME_Ifitem:
|
||||
if (ifitemcount > 2)
|
||||
{
|
||||
sc.ScriptMessage("Too many ifitem blocks, ignoring.");
|
||||
sc.UnGet();
|
||||
Skip();
|
||||
}
|
||||
else if (!ParseIfItem(node, ifitemcount++)) return false;
|
||||
if (!ParseIfItem(node)) return false;
|
||||
break;
|
||||
|
||||
case NAME_Choice:
|
||||
|
|
Loading…
Reference in a new issue