Recent Changes - Search:

Britannia Wiki

Components

Reference


Project Britannia.com


PmWiki

edit SideBar

The Usecode System

The Usecode System - Preliminary Documentation

The purpose of the usecode system is to be able to leverage the conversation script compiler to be able to easily create object actions..or "use" actions via simple scripts. This will allow developers not necessarily familiar with skrit the ability to attach actions to different items.

The usecode system consists of three basic pieces:

The usecode library

The usecode scripts will call into the usecode library, a library of common functions that can be used to perform actions and query different flags and statuses. The usecode library can also be used from within conversation and banter scripts and will slowly replace the ConvoApi functions.

Usecode library functions are located in \world\global\usecode\library

To call them use the format: library.function

where function is a function within library.skrit. For example: Containers.IsLocked relates to a function called: IsLocked$ within Containers.skrit

USING PARAMETERS

The usecode functions can also accept parameters if the functions support them. Parameters can be passed by using URL style formatting: Library.Function?Parm1:Val1&Parm2:Val2

eg:

 Containers.IsLocked?debug:true

An HTML based reference of the usecode library can be found at: http://builds.yanksandbrits.net/usecode/

The usecode script

The usecode script is constructed in the same way as a Conversation or Banter script, the difference being that each option will be a menu item in a pop-up menu.

The usecode component

This is a skrit component that is attached to the template of an object. This is where you define what usecode script is executed when the object is either used or receives a particular message.


DIFFERENCE FROM NORMAL CONVO SCRIPTS

REQUIRED TRIGGERS

The script MUST have the following trigger:

  trigger: #InitializeActions

This is used by the system to initially populate the usecode menu.

FLAGS

Flags have changed in regards to UseCode flags. There are now 3 varieties of flags that can be checked:

  • When$ - When a particular condition is met
  • WhenAny$ - When any of a list of conditions are met
  • WhenAll$ - When all of a list of conditions are met
  • For multiple conditions, they are separated by a '|'
  • You can also negate the result of a condition by prefixing it with '!'

eg:

  <flag *WhenAll$("Containers.IsOpenable|!Containers.IsLocked") = true>

Will result in true if the container is openable and the container is not locked.

*Note: These can be used in Convo and Banter scripts instead of normal flags too

ACTIONS

The following shortcut actions are available:

ActionDescriptionExample
USEPerform a default USE on the objectAction:skrit Use$;
DOPerform a usecode action. This action is also available from Banter and Convo scriptsAction: skrit Do$("Containers.PickLock");
EXITExit out of the usecode scriptAction: skrit Exit$;

INITIATORS AND TARGETS

The usecode functions need to be aware of the direction of the action. This is handled behind the scenes by setting an Initiator and a Target for the action. Unless otherwise noted in the library functions, the player is usually the "initiator" and the object or npc being acted upon is usually the "target". This relationship should be maintained for any new library functions that are created, and also needs to be manually set if library functions are called from skrit.


EXAMPLES

- Creating a usecode enabled chest - Extending the usecode library - Calling usecode library functions from skrit


EXAMPLE: Creating a usecode enabled chest

In this example, a script will be created to attach to the right+click event on a treasure chest. For this example, we want to provide the following actions:

  • Open - This should fire the default "use" action on the object
  • Pick Lock - This should only appear if the chest is locked and the player has lockpicks
  • Do Nothing - This should allow the player to exit out of the menu
SCRIPT

filename: \world\global\usecode\source\chest_usecode.txt This script was run through the usecode compiler to generate chest_usecode.skrit and placed into: \world\global\usecode

 /////////////////////////////////
 // Usecode Script for Treasure Chest
 /////////////////////////////////

 Look first:
 You see a treasure chest.

 ////////////////////////////////////
 // Required Tags
 ////////////////////////////////////
 trigger: #InitializeActions
 response: "" 
 Add options: +<flag *When$("Containers.IsOpenable") = true> Open 
 Add options: +<flag *When$("Containers.IsPickable") = true> Attempt to Pick Lock
 Add options: +Do Nothing

 trigger: #DefaultAction
 response: ""
 Action: skrit Use$;

 ////////////////////////////////////
 // Actions
 ////////////////////////////////////
 trigger: Open
 response: "" 
 Action: skrit Use$;

 trigger: Attempt to Pick Lock
 response: "" 
 Action: skrit Do$("Containers.PickLock");

 trigger: Do Nothing
 response: ""
 Action: skrit Exit$;

If you have written conversation scripts, the above script should look familiar. There are a few differences though.

 Look first:
 You see a treasure chest.

This line will be displayed at the top of the menu and is a short description of the item being used.

 trigger: #InitializeActions

All usecode scripts must have a trigger: #InitializeActions which is used to initially populate the menu items.

 response: ""

The conversation compiler always needs a "response" action. Just populate this with an empty string for now, it may be used in the future.

 Add options: +<flag *When$("Containers.IsOpenable") = true> Open
 Add options: +<flag *When$("Containers.IsPickable") = true> Attempt to Pick Lock
 Add options: +Do Nothing

These three lines will add menu items. The first two execute usecode functions to determine a flag and only if it's true will the menu item be added. The options relate to associated triggers of the same name which will perform the actions:

	trigger: Open
	trigger: Attempt to Pick Lock
	trigger: Do Nothing
TEMPLATE

The template needs to be created and tied to the usecode script. This template is located in

 [t:template,n:lookup_container_usecode_test]
 {
	specializes = pb_crate_lookup;
	common:screen_name = "Chest";
	[use_code]
	{
		usecode_script = "chest_usecode";
		usecode_rclick_active = true;
		usecode_lclick_active = false;
		usecode_action_msg = WE_REQ_ACTIVATE;
	}

	[openable]
	{
		locked = true;
		pickable = true;
	}

	[inventory]
	{
		[delayed_pcontent]
		{
			[all*]
			{
				il_main = hoe;
			}
		}
	}
 }

