Object Scripts

Object scripts control the complex behaviour of an object. For details on scripting see the C4Script documentation.

Creation

For every object, the engine calls the function Initialize in the object script when it is created and completed.
func Initialize()
{
  CreateContents(ROCK);
  return(1);
}
An object with this script will be given a rock right after it has been created. The Initialize function is called only when the object has reached full size (a building only when its construction has been completed and a living being only when it is fully grown).

TimerCall

Each object definition can define a timer call in its DefCore. The TimerCall is a function which will be called at regular intervals. The DefCore entry Timer determines the rate of calls. If no rate is specifed, the default value is 35 frames (roughly once per second).

ActMap.txt

An active object can also define activity script calls in its ActMap. The defined StartCall is made whenever an action begins (or repeats), an EndCall is made at the end of each activity. PhaseCall is called at each animation phase step and should only be used for very short animations. The call frequency of PhaseCalls is determined by the speed of the animation.

#include

An object script can also include the functionality of another script.
#include CLNK
At this position the complete script of the specified object definition (that of the clonk, in this case) is inserted. Obviously, the included definition must be valid and loaded. Declared functions can be overloaded by functions of the same name that occur later in the script. Also see inherited().

Access Control

You can specify an access declaration for functions in object scripts:
public may be called by the object itself, by the engine, or by other objects
protected may only be called by the object itself or by the engine
private may only be called by the object itself
A special case: the callbacks TimerCall, StartCall, PhaseCall, and EndCall will work even if the function called was declared private (for downwards compatibility reasons) but the functions for all other engine calls (see below) must be declared protected or public.
Functions with no special declaration are public. If you are unsure or don't care, leave your functions public.

Object calls made by the engine

