Objektscripte

Objektscripte kontrollieren die komplexen Verhaltensweisen eines Objekts. Für eine Beschreibung der Scriptsprache C4Script siehe C4Script-Dokumentation.

Erschaffung

Für jedes Objekt ruft die Engine bei der Erschaffung des Objekts die Funktion Initialize im Objektscript auf.
func Initialize()
{
  CreateContents(ROCK);
  return(1);
}
Ein Objekt mit diesem Script enthält sofort nach seiner Erschaffung einen Stein. Die Initialisierungsfunktion wird erst aufgerufen, nachdem das Objekt seine volle Größe erreicht hat. Bei Bauwerken also erst, nachdem sie vollständig gebaut wurden und bei Lebewesen erst, wenn sie voll ausgewachsen sind.

TimerCall

Jede Objektdefinition kann im DefCore einen TimerCall bestimmen. Der TimerCall ist eine Funktion, die in regelmäßigen Abständen im Objektscript aufgerufen wird. Den Zeitabstand der Aufrufe bestimmt der DefCore-Eintrag Timer. Ohne spezielle Angabe für den Timer gilt der Vorgabewert von 35 Frames (also ca. einmal pro Sekunde).

ActMap.txt

Ein aktives Objekt kann außerdem in seiner Aktivitätsdefinition Script-Aufrufe enthalten. Die als StartCall definierte Funktion wird immer dann aufgerufen wird, wenn die Aktivitätsschleife erneut startet. EndCall wird aufgerufen, wenn die Aktivitätsschleife endet. PhaseCall wird bei jedem Animationsschritt aufgerufen (da dies äußerst rechenintensiv ist, sollte PhaseCall nur bei seltenen und kurzzeitig ausgeführten Aktivitäten eingesetzt werden). Die Frequenz der Aufrufe bestimmt sich aus der Aktivitätsgeschwindigkeit.

#include

Ein Objektscript kann auf dem Script eines anderen Objekts basieren:
#include CLNK
An dieser Position wird das komplette Script der jeweiligen Objektdefinition (hier des Clonks) eingefügt, die selbstverständlich vorhanden und geladen sein muss. Funktionen können durch später im Script folgende Funktionen gleichen Namens überladen werden. Siehe auch inherited().

Zugangsberechtigung

Für Funktionen in Objektscripten kann eine Zugangsberechtigung festgelegt werden:
public darf vom Objekt selbst, von der Engine oder von anderen Objekten aufgerufen werden
protected darf nur vom Objekt selbst oder von der Engine aufgerufen werden
private darf nur vom Objekt selbst aufgerufen werden
TimerCall, StartCall, PhaseCall und EndCall können zwar zur Abwärtskompatibilität auch private Funktionen aufrufen; sie sollten jedoch der Einheitlichkeit halber besser protected sein. Objekt-Calls der Engine (siehe unten) können nur protected oder public aufrufen.
Funktionen ohne besondere Deklaration gelten als public. Wer sich also unsicher ist, welche Zugangsberechtigung er verwenden muss, oder aus moralischen oder ideologischen Gründen keine Funktionen nach außen hin schützen will, kann die Zugangsberechtigung einfach weglassen, und ist damit immer auf der sicheren Seite.

Objekt-Calls der Engine

