[Gelöst] Szenarien Skript für jeden Spieler einzeln durchg

Hi,

kurz:
ich suche eine Möglichkeit, wie ein Szenarienskript eine Reihe von Funktionen für jeden Spieler einzeln durchgeht. Also eine Liste von Befehlen nur für Spieler 1 und eine Liste von Befehlen nur für Spieler 2 usw.

Hintergrund:
Ich habe das normale Objektpack, das Erweiterungspack (auch wenn es nur eingeschränkt funzt) und Space Empire in der neusten Rage Version zusammengetan.
Ich möchte sozusagen eine Entwicklung im Zeitalter haben.  Das heißt am Anfang hat man nur wenige startgebäude, die man bauen kann und im Laufe des Spiels (wenn ein Wert an klunkern erreicht wurde), bekommt der Spieler Pläne mit Bauplänen, die er einsetzen kann und wodurch er dann neue Gebäude errichten kann. Ich habe 7 solche Entwicklungen vorgesehen.
Das Problem ist nun, dass ich mich erst seit 2 Tagen mit dem Skript und der sprache beschäftige. Soweit ich sehe, gibt es nur den linearen Ablauf des Skripts, wobei man durch den Counter und "goto" auch an beliebige stellen springen kann.  Ich habe es bisher nun wie folgt gelöst:
Es gibt eine Schleife die zb. so aussieht:

func Script20()
{
if(GetWealth(0)> 19) return(goto(500010));
}

func Script21()
{
if(GetWealth(1)> 19) return(goto(900010));
goto(20);
}

// Update 1 für Spieler 1, 0   (heißt spieler 2 hat 0 updates, während spieler 1 hier sein erstes bekmomt)
func Script500010()
{
SetWealth(0,0);
CreateContents(PLAN,FindBase(),1)-> Init(HUT2,SAWM,WMIL);
CreateContents(PLAN,FindBase(),1)-> Init(IGLO,IDOL);
CreateContents(PLAN,FindBase(),1)-> Init(CNKT,ANVL,FNDR);
CreateContents(PLAN,FindBase(),1)-> Init(LNKT,F_EL,HUT3);
goto(22);
}

//
func Script900010()
{
SetWealth(1,0);
CreateContents(PLAN,FindBase(1),1)-> Init(HUT2,SAWM,WMIL);
CreateContents(PLAN,FindBase(1),1)-> Init(IGLO,IDOL);
CreateContents(PLAN,FindBase(1),1)-> Init(CNKT,ANVL,FNDR);
CreateContents(PLAN,FindBase(1),1)-> Init(LNKT,F_EL,HUT3);
goto(36);
}

usw usw. …

Letzendlich bedeutet das, dass ich jede mögliche Kombination abdecken muss und somit seeeeehr viel schreiben muss. Bei 3 Spielern wäre das schon nicht mehr zumutbar.
Ich brauche also nun irgendwas, wie ich das umsetzen kann, ohne ein mega skript zu schreiben.  Das mit der Spieler Einteilung wäre jetzt mein erster Gedanke. Wenn es ncoh was anderes gibt, bin ich dafür natürlich auch offen :slight_smile:

Ach und vllt wisst ihr ja auch, wie das Forschungsgebäude funktioniert. Und zwar ist es ja so, dass man dort alles erforschen kann. Deswegen kann ich das Gebäude für meine Entwicklungsstufen nicht verwenden und nehme stattdessen dieses Item "Plan". Es würde mir aber noch besser gefallen, wenn man im Skript einstellen könnte, dass im Forschungsgebäude nur bestimmte Baupläne erforschbar sind, welche mit der Zeit dann eben immer mehr werden. Kennt ihr dafür war?

Falls die Problematik nicht ganz klar wurde, bitte Fragen, dann erkläre ich es genauer :slight_smile:
Auch falls es noch andere Clonkforen geben sollte, wo ich nachfragen kann, weist mich bitte darauf hin :slight_smile:

Da wäre doch eine Schleife das beste.

for-schleife.

In der Doku gibts auch bei GetPlayerByIndex unten in den Beispielen genau die Schleife die du brauchst.

Ich hoffe dir ist damit geholfen. :slight_smile:

ah super, DANKE :)  habe mir schon fast gedacht, dass es irgendwie mit einer for-schleife geht… bin nur bisher noch nicht ganz dahintergestiegen, wie diese funktioniert… hatte mir deswegen meine eigene schleife mit "goto" gebaut :smiley:

Kannst du mir vllt kurz erklären, wie man das mit der for schleife, bzw. mit dem von dir genannten Beispiel dann umsetzen kann?
das Beispiel ist ja:
for(var i = 0; i < GetPlayerCount(); i++)

das ist nun also eine schleife, die bei 5 spielern, die zahlen 0 bis 4 durchgeht, wobei 0 ja der erste Spieler ist, also alle 5 spieler abgedeckt werden.
Aber wie nutze ich das nun für meine Zwecke?
Ich stelle es mir wie folgt vor:

func Script20()
{
if(GetWealth(0)> 19) return(goto(21));
goto(20);
}

func Script21()
{
SetWealth(0,0);
CreateContents(PLAN,FindBase(),1)-> Init(HUT2,SAWM,WMIL);
}

func Script22()
{
if(GetWealth(0)> 999) return(goto(23));
goto(22);
}

func Script23()
{
SetWealth(0,0);
CreateContents(PLAN,FindBase(),1)-> Init(CHEM,FLNT,TFLN);
goto(24);
}

usw… usw.