The engine calls the following functions is objects at the given time.
Function Parameter Description
Initialize When the object is completed (Con >= 100).
Completion Obsolete. Same as Initialze.
Construction object pByObj When the object is created. The parameter is a pointer to the object the script of which has created this object. Also see Construction
Destruction When the object is removed.
Hit int xdir, int ydir When the object collides with the landscape or is collected at high velocity (>=15; see OCF_HitSpeed1).
xdir and ydir are the impact speed with precision 100 (see GetXDir). The parameters are not passed in case of collection.
Hit2 int xdir, int ydir Like Hit, with speeds >= 20 (see OCF_HitSpeed2).
Hit3 int xdir, int ydir Like Hit, with speeds >= 60 (see OCF_HitSpeed3).
Grab object pTarget, bool fGrab When the object grabs or lets go of another object.
Grabbed object pByObject, bool fGrab When the object is grabbed or let go by another object. Since 4.9.8.4.
RejectGrabbed object byObject When the object should be grabbed by another object. If the function returns true the grabbing is prevented and byObject's Grab-command fails. Since 4.9.10.14 LC [353].
Get object pTarget When the object takes another object from a container.
Put When the object puts another object into a container.
Damage int iChange, int iByPlayer When the object is damage.
DeepBreath When a living being surfaces after having used up more than half of its breath.
Incineration int iByPlayer When the object is incinerated. Notice: with objects changing their definition via BurnTo, this call is made to the burned version!
IncinerationEx int iByPlayer When the object is incinerated in and immediately extinguished by a surrounding liquid. Otherwise as Incineration. From CE.
Death When a living being dies.
Activate object pByObj Activation by double dig. Only applies to collected items or directly controlled crew objects. Called after internal handling of the double dig command has been completed (e.g. chopping of trees etc.)
Contact_ When the object collides with the landscape. See CNAT - Contact Attachment.
Control_ object pByObj When the object is controlled from the outside. See Control Functions.
Contained_ object pByObj When the object is controlled from the inside. See Control Functions.
ControlCommand string strCommand, object pTarget, int iTx, int iTy, object pTarget2, int iData, object pCmdObj When the object has received a command to be independently executed. See Control functions.
ControlCommandFinished string strCommand, object pTarget, int iTx, int iTy, object pTarget2, C4Value Data When the object has completed a command or execution of a command has failed.
ControlTransfer object pObj, int iTx, int iTy When an object (pObj) using the internal pathfinding algorithm is trying to pass the transfer zone of this object on its way to point iTx/iTy. The transfer function can then help the object along by giving special script commands and returning true. Also see SetTransferZone().
UpdateTransferZone When an object is loaded from a savegame or network synchronization is performed. Objects with a transfer zone should reset the zone in this call. Also see SetTransferZone().
IsFulfilled Only in game goal objects. A return value true indicates that this goal is fulfilled.
ControlContents id idTarget When a new inventory object is selected. See Control Functions.
Selection object pContainer When the object is selected in an inventory change. If you are processing this event, the function should play its own selection sound.
CatchBlow int iLevel, object pBy When the object is hit or punched by another object.
QueryCatchBlow object pBy Called before the object is hit or punched by another object. By returning true, QueryCatchBlow can reject physical blows.
LineBreak int iCause When a line object is broken. iCause: 0 by movement, 1 because of a damaged or destroyed target object.
BuildNeedsMaterial id idMaterial, int iAmount When the object is building another object and building material is required. The parameters are the type and amount of the first needed material. If this function returns true, no material message is displayed above the object.
AttachTargetLost When the object is in an ATTACH action and has lost its action target. At this time, the object's action has already been reset.
CrewSelection bool fDeselect, bool fCursorOnly When crew selection is changed. fCursorOnly specifies whether only that crew member has been selected which is also the cursor.
GetObject2Drop object pForCollectionOfObj Called to determine the least needed inventory object when a clonk tries to collect a new object and his inventory is full. The function should return the object to be dropped to gain space, or 0 if none.
OnMenuSelection int iItemIndex, object pMenuObject When an object menu entry is selected.
CalcValue object pInBase, int iForPlayer Calculates the value of an object. Also see GetValue().
CalcDefValue object pInBase, int iForPlayer Calculates the value of an object type available to buy. Also see GetValue().
CalcBuyValue id idItem, int iDefValue Returns the buying price of the object type.
CalcSellValue object pObj, int iObjValue Returns the selling price of the object type.
LiftTop When an object with LIFT action lifts its action target to the height specified in its DefCore or above.
Stuck When the action target of the object's PUSH or LIFT action is stuck.
GrabLost When the action target of the object's PUSH or PULL action is lost.
Collection object pObj, bool fPut When the object has collected another object (by ingame collection or grabbing and getting).
Collection2 object pObj When the object has collected another object (in all cases, even in script controlled collection or entering).
Departure object pContainer When this object has left another object (pContainer).
Ejection object pObj When another object has left the contents of this object (also see script command Exit).
Entrance object pContainer When the object has enteres another object (pContainer).
ActivateEntrance object pByObj When another object is trying to enter this object through the entrance.
RejectCollect id idObj, object pObj Called before Collection. If RejectCollect returns true, the collection of the other object is prevented.
RejectEntrance object pIntoObj Called before Entrance. If RejectEntrance returns true, then entrance of the other object is prevented.
InitializePlayer int iPlr, int iX, int iY, object pBase, int iTeam, id idExtra Callback in goals, rules and environment objects after placing a joined player and before calling the callback in the scenario script. By specifying an ID it is possible to distinguish different types of script players. For example a scenario could dynamically provide alien or clonk enemies.
SellTo int iByPlr When the object is sold. Should return 0 or the id of the object type which is actually added to the player's homebase material.
Sale int iByPlr When the object is sold.
Purchase int iByPlr, object BuyObject When the object is bought.
Recruitment int iPlr When the objet is added to the crew of a player.
RejectTeamSwitch int iPlr, int iNewTeam Callback in game goal, rule, and environment objects and in the scenario script. If RejectTeamSwitch returns true, the team switch of a player can be prevented (see SetPlayerTeam). From 4.9.6.0 CR.
ContentsDestruction object pObj This function is called in the container of pObj when pObj is removed.
DoMagicEnergy int iChange, object pObj, bool fAllowPartial Is called whenever the magic energy changes.
array GetCustomComponents object pBuilder Callback for setting components of an object. It is called by menus containing menu entries with this ID, as well as when constructing an object. pBuilder is the menu object or builder. The function must return an array of IDs. See also GetComponent, SetComponent, Split2Components.
IsFullfilledforPlr int iPlr If the rule "Rivalry" (RVLR) is enabled, IsFulfilledforPlr is being called, otherwise IsFulfilled. Only for goal objects. The function should return true if the goal is fulfilled for iPlr.
MouseSelection int iPlr Called when the object is being clicked on with the mouse. The object must be of the category C4D_MouseSelect.
OnActionJump int iXDir100, int iYDir100, bool fByCom Is being called whenever the object changes into the action "Jump". The x- and y-speed are passed as iXDir100 and iYDir100 with a precision of 100. fByCom is true for real jumps, i.e. by pressing [Up], by Command (Mouse control or SetCommand and similar), by calling Jump() or when releasing while scaling or hangling, otherwise false. If OnActionJump returns true, the engine jump is being suppressed.
OnOwnerChanged int iNewOwner, int iOldOwner Is called when the object's owner changes.
RejectContents If returning true, the contents menu can't be opened.
RejectFight object pEnemy Is being called before clonks start fighting. Returning true suppresses the fight.