Die Engine ruft zu Zeiten die folgenden Funktionen in Objektscripten auf.
Funktion Parameter Beschreibung
Initialize Wenn das Objekt fertiggestellt wird (Con größer gleich 100).
Completion Veraltet. Wie Initialize.
Construction object pByObj Wenn das Objekt erzeugt wird. Als Parameter wird das Objekt übergeben, in dem das erzeugende Script steht. Siehe auch Construction
Destruction Wenn das Objekt gelöscht wird.
Hit int xdir, int ydir Wenn das Objekt bei hoher Geschwindigkeit (>= 15; siehe OCF_HitSpeed1) mit der Landschaft kollidiert oder aufgenommen wird (Collection).
xdir und ydir geben die Aufprallgeschwindigkeit mit Precision 100 (siehe GetXDir) an. Die Parameter werden bei Collection nicht übergeben.
Hit2 int xdir, int ydir Wie Hit, bei Geschwindigkeiten >= 20 (siehe OCF_HitSpeed2).
Hit3 int xdir, int ydir Wie Hit, bei Geschwindigkeiten >= 60 (siehe OCF_HitSpeed3).
Grab object pTarget, bool fGrab Wenn das Objekt ein anderes Objekt anfasst oder loslässt.
Grabbed object pByObject, bool fGrab Wenn das Objekt durch ein anderes Objekt angefasst oder losgelassen wird. Ab 4.9.8.4.
RejectGrabbed object byObject Wenn das Objekt durch ein anderes Objekt angefasst werden soll. Falls true zurückgegeben wird, wird das Anfassen verhindert und der Grab-Befehl von byObject schlägt fehl. Ab 4.9.10.14 LC [353].
Get object pTarget Wenn das Objekt ein Objekt aus einem anderen Objekt herausnimmt.
Put Wenn das Objekt ein Objekt in einem anderen Objekt ablegt.
Damage int iChange, int iByPlayer Wenn das Objekt beschädigt wird.
DeepBreath Wenn das Lebewesen nach dem Auftauchen mehr als die Hälfte seiner Atemkapazität auffüllt.
Incineration int iByPlayer Wenn das Objekt entzündet wird. Achtung: Bei Objekten, die ihre Definition mit BurnTo ändern, findet der Aufruf im verbrannten Objekt statt!
IncinerationEx int iByPlayer Wenn das Objekt in einer löschenden Flüssigkeit gesprengt, und damit nicht angezündet wird. Aufruf analog zu Incineration. Ab CE.
Death Wenn ein Lebwesen stirbt.
Activate object pByObj Aktivierung durch einen Doppelklick auf Graben. Nur getragene Objekte und direkt spielergesteuerte Objekte. Wird aufgerufen, nachdem die interne Befehlskette (z.B. Bäume fällen) abgearbeitet wurde.
Contact_ Wenn das Objekt die Landschaft berührt. Siehe CNAT - Contact Attachment.
Control_ object pByObj Wenn das Objekt von außen gesteuert wird. Siehe Control-Funktionen.
Contained_ object pByObj Wenn das Objekt von innen gesteuert wird. Siehe Control-Funktionen.
ControlCommand string strCommand, object pTarget, int iTx, int iTy, object pTarget2, int iData, object pCmdObj Wenn dem Objekt durch den Spieler ein selbständig auszuführender Befehl gegeben wurde. Siehe Control-Funktionen.
ControlCommandFinished string strCommand, object pTarget, int iTx, int iTy, object pTarget2, C4Value Data Wenn das Objekt einen selbständigen auszuführenden Befehl vollendet hat oder die Ausführung des Befehls fehlgeschlagen ist.
ControlTransfer object pObj, int iTx, int iTy Wenn ein durch die Wegfindungsroutine gesteuertes Objekt (pObj) die Transferzone dieses Objekts zum Zielpunkt iTx/iTy passieren möchte. Die Transferfunktion kann dem Objekt entsprechende Kommandos geben und sollte bei erfolgreicher Bearbeitung true zurückliefern. Siehe auch SetTransferZone().
UpdateTransferZone Wenn ein Objekt geladen oder synchronisiert wird. Objekte mit einer TransferZone sollten diese bei jedem Aufruf von UpdateTransferZone neu setzen. Siehe auch SetTransferZone().
IsFulfilled Nur bei Spielziel-Objekten. Bei Rückgabewert true ist das Spielziel erfüllt.
ControlContents id idTarget Wenn ein neues Inhaltsobjekt angewählt wird. Siehe Control-Funktionen.
Selection object pContainer Wenn das Objekt durch einen Inventarwechsel ausgewählt wird. Wenn die Funktion abgefangen wird, sollte ein eigener Auswahlsound abgespielt werden.
CatchBlow int iLevel, object pBy Wenn das Objekt von einem anderen Objekt geschlagen oder getroffen wird.
QueryCatchBlow object pBy Bevor das Objekt von einem anderen Objekt geschlagen oder getroffen wird. Wenn QueryCatchBlow true zurückgibt, können damit physikalische Treffer abgefangen werden.
LineBreak int iCause Wenn ein Leitungsobjekt unterbrochen wird. iCause: 0 durch Bewegung, 1 durch fehlendes oder unvollständiges Zielobjekt.
BuildNeedsMaterial id idMaterial, int iAmount Wenn das Objekt ein anderes Objekt baut und noch Baumaterial benötigt wird. Parameter sind Typ und Menge des ersten noch benötigten Baustoffs. Durch Rückgabewert true kann die Textmeldung über fehlendes Material abgefangen werden.
AttachTargetLost Wenn das Objekt eine ATTACH-Aktivität besessen hatte, aber das Actiontarget verloren hat. Die Aktivität ist beim Aufruf bereits zurückgesetzt.
CrewSelection bool fDeselect, bool fCursorOnly Bei Änderung der Crewauswahl. fCursorOnly gibt an, ob nur das Mannschaftsmitglied angewählt wurde, welches den Cursor hat.
GetObject2Drop object pForCollectionOfObj Zur Ermittlung des am wenigsten gebrauchten Objekts, wenn der Clonk versucht, ein neues aufzunehmen. Die Funktion sollte das abzulegende Objekt zurückliefern, oder 0 für keins.
OnMenuSelection int iItemIndex, object pMenuObject Wenn ein Menueintrag ausgewählt wurde.
CalcValue object pInBase, int iForPlayer Ermittelt den Wert eines Objekts. Siehe auch GetValue().
CalcDefValue object pInBase, int iForPlayer Ermittelt den Wert eines (noch nicht gekauften) Objekttyps. Siehe auch GetValue().
CalcBuyValue id idItem, int iDefValue Rückgabewert ist Einkaufspreis des Objekttyps.
CalcSellValue object pObj, int iObjValue Rückgabewert ist Verkaufspreis des Objekttyps.
LiftTop Wenn das Objekt bei einer LIFT-Aktivität ein anderes Objekt höher angehoben hat als in der DefCore angegeben.
Stuck Wird aufgerufen, wenn das Ziel einer PUSH- oder LIFT-Aktivität festhängt.
GrabLost Wenn das Ziel einer PUSH- oder PULL-Aktion verloren geht.
Collection object pObj, bool fPut Wenn das Objekt ein anderes Objekt (pObj) aufgenommen hat (nur durch einsammeln oder anfassen und ablegen).
Collection2 object pObj Wenn das Objekt ein anderes Objekt (pObj) aufgenommen hat (immer, auch durch Scriptbefehl Enter)
Departure object pContainer Wenn das Objekt ein anderes Objekt (pContainer) verlassen hat.
Ejection object pObj Wenn ein Objekt (pObj) dieses Objekt verlassen hat (auch durch Scriptbefehl Exit).
Entrance object pContainer Wenn das Objekt ein anderes Objekt (pContainer) betreten hat.
ActivateEntrance object pByObj Wenn ein anderes Objekt versucht, das Objekt durch Entrance zu betreten.
RejectCollect id idObj, object pObj Wird vor Collection aufgerufen. Wenn RejectCollect true zurückgibt, kann damit die Aufnahme des anderen Objekts verhindert werden.
RejectEntrance object pIntoObj Wird vor Entrance aufgerufen. Wenn RejectEntrance true zurückgibt, kann damit das Hineinversetzen in das andere Objekt verhindert werden.
InitializePlayer int iPlr, int iX, int iY, object pBase, int iTeam, id idExtra Aufruf in Spielziel, -regel und Umweltobjekten nach der Platzierung eines beitretenden Spielers, und vor dem entsprechenden Aufruf im Szenarioscript. Durch Angabe einer ID lassen sich Scriptspieler-Typen unterscheiden. Beispielsweise könnte ein Szenario dynamisch Alien- oder Clonkgegner anbieten.
SellTo int iByPlr Wenn das Objekt verkauft wird. Rückgabewert 0 oder die ID des Objekts, welches dem Heimatbasismaterial hinzugefügt wird.
Sale int iByPlr Wenn das Objekt verkauft wird. Ab CE.
Purchase int iByPlr, object BuyObject Wenn das Objekt gekauft wird. Ab CE.
Recruitment int iPlr Wenn das Objekt der Crew eines Spielers hinzugefügt wird. Ab CE 4.95.2.
RejectTeamSwitch int iPlr, int iNewTeam Aufruf in Spielziel, -regel und Umweltobjekten und dem Szenarioscript. Wenn RejectTeamSwitch true zurückgibt, kann der Teamwechsel eines Spielers (durch SetPlayerTeam) verhindert werden. Ab 4.9.6.0 CR.
ContentsDestruction object pObj Die Funktion wird im Container von pObj aufgerufen, wenn dieses gelöscht wird.
DoMagicEnergy int iChange, object pObj, bool fAllowPartial Wird bei jeder Veränderung der Mana aufgerufen.
array GetCustomComponents object pBuilder Callback um Komponenten eines Objektes zu setzen. Wird in jedem Menü aufgerufen, dass das Objekt bzw. ID hat. Wird auch beim Bauen eines Objektes aufgerufen. pBuilder ist das Menü-aufrufende-Objekt bzw. der Erbauer. Rückgabewert muss ein Array mit ID/IDs sein. Siehe auch GetComponent, SetComponent, Split2Components.
IsFullfilledforPlr int iPlr Wenn die Regel "Wettstreit" (EN=Rivalry; ID=RVLR) aktiviert ist, wird IsFulfilledforPlr aufgerufen, ansonsten IsFulfilled. Nur bei Spielziel-Objekten. Bei Rückgabewert true ist das Spielziel für iPlr erfüllt.
MouseSelection int iPlr Wenn das Objekt per Maus angeklickt wurde. Objekt muss die Category C4D_MouseSelect haben.
OnActionJump int iXDir100, int iYDir100, bool fByCom Wird immer aufgerufen wenn das Objekt in die Aktion "Jump" wechselt. Als iXDir100 und iYDir100 werden die X- bzw. Y-Geschwindigkeit mit einer Präzision von 100 übergeben. fByCom ist true bei echtem Sprung; also wenn man per Sprungtaste, per Command (Maus oder Script-Commands) oder per Jump() springt; oder wenn man beim Hangeln/Klettern loslässt; ansonsten false. Wenn OnActionJump true zurückgibt, wird der Engine-Sprung unterbunden.
OnOwnerChanged int iNewOwner, int iOldOwner Wird aufgerufen, wenn das Objekt seinen Besitzer wechselt.
RejectContents Wenn true zurückgegeben wird, lässt sich kein Inhaltsmenü öffnen.
RejectFight object pEnemy Wird vor jedem Kampf aufgerufen. Wenn true zurückgegeben wird, findet kein Kampf statt.