Eine Auflistung für jeden Spieler, die für jeden Spieler unabhängig von den anderen Spielern durchgegangen wird. Da fällt mir ein, möglicherweise wäre eine Lösung auch, wenn ich in der eben geschehenen Auflistung nicht direkt den Spieler benennen würde, sondern anstelle der 0 für spieler 1, eben eine Variable einsetze, sodass jeder spieler durchgegangen wird =) Wäre das umsetzbar? Oder ist das gar das, was du mir mit der for-schleife vorschlägst? Ich hab die for-schleife leider nicht nicht verstanden =/
Also wo bringe ich in dem genannten Konstrukt die for schleife unter?

Ich bin wie gesagt noch sehr neu, was das skript schreiben angeht, habe auch absolut keine Ahnung vom sonstigen Programmieren, weshalb ich schon sehr stolz bin ,dass ich überhaupt was funktioierendes auf die Beine gestellt habe :smiley: nur halt leider sehr umständlich.

Hmmm, vlielleicht sowas?

func CheckAllPlayerWealths()
{
  for(var i = 0; i < GetPlayerCount(); i++)
  {
    if(GetWealth(i) > 19)
    {
      SetWealth(i, 0);
      CreateContents(PLAN,FindBase(), i) -> Init(HUT2,SAWM,WMIL);
      CreateContents(PLAN,FindBase(), i) -> Init(IGLO,IDOL);
      CreateContents(PLAN,FindBase(), i) -> Init(CNKT,ANVL,FNDR);
      CreateContents(PLAN,FindBase(), i) -> Init(LNKT,F_EL,HUT3);
      Log(“Hurra, Spieler %s kriegt neue Baupläne!”, GetPlayerName(i));
    }
  }
}


Wenn die for schleife ausgeführt wird, wird das i mitgenommen und hat einen Wert, der beim ersten mal 0 ist (wegen var i = 0). Wenn die Forschleife dann einmal durchgegangen ist springt sie zurück und geht alles nochmal durch, nur, dass i davor eins größer gemacht wird, weil da i++ steht. Und das geht so lange so, bis i < GetPlayerCount() falsch ist.

SetPlrKnowledge gibt dem Spieler btw direkt Baupläne, ohne dass er erst diese Schriftrollen angucken muss.

Genau sowas. Nur empfehle ich vor der if(getWealth(i) > 19) das hier einzufügen: "var i = GetPlayerByIndex(i);"

Es kann immer ein Spieler leaven oder beim Start rausfliegen, das verfälscht dann die normale GetPlayerCount Zählung. GetPlayerByIndex machts sicher. :slight_smile:

Edit:
Der Sauberkeit halber:

func CheckAllPlayerWealths()
{
  for(var i = 0; i < GetPlayerCount(); i++)
  {
    var iPlr = GetPlayerByIndex(i);
    if(GetWealth(i) > 19 && FindBase(iPlr))
    {
      SetWealth(iPlr, 0);
      CreateContents(PLAN,FindBase(iPlr), iPlr) -> Init(HUT2,SAWM,WMIL);
      CreateContents(PLAN,FindBase(iPlr), iPlr) -> Init(IGLO,IDOL);
      CreateContents(PLAN,FindBase(iPlr), iPlr) -> Init(CNKT,ANVL,FNDR);
      CreateContents(PLAN,FindBase(iPlr), iPlr) -> Init(LNKT,F_EL,HUT3);
      Log("Hurra, Spieler %s kriegt neue Baupläne!", GetPlayerName(iPlr));
    }
  }
}


FindBase könnte vllt. Probleme machen, wenn nicht jeder Spieler eine Basis hat. Nur jeder Spieler mit Basis (… und mehr als 19 Clunker) kriegt beim Aufruf dieser Funktion (CheckAllPlayerWealths) Baupläne.

wow, super, danke euch beiden :slight_smile: hatte schon befürchtet ich müsste tagelang auf antworten warten, weil clonk ja schon recht alt ist :slight_smile:

Also ich habe jetzt mal zum testen folgendes Script:

(Raute)strict 2

func Initialize() {
  
  return(0);
}

func CheckAllPlayerWealths()
{
  for(var i = 0; i < GetPlayerCount(); i++)
  {
    var iPlr = GetPlayerByIndex(i);
    if(GetWealth(i) > 19 && FindBase(iPlr))
    {
      SetWealth(iPlr, 0);
      CreateContents(PLAN,FindBase(iPlr), iPlr) -> Init(HUT2,SAWM,WMIL);
      CreateContents(PLAN,FindBase(iPlr), iPlr) -> Init(IGLO,IDOL);
      CreateContents(PLAN,FindBase(iPlr), iPlr) -> Init(CNKT,ANVL,FNDR);
      CreateContents(PLAN,FindBase(iPlr), iPlr) -> Init(LNKT,F_EL,HUT3);
      Log("Hurra, Spieler %s kriegt neue Baupläne!", GetPlayerName(iPlr));
    }
  }
}

Sollte das nicht schon aussreichen, um bei mehr als 19 Gold die Pläne zu bekommen?  Aktuell passiert nämlich leider nichts, wenn ich das spiel starte und mehr als 19 gold hab…

Dazu noch die Fragen: brauche ich immer ein "func Initialize()" auch wenn ich garnichts darin schreibe?
Funktioniert das Script so, auch völlig ohne den Counter?  Denn angenommen ich kriege diese eine Schleife jetzt zum laufen. Schreibe ich direkt hintendran nochmal exakt dieselbe Funktion nur eben mit neuen Bauplänen und anderer Goldmenge? Funktioniert das dann auch völlig unabhängig, also es muss nicht erst jeder die ersten Pläne haben, bevor jemand die 2ten Pläne bekommt, sondern es kann jeder unabhängig von den anderen Spielern Pläne bekommen, sofern er die Bedingung dafür erfüllt? Und der bekommt dann nicht ständig wenn er mehr als 19Gold hat dieselben Pläne, sondern jedes Plan-pack kann man nur einmal kriegen.
Ist all dies hier berücksichtigt?

