================================================================
ZRP Support Utility: The Execute Lua Command Function
================================================================

Execute Script Command: This is for advanced use. You can enter 
a Lua statement in the parameter edit box, and the utility will 
execute it. You should save your game before using this function 
because an invalid statement can cause the game to exit to the 
desktop if the error occurs in the C++ engine.  (Lua script 
errors are caught and reported without CTD.)

You can enter multiple statements on the same line by separating 
them with semicolons.

Select the Execute Script Line function, then click in the edit 
box.  Note that you will see helpful information just above the 
edit box as you go.

You can press F4 to clear the line, F8 to restore the last line 
entered, and F9 to prepend "print " to the last line entered.

You can enter function calls, object references, global variables 
-- anything you could put in a Lua statement block, if it will 
fit -- as well as commands like "print " or "echo " to view data. 
There are some shortcuts in the preprocessor to make your life a 
bit easier, and you can provide constructive feedback to me 
(NatVac) at either the GSC SoC forum, Mod Discussion section, or 
the SoC Mods section at the Zone Survival Guide forum.

Press the Enter key to tell the game to parse the line and try 
to execute it. The dialog will close if the attempt is successful 
and you will be returned to the game, unless you are inspecting 
data (examples below).

To view/set script variables, the variables must have global 
scope (that is, not marked 'local').  You must specify the 
complete qualifier to access the variable.  If the variable is 
in _z.script, you need '_z.' in front of the variable name.

To view the value of a variable, just enter it in the field:

script_name.variable

... and press Enter or click 'OK'.  (This last step will be 
assumed from now on, for brevity.)

If it is a boolean (true/false), string (of characters), or 
number, it will be displayed as such.  More complicated types 
are displayed as "userdata" (usually an object) or "table".  
Nil values are "nil", and that may mean the variable does not 
exist -- check for typos.

To change its value, use the '=' assignment operator:

script_name.variable = newvalue

Because this is a valid statement, if there is a script_name 
object, the dialog will close and return you to the game when 
you click the OK button or press the Enter key.

To execute functions, you need the '()' symbols after the 
function references, with any parameters they might need.

myfunc()
_z.game_version()

Note that the last function returns a value, but the dialog 
will close.  You need to prefix a special keyword like "echo"
or "print" followed by a space to see the results of functions. 

show _z.game_version()

If you forget the keyword and the dialog closes, re-enter the 
dialog and press F9.


More examples: 

_VERSION

This shows the Lua scripting engine version particulars.


_z.mainmenu_anims = false 

This sets the variable 'mainmenu_anims' in the _z.script object 
to false, which disables the background animations on some of the 
menu dialogs. Setting it to 'true' re-enables them. In this 
manner you can see changes immediately without having to exit and 
restart the game.


xr_motivator.show_hit_damage = true

This will set the variable 'show_hit_damage' to true in the file 
xr_motivator.script.  With the ZRP version, that will enable the 
on-screen (and in-PDA) display of the damage you do when you 
shoot someone.


dbglog("Your health is "..tostring(db.actor.health*100)) 

This shows the player's health on a scale from 0 to 100. A 
convenience function allows you to just enter a variable, and 
see the result printed on the dialog:


db.actor.health
echo db.actor.health
show db.actor.health
print db.actor.health

These will all show the health of the actor.  Internally, the 
"non-statement" (didn't parse completely) is turned into a 
Lua statement by prepending "return " and echoing any result 
to the dialog.

echo db.actor:mass()
print alife():switch_distance()

You can use functions there, too, but understand that you will 
need one of the keywords "echo", "show", or "print" to display 
the results of a function.  Otherwise the dialog window will 
close, returning you to the game.  If you did that, you can 
re-open the dialog and press F9 to try again with "print " in 
front.

NOTE:  Passing in an argument where none is expected or omitting 
a required argument may result in a crash.  You did save, right?


Quick note:  Anything after a pair of hyphens (--) is considered 
a comment.


relation_registry.set_community_goodwill("dolg", db.actor:id(), 1000)

This makes you friends with Duty. 


db.actor:give_money(-db.actor:money()) 

This empties your wallet.


treasure_manager.get_treasure_manager():check()

This gives you all the secrets.


"Wreck Riches" stash:
treasure_manager.get_treasure_manager():give_treasure("esc_secret_truck_goods")
"Lucky One" stash:
treasure_manager.get_treasure_manager():give_treasure("ros_secret_0015")

These give you just the specific secrets, from the [list] section 
in config\misc\treasure_manager.ltx.


game.start_tutorial("mov_desire_5")

Show the "I want immortality" ending.  Note that this effectively 
ends the game, showing the credits after the cutscene movie, then 
disconnecting from your current game. You did save first, right?


sim_statistic.mark_all_respawns() 

This turns on debugging info about spawn sites, visible in your 
PDA maps.

sim_statistic.unmark_all_respawns() 

This turns OFF debugging info about spawn sites. You must be 
using a fixed version of sim_statistic.script, included in this 
version of ZRP but not installed by default.  The game's internal 
version of the script (loaded by default if no external one 
exists) works to turn on the markers.


Some functionality is not available, simply because it is not 
adjustable via script.  For example, you can examine some alife() 
data but you may not be able to change it.  So

alife():switch_distance(175)

fails with a crash, but

alife():switch_distance()

works.  You can't change switch_distance during the game.


Remember that object() is different for different contexts.

alife():release(db.actor:object("medkit"), false) -- crash

While "db.actor:object()" returns an object if it exists, it is 
not the kind of object needed by alife():release().  You need to 
use alife():object() on the ID number of the object:

alife():release(alife():object(db.actor:object("medkit")),false)

You can perform an object deletion in three script executions:

my_obj = db.actor:object("decoder")  -- or "medkit" (or whatever)
my_obj  --> says it's userdata, which means it's a valid object
alife():release(alife():object(my_obj:id()),false)

What this does:  First, you create a global variable called 
"my_obj" and assign to it the object found by "db.actor:object()". 
If entering "my_obj" (second command) returns nil, then you don't 
have the object, so don't execute the third command.  The third 
command removes the object from the game.

It might be easier to write script functions that do what you 
want and then call them with this utility.


Fix for Kruglov saying "Now is not the time to talk" leaving you 
with only "See you!" as a response, or stuck at burner tunnel 
(should not happen in the demo, but eh):

npc_kruglov = level_object_by_sid(503)
xr_gulag.resetJob(npc_kruglov)

Just execute those two lines in Rostok near Kruglov, either one 
at a time or both on one line separated by a semicolon (;).  
Afterward, Kruglov's comment won't change, but his behavior will. 

Tip: This is already a custom script, and is mainly shown here for 
educational purposes.

================================================================
See the ZRP_SupportUtilities_ModdingNotes.txt file for more info.
================================================================

Finally, a limitation of note:  You won't be able to use the tilde 
key (~) if you have it bound to the console (the default binding). 
You can work around "a ~= b" with "(not (a == b))", or you can 
put your code in an external script and execute that.


Please consider what you have seen to be a work in progress, and 
contribute your constructive comments and wishes to me (and 
others) at the previously-mentioned forum sites.  --NatVac
