FAQ (Entwicklermodus)

Aus Clonk Wiki
Wechseln zu: Navigation, Suche

Hier wurden einige Fragen gesammelt, die verschiedene Entwickler im Laufe der Zeit gestellt haben. Für allgemeine Fragen siehe FAQ.

Inhaltsverzeichnis

Allgemeines[Bearbeiten]

Erklär mir das mit den Klammern[Bearbeiten]

Es gibt drei Arten von Klammern: ( ), { } und [ ].

Die häufigsten sind wohl die 'runden Klammern' also ( und ). Sie werden von Funktionen benötigt um Parameter zu erhalten:

C4Script
clonk3->SetPosition(5,
 
20);

Auch wenn eine Funktion keine Parameter erhält, müssen die Klammern dennoch vorhanden sein, da es sonst nicht als Funktion sondern als Variable zählt:

C4Script
GetAction();
Natürlich kann eine Funktion auch eine andere Funktion als Parameter erhalten:

C4Script
GetContainer()->SetPosition(LandscapeWidth()/2,
 
LandscapeHeight()/2);

Die 'geschwungenen Klammern' begrenzen eine Funktion:

C4Script
func
 
IsTestObject(){
 
return(true);
 
}

func
 
Add(a,
 
b){
  
return
 
a
 
+
 
b;
}

'eckige Klammern' werden für Arrays benötigt:

C4Script
var
 
testarray
 
=
 
[5,
 
7];
testarray[0];
  
// == 5
testarray[1];
  
// == 7

Kann man per Message() ausgegebene Texte formatieren?[Bearbeiten]

Ja:

C4Script
//Gibt den Text Kursiv aus:
Message("<i> Willkommen </i>");
 

//Gibt den Text farbig (in diesem Beispiel rot) aus:
Message("<c ff0000> Ich grüße dich </c>");

Bei "<c>" müssen die Buchstaben der Farbcodes unbedingt klein geschrieben werden, da das ganze sonst nicht funktioniert.

Wenn ich LocalN("Punch") = 0; aufrufe, bekomme ich folgende Fehlermeldung, was mache ich falsch?[Bearbeiten]

 postfix-operator "=" first parameter: "any" cannot be converted to "&"

Wahrscheinlich hast du versucht, eine neue Variable zu erzeugen beziehungsweise einer nichtvorhandenen einen Wert zuzuweisen. Das ist allerdings nicht möglich, mit VarN(), LocalN() und GlobalN() kann im Gegensatz zu Var(), Local() und Global() nur auf vorher deklarierte Variablen zugegriffen werden.

Warum hat Message() als zweiten Parameter das Objekt worüber es erscheint? Das ist total unbequem, wenn man einen Formatstring angeben will![Bearbeiten]

Das war schon immer so™

Wieso funktioniert GameOver(); im Entwicklermodus nicht?[Bearbeiten]

Es funktioniert schon, die Engine beendet sich nur nicht, damit man das Spiel auch nach dem Ende noch untersuchen kann. Wenn man sie manuell beendet, wird das Spiel wie im Spielermodus ausgewertet.

Ist Pathfree oder Distance rechenintensiver?[Bearbeiten]

PathFree ist um ein vielfaches rechenintensiver als Distance. Bei Distance wird lediglich der Satz des Herrn P. aus A. angewandt, bei PathFree müssen jede Menge Landschaftspixel überprüft werden.

Unterscheidet die Clonk-Engine für C4Script zwischen Groß-und Kleinschreibung?[Bearbeiten]

Ja.

Wie werden eigentlich C4Group-Gruppendateien komprimiert?[Bearbeiten]

Mit GZIP. Allerdings sind die "Magic Bytes" im Header verändert.

Ist die Funktion ChangeDef eigentlich das gleiche, wie CreateObject(...) und sofort danach RemoveObject?[Bearbeiten]

Nein, es wird dann kein Initialize aufgerufen, die Locals bleiben erhalten, die Physicals ändern sich auch nicht und der Besitzer bleibt auch gleich. Vielleicht auch noch andere Sachen.

Wie funktioniert der iGrowth-Parameter bei PlaceVegetation?[Bearbeiten]

iGrowth -1 plaziert einen voll ausgewachsenen oder einen sich in zufälligem Wachstumsstadium befindlichen Baum. Ansonsten gilt iGrowth im Gegensatz zu DoCon-Werten als echter interner Growth-Wert, d.h. er hat einen Wertebereich von 0 bis 100000 ähnlich den Physical-Werten. 50% sind also 50000.

Wieviele Vertices kann ein Objekt in Clonk maximal haben?[Bearbeiten]

30. 15 können via Scenario.txt gesetzt werden, weitere 15 können mit AddVertex()[1] hinzugefügt werden.

Wie kriege ich aus einem Objekt-Script ein Objekt zur Crew hinzugefügt?[Bearbeiten]

Siehe MakeCrewMember in der Doku.