Edit: gibt es hier was, womit ich im Forum den Teil als "Code" markieren kann, sodass bei einer Raute es nicht fett gedruckt wird? ^^

Wenn das dein Szenarien script ist, passiert wirklich nichts.
Denn die Funktion "CheckAllPlayerWealth" wird nie aufgerufen.

Am Besten man bastelt sich mit ScriptGo einen einfachen Timer.
Damit jeder Spieler nur einmal die Pläne kriegt, müssen wir einen Array anlegen, um für jeden Spieler ein Wert zu speichern. 0 für noch nicht bekommen, 1 für bereits bekommen.
Arrays sind ein wenig komplizierter, sollte man sich aber definitiv mal angucken.

Analog dazu dein benötiger Szenarien script:


(Raute)strict 2

static aPlrGivenPlans; // Static weil Szenarien script

func Initialize() { // ist uebrigens nicht notwendig im Szenarienscript, wenn mans nicht braucht. Aber wir brauchens jetzt.
 
aPlrGivenPlans = []; // Array erstellen. 'Ein mit Nullen gefühltes Feld wird erstellt'

  return(ScriptGo(1)); // Unser Timer
}
func Script10(){
CheckAllPlayerWealth(); // Funktion aufrufen, zum pruefen!
goto(1); // und wieder zu 1, damit bei 10 wieder geprueft wird.
}

func CheckAllPlayerWealths()
{
  for(var i = 0; i < GetPlayerCount(); i++)
  {
    var iPlr = GetPlayerByIndex(i);
    if(GetWealth(iPlr) > 19 && FindBase(iPlr) && (aPlrGivenPlans[iPlr] != 1) ) // Geld? Basis? Bereits bekommen?
    {
      SetWealth(iPlr, 0);
      CreateContents(PLAN,FindBase(iPlr), iPlr) -> Init(HUT2,SAWM,WMIL);
      CreateContents(PLAN,FindBase(iPlr), iPlr) -> Init(IGLO,IDOL);
      CreateContents(PLAN,FindBase(iPlr), iPlr) -> Init(CNKT,ANVL,FNDR);
      CreateContents(PLAN,FindBase(iPlr), iPlr) -> Init(LNKT,F_EL,HUT3);
      Log("Hurra, Spieler %s kriegt neue Baupläne!", GetPlayerName(iPlr));
      aPlrGivenPlans[iPlr] = 1; // Arraywert setzen, damit nur einmal Pläne ausgeben werden
    }
  }
}


Das mit der Raute ist wegen der Markdown implementierung. Kannst hier aber strict2 weglassen, ist ja selbstverständlich, dass das da ist.
Und ja, es ist unabhängig von anderen Spielern. Jeder Spieler ist für sich selbst.

Ist wohl beim kopieren versehentlich passiert, aber bevor das Script falsch kopiert wird: Das GetWealth(i) müsste GetWealth(iPlr) sein.

>Das mit der Raute ist wegen der Markdown implementierung.


Markdown-Formatierungen kann man über \ escapen, ergo \# damit die Raute angezeigt wird.

okay super :slight_smile:
werde das von dir Gecko geschriebene Script dann mal morgen testen und dann berichten, ob alles funktioniert :slight_smile: und danke für die Erklärungen hinter den Befehlen :slight_smile:
Danke auch an Pyrit für den Hinweis, dass man diese Schriftrollen umgehen kann, einem Freund von mir ist es nämlich eben beim testspiel passiert, dass er ne schriftrolle aus dem Rand geworfen hat :smiley:
(ja ich habe das Script tatsächlich schon für 2 spieler ohne diese ganzen schleifen und array befehle fertig :smiley: war ne mordsarbeit bei 8^2 verschiedenen Möglichkeiten und für jede Möglichkeit 4 Befehle :D  Deswegen brauche ich für 3 oder mehr Spieler dann eure neuen Befehle :slight_smile: )

was heißt das "&&" ?
Und es sollte jetzt, wenn ich es so kopiere und natürlich eine richtige Raute nehme und den Hinweis von ClonkGeist beachte, schon mit einer Entwicklungsstufe für mehrere Spieler funktionieren, richtig? Werde ich morgen dann testen.

Kann man, ohne das Gebäude Forschungsstation zu ändern, hier eigentlich irgendwie einstellen, dass man eben nicht alles erforschen kann, sobald die Forschungsstation gebaut ist? Am besten würde ich es nämlich finden, wenn man einfach ganz am anfang eine Forschungsstation baut und dann nach und nach in dieser Station neue Forshcungsmöglichkeiten freigeschaltet werden. So muss man die Gebäude dann immernoch einzeln erforschen, bekommt sie also nicht mal eben so geschenkt, kann aber auch nicht gleich an anfang ein Raumschiff oderso erforschen.  Das wäre perfekt… ich befürchte aber, dass ich dazu die Forschungsstation bearbeiten muss und da traue ich mich noch nicht dran, weil ich bisher noch nicht weiß, wo und was ich dafür alles ändern müsste :D 

Ach wenn wir schon dabei sind:
Ich hab noch ein Problem mit dem Bohrturm. Und zwar kann der normale Bohrturm des Obejkt pakets schon Granit und alles durchbohren. Der neue Bohrturm aus dem Space Empire Paket kann dies allerdings nicht. Habe schon alles verglichen und versucht rauszufinden welche Werte dafür verantwortlich sind… habe es aber nicht rausfinden können. Denn es wäre deutlich logischer, wenn der alte Turm eben nicht durch Granit und stein kommt, aber dafür der neue Turm :wink:

>was heißt das "&&" ?


Ist ein logisches Und. Siehe Operatoren in der Doku. :)