Control-Funktionen

Die Engine ruft bei jedem Spielerkommando (Left, Up, Right, Down, Dig, Throw, Special, Special2, CursorLeft, CursorToggle, CursorRight) im Script eines spielergesteuerten Objekts die entsprechende Control-Funktion auf, wenn diese vorhanden ist. Gibt die aufgerufene Control-Funktion 1 zurück, so wird die interne Bearbeitung des Spielerkommandos übersprungen. Ist die Funktion nicht vorhanden oder gibt 0 zurück, findet die interne Bearbeitung des Spielerkommandos statt.
func ControlThrow()
{
  if (FindContents(SPER))
    return(SetAction("ThrowSpear"));
  return(0);
}
Trägt ein Clonk mit diesem Script einen Speer, so führt er seine eigene spezielle Wurf-Aktion aus, sobald der Spieler das Werfen-Kommando gibt (in diesem Fall wird das Werfen-Kommando jedoch nicht wie üblich an alle weiteren ausgewählten Mannschaftsmitglieder weitergegeben). Trägt er keinen Speer, gibt die Funktion 0 zurück und die normale interne Wurf-Aktion wird ausgeführt.
Control-Funktionen werden außerdem an angefasste (indirekt gesteuerte) Objekte weitergeleitet.
Einzelklicks und Doppelklicks: Die Engine ruft bei jedem Spielerkommando zunächst die einfache Variante der Control-Funktion auf (z.B. ControlDown) und anschließend die spezifizierte Variante (also ControlDownSingle bzw. ControlDownDouble). Beim Überladen von Control-Funktionen ist dementsprechend darauf zu achten, dass auch die richtige Variante abgefangen wird.
ContainedControl: Befindet sich das direkt spielergesteuerte Objekt in einem anderen Objekt (Behälter), so werden zunächst die Standardkommandos Down (Verlassen), Throw (Ablegen), Up (Kaufen, in Basisgebäude) und Dig (Verkaufen, in Basisgebäude) ausgewertet. Anschließend wird die Steuerung als Contained-Funktion an den Behälter weitergegeben. Ausnahme: die Spezialkommandos ControlSpecial, ControlSpecial2, ControlCursorLeft, ControlCursorToggle, ControlCursorRight und ControlWheelUp/Down sind nur für die direkte Steuerung gedacht und werden nicht an den Behälter umgeleitet.
ControlCommand: die Engine führt auch Objekt-Calls für selbständig auszuführende Befehle (Commands) aus, die direkt durch den Spieler gegeben wurden (z.B. durch Maussteuerung).
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);
}
Durch Rückgabe des Werts 1 kann der Befehl abgefangen und die interne Verarbeitung verhindert werden. "pCmdObj" ist in jedem Fall das Objekt, für das das Kommando gesetzt werden soll, auch wenn der Aufruf von einem enthaltenen Objekt kommt (siehe VehicleControl in der DefCore). Der Script-Befehl SetCommand verursacht keinen ControlCommand-Aufruf.
ControlCommand-Aufrufe werden an angefasste oder von innen gesteuerte Fahrzeuge weitergeleitet, wenn diese ein entsprechendes VehicleControl-Flag besitzen. Diese Weiterleitung wird nach dem ControlCommand-Aufruf des Clonk-Scripts durchgeführt, aber noch vor der internen Verarbeitung, so dass auch das gesteuerte Fahrzeug bei Bedarf den Befehl auswerten und abfangen (überladen) kann.
ControlWheelUp und ControlWheelDown werden durch Mausraddrehungen außerhalb von Menüs aufgerufen. Wenn sie nicht überladen sind, führen sie einen ShiftContents-Befehl durch. Dessen Auswirkungen können wiederum durch ControlContents abgefangen werden.
ControlContents wird aufgerufen, wenn durch das Mausrad, direktes Anklicken mit der Maus oder einen ShiftContents-Befehl im Script (zum Beispiel bei ControlSpecial oder ControlSpecial2) ein Inventarwechsel stattgefunden hat. Hier können zum Beispiel Aktionen wie das Ablegen von Waffen bei entsprechenden Clonks, oder eigene Inventarwechseldsounds, ausgeführt werden. Wird die Funktion mit einem Rückgabewert ungleich 0 abgefangen, wird der Inventarwechsel unterdrückt. Ansonsten rückt das Objekt mit dem entsprechenden, im ersten Parameter übergebenen ID nach vorne und es wird ein Selection-Call an das neue, erste Inhaltsobjekt ausgeführt. Wird dieser nicht abgefangen, wird der Soundeffekt "Grab" beim inventarwechselnden Objekt abgespielt.

Context-Funktionen

Context-Funktionen in Objektscripten (Context_) erscheinen im Spiel im Kontextmenü des Objekts. Die Engine übergibt beim Aufruf einen Zeiger auf das aufrufende Objekt als ersten Parameter (bei Mannschaftsmitgliedern immer das Objekt selbst). Context-Funktionen sollten immer eine gültige Funktionsbeschreibung haben und müssen public sein.
public func ContextConstruction(object pCaller)
{
  [Bauauftrag|Image=CXCN|Condition=HasKnowledge]
  SetCommand(this(), "Construct");
  return(1);
}
Über das Condition-Feld kann bestimmt werden, dass die Funktion nur dann im Kontextmenü auftaucht, wenn die entsprechende Funktion (hier HasKnowledge) im Objektscript vorhanden ist und einen positiven Wert zurückliefert. Das Menüobjekt wird als erster Parameter an die Condition-Funktion übergeben.
sulai, November 2003
Sven2, Februar 2004
matthes, Juli 2004
Clonkonaut, April 2008
Der Tod, April 2022