Wie kann ich mit Hilfe der Funktion "SelectCrew()" programmieren, dass anstelle aller ausgewählten Clonks ein anderer Clonk ausgewählt wird?[Bearbeiten]

Das einfachste wird wohl so sein:

C4Script
global
 
func
 
SelectSingleCrew(pCrewMember)
{
  
var
 
iOwner
 
=
 
GetOwner(pCrewMember);
  
var
 
pObj,
 
i
 
=
 
0;
  
while(pObj
 
=
 
GetCrew(iOwner,
 
i++))
    
SelectCrew(iOwner,
 
pObj,
 
pObj
 
==
 
pCrewMember);
  
return(1);
}

Das wären dann zwar ein paar unnötige SelectCrew-Aufrufe, aber dafür ist das Script einfacher :)

Was muss ich tun, damit bei Oversize=1 die Grafik auch vergrößert dargestellt wird??[Bearbeiten]

Eine Action setzen. Aber Vorsicht! Beim Stretchen wird dann NUR das Facet dargestellt. Klartext: Ein gestrechtet Hochofen würde nur aus der Feuer-Grafik bestehen.


Objektverhalten[Bearbeiten]

Warum kann ein Clonk, der Mitglied einer Mannschaft ist, per SetCommand einen Baum fällen und ein "unabhängiger" Clonk nicht?[Bearbeiten]

Clonks, die sich in Mannschaften befinden, bekommen mit der Höhe ihres Ranks Fähigkeiten (z.B. Klettern). Wenig bekannt ist, dass Clonks des Ranks 0 (mit dem normale Clonks geboren werden) automatisch die CanDig, CanChop und CanConstruct-Eigenschaften besitzen. Für Clonks außerhalb einer Clonk-Crew müssen diese Eigenschaften manuell entweder in der DefCore.txt oder per SetPhysical gesetzt werden.

Gibt es eine Möglichkeit zu verhindern, dass ein Clonk bauen kann?[Bearbeiten]

Es gibt die Physical "CanConstruct" - die musst du per SetPhysical() auf 0 setzen, dann kann der Clonk nicht mehr bauen. Die Physical sollte aber nur temporär verändert werden (siehe Doku), da du sonst noch einen Clonk kaputtmachst...

Ich bräuchte ein Script für einen Clonk, der auf Anfassen + Doppel-graben dem, den er anfasst, folgt.[Bearbeiten]

C4Script
protected
 
func
 
ControlDigDouble(pClonk)
{
  
SetCommand(this(),
 
Follow,
 
pClonk);
}

Wie kann man ein Wasserfass in einem Haus in zwei Eisklumpen verwandeln?[Bearbeiten]

C4Script
protected
 
func
 
TimerCall()
{
  
var
 
barrel;
  
if(barrel
 
=
 
FindContents(WBRL))
  
{
    
CreateContents(ICE1);
    
CreateContents(ICE1);
    
RemoveObject(barrel);
    
CreateContents(BARL);
  
}
}

Wie kann man bei einem Gebäude, das eine Heimatbasis sein soll, die Position der Flagge festlegen?[Bearbeiten]

Der erste Eckpunkt bzw. Vertex bestimmt die Flaggenposition. Das gilt übrigens für alles, was mit der Procedure ATTACH befestigt wird.

Wie kann man ein Fahrzeug vollständig anhalten?[Bearbeiten]

Im Fahrzeugscript:

C4Script
SetXDir(0,[Fahrzeug]);
SetYDir(0,[Fahrzeug]);
SetComDir(COMD_Stop(),[Fahrzeug]);

Wie kann man per Script eine Energieleitung verlegen?[Bearbeiten]

C4Script
ObjectSetAction(CreateObject(PWRL,
 
0,
 
0,
 
-1),
 
"Connect",
 
[Versorger],
 
[Verbraucher]);

Was muss ich machen, damit ein Objekt Strom erzeugt?[Bearbeiten]

in der DefCore.txt:

 [Physical]
 Energy=100000

Die Zahl gibt die maximal speicherbare Energiemenge an. Man kann auch eine andere Zahl nehmen.

 [DefCore]
 LineConnect=18

Damit man auch Energieleitungen anschließen kann. Im Script regelmäßig DoEnergy aufrufen, um Energie zu erzeugen. Die Parameter stehen in der Doku.


Gibt es eine Möglichkeit, zu verhindern, dass eine bestimmte Sorte Clonks bestimmte Gebäude betreten kann?[Bearbeiten]

Sogar mehrere. Entweder ein Objekt, das regelmäßig überprüft, ob ein Clonk der falschen Sorte den Befehl hat, das Gebäude zu betreten:

C4Script
var
 