>Kann man, ohne das Gebäude Forschungsstation zu ändern, hier eigentlich irgendwie einstellen, dass man eben nicht alles erforschen kann, sobald die Forschungsstation gebaut ist?


Im Szenario.txt kann man bei "[Definitions]" SkipDefs=WMIL machen. Dadurch können diese Dinge (deren ID's man angibt, mit Simikolon gerennt) nicht erforscht werden, allerdings sind sie gar nicht erst existent. Können folglich auch nicht erstellt werden. Vielleicht kennt jemand ja eine bessere Möglichkeit. :D

>[...]der normale Bohrturm des Obejkt pakets schon Granit und alles durchbohren.


FreeRect ist das Zauberwort. DigFree gräbt nur Frei. FreeRect macht alles Frei.

>Im Szenario.txt kann man bei "[Definitions]" SkipDefs=WMIL machen. Dadurch können diese Dinge (deren ID's man angibt, mit Simikolon gerennt) nicht erforscht werden, allerdings sind sie gar nicht erst existent. Können folglich auch nicht erstellt werden. Vielleicht kennt jemand ja eine bessere Möglichkeit. :D


Ja! Ich! Ich! \*fingerschnipp\*
Das Forschungssystem arbeitet doch mit einer Art TechTree, sodass man nur ein Objekt erforschen kann, wenn dessen Grundlage bereits erforscht wurde. Fallbeispiel: Pumpe -> Bohrturm. Ein Bohrturm kann erst erforscht werden, wenn der Bauplan der Pumpe bereits bekannt ist, was auch logisch erscheint. Wie soll ein Bohrturm funktionieren, ohne dass man die Pumpentechnologie erforscht hat? Das ganze ist im Objektscript der einzelnen Objekte selbst unter der Funktion GetResearchBase() definiert. Das Problem sollte gelöst sein, wenn man in einem #appendto bei GetResearchBase() die ID vom Objekt zurückgibt. Somit ist die Erforschungsbasis des Objekts das Objekt selbst, weshalb es nie erforscht werden kann.
Dein Ansatz war aber auch ganz nett. Typisch Gecko halt. Funktioniert einwandfrei, kann man aber schöner machen. :P

>FreeRect ist das Zauberwort. DigFree gräbt nur Frei. FreeRect macht alles Frei.


Mit dem Unterschied, dass DigFree() einen Kreis freimacht und FreeRect() ein Rechteck. Dazwischen gibts auch noch DigFreeRect(), was selbsterklärend sein dürfte. Soweit ich weiß, gibt es leider keine Funktion, die sämtliches Material Kreisförmig wegmacht, aber das lässt sich ganz leicht in einer eigenen Funktion schreiben.

>werde das von dir Gecko geschriebene Script


Vorweg ein kleiner Hinweis. Du hast zwar Gecko angeschrieben, aber auf eine Nachricht von ClonkGeist geantwortet. Im Forum hier gibt es Baumstruktur. Auf jeden Post kann beliebig oft geantwortet werden, wobei die Antworten dann "paralell" angeordnet werden, anstatt nacheinander. Letztendlich sieht man an der Einrückung des Posts, welcher Post auf welchen Antwortet. Das erlaubt natürlich auch beliebig viele Abzweigungen in der Diskussion. :D
Wenn man Stellungnahme zu zwei verschiedenen Kommentaren machen will, sollte man das dann in zwei Posts splitten, die dann jeweils am richtigen Ort eingefügt werden. Keine Sorge, das gilt auch nicht als Doppelpost, da du an verschiedenen Orten anknüpfst. Ein Doppelpost wäre es nur, wenn du auf deine eigenen Nachrichten antwortest, anstatt sie zu editieren. :)

>was heißt das "&&" ?


Wie Gecko bereits geschrieben hat, ist das ein Und. Lass dich nicht verwirren, weil es doppelt geschrieben ist, das ist schon richtig so. && ist ein logisches Und, welches mit true/false arbeitet, & ist ein bitweises und, was wiederum jedes einzelne bit in einer Zahl mit dem entsprechenden Bit einer anderen Zahl verundet. Bitweise Operatoren braucht man nicht so oft wie logische, eigentlich nur, wenn man sich eine Bitmaske zusammenstellt und auslesen will.

Danke =)

Vorweg zu der Forumsstruktur:
ja ich hab schon gemerkt, dass das hier so strukturiert wird… habe auch schon ein paar andere Threads hier gelesen. Ich persönlich finde diese Struktur aber alles andere als geeignet… Denn sie ist sehr unübersichtlich. So hat man dann bei einem Thread vom Zeitraum vom 5.9 bis 10.9. 10 verschiedene Antworten die direkt an ans Threadthema anschließen. Dann liest man sich das durch und denkt, nun hat man alles gelesen. Aber nein, dann kommen darunter "völlig durcheinander" noch weitere Antworten zu einezelnen Beiträgen. Einer vom 6.9, der andre vom 8.9 und dann plötzlich wieder einer vom 5.9.
Das macht es für den LEser seeehr viel schwieriger den Überblick zu behalten und alle wichtigen Infos aus dem Thread mitzunehmen.  Deswegen möchte ich bewusst nur in einem Strang bleiben, sodass es ein linearer Aufbau ausschließlich nach Datum sortierter Antworten ist.
Einzige frage die ich mir gerade stelle: es wird ja immer mehr nach rechts gerückt… gibt es da ein Limit bis es nicht weiter nach rechts geht, oder kann man iwann einfach nicht mehr antworten? :smiley: Das könnte also in der Tat ein Problem werden… aber ich fänds schade, weil sonst die Zusammenhänge verloren gehen würden.

