bool ParsePage() { FStrifeDialogueNode *node = new FStrifeDialogueNode; FStrifeDialogueReply **replyptr = &node->Children; memset(node, 0, sizeof(*node)); //node->ItemCheckCount[0] = node->ItemCheckCount[1] = node->ItemCheckCount[2] = -1; node->ThisNodeNum = StrifeDialogues.Push(node); node->ItemCheckNode = -1; FString SpeakerName; FString Dialogue; while (!sc.CheckToken('}')) { bool block = false; FName key = ParseKey(true, &block); if (!block) { switch(key) { case NAME_Name: SpeakerName = CheckString(key); break; case NAME_Panel: node->Backdrop = TexMan.CheckForTexture (CheckString(key), FTexture::TEX_MiscPatch); break; case NAME_Voice: { const char * name = CheckString(key); if (name[0] != 0) { FString soundname = "svox/"; soundname += name; node->SpeakerVoice = FSoundID(S_FindSound(soundname)); if (node->SpeakerVoice == 0 && namespace_bits == Zd) { node->SpeakerVoice = FSoundID(S_FindSound(name)); } } } break; case NAME_Dialog: Dialogue = CheckString(key); break; case NAME_Drop: node->DropType = CheckActorType(key); break; case NAME_Link: node->ItemCheckNode = CheckInt(key); break; } } else { switch(key) { case NAME_Ifitem: if (!ParseIfItem(node)) return false; break; case NAME_Choice: if (!ParseChoice(replyptr)) return false; break; default: sc.UnGet(); Skip(); } } } node->SpeakerName = ncopystring(SpeakerName); node->Dialogue = ncopystring(Dialogue); return true; }
bool ParseChoice(FStrifeDialogueReply **&replyptr) { FStrifeDialogueReply *reply = new FStrifeDialogueReply; memset(reply, 0, sizeof(*reply)); reply->Next = *replyptr; *replyptr = reply; replyptr = &reply->Next; FString ReplyString; FString QuickYes; FString QuickNo; FString LogString; bool closeDialog = false; reply->NeedsGold = false; while (!sc.CheckToken('}')) { bool block = false; FName key = ParseKey(true, &block); if (!block) { switch(key) { case NAME_Text: ReplyString = CheckString(key); break; case NAME_Displaycost: reply->NeedsGold = CheckBool(key); break; case NAME_Yesmessage: QuickYes = CheckString(key); //if (!QuickYes.Compare("_")) QuickYes = ""; break; case NAME_Nomessage: QuickNo = CheckString(key); break; case NAME_Log: if (namespace_bits == St) { const char *s = CheckString(key); if(strlen(s) < 4 || strnicmp(s, "LOG", 3) != 0) { sc.ScriptMessage("Log must be in the format of LOG# to compile, ignoring."); } else { reply->LogNumber = atoi(s + 3); } } else { LogString = CheckString(key); } break; case NAME_Giveitem: reply->GiveType = CheckActorType(key); break; case NAME_Nextpage: reply->NextNode = CheckInt(key); break; case NAME_Closedialog: closeDialog = CheckBool(key); break; case NAME_Special: reply->ActionSpecial = CheckInt(key); if (reply->ActionSpecial < 0 || reply->ActionSpecial > 255) reply->ActionSpecial = 0; break; case NAME_Arg0: case NAME_Arg1: case NAME_Arg2: case NAME_Arg3: case NAME_Arg4: reply->Args[int(key)-int(NAME_Arg0)] = CheckInt(key); break; } } else { switch(key) { case NAME_Cost: ParseCost(reply); break; default: sc.UnGet(); Skip(); } } } // Todo: Finalize if (reply->ItemCheck.Size() > 0) { if (reply->ItemCheck[0].Amount <= 0) reply->NeedsGold = false; } reply->Reply = ncopystring(ReplyString); reply->QuickYes = ncopystring(QuickYes); if (reply->ItemCheck.Size() > 0 && reply->ItemCheck[0].Item != NULL) { reply->QuickNo = ncopystring(QuickNo); } else { reply->QuickNo = NULL; } reply->LogString = ncopystring(LogString); if(!closeDialog) reply->NextNode *= -1; return true; }
static void ParseReplies (FStrifeDialogueReply **replyptr, Response *responses) { FStrifeDialogueReply *reply; int j, k; // Byte swap first. for (j = 0; j < 5; ++j) { responses[j].GiveType = LittleLong(responses[j].GiveType); responses[j].Link = LittleLong(responses[j].Link); responses[j].Log = LittleLong(responses[j].Log); for (k = 0; k < 3; ++k) { responses[j].Item[k] = LittleLong(responses[j].Item[k]); responses[j].Count[k] = LittleLong(responses[j].Count[k]); } } for (j = 0; j < 5; ++j) { Response *rsp = &responses[j]; // If the reply has no text and goes nowhere, then it doesn't // need to be remembered. if (rsp->Reply[0] == 0 && rsp->Link == 0) { continue; } reply = new FStrifeDialogueReply; // The next node to use when this reply is chosen. reply->NextNode = rsp->Link; // The message to record in the log for this reply. reply->LogNumber = rsp->Log; reply->LogString = NULL; // The item to receive when this reply is used. reply->GiveType = GetStrifeType (rsp->GiveType); 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].Item = GetStrifeType (rsp->Item[k]); reply->ItemCheck[k].Amount = rsp->Count[k]; } // 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) { char moneystr[128]; mysnprintf (moneystr, countof(moneystr), "%s for %u", rsp->Reply, rsp->Count[0]); reply->Reply = copystring (moneystr); reply->NeedsGold = true; } else { reply->Reply = copystring (rsp->Reply); reply->NeedsGold = false; } // QuickYes messages are shown when you meet the item checks. // QuickNo messages are shown when you don't. if (rsp->Yes[0] == '_' && rsp->Yes[1] == 0) { reply->QuickYes = NULL; } else { reply->QuickYes = ncopystring (rsp->Yes); } if (reply->ItemCheck[0].Item != 0) { reply->QuickNo = ncopystring (rsp->No); } else { reply->QuickNo = NULL; } reply->Next = *replyptr; *replyptr = reply; replyptr = &reply->Next; } }
static FStrifeDialogueNode *ReadTeaserNode (FileReader *lump, DWORD &prevSpeakerType) { FStrifeDialogueNode *node; TeaserSpeech speech; char fullsound[16]; const PClass *type; int j; node = new FStrifeDialogueNode; lump->Read (&speech, sizeof(speech)); // Byte swap all the ints in the original data speech.SpeakerType = LittleLong(speech.SpeakerType); speech.DropType = LittleLong(speech.DropType); // Assign the first instance of a conversation as the default for its // actor, so newly spawned actors will use this conversation by default. type = GetStrifeType (speech.SpeakerType); node->SpeakerType = type; if ((signed)speech.SpeakerType >= 0 && prevSpeakerType != speech.SpeakerType) { if (type != NULL) { ClassRoots[type->TypeName] = StrifeDialogues.Size(); } DialogueRoots[speech.SpeakerType] = StrifeDialogues.Size(); prevSpeakerType = speech.SpeakerType; } // Convert the rest of the data to our own internal format. node->Dialogue = ncopystring (speech.Dialogue); // The Teaser version doesn't have portraits. node->Backdrop.SetInvalid(); // The speaker's voice for this node, if any. if (speech.VoiceNumber != 0) { mysnprintf (fullsound, countof(fullsound), "svox/voc%u", speech.VoiceNumber); node->SpeakerVoice = fullsound; } else { node->SpeakerVoice = 0; } // The speaker's name, if any. speech.Dialogue[0] = 0; //speech.Name[16] = 0; node->SpeakerName = ncopystring (speech.Name); // The item the speaker should drop when killed. 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].Item = NULL; node->ItemCheck[j].Amount = -1; } node->ItemCheckNode = 0; node->Children = NULL; ParseReplies (&node->Children, &speech.Responses[0]); return node; }
static FStrifeDialogueNode *ReadRetailNode (FileReader *lump, DWORD &prevSpeakerType) { FStrifeDialogueNode *node; Speech speech; char fullsound[16]; const PClass *type; int j; node = new FStrifeDialogueNode; lump->Read (&speech, sizeof(speech)); // Byte swap all the ints in the original data speech.SpeakerType = LittleLong(speech.SpeakerType); speech.DropType = LittleLong(speech.DropType); speech.Link = LittleLong(speech.Link); // Assign the first instance of a conversation as the default for its // actor, so newly spawned actors will use this conversation by default. type = GetStrifeType (speech.SpeakerType); node->SpeakerType = type; if ((signed)(speech.SpeakerType) >= 0 && prevSpeakerType != speech.SpeakerType) { if (type != NULL) { ClassRoots[type->TypeName] = StrifeDialogues.Size(); } DialogueRoots[speech.SpeakerType] = StrifeDialogues.Size(); prevSpeakerType = speech.SpeakerType; } // Convert the rest of the data to our own internal format. node->Dialogue = ncopystring (speech.Dialogue); // The speaker's portrait, if any. speech.Dialogue[0] = 0; //speech.Backdrop[8] = 0; node->Backdrop = TexMan.CheckForTexture (speech.Backdrop, FTexture::TEX_MiscPatch); // The speaker's voice for this node, if any. speech.Backdrop[0] = 0; //speech.Sound[8] = 0; mysnprintf (fullsound, countof(fullsound), "svox/%s", speech.Sound); node->SpeakerVoice = fullsound; // The speaker's name, if any. speech.Sound[0] = 0; //speech.Name[16] = 0; node->SpeakerName = ncopystring (speech.Name); // The item the speaker should drop when killed. 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].Item = GetStrifeType (speech.ItemCheck[j]); node->ItemCheck[j].Amount = -1; } node->ItemCheckNode = speech.Link; node->Children = NULL; ParseReplies (&node->Children, &speech.Responses[0]); return node; }
static FStrifeDialogueNode *ReadTeaserNode (FWadLump *lump, DWORD &prevSpeakerType) { FStrifeDialogueNode *node; TeaserSpeech speech; char fullsound[16]; const TypeInfo *type; int j; node = new FStrifeDialogueNode; lump->Read (&speech, sizeof(speech)); // Byte swap all the ints in the original data speech.SpeakerType = LONG(speech.SpeakerType); speech.DropType = LONG(speech.DropType); // Assign the first instance of a conversation as the default for its // actor, so newly spawned actors will use this conversation by default. type = GetStrifeType (speech.SpeakerType); node->SpeakerType = type; if (prevSpeakerType != speech.SpeakerType) { if (type != NULL) { GetDefaultByType (type)->Conversation = node; } prevSpeakerType = speech.SpeakerType; } // Convert the rest of the data to our own internal format. node->Dialogue = ncopystring (speech.Dialogue); // The Teaser version doesn't have portraits. node->Backdrop = -1; // The speaker's voice for this node, if any. if (speech.VoiceNumber != 0) { sprintf (fullsound, "svox/voc%lu", speech.VoiceNumber); node->SpeakerVoice = S_FindSound (fullsound); } else { node->SpeakerVoice = 0; } // The speaker's name, if any. speech.Name[16] = 0; node->SpeakerName = ncopystring (speech.Name); // The item the speaker should drop when killed. node->DropType = GetStrifeType (speech.DropType); // Items you need to have to make the speaker use a different node. for (j = 0; j < 3; ++j) { node->ItemCheck[j] = NULL; } node->ItemCheckNode = 0; node->Children = NULL; ParseReplies (&node->Children, &speech.Responses[0]); return node; }