// // CPT operator / SondeerGame // This source file is (c) by Deltares. // - October 2014 // //=============================================================================== // Menu that shows up, when you are having a conversation with the land owner or // with your contractor/boss or with the office. // // must be opened with an extra parameter with the string "landowner", "contractor" or "office"!!! // ------------------------------------------------------------ // Created by Maarten van Zomeren // © 2006, Geodelft // // Date Id Modification /// jln - 18-07-2008 Based upon MenuActionCenter.uc, let's see what we can come up with. //============================================================================= class MenuPhoneCall extends GeoGUIPage; var automated GeoFrame DialogBackground; var automated GeoTitle Title; var automated GeoButton NextButton; var automated GeoButton HangupButton; var automated GeoImage ConversationPicture; var automated GeoScrollText ConversationText; var automated GeoComboBox AnswerCombo; var float HGap; var float HGapEdge; var float VGap; var float VGapEdge; var float ButtonVGap; //var float ButtonsLeftOffset; // this is the horizontal position where the second // column of the menu starts (the buttons and the picture) var string ConversationPartner; // who are you calling: either "landowner", "contractor"(opdr.gever) or "office"(boss) var int PhoneChatIndex; // Which chat index for this conversation, how many times did you call this person before var array Lines, Answers, AnswersInBox, Replies; var int MessageNr; var int EndMsgNr; // answer chosen, determines text of end message var string SelectOption; var string IntroMsg; var bool bChangingCombo; var bool bDisplayLastAnswer; struct ConversationArray { //var QAHashTable table; var array Answers; var array Replies; var ConversationNode Messages; var bool bAskQuestion; var array EndMessages; // var array Answers; // var array Replies; }; var array conversation; //==================================================================================== // Subclasses must call super.InitComponent() before adding their own functionality! //==================================================================================== function InitComponent(GUIController MyController, GUIComponent MyOwner) { Super.InitComponent(MyController, MyOwner); /// Try to brake: GeoPC.BrakeVehicle(); PhoneChatIndex = 0; OnClose = InternalOnClose; //OnKeyEvent = InternalOnKeyEvent; // Menu Background DialogBackground.WinLeft = (1 - DialogBackground.WinWidth) / 2; DialogBackground.WinTop = (1 - DialogBackground.WinHeight) / 2; // Menu Title Title.WinTop = DialogBackground.WinTop + VGapEdge; Title.WinLeft = DialogBackground.WinLeft + HGapEdge; // Hangup Button HangupButton.WinTop = DialogBackground.WinTop + DialogBackground.WinHeight - HangupButton.WinHeight - VGapEdge; HangupButton.WinLeft = DialogBackground.WinLeft + DialogBackground.WinWidth - HangupButton.WinWidth - HGapEdge; HangupButton.MenuState = MSAT_Disabled; // BUTTON Next NextButton.WinTop = HangupButton.WinTop - NextButton.WinHeight - ButtonVGap; NextButton.WinLeft = DialogBackground.WinLeft + DialogBackground.WinWidth - NextButton.WinWidth - HGapEdge; // Combo AnswerBox AnswerCombo.WinLeft = DialogBackground.WinLeft + HGapEdge; AnswerCombo.WinWidth = (NextButton.WinLeft - HGap) - AnswerCombo.WinLeft; AnswerCombo.WinTop = DialogBackground.WinTop + DialogBackground.WinHeight - AnswerCombo.WinHeight - VGapEdge; // Scroll Panel containing the text //NOSTB NumberOfScrollTextBox ConversationText.WinTop = Title.WinTop + Title.WinHeight + VGap; ConversationText.WinLeft = AnswerCombo.WinLeft; ConversationText.WinWidth = AnswerCombo.WinWidth; ConversationText.WinHeight = AnswerCombo.WinTop - HGap - ConversationText.WinTop; // Call Picture ConversationPicture.WinTop = ConversationText.WinTop; ConversationPicture.WinLeft = ConversationText.WinLeft + ConversationText.WinWidth + HGap; ConversationPicture.WinWidth = DialogBackground.WinLeft + DialogBackground.WinWidth - ConversationPicture.WinLeft; ConversationPicture.WinHeight = 2*ConversationPicture.WinWidth; } /// wsl - 15-10-2008 Parameter 1 is the conversation partner /// (should be either "landowner", "contractor" or "office") /// Parameter 2 is not used event HandleParameters(string Param1, string Param2) { local string leftletter; //local Volume V; leftletter = Left(Param1, 1); // PhoneChatIndex = GeoPC.ConverSationIndex; //L//og ("Phone volume: " @ GeoPC.PlayerReplicationInfo.PlayerVolume); //Log ("PHysics volume: " @ GeoPC.Pawn.PhysicsVolume); //ForEach GeoPc.AllActors(class'Volume',V) // Log("Volume: " @ V); /* if(PhoneVolume(GeoPC.PlayerReplicationInfo.PlayerVolume)!=none) { Log("Inside phone volume!!"); GeoPC.bPositionTriggered = true; } else { GeoPC.bPositionTriggered = false; }*/ switch(leftletter) { case "l": case "L": ConversationPartner = "landowner"; // PhoneChatIndex = GeoPC.playeractions.TimesCalledLandOwner; GeoPC.playeractions.TimesCalledLandOwner = GeoPC.playeractions.TimesCalledLandOwner + 1; break; case "c": case "C": ConversationPartner = "contractor"; // dependent on phone trigger in level; if on that location, keep track in different number if(GeoPC.bPositionTriggered) { // PhoneChatIndex = GeoPC.playeractions.TimesCalledContractorLocation; GeoPC.playeractions.TimesCalledContractorLocation = GeoPC.playeractions.TimesCalledContractorLocation + 1; } else { // PhoneChatIndex = GeoPC.playeractions.TimesCalledContractor; GeoPC.playeractions.TimesCalledContractor = GeoPC.playeractions.TimesCalledContractor + 1; } break; case "o": case "O": ConversationPartner = "office"; //PhoneChatIndex = GeoPC.playeractions.TimesCalledOffice; GeoPC.playeractions.TimesCalledOffice = GeoPC.playeractions.TimesCalledOffice + 1; break; case "g": case "g": ConversationPartner = "guard"; PhoneChatIndex = 0; break; } InitCall(); } function InitCall() { ConversationText.SetContent(""); MessageNr = 0; InitConversationMessages(); PrintConversationData(); UpdateLanguage(); DisplayNextMessage(); } // get all the necessary information from the scenario int files. function InitConversationMessages() { local string section, file; local int i, j, ianswers, ireplies; local string picture; section = "PhoneCall" $ "." $ ConversationPartner $ "." $ PhoneChatIndex; // if level 1, we need to let conversation with contractor or office depend on player position. log("============ |||||||| GeoPC.bPositionTriggered = "$GeoPC.bPositionTriggered); If(GeoPC.GetScenarioNumber() == 1 && GeoPC.bPositionTriggered) { if(ConversationPartner == "office" || ConversationPartner == "contractor") { section = section $ ".location"; } } else if(GeoPC.GetScenarioNumber() == 3 && GeoPC.playeractions.DidBringPermit) { if(ConversationPartner == "guard") { section = section $ ".didbringpermit"; } } file = "Scenario" $ GeoPC.GetScenarioNumber(); Log("[MenuPhoneCall] Section: " @ section); Log("[MenuPhoneCall] File: " @ file); // intro message IntroMSG = GeoPC.Il8N("IntroMsg", section, true); /// Update title: Title.Caption = GeoPC.Il8N("Title", section, true); /// Update picture picture = GeoPC.Il8N("PersonPhoto", section, true); ConversationPicture.Image = Material(DynamicLoadObject(picture, class'Material')); conversation.Length = int(GeoPC.Il8N("ConversationLength", section, true)); AnswersInBox.Remove(0, AnswersInBox.Length); Replies.Remove(0, Replies.Length); for (i = 0 ; i < conversation.Length; i++) { Log("[MenuPhoneCall] Chat element - Answers: " @ section $ "." $ i); ianswers = int(GeoPC.Il8N("Answers", section $ "." $ i, true)); ireplies = ianswers; //int(GeoPC.Il8N("Replies", section $ "." $ i, true)); conversation[i].Messages = new class'ConversationNode'; conversation[i].Messages.AddString( GeoPC.Il8N("MessageAsked", section $ "." $ i, true) ); // conversation[i].messages = GeoPC.Il8N("MessageAsked", section $ "." $ i, true); conversation[i].bAskQuestion = (ianswers > 0); // int(GeoPC.Il8N("bAskQuestion", section $ "." $ i, true)) == 1; for (j = 0 ; j < ianswers; j++) { conversation[i].Answers[j] = new class'ConversationNode'; conversation[i].Replies[j] = new class'ConversationNode'; Log("[MenuPhoneCall] Sub Chat element - Answers: " @ j @ " - " @ section $ "." $ i); conversation[i].Answers[j].SetConversationEnd( int(GeoPC.Il8N("Answer" $ j $ "IsEnd" , section $ "." $ i, true)) ); conversation[i].Answers[j].SetEventName( GeoPC.Il8N("Answer" $ j $ "Event", section $ "." $ i, true) ); conversation[i].Answers[j].AddString( GeoPC.Il8N("Answer" $ j, section $ "." $ i, true) ); conversation[i].Replies[j].AddString( GeoPC.Il8N("Reply" $ j, section $ "." $ i, true) ); // get end messages per 'answer' given conversation[i].EndMessages[j] = GeoPC.Il8N("EndMsg" $ j, section $ "." $ i, true); } } } function PrintConversationData() { local int i, j; log("============ PrintConversationData ================="); Log("ConversationPartner: " @ ConversationPartner); Log("PhoneChatIndex: " @ PhoneChatIndex); for (i = 0; i < conversation.Length; i++) { Log("Conversation: " $ i); Log("Message:" $ conversation[i].messages.getString()); Log("Question asked?:" $ conversation[i].bAskQuestion); for (j = 0 ; j < conversation[i].Answers.Length; j++) { Log(" Answer: " $ conversation[i].Answers[j].GetString()); Log(" Reply: " $ conversation[i].Replies[j].GetString()); } } } //=================================================================================== // Makes appropriate changes to the menu after a change of language // Subclasses must call super.UpdateLanguage() before adding their own functionality //=================================================================================== function UpdateLanguage() { local string section; /// Get default texts for phone windows. section = "Phone" ; SelectOption = GeoPC.Il8N("selectoption" , section, false); ConversationText.SetContent( IntroMsg ); } // Determine next line of text to write, then write it in the textbox; // either fill or hide answer combobox if appropriate; // check for last function DisplayNextMessage() { local string EndMsgText; Lines[0] = conversation[MessageNr].Messages.GetString(); log(""); Log("Next message (" $ MessageNr $ ") :" @ Lines[0] $ " - Q:" $ conversation[MessageNr].bAskQuestion); /// display the main message text. ConversationText.AddText("|"$Lines[0]); if (conversation[MessageNr].bAskQuestion) { FillAnswerCombo(); } else { HideQuestion(); NextButton.MenuState = MSAT_Blurry; } log("End? MessageNr = "$MessageNr$", Conversation.Length = "$Conversation.Length); log("End? conversation[MessageNr - 1].bAskQuestion = "$conversation[MessageNr - 1].bAskQuestion); if (MessageNr >= Conversation.Length - 1) { if(conversation[MessageNr].bAskQuestion) { bDisplayLastAnswer = true; } else { /// wrap up things and make the hang up button available. NextButton.MenuState = MSAT_Disabled; HangupButton.MenuState = MSAT_Blurry; HideQuestion(); /// Add end message text to the text field: EndMsgText = conversation[MessageNr].EndMessages[EndMsgNr]; if(Left(EndMsgText, 1) == "<") { // not something the player says ConversationText.AddText("|"$EndMsgText); } else { // player says, so put ==> before it ConversationText.AddText("|==> "$EndMsgText); } } } MessageNr++; } /// display answers & replies to previous question (if appropriate) and, if necessary, do event and display reply on answer function DoAnswersReplies() { local string eventName; //log("DoAnswersReplies"); if ( MessageNr > 0 && conversation[MessageNr - 1].bAskQuestion) { //Log("Previous line (" $ MessageNr-1 $ ") was a question! Answer index:" @ AnswerCombo.GetIndex() ); ConversationText.AddText("|==> "$AnswerCombo.GetText()); //Log("Event & end? "@ Conversation[MessageNr-1].Answers[AnswerCombo.GetIndex()].GetConversationEnd() @ " - " @ Conversation[MessageNr-1].Answers[AnswerCombo.GetIndex()].GetEventName()); eventName = Conversation[MessageNr - 1].Answers[AnswerCombo.GetIndex()].GetEventName(); if(len(eventName) > 0) { GeoPC.ConsoleCommand(eventname); log("Triggering event with name "$eventName); GeoPC.TriggerActions(eventName); } ConversationText.AddText("|" $ Conversation[MessageNr - 1].Replies[AnswerCombo.GetIndex()].GetString() ); EndMsgNr = AnswerCombo.GetIndex(); } } // this function add the question field in the menu and add the questions to it. // it is always called from NextLine(). function FillAnswerCombo() { local int i; local array comboStrings; local array theAnswers; //Log("FillAnswerCombo"); NextButton.MenuState = MSAT_Disabled; theAnswers = conversation[MessageNr].Answers; comboStrings.Insert(0, theAnswers.Length + 1); comboStrings[0] = SelectOption; for(i = 0; i < theAnswers.Length; ++i) { comboStrings[i+1] = theAnswers[i].GetString(); } for(i = AnswerCombo.ItemCount() - 1; i > -1; i--) { AnswerCombo.RemoveItem(i); } AnswerCombo.SetVisibility(true); for(i = 0; i < comboStrings.Length; i++) { //Log("Answer Q: " @ comboStrings[i] @ " - " @ comboStrings.Length); AnswerCombo.AddItem(comboStrings[i],,comboStrings[i]); } } //After this function the question field in the menu is gone and the values it had are also gone function HideQuestion() { local int i; //Log("Hide question"); AnswerCombo.SetVisibility(false); for(i = AnswerCombo.ItemCount() - 1; i > -1; i--) { AnswerCombo.RemoveItem(i); } } //============================================================================= // Date Id Modification // 2007-04-05 Zmr Created this header //============================================================================= Event Opened(GUIComponent Sender) { Super.Opened(Sender); bVisible = true; } function bool InternalOnClick(GUIComponent Sender) { local string EndMsgText; if (Sender == HangupButton) { Controller.CloseMenu(false); } else if (Sender == NextButton) { DoAnswersReplies(); if(!bDisplayLastAnswer) { DisplayNextMessage(); } else { /// wrap up things and make the hang up button available. NextButton.MenuState = MSAT_Disabled; HangupButton.MenuState = MSAT_Blurry; HideQuestion(); /// Add end message text to the text field: EndMsgText = conversation[MessageNr - 1].EndMessages[EndMsgNr]; if(Left(EndMsgText, 1) == "<") { // not something the player says ConversationText.AddText("|"$EndMsgText); } else { // player says, so put ==> before it ConversationText.AddText("|==> "$EndMsgText); } } } return true; } function InternalOnClose(optional Bool bCanceled) { Super.OnClose(bCanceled); } function bool InternalOnKeyEvent(out byte Key, out byte State, float delta) { if(Key == 0x1B) { // do nothing; this catches the Escape keypress so it doesn't close this menu from 'above' } return true; } /* was this evne used? function OnMouseComboPressed(GUIComponent Sender, bool bRepeat) { log("In OnMouseComboPressed, sender = "$Sender); AnswerCombo.MyComboBox.InternalOnMousePressed(Sender, bRepeat); NextButton.MenuState=MSAT_Blurry; } */ function OnComboChange(GUIComponent Sender) { local int i; local int index; local array tempAr; log(""); log("OnComboChange, bChangingCombo was "$bChangingCombo); // // Apparently calling GetItem() on the combobox results in a call to OnComboChange.... // so return if we're currently changing the combo box (bit of a hack...) // Also, I don't really want to rearrange the combobox in this function, but I just could // not find another way. So if anyone has an idea.... // if( bChangingCombo ) return; if( AnswerCombo.MyComboBox.List.GetItemAtIndex(0) == SelectOption) //CurrentLanguage.getValue("maakselectie") ) { // initialise the hack... ;) bChangingCombo = true; index = AnswerCombo.GetIndex(); if(index != 0 ) { log("chose a valid answer from the list (not the first)"); tempAr.Insert(0, AnswerCombo.ItemCount()-1); for( i = 1; i < AnswerCombo.ItemCount(); ++i) { tempAr[i-1] = AnswerCombo.GetItem(i); } while( AnswerCombo.ItemCount()!= 0 ) { AnswerCombo.RemoveItem(0); } for( i = 0; i < tempAr.Length; ++i) { AnswerCombo.AddItem(tempAr[i],,tempAr[i]); } AnswerCombo.SetIndex(index-1); NextButton.MenuState=MSAT_Blurry; } else { log("chose the first from the list (wrong!)"); } } // and switch off the hack! bChangingCombo = false; } defaultproperties { Begin Object Class=GeoFrame name=TDialogBackground WinWidth=0.85 WinHeight=0.9 End Object Begin Object class=GeoTitle Name=TMenuTitle IniOption="TMenuTitle" End Object Begin Object Class=GeoButton Name=TNextButton IniOption="TNextButton" WinWidth=0.2 OnClick=InternalOnClick bNeverFocus=true End Object Begin Object Class=GeoButton Name=THangupButton IniOption="THangupButton" WinWidth=0.15 OnClick=InternalOnClick End Object Begin Object Class=GeoImage Name=TCallPic Image=Material'InGameMenuImagesT.ImageButtons.ST_portait' End Object Begin Object Class=GeoScrollText Name=TScrollText End Object Begin Object class=GeoComboBox Name=TAnswerCombo OnChange=OnComboChange //OnMousePressed=OnMouseComboPressed bVisible=false End Object DialogBackground=TDialogBackground Title=TMenuTitle NextButton=TNextButton HangupButton=THangupButton ConversationPicture=TCallPic ConversationText=TScrollText AnswerCombo=TAnswerCombo HGap=0.02 HGapEdge=0.05 VGap=0.03 VGapEdge=0.06 ButtonVGap=0.02 bRequire640x480=false bAllowedAsLast=true bChangingCombo=false bPersistent=false }