Control Functions

At every player command (Left, Up, Right, Down, Dig, Throw, Special, Special2, CursorLeft, CursorToggle, CursorRight) the engine calls the corresponding control function in the script of the currently controlled object of the player. If the function is defined and returns true, the internal handling of the player command is skipped. If the function is not defined or returns false, internal processing is done.
func ControlThrow()
{
  if (FindContents(SPER))
    return(SetAction("ThrowSpear"));
  return(0);
}
If a clonk with this script is carrying a spear and the player hits the throw button, the clonk performs a special throw action. In this case, however, the command is not passed to the other selected clonks as usual. If the clonk does not carry a spear, the function returns 0 and the regular throwing action is performed.
Control functions are also transferred to grabbed (indirectly controlled) objects.
Single and double clicks: for each player command the engine will first call the simple variant of the control function (e.g. ControlDown) and then the more specific variant (i.e. ControlDownSingle or ControlDownDouble). When overloading control functions you should pay attention to catch the correct variant to overload.
ContainedControl: if a directly controlled object is contained in another object (container) the basic commands down (exit), throw (put), up (buy at base), dig (sell at base) are evaluated internally first. Then the command is passed to the container for special handling there. Exception: the commands ControlSpecial, ControlSpecial2, ControlCursorLeft, ControlCursorToggle, ControlCursorRight, and ControlWheelUp/Down are only direct commands and are not passed to the container.
ControlCommand: the engine also performs object calls for independently executed commands which have been given directly by the player (i.e. by mouse control).
func ControlCommand(string strCommand, object pTarget, int iTx, int iTy, object pTarget2, int iData, object pCmdObj)
{
  // Ein Kommando mit Zielobjekt
  if (pTarget)
    Message("Befehl: %s Ziel: %s Koordinaten: %d/%d", this(), strCommand, pTarget->GetName(), iTx, iTy);
  // Ein Kommando ohne Zielobjekt
  else
    Message("Befehl: %s Koordinaten: %d/%d", this(), strCommand, iTx, iTy);
  // Kommando nicht abfangen
  return(0);
}
By returning true the command can be intercepted and internal handling can be prevented. "pCmdObj" is always the object receiving the command, even if the call was transferred by a contained object (see VehicleControl in DefCore). The script command SetCommand does not cause ControlCommand calls.
ControlCommand calls are also transferred to grabbed objects or objects controlled from the inside if these have the VehicleControl flag set. This transferred call is made after the ControlCommand call to the clonk, but before internal handling. So the vehicle, too, has the opportunity to intercept and overload the command.
ControlWheelUp and ControlWheelDown are generated by the mouse wheel (and only when not in an object menu). If they are not overloaded, they will cause ShiftContents commands. That in return could be intercepted in ControlContents.
ControlContents is called when an inventory change is made by direct mouse click, mouse wheel rotation, or a ShiftContents script command (e.g. in ControlSpecial or ControlSpecial2). Here you can perform special actions such as the arming of weapons or custom inventory sounds. If the function is intercepted with a return value true, the inventory change is prevented. Otherwise, the first object with the given id moves to the front of the inventory and a Selection call is made to the newly selected object. If the latter call is not overloaded, the sound effect "Grab" is played for the container object.

Context Functions

Context functions (Context_ in object scripts) are displayed as entries in the context menu of the object. When calling a context function, the engine will pass a pointer to the calling object as the first parameter (with crew members this is always the object itself). Context functions should always have a valid function description and be declared pubic.
public func ContextConstruction(object pCaller)
{
  [Bauauftrag|Image=CXCN|Condition=HasKnowledge]
  SetCommand(this(), "Construct");
  return(1);
}
If the condition field is used, the context function is only displayed as a menu entry if the script function defined by the condition field (in this case HasKnowledge) is found in the object's script and returns true. The menu object is passed as the first parameter to the condition function.
sulai, November 2003
Sven2, Februar 2004
matthes, Juli 2004
Clonkonaut, April 2008
Der Tod, April 2022