EXAMPLE: Adding a new usecode function

In this example, we'll be extending the usecode library by adding a new usecode function. This will simply be a new library called: Samples

  • with a function called: Execute
  • and a parameterized function called: ExecWParam
  • and a flag called: Check
  1. Create a new skrit file called \world\global\usecode\library\Samples.skrit using the following template
	/** @file Samples.skrit
  • Usecode Library: Sample library
	 */

	/** Add as an additional parameter to a function call to enable debug messages for that function.

		\par Usecode Example	
		\code
		Add options: +<flag *When$("Library.Function?debug:true")=true>Option 1
		Add options: +<flag *When$("Library.Function?param_1:val_1&debug:true")=true>Option 1
		\endcode	

	*/
	property bool debug$ = false;

	string modulename$ = "SAMPLES";
	#include "stdinclude.skrit"

The above structure is the standard structure to use for creating a new library. Make sure you include the commenting style so that the code can be run through dOxygen to generate HTML documentation of the library. You can find more information about dOxygen and how to format your comments at: http://www.stack.nl/~dimitri/doxygen/

ADDING A FLAG

The first thing we will add to this is a new flag to be used in the flag blocks of a usecode script. Add:

	/** A simple flag, always returns true.

	    \par Usecode Example
		\code
		Add options: +<flag *When$("Samples.Check")=true>Option 1
		\endcode

	 */
	bool Check$()
	{
		return BoolFlag$("Always returning true",true);
	}

Notice the comment above the function. This is a formal comment structure that dOxygen will parse and display in the HTML documentation.

Also, the BoolFlag$ function will set the appropriate flags to a boolean value. It will also display the message provided in the event that debug is turned on.

ADDING A FUNCTION

Next we'll add a simple function. This function will display "Got Here" to the screen.

	/** Display "Got Here" to the screen. 

	    \par Usecode Example
		\code
		Action: skrit Do$("Samples.Execute");
		\endcode

	*/
	void Execute$()
	{
		report.screen("Got Here");
		showdebug$("Displaying 'got here' to the screen");
	}

The showdebug$ function will display the message provided if debugging mode is turned on.

ADDING A FUNCTION WITH PARAMETERS

Next we'll add a function that will display a passed in string to the screen

At the top of the file, below:

	property bool debug$ = false;

Add

	property string msg$ = "";

Next, add the following function:

	/** Display a message to the screen. 

		\param msg (required) Message to display to the screen. (string)

	    \par Usecode Example
		\code
		Action: skrit Do$("Samples.ExecWParam?msg:I got here from the script");
		\endcode

	*/
	void ExecWParam$()
	{
		report.screen(msg$);
		showdebug$("Displaying " + msg$ + " to the screen");
	}

The final file should be saved to: \world\global\usecode\library\Samples.skrit

	/** @file Samples.skrit
	 *  Usecode Library: Sample library
	 */

	/** Add as an additional parameter to a function call to enable debug messages for that function.

		\par Usecode Example	
		\code
		Add options: +<flag *When$("Library.Function?debug:true")=true>Option 1
		Add options: +<flag *When$("Library.Function?param_1:val_1&debug:true")=true>Option 1
		\endcode	

	*/
	property bool debug$ = false;
	property string msg$ = "";

	string modulename$ = "SAMPLES";
	#include "stdinclude.skrit"

	////////////////////////////////////////////////////////////
	// FLAGS
	////////////////////////////////////////////////////////////

	/** A simple flag, always returns true.

	    \par Usecode Example
		\code
		Add options: +<flag *When$("Samples.Check")=true>Option 1
		\endcode

	 */
	bool Check$()
	{
		return BoolFlag$("Always returning true",true);
	}


	////////////////////////////////////////////////////////////
	// ACTIONS
	////////////////////////////////////////////////////////////

	/** Display "Got Here" to the screen. 

	    \par Usecode Example
		\code
		Action: skrit Do$("Samples.Execute");
		\endcode

	*/
	void Execute$()
	{
		report.screen("Got Here");
		showdebug$("Displaying 'got here' to the screen");
	}

	/** Display a message to the screen. 

		\param msg (required) Message to display to the screen. (string)

	    \par Usecode Example
		\code
		Action: skrit Do$("Samples.ExecWParam?msg:I got here from the script");
		\endcode

	*/
	void ExecWParam$()
	{
		report.screen(msg$);
		showdebug$("Displaying " + msg$ + " to the screen");
	}

EXAMPLE: Calling usecode library functions from skrit

It is also possible to call these usecode library functions from skrit. The low-level usecode functions are located within the k_inc_pb_usecode_utils.skrit file.

To execute a usecode action, first include the usecode utils:

 #include "k_inc_pb_usecode_utils"

Then in your code, call the usecode library with ucExecLibraryFunction$ the same way you would use Do$() in the usecode script

 {
	...

	/* make sure you preset the initiator and the target before calling the function */
	ucSetInitiator$( <goid of user> );
	ucSetTarget$( <goid of chest> );

	ucExecLibraryFunction$("Containers.PickLock");
	...
 }  

You can also retrieve flags from skrit:

 {
	...
	/* make sure you preset the initiator and the target before calling the function */
	ucSetInitiator$( <goid of user> );
	ucSetTarget$( <goid of chest> );
	bool result = ucFlagB$("Containers.IsLocked");

	or
	bool result = ucFlagBAll$("Containers.IsOpenable|!Containers.IsLocked");
	...
 }
Edit - History - Print - Recent Changes - Search
Page last modified on April 29, 2008, at 01:26 AM