X3 Tutorial : Sending an Incoming Question

The place to discuss scripting and game modifications for X³: Reunion.

Moderators: Scripting / Modding Moderators, Moderators for English X Forum

User avatar
LV
Sith Lord
Posts: 6363
Joined: Wed, 6. Nov 02, 21:31
x3tc

X3 Tutorial : Sending an Incoming Question

Post by LV » Mon, 31. Oct 05, 00:56

Respect here goes to OML who's code I copied :)

A quick guide to sending an incoming question to a Player for experienced X2 script writers

Code: Select all

 <t id="2">[u][author][b]%s[/b][/author] My ship %s needs an escort to %s. I'll pay you %s credits if you will escort me[/u]\n
   [select value="yes"]Yes I will Protect You[/select]\n
   [select value="no"]No[/select]\n
  </t>
Your t file entry, As any experienced scripter will see, the initial message is the same as X2 but after it you have the select value buttons which return the string chosen to a script. You can have more than 2 but I have not tested the max yet, I do know OML had to write some other handler scripts for more Questions

Code: Select all

   [select value="killme"]Please Kill me[/select]\n
   [select value="irepent"]You'll Never Take Me Alive, copper![/select]\n
In the second example if you pick "Please Kill Me" it will return 'killme' to the preset script.


Next we call the handler script

Code: Select all

$m = sprintf: pageid=5497 textid=2, $pilotname, $shipname, $destination, $offer, null
094   send incoming question $m to player: callback='plugin.escort.me.reply'


This is the script where the [select value="yes"]Yes I will Protect You[/select] returns your choice to.

Code: Select all

Script plugin.escort.me.reply
Version: 0
for Script Engine Version: 28

Description
Description
Arguments
1: val , Var/String , 'val' 
Source Text

001   if $val == 'yes'
002    set global variable: name='lv.escort.me' value=1
003   else if $val == 'no'
004    set global variable: name='lv.escort.me' value=2
005   end
As you can see the callback asks for a string variable Arguments 1: val , Var/String , 'val' in the initail t file entry at the top of this thread you will see the two choices are 'yes' and 'no' all you need to do then is check what value the players answer has returned

Code: Select all

 if $val == 'yes'

For the purpose of my script the choice is a global variable switch that is checked from another script a few seconds later for the answer, You can run scripts from in here and do all sorts of other code it is just the initail variable that matters.

--------------------------------------------------------
I'll be uploading the escort script within the next couple of days so feel free to use the code as a template once I upload it.

LV
Last edited by LV on Thu, 5. May 11, 09:22, edited 1 time in total.

Stealth
Posts: 1123
Joined: Wed, 6. Nov 02, 21:31
x2

Post by Stealth » Mon, 31. Oct 05, 02:13

While we're at it, here's a tip for anyone willing to make their own missions:

Find a live, willing spellchecker/grammarchecker person and ask them to verify it. I know, it sounds useless, but what generally makes a mission not even worth installing or playing, and what really kills the suspension of disbelief is poor spelling.

Get your mission spell-checked. Saying you're textually emulating an accent isn't good enough. :P
Image

User avatar
LV
Sith Lord
Posts: 6363
Joined: Wed, 6. Nov 02, 21:31
x3tc

Post by LV » Mon, 31. Oct 05, 02:41

Spelling has no relevance in relation to this post, but it is a good tip for mission writing, That's why I have Toastie locked in one of my cupborads ;)

Xenon_Slayer
EGOSOFT
EGOSOFT
Posts: 11464
Joined: Sat, 9. Nov 02, 12:45
x4

Post by Xenon_Slayer » Wed, 2. Nov 05, 12:13

Heres some more info on this new command.
  • You can have up to 5 buttons per message. I like to put them on seperate lines but I think you could put them in between text. Got to test that.
  • You can only have 5 variables in. If your using up all 5 buttons that makes it a tight squeze to get all the info into one %s each. I believe there is a way past this. Try using "string arrays". Making a long list, using "-" as a break between values.
  • You can make mini menus. I am currently making a huge script which will take this to the max. I will explain the working below.
  • You can use existing objects as variables but you need the "Steralise object" command in the Objects menu.
  • You can return up to 10 variables per message. Thats the maximum number of arguments.
  • If the script is running on an object and then you use the ask question command, the callback will not run on that object and the current script will not know what button you clicked. I have found a way past this, explained later.
Come watch me on Twitch where I occasionally play several of the X games

Xenon_Slayer
EGOSOFT
EGOSOFT
Posts: 11464
Joined: Sat, 9. Nov 02, 12:45
x4