obj;
//Alle Clonks finden
while(obj=FindObject([ID
 
der
 
Clonksorte))
 
{
  
//Wenn der Clonk den Betretenbefehl hat
  
if(GetCommand(obj)
 
eq
 
"Enter")
  
//Und als Ziel ein Gebäude der falschen Sorte
  
if(GetID(GetCommand(obj,1))==[ID
 
des
 
Gebudes])
  
//Befehl löschen
  
SetCommand(obj,
 
"None");
  
//dann noch überprüfen, ob der Clonk in einem falschen Gebäude enthalten ist (Contained())
  
//und gegebenenfalls rausschmeißen (SetCommand(obj, "Exit"))
}

Oder, falls man das Gebäude umscripten kann, in ActivateEntrance und in RejectCollect eine Überprüfung einbauen.

Wie groß ist der Suchbereich, in dem Clonks sich Materialien für Gebäude etc. suchen?[Bearbeiten]

Waagerecht +/-500 Pixel; Senkrecht +/-250 Pixel.

Wie kann ich ein Objekt "schwerelos" machen?[Bearbeiten]

Es gibt mehrere Möglichkeiten:

  • Eine Aktivität mit Procedure=FLOAT. Diese Methode benutzen zum Beispiel Ballon und Luftschiff. Dabei kann das Objekt bei gesetzter ComDir je nach Float-Physical beschleunigen. Für ein einzelnes Objekt oftmals die beste Möglichkeit.
  • Category Staticback setzen (SetCategory()) oder gleich in der Defcore angeben. Solche Objekte sind dann allerdings im Hintergrund und verhalten sich auch teilweise anderweitig anders - Fällbare Objekte lassen sich zu Beispiel fällen, einen Baum sollte man also nicht auf diese Weise schweben lassen ;-) - aber das ist möglicherweise sogar beabsichtigt.
  • Jeden Frame (Zum Beispiel per TimerCall) per SetYDir() die Auswirkungen der Schwerkraft rückgängig machen. Dies hat den Vorteil, dass es mit jedem Objekt funktioniert und am flexibelsten ist. Dieser Script nutzt Präzisionsangaben um den GetGravity-Wert umzurechnen:
 SetYDir(GetYDir(obj,5000)-GetGravity(),obj,5000);

Wie kann ich die Anzahl von Objekten eines bestimmten Typs begrenzen?[Bearbeiten]

Im Objektscript in Initialize

C4Script
if(ObjectCount(GetID())
 
>
 
[Maximale
 
Anzahl])
 
return(RemoveObject());

hineinschreiben.

Wie kann man das hinkriegen das die Clonks, wenn sie sterben, ihren Inhalt nicht verlieren sondern vernichten (RemoveObject)? In der Funktion "Death" geht's nicht, die verlieren den Inhalt immer schon vorher.[Bearbeiten]

Man muss die Objekte im StartCall der Aktion "Death" löschen.

Was muss im Script meines Clonks stehen, wenn er sobald er ins Wasser kommt, an Lebensenergie verlieren soll?[Bearbeiten]

  • In einem Timercall:
C4Script
if(InLiquid())
  
if(GetMaterial()
 
==
 
Material("Water"))
    
DoEnergy(-1);
  • In die Schwimm-Action einen StartCall hinzufügen der Energie wegnimmt. Beachte dass man dann langsamer Energie verliert, wenn man langsamer schwimmt.

Szenarien[Bearbeiten]

Gibt es eine Möglichkeit, den Spielerbeitritt per Script auszuschalten?[Bearbeiten]

Ja, wenn man die maximale Spielerzahl auf 0 setzt, kann niemand mehr beitreten:

C4Script
SetMaxPlayer(0);

Die Runde soll beendet werden, wenn ein bestimmtes Objekt in die Heimatbasis gebracht wird.[Bearbeiten]

Angenommen, das Objekt sei ein Kristall, mit der ID CRYS.

C4Script
public
 
func
 
FindeKristallInHuette(iSpieler)
{
  
return(FindContents(FindBase(iSpieler),
 
CRYS));
}

Jetzt kannst du mit FindeKristallInHütte abfragen, ob in der (ersten) Heimatbasis von Spieler X ein Kristall ist. Mit folgenden Szenarioskript könntest du bei Script-Counter 10 jeweils prüfen, ob der Kristall in der Heimatbasis von Spieler 1 ist:

C4Script
protected
 
func
 
Script10()
{
  
//wenn Kristall nicht in Hütte, abbrechen
  
if(!FindeKristallInHuette(0))
 
return(goto(10));
  
return(1);
}

Der Script-Counter wird durch goto solange auf 10 zurückgesetzt (und die Funktion somit immer wieder aufgerufen), bis der Kristall in der Heimatbasis des ersten Spielers angekommen ist. Danach läuft der Scriptcounter weiter und ermöglicht Reaktionen z.B. in einer Script20-Funktion. Beachte allerdings, dass der Spieler den Kristall verkaufen könnte - das würde von diesem Skript nicht bemerkt!

Ich habe einen Kohlebaum erstellt, wenn ich ihn aber in Sägewerk stecke kommt er wieder als Baum heraus, wie kriege ich es hin, das er in Kohle zerlegt wird?[Bearbeiten]

Sägewerke können von Hause aus nur Objekte zersägen, die vollständig aus Holz bestehen. Du müsstest also das Sägewerk überladen, um diese Funktionalität zu erreichen.