So. Erstmal zum Script. Ich hab es wie erwähnt nun übernommen und so getestet. Es erscheint dann die Fehlermeldung "Syntax error" in Script10. Das heißt soweit ich weiß, dass z.b irgendein Zeichen fehlt wie z.b ;  oder ein unbekanntes Zeichen verwendet wurde. Ich habe mal vor "// Geld? Basis? Bereits bekommen?" Ein Semikolon gesetzt, weil da keines war, aber das ändert leider nichts an der Fehlermeldung. Was könnte es sonst sein?

Nun zum Bohrturm. beim normalen Bohrturm Skript aus den Objekten findet sich tatsächlich die Funktion:
private func StartDrillHead(object pCaller)
{
  PipeHeadCheck();
  Sound("Click");
  if (!EnergyCheck(1000)) return(0);
  SetComDir(COMD_Down(), pDrillHead);
  ObjectSetAction(pDrillHead, "Drill");
  SetPlrView(pCaller->GetController(), pDrillHead);
  DigFreeRect(GetX(pDrillHead)-1, GetY() + GetObjHeight() / 2, 3, GetY(pDrillHead) - GetY() - GetObjHeight() / 2);
}


Also habe ich die letzte Zeile mit dem DigFreeRect… kopiert und wollte sie in das Script des neuen Bohrturms einfügen. Erstaunlicherweise hat der neue Bohrturm überhaupt keinen Eintrag, der die Wörter "dig" oder "free" enthält. Deswegen weiß ich nicht, wo sein Graben Befehl steckt… Den Befehl einfach irgendwo einzufügen hat natürlich nichts gebracht :D   Dann fiel mir eben auf, dass das Skript des Bohrkopfes entscheidend sein könnte. Und im Skript des alten BohrturmKopfes finden sich tatsächlich Anweisungen, wie sich der Bohrer bei verschiedenen Materialien verhalten soll:

private func Drilling()
{
  // Material prüfen
  var mat = GetMaterial(0,3);
  // Nicht durch SolidMasks bohren
  if (Material("Vehicle") == mat)
  {
    Sound("MetalHit3");
    return(0);
  }
  // Schneller in freien Bereichen
  if ((Material("Tunnel") == mat) || (Material("Sky") == mat))
  {
    SetPhysical("Float", 150, 2);
    return(1);
  }
  // Langsamer in festen Materialien
  if (!GetMaterialVal("DigFree", "Material", mat))
    if (!GetMaterialVal("Instable", "Material", mat))
    {
      var iSpeed = 25;
      // Etwas hardgecodete Erkennung
      if (Material("Granite") == mat)
        iSpeed = 10;
      // Langsamere Geschwindigkeit
      SetPhysical("Float", iSpeed + Random(2 * iSpeed), 2);
      FreeRect(GetX() - 1, GetY(), 3, 4, C4M_Solid);
      return(1);
    }
  // Normale Geschwindigkeit
  SetPhysical("Float", 100, 2);
  return(1);
}


Aber beim neuen Bohrturm findet sich auch beim Bohrkopf kein einziger Befehl mit "dig" oder "free" =/
Hier mal das komplette Script des neuen Bohrkopfes:

/– Bohrkopf –/

/#strict

local derrick;

public func Init(par_derrick)
{
  derrick = par_derrick;
  SetAction("Level");
}

protected func DestructCheck()
{
  if (!FindLine()) RemoveObject();
}

private func TopCheck()
{
  var minY = GetY(derrick) + 20;
  if (GetY() >= minY) return(1);
  SetComDir(COMD_Stop());
  SetYDir(0);
  SetPosition(GetX(), minY);
  Sound("Click");
  return(0);
}

protected func ContactBottom()
{
  SetAction("Level");
  SetComDir(COMD_Stop());
  SetYDir(0);
  Sound("Click");
}

private FindLine: return(FindObject(SPIP,0,0,0,0,0,"Connect",Contents()));


Wo kann ich hier die Anweisung für verschiedene Materialien unterbringen? Habe sie einfach unten dran kopiert, aber das hat nichts geändert =( (der neue Bohrturm ist übrigens aus "Space Launch", nur falls das wen interessiert)

Nun zur Forschungsstation:
Danke für die Vorschläge :slight_smile: Leider sind beide Vorschläge nicht ganz das was ich suche. Wenn ich will, dass garnichts erforscht werden kann, dann sorge ich einfach dafür, dass niemand die Forschungsstation bauen kann :smiley: aber gut, so könnte ich zumindest einzelne Dinge ausschließen, aber das will ich ja auch nicht :wink:
Ich möchte einfach, dass man am Anfang z.b nur die hier schon in den Schriftrollen erwähnten Gebäude erforschen kann. So. Wenn man dann z.b 300Gold erreicht hat, werden diese wie bisher auch abgezogen und man erhält dann die Möglichkeit weitere Gebäude in der Forschungsstation zu erforschen :slight_smile:
Falls es dafür keine vernünftige Lösung gibt, könnte man bestimmt aus Pitirs Vorschlag etwas machen. Man könnte z.b. kleine Burg als Voraussetzung dafür machen, dass Wachturm, Werktstatt, Lore Brücke usw usw. erforscht werden können. Und anstatt dann bei 300 Gold all diese Gebäude freizuschalten, schaltet man dann nur die kleine Burg frei und der Rest kann nun erforscht werden :)    Dazu müsste man aber halt ein einzelnes Gebäude als Voraussetzung für viele Gebäude einstellen können, geht das?

Ach noch ne Frage: in dem Space Empire Paket sind verschiedene Space Pakete drin, also z.b. Hazard, Space Launch und CognitionAlliance. D.h es gibt glaube ich 3 verschiedene neue Fahrstühle, welche aber alle den alten normalen Fahrstuhl ersetzen wollen. Glücklicherweise habe ich aus dem Fallout Pack den Metallfahrstuhl geholt, und offensichtlich versuchen die neuen Fahrstühle nur einen davon zu ersetzen, sodass ich immer einen "alten" Fahrstuhl im Spiel habe. Meine Frage ist nun aber: alle drei neuen Fahrstühle "kämpfen" sozusagen um den Platz im Spiel. Wie entscheidet sich, welcher sich letzlich durchsetzt? Ist es ohne großen Aufwand möglich, dafür zu sorgen, dass alle drei Arten ins Spiel kommen? Oder müsste ich dazu sehr viel umschreiben?  Wenn ich es so wie es jetzt ist lasse, wäre es dann besser, die 2 Fahrstühle, die sich nicht durchsetzen, ganz aus meinem Objektpaket zu löschen?

Ach und wenn ich schonmal hier bin: In dem Space Empire Pack gibt es verschiedene Bunker, auf denen man Geschütze installieren kann. Z.b ein Maschinengewehrgeschütze, ein "Vulcan-geschütz" oder auch Plasmakanonen.  Ich hab gestern erstaunt festgestellt, dass die Plasmakanone feindliche Clonks heilt, anstatt ihnen schaden zuzufügen :smiley: Und sie heilt ziemlich stark. Wenn eine Plasmakanone feuert, heilt sie so stark, dass 5 Maschinengewehre die auf denselben Clonk feuern, ihn nicht töten können ^^  Ihr wisst nicht zufällig, wo man sowas für gewöhnlich umstellen könnte? Bei der Plasmakanone selbst? oder bei den Partikeln? Und wie würde so ein Befehl aussehen?

>Ich persönlich finde diese Struktur aber alles andere als geeignet... Denn sie ist sehr unübersichtlich.


Das ist Gewöhnungssache, denke ich. Ich mag dieses System sogar sehr, weil eine diskussion dann wirklich ihre eigenen Wege gehen kann. Wenn man wissen will, worauf der Post eine Antwort ist, benutzt man den Pfeil oben rechts im Header vom Post.

>Deswegen möchte ich bewusst nur in einem Strang bleiben, sodass es ein linearer Aufbau ausschließlich nach Datum sortierter Antworten ist.


Du willst das System über den Haufen werfen, indem du es ignorierst? Ich glaube, ein paar Leute hier werden davon nicht begeistert sein. o.o
Grundsätzlich finde ich solche ellenlangen Posts, die mehrere Themen zusammenfassen unübersichtlich. Hängt vielleicht damit zusammen, dass ich die Baumstruktur nun sei Jahren gewöhnt bin. Mir ist es lieber, wenn zu den einzelnen Themen wirklich  an der richtigen Stelle sachlich Stellungnahme gemacht wird und nicht alles in einen riesigen Post gequetscht wird. Und ich fühle mich genötigt, zu allen Stichpunkten stellung zu nehmen, was den Post um bestimmt eine halbe Stunde verzögert.

>Einzige frage die ich mir gerade stelle: es wird ja immer mehr nach rechts gerückt... gibt es da ein Limit bis es nicht weiter nach rechts geht, oder kann man iwann einfach nicht mehr antworten? :D


Ein Beantwortungslimit gibt es nicht, aber irgendwann wird nicht weiter eingerückt, da die Textbox sonst zu klein wird. Ich persönlich habe die Einrückung in den Einstellungen auf das minimum von 1% gestellt. Somit sind die Nachrichten so breit wie es geht und werden nur langsam immer schmäler. Das Limit ist bei ungefähr einem Drittel Bildschirmbreite erreicht.

>"Syntax error" in Script10. Das heißt soweit ich weiß, dass z.b irgendein Zeichen fehlt wie z.b ;  oder ein unbekanntes Zeichen verwendet wurde.


Syntax Error bedeutet eigentlich nur, dass der Compiler einen Fehler beim compilen bemerkt hat. Beim compilen spuckt er dann die Fehlermeldungen aus, mit Position im Script. Stolpert die Engine ingame dann nochmal über die Stelle,  wird die Meldung "ERROR: Syntax error: see previous parser for details" ausgegeben, was soviel bedeutet, wie "Guck in der Liste nach, die ich Anfangs ausgegeben habe."
Deshalb die Empfehlung von mir: Lass die Engine das ganze nochmal compilen, pausiere das Spiel und scroll im log nach oben. Dort sind die Positionen der Fehler gespeichert: Objektpfad.c4d\Script.c:17:34

>Aber beim neuen Bohrturm findet sich auch beim Bohrkopf kein einziger Befehl mit "dig" oder "free" =/


Wenn du den Bohrturm meinst, der nur frei_graben_ kann, kann es sein, dass das ganze über die ActMap geregelt ist. Im Script vom Clonk ist nirgendwo ein DigFree() versehen, das wird über die Graben-Aktion durch den Eintrag Procedure=DIG geregelt.

>3 verschiedene neue Fahrstühle, welche aber alle den alten normalen Fahrstuhl ersetzen wollen.


Bist du dir sicher, dass sie ihn ersetzen wollen? Ich sehe das eigentlich nur als Ergänzung an. Sie wurden halt gemacht, damit der zum Pack gehörende Style nachempfunden wird. Ersetzt wird das ganze nur, wenn die C4ID vom Fahrstuhl wirklich verwendet wird. Und Entwickler die bereits belegte C4IDs in ihren Packs verwenden, sind doof. :P

[topic branch moved]

hmm… okay, danke für die Argumente für die baumstruktur. Stimmt schon, dass es vor und nachteile hat… ich bin halt eine normale Forumsstruktur gewohnt :smiley:
Aber selbst wenn ich mich dem nun füge, werde ich es unmöglich übersichtlich halten können. Ich meine ich würde jetzt zum Thema Forumsstruktur einmal an Zapper und einmal an Pitri antworten, und zwar so ziemlich denselben Text. Das ist doch unnötig…  usw usw, siehe Post an Zapper :wink:

So jetzt zu den eigentlichen Fragen:

Zum Skript für die Baupläne, der Fehler lautet:
ERROR: unknown identifier: CheckAllPlayerWealth (in Script10, selbsterstellte.c4f\test.c4s\Script.c:12:22)
heißt das nun, dass in Zeile 12 und 22 ein Fehler ist? das kan eig nicht sein, denn Zeile 12 und 22 sind:
goto(1); // und wieder zu 1, damit bei 10 wieder geprueft wird.
und
SetWealth(iPlr, 0);


Zum Bohrturm:

Beim neuen Bohrtrum im Bohrkopfteil steht in der ActMap:
[Action]
Name=Level
Procedure=FLOAT
Length=1
Delay=5
FacetBase=1
NextAction=Level
StartCall=TopCheck

[Action]
Name=Drilling
Procedure=FLOAT
Length=1
Delay=10
FacetBase=1
NextAction=Drilling
DigFree=1
Sound=Drill


Fertig editiert:
Okay, also hier haben wir tatsächlich in der ActMap den Befehl DigFree=1. Ich habe das jetzt mal umgeändert in FreeRect=1. Aber es kommt dann folgende Fehlermeldung:
ERROR: declaration expected, but found identifier 'if' (C:\Programme\Clonk Rage\Sammlung.c4d\Space Empire.c4d\SpaceLaunch.c4d\Structures.c4d\Derrick.c4d\Script.c:124:7)
WARNING: Unexpected value "FreeRect"! (in section "Action", after line 9, C:\Programme\Clonk Rage\Sammlung.c4d\Space Empire.c4d\SpaceLaunch.c4d\Structures.c4d\Derrick.c4d\PipeHead.c4d\ActMap.txt)

Was sagt mir die Fehlermeldung jetzt?

Zu den Fahrstühlen:
Es ist jedenfalls so, dass nur einer der 3 Fahrstühle bei den Spieleinstellungen eingestellt werden kann und außerdem der alte Fahrstuhl nicht verfügbar ist. Deswegen gehe ich mal davon aus, dass sie ihn überschreiben… sie haben aber andere Namen (wobei die 3 neuen Fahrstühle alle "Liftdock" im DefCore stehen haben) und andere IDs, also keine Ahnung, wie das zusammenspielt =/

>ERROR: unknown identifier: CheckAllPlayerWealth (in Script10, selbsterstellte.c4f\test.c4s\Script.c:12:22)
>heißt das nun, dass in Zeile 12 und 22 ein Fehler ist? das kan eig nicht sein, denn Zeile 12 und 22 sind


Das bedeutet, dass in deinem Script in Zeile 12, Zeichen 22 der Zeile die Funktion CheckAllPlayerWealth() aufgerufen wird. Der Script kennt die funktion aber aus bestimmten Gründen nicht. Entweder ist das falsch geschrieben, oder du hast die Funktion in einem anderen Script deklariert, aber nicht global verfügbar gemacht. Ich bräuchte dazu etwas mehr Information als bisher gegeben. Wo ist CheckAllPlayerWealth() definiert und ist es überhaupt richtig geschrieben oder ein Tippfehler?
Die beiden angegebenen Zahlen sind wirklich die Koordinaten zum Problem: Zeile und Spalte. Unknown identifer bedeutet immer, dass du etwas verwendest, was die Engine nicht kennt. Sei es Funktionsnamen oder Variablennamen die nicht deklariert sind.

>Okay, also hier haben wir tatsächlich in der ActMap den Befehl DigFree=1. Ich habe das jetzt mal umgeändert in FreeRect=1.


Dass das nicht geht, war abzusehen. In ActMap und DefCore sind nur gewisse Einträge zugelassen, die sind in der engine definiert. Man kann nicht jeden beliebigen Funktionsnamen eintragen. Das ist ein wenig blöd, da das hardgecodet ist. Soweit ich weiß, haben die Bohrtürme in früheren Clonk-Versionen so funktioniert, dass sie nicht durch gestein bohren konnten. Das hat sehr wahrscheinlich die ActMap-Variante verwendet. Und die wurde wahrscheinlich in Star Empires übernommen. Wenn du willst, dass man damit auch durch Gestein graben will, müsstest du den script vom Bohrturm im Originalpack übernehmen.

>Es ist jedenfalls so, dass nur einer der 3 Fahrstühle bei den Spieleinstellungen eingestellt werden
>und andere IDs


Okay, wenn sie verschiedene IDs haben, verstehe ich nicht, warum man sie nicht parallel verwenden kann.

Zum Script:
Zeile 12, Zeichen 22 ergibt aber irgendwie keinen Sinn… in Zeile 12 ist doch nur der goto Befehl, Zeichen 22 ist sogar hinter den // , also stimmt das nicht… Daher schließe ich, dass gewisse Zeilen nicht als Zeilen gewertet werden? Werden leere Zeilen berücksichtigt, werden Zeilen mit "{" als Zeile gewertet? Und ab wo wird gezählt? Oder wie läuft das?
Zu deiner Frage wo "CheckAllPlayerWealth() " definiert ist, habe ich keine richtige Antwort… ich habe lediglich das Gecko von geschriebene Script kopiert und eingefügt (und den hinweis von Clonkgeist zur Raute und iPLr berücksichtigt).  Mehr habe ich nicht gemacht. Das heißt, wenn dort der Befehl CheckAllPlayerWealth()  nicht definiert ist, habe ich das auch nirgendwo anders gemacht, weshalb er wohl nirgends definiert ist?
Zum Thema Engine, ich hab Version 4.9.10.4 ich dachte das wäre die neuste Version, war aber noch kostenpflichtig. Habe mir letztens mit meinem Laptop die Freeware Version runtergeladen und habe beim Netzwerkspiel festgestellt, dass es eine Fehlermeldung gibt, dass die Engine nicht identisch wäre, weshalb ich nicht teilnehmen könne (in eine richtugn gings nicht, in die andere richtug gings schon). Das ist jetzt nur meine spontane Idee, falls der befehl CheckAllPlayerWealth() erst seit der Freeware existiert ^^ Falls das nichts damit zu tun hat, dann ist das egal und braucht nicht weiter nachgeforscht zu werden :wink:

Zum Bohrturm:
einfach die beiden Skripte der Bohrtürme zu tauschen kam mir auch in den Sinn… allerdings gibt es da ja sicher Werte, die ich nicht tauschen darf, oder? Ich meine z.b das Aussehen der Türme, oder den EMP Effekt, oder die Energiekosten oder die Baumaterialkosten… Das würde doch alles über den Haufen geworfen und nicht mehr funktionieren, wenn ich einfach die skripte tausche, oder?
edit: ansonsten würde es auch reichen, wenn ich einfach nur das Aussehen des Turmes tauschen könnte. Wie man die Baukosten ändert, weiß ich. Es ist nur noch das Aussehen, was sozusagen stört, weil ein altes Gebäude besser ist, als ein Zukunftsgebäude.

Zu den Fahrstühlen:
naja gut… war auch mehr eine Interessenfrage. Mir reicht 1 Zukunftsfahrstuhl aus, also brauch man hier auch nicht weiter nachforschen.

Ich hoffe das ist jetzt in Ordnung, wenn ich hier in einem Strang das Thema Forschungsstation weiterführe.^^

Ich habe zufällig festgestellt, dass bei erstellbaren Objekten im Script eine Anweisung gibt, wann sie erforschbar sind. Als Beispiel mal die Haubitze:
public func GetResearchBase() { return(CATA); }
(sehe gerade, das ist das was Pitri genannt hatte :D)
Das heißt man muss erst den Katapult erforscht haben, dann kann man die Haubitze erforschen :slight_smile:
Wie könnte ich dies nun erweitern? Kann ich in die Klammer in der zurzeit CATA steht noch einfach beliebig viele weitere IDs einfügen, die Voraussetzung sein sollen? Oder wie würde ich das machen, wenn ich nun mehr als diese eine Voraussetzung haben wollen würde?

Für mein Beispiel würde ich dort nun also noch die ID der kleinen Burg eintragen. Dasselbe müsste ich dann bei jedem einzelnen Objekt machen. Natürlich dann auch noch mit anderen "Auslösern" als nur der kleinen Burg.  So würde es dann reichen, bei einer bestimmten Menge Gold, einfach den Bauplan für das "auslösergebäude" auszuhändigen. Der Rest könnte dann bis zu einem gewissen Level erforscht werden, bis das nächste "auslösergebäude" das ganze stoppt und es erst weitergeht, wenn dieses durch Gold erreicht wurde.
Es wäre natürlich recht viel Arbeit bei jedem einzelnen Objekt nun sowas hinzuzufügen… geht das irgendwie anders/leichter?

>Zeile 12, Zeichen 22 ergibt aber irgendwie keinen Sinn.. in Zeile 12 ist doch nur der goto Befehl, Zeichen 22 ist sogar hinter den // , also stimmt das nicht... Daher schließe ich, dass gewisse Zeilen nicht als Zeilen gewertet werden? Werden leere Zeilen berücksichtigt, werden Zeilen mit "{" als Zeile gewertet? Und ab wo wird gezählt? Oder wie läuft das?


Leere Zeilen zählen auch. Am besten ist es, wenn du dir einen Editor zulegst, der die Zeilen mitzählt. Ich selbst benutze C4scripter, aber Notepad++ soll auch gut funktionieren. Die Koordinaten sind immer so eine Sache. Die stimmen meißt nicht genau. Beispielsweise bei einem Semikolon-fehler: Die Engine parst den Script und merkt erst in der nächsten Zeile, dass zwischen dem letzten und dem aktuellen Befehl kein Semikolon vorkomt. Woraus resultiert, dass die Engine in der Situation die Zeile des darauffolgenden Befehls ausgibt und nicht die Zeile, in der das Semikolon vergessen wurde. Die Koordinaten sind trotzdem ein guter Ansatz, bei dem man in der Nähe schauen sollte. In der Regel passiert der Fehler bei oder vor den Koordinaten. Schau einfach mal da in der Gegend.

>Zum Thema Engine, ich hab Version 4.9.10.4 ich dachte das wäre die neuste Version, war aber noch kostenpflichtig. Habe mir letztens mit meinem Laptop die Freeware Version runtergeladen und habe beim Netzwerkspiel festgestellt, dass es eine Fehlermeldung gibt, dass die Engine nicht identisch wäre


Die aktuelle ist 4.9.10.7 oder kurz [330]. Guck am besten nochmal auf clonk.de nach der Version.

>wenn dort der Befehl CheckAllPlayerWealth()  nicht definiert ist [...]


Nein, CheckAllPlayerWealth() ist keine Engine-Funktion. Die muss selbst definiert werden. Jetzt fällt mir auch auf, woher der Fehler kommt:

>ich habe lediglich das Gecko von geschriebene Script kopiert und eingefügt


Gecko hat beim Aufruf CheckAllPlayerWealth() benutzt, obwohl die Funktion CheckAllPlayerWealths() heißt. Du musst einen der beiden Namen anpassen.