Post by Xenon_Slayer » Wed, 2. Nov 05, 13:06

Making Menus

If you get the basics of this new command this is a little more advanced. Making menus is possible but it is not what this command was designed to do. Due to this, there are pros and cons. More cons.
Pros
  • You can make menus with buttons (obviously).
  • Its relatively easy once you get it right.
  • Well...menus are cool right...
Hmm. I'm not very convincing. Menus are not exactly very exiting but its a new kind of function to the script editor.

Cons
  • These menus are still messages. They appear in the logbook.
  • They are only accessable in the incoming message menu.
  • They get annoying "incoming message" announcements!
  • You can only have 5 buttons.
These are small but very annoying faults. If you use these menus a lot then the logbook will be very full! I truly hope something else is thought up.

Actualy making the menus is easy. You need to add several menus into the "t" file and just link them up using their text IDs.

Code: Select all

 (Pageid = 1000)
 <t id="2">What do you want to talk about?
   [select value="Menu,3"]Race[/Select]\n 
   [select value="Menu,5"]Ship Types[/Select]\n
   [select value="End"]End[/Select]\n 
 </t>

 <t id="3">Which race do you want to talk about?
   [select value="Selection,Argon"]Argon[/Select]\n 
   [select value="Selection,Boron"]Boron[/Select]\n
   [select value="Selection,Paranid"]Paranid[/Select]\n 
   [select value="Menu,4"]More[/Select]\n  
   [select value="Menu,2"]Back[/Select]\n
 </t>
 <t id="4">What race do you want to talk about?
   [select value="Selection,Split"]Split[/Select]\n 
   [select value="Selection,Teladi"]Teladi[/Select]\n
   [select value="Selection,Xenon"]Xenon[/Select]\n 
   [select value="Menu,3"]Back[/Select]\n
   [select value="End"]End[/Select]\n 
 </t>


 <t id="5">What ship type do you want to talk about?
   [select value="Selection,M1"]M1[/Select]\n 
   [select value="Selection,M2"]M2[/Select]\n
   [select value="Selection,M3"]M3[/Select]\n  
   [select value="Menu,6"]More[/Select]\n  
   [select value="Menu,2"]Back[/Select]\n
 </t>
 <t id="6">What ship type do you want to talk about?
   [select value="Selection,M4"]M4[/Select]\n 
   [select value="Selection,M5"]M5[/Select]\n
   [select value="Selection,M6"]M6[/Select]\n  
   [select value="Menu,7"]More[/Select]\n  
   [select value="Menu,5"]Back[/Select]\n
 </t>
 <t id="7">What ship type do you want to talk about?
   [select value="Selection,TS"]TS[/Select]\n 
   [select value="Selection,TL"]TL[/Select]\n
   [select value="Menu,6"]Back[/Select]\n
   [select value="End"]End[/Select]\n  
 </t>
If you have a look at each line. Each of the first variables is some kind of command for the script it will run on. I use the word "Menu".

Code: Select all

If Var1 = "Menu"
  $Text = sprintf: pageid=1000 textid=$Var2, null, null, null, null, null
  send incoming question $Text to player: callback='Chat.menu'
End
The command "End" would be designed to tell the script to stop what its doing.
The command "Selection" is just something I made up. It would proberbly run a script, telling you info about the subject you selected.

Hopfully that seems clear to everyone.
Come watch me on Twitch where I occasionally play several of the X games

CBJ
EGOSOFT
EGOSOFT
Posts: 40644
Joined: Tue, 29. Apr 03, 00:56
x4

Post by CBJ » Wed, 2. Nov 05, 13:54

Perhaps I should add a little explanation here, which might make using this command easier. The data that is passed to the handler script is the value string specified in the button you select.

Code: Select all

[select value="value string"]Button Text[/Select]
This value string can be replaced with a %s symbol, allowing you to substitute in any text you like at run-time.

Code: Select all

[select value="%s"]Button Text[/Select]
The handling of this value string is pretty flexible. You can pass strings, numbers, and even arrays and objects using it, allowing you to pass whatever data is needed to the handler script that responds to the button selection.

The rest of this explanation will focus entirely on the values that you can pass using the %s substitution.

To pass a single value, string or number, you just substitute in the value itself.

Code: Select all

my string

Code: Select all

123
To pass an array of values, you simply list the values, separated by commas, between curly braces.

Code: Select all

{value1,value2,value3}
Each element of the array can be a string, number or object (we'll come to this) or even another array.

Code: Select all

{my string,123,{arrayval1,arrayval2,arrayval3},99}
To pass an object, you need to use an additional function called Serialise Object. This function turns an object reference into a string using a special format

Code: Select all

$#-nnnn$
This string can then be used like any other, so you can pass it on its own, or you can pass it as an array element.

Code: Select all

$#-1234$

Code: Select all

{$#-4321$,some text,999}
You won't need to worry about turning these serialised object strings back into objects in the handler string as this is done automatically.

So, to summarise, by building a string containing one or more values and substituting this into the value string of a button, you can pass pretty much any data you like when selecting that button.

AalaarDB
Posts: 2279
Joined: Thu, 29. Jan 04, 09:19
x3tc

Post by AalaarDB » Mon, 7. Nov 05, 02:35

Is there a way to pass data from question script to the reply script? And don't say globals

CBJ
EGOSOFT
EGOSOFT
Posts: 40644
Joined: Tue, 29. Apr 03, 00:56
x4

Post by CBJ » Mon, 7. Nov 05, 02:38

That's what all this is about. You pass the information in the value string of the button, and the system is flexible enough to allow you to pass pretty much whatever data you like, including objects.

AalaarDB
Posts: 2279
Joined: Thu, 29. Jan 04, 09:19
x3tc

Post by AalaarDB » Mon, 7. Nov 05, 06:49

Let's say I want to write a mission were there can be several instances at a time. I will need an array of data to keep the mission data in. It looks like I can send all the data I want in along with the question. I can even send the mission data, or an array index. But the callback looks like it loses data because it only accepts one variable, in the sample case the string val. So is there a way to send in an array index and get back an array index? For instance: I could concatenate the index to the button string if I really wanted, but is there a string function that can extract that? Or some other method, as I do not have X3 yet (will go to store tomorrow and hope they have it)

Thus, is there a way to pass data from the question script

Code: Select all

$m = sprintf: pageid=5497 textid=2, $pilotname, $shipname, $destination, $offer, $MISSIONDATA
094   send incoming question $m to player: callback='plugin.escort.me.reply'
and receive it in the reply script

Code: Select all

001   if $val == 'easy' 
002    get global variable: name='missionData' value=$data
003    $data[$index]='easy'
004   else if $val == 'hard' 
005    set global variable: name='lv.escort.me' value=2 
006   end

Xenon_Slayer
EGOSOFT
EGOSOFT
Posts: 11464
Joined: Sat, 9. Nov 02, 12:45
x4

Post by Xenon_Slayer » Mon, 7. Nov 05, 12:31

Heres a quick guide for passing variables in this feature.

You have this line:

Code: Select all

$text = sprintf: pageid=2040 textid=7, $Variable1, $Variable2, $Variable3, $Variable4, $Variable5
send incoming question $text to player: callback='plugin.question.test'
Pageid 2040
Textid 7
[select value="%s,%s,Yes"]Button Text1[/Select]/n
[select value="%s,%s,No"]Button Text2[/Select]/n
[select value="%s"]Button Text2[/Select]

plugin.question.test
Arguments:
Var1
Var2
Var3

If "Button Text1" was pressed the results will be.
$Var1=$Variable1
$Var2=$Variable2
$Var3="Yes"

If "Button Text2" was pressed the results will be.
$Var1=$Variable3
$Var2=$Variable4
$Var3=No

If "Button Text3" was pressed the results will be.
$Var1=$Variable5
$Var2=null
$Var3=null

You see. In the text. Where there is the %s the value is replaced by the variable. This means there can only be a maximum of 5 "%s" in a text file because the command "$text = sprintf: pageid=2040 textid=7, $Variable1, $Variable2, $Variable3, $Variable4, $Variable5" only has 5 slots for variables.

When you select the button, ALL of the variables in the bracket are transfered. They are seperated by a comma. You can have up to 10 variables in each bracket because there are only 10 arguments available in the called script.

If the bracket was: [select value="1,2,3,4,5,6,7,8,9,10"]
There will need to be 10 arguments in the callback script to fit them all in.
Come watch me on Twitch where I occasionally play several of the X games

CBJ
EGOSOFT
EGOSOFT
Posts: 40644
Joined: Tue, 29. Apr 03, 00:56
x4

Post by CBJ » Mon, 7. Nov 05, 14:32

aalaardb wrote:But the callback looks like it loses data because it only accepts one variable, in the sample case the string val.
I don't think you read my post properly. I explained how to pass arrays of data, objects, and all kinds of other things. The string that you create is turned into an array automatically and the callback script receives it as an array with the values already parsed out into values (strings, numbers and objects) within that array.
OML wrote:{snip}
You missed some curly braces out when passing arrays in your examples. ;)

AalaarDB
Posts: 2279
Joined: Thu, 29. Jan 04, 09:19
x3tc

Post by AalaarDB » Mon, 7. Nov 05, 21:37

Thanks OML, commas are the answer I was looking for. Also, I didn't even think of passing the answer text in as an array variable until now, yes that was a solution too.

AalaarDB
Posts: 2279
Joined: Thu, 29. Jan 04, 09:19
x3tc

Post by AalaarDB » Mon, 28. Nov 05, 08:51

Can you please illustrate how to pass an array please CBJ? I never could type { or } inside of the script editor so when you said
To pass an array of values, you simply list the values, separated by commas, between curly braces.

Code: Select all

{value1,value2,value3} 
I thought you meant something else and it's become a big mess since then.

Here's what I did:

Code: Select all

Text file:
message stuff....
[select value="yes,%s"]Yes[/select]
[select value="no,%s"]No[/select]

Code: Select all

question script:
$array= array size 0
append 'string1' to $array
append 'string2' to $array
$string= sprintf text:text id:id $message_stuff, $array, $array
send incoming question: $string callback reply

Code: Select all

answer script, first 2 are input variables:
$input Var/String Input
$data Value Data

$datatype= datatype[$data]
write to logbook $datatype
write to logbook $data
Guess what is in the logbook? A string, specifically the string "ARRAY {. string1, string2}. This caused me several headaches because it prints like a real array would print. When my first script broke because I thought what I had was an array not a string I found the can't print arrays bug. I mistakenly called it the no array of arrays bug at the time, for good reason! I thought that can't print arrays problem was the problem in the broken first script but it's not.

If it is not possible to pass arrays in the way I intended that's ok, I can concatenate 2 numbers and get the index to the array anyways, it just would be nice.

This is what tutorials are for......



PS: Let me just be clear on the question here. How can I pass the array as memory pointers (or something just as easy) like they are elsewhere? And if I cannot, then why not? Makes much more sense to me to happen that way rather than consume valuable resources creating the string then extracting the data from the string.


Edit again: constraints on the solution are only one %s per select value. I need 4 selections, easy, medium, hard and cancel, plus one %s for the message text. Thus, if you meant something like [select value="{yes,%s,%s}"] that is unacceptable, I'd rather go the concatenate route.

AalaarDB
Posts: 2279
Joined: Thu, 29. Jan 04, 09:19
x3tc

Post by AalaarDB » Thu, 1. Dec 05, 03:47

Help please.

Code: Select all

Text file:
<t id="37">[b][author]Aalaar[/author][/b]Test\n\n [select value="yes,%s"]Yes[/select]\n [select value="no,%s"]No[/select]\n</t>

Code: Select all

Send Question script:
001 @ $string = [THIS] -> call script 'ADB.MissionIndexToString' :  Mission Number=5  Sector / Number=45
002   $message = sprintf: pageid=7353 textid=37, $string, $string, null, null, null
003   $datatype =  datatyp[ $string ]
004   write to player logbook: printf: fmt='send %s %s', $datatype, $string, null, null, null
005   send incoming question $message to player: callback='aastringtestreply'

Code: Select all

MissionIndexToString script:
007   *$string = $missionNumber + 'thisisastring' + $sectorNumber
008   $string = '0' + $missionNumber + 'thisisastring' + '0' + $sectorNumber

Code: Select all

Callback script:
Arguments
1: input , Var/String , 'Input' 
2: index , Var/String , 'Index' 
3: extra , Var/String , 'extra' 
Source Text
001   $datatype =  datatyp[ $index ]
002   write to player logbook: printf: fmt='reply %s %s', $datatype, $index, null, null, null
003   write to player logbook $extra


The sent datatype is a string
The received datatype is an int, specifically 5.
If both mission number and sector number are 0, I get the string 0thisisastring0, when I use the commented out line.
If both mission number and sector number are not 0, like 5 and 45, and I use the string that appends 0 before the number, it still is an int.

User avatar
Red Spot
Posts: 3224
Joined: Fri, 4. Feb 05, 14:44
x3

Post by Red Spot » Wed, 7. Dec 05, 20:04

guys is it somehow possible to make a question like the jump-command has ..
like it asking you for a number (or whatever)

basicly that the player has to give the answer rather than have to select an answer .. ??
(like when you start a command with an argument ..)

G

Post Reply

Return to “X³: Reunion - Scripts and Modding”