[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:
Braden Obrzut 2010-08-18 09:10:06 +00:00
parent 320dce2494
commit 3c884e2c16
4 changed files with 60 additions and 47 deletions

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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: