[Gelöst] x% Material abgebaut

Im Star Empire gibt es ein Ziel, dass eine bestimmte Menge Gold abgebaut werden muss, um das Spiel zu gewinnen. Je häufiger die Regel aktiviert, desto weniger.
Nun möchte ich das als Bedingung für das hinzufügen von weiteren Regeln nutzen. Zum Beispiel "sobald 10% Gold abgebaut wurden, wird die Monsterangriffsregel einmalig aktiviert -> es greifen Monster an"   Oder auch ohne weitere Regel, sondern nur "sobald x% abgebaut ist, werden xy gespawnt".

Leider werde ich aus dem Skript nicht ganz schlau, wie ich es verwenden könnte, um mein Ziel zu erreichen. Könnt ihr vllt mal kurz drüberschauen, und mir das so zusammenbasteln, dass ich es als Voraussetzung für oben genannte Beispiele nutzen kann?

Das Skript sieht wie folgt aus:

/– Goldmine –/

#strict
#include GOAL

local count, pixels, objs;

protected func Initialize()
{
  // anderes Objekt vorhanden?
  var obj = FindObject(GetID());
  if (obj)
  {
    // sich selber dazuzählen
    obj->IncCount();
    return(RemoveObject());
  }
  count = 1;
  return(inherited());
}

public func IncCount()
{
  ++count;
}

public func Percentage©
{
  if (count==1) return(0);        // alles abzubauen -> kein Rest
  if (count==2) return(c/10);     // 90% abzubauen
  if (count==3) return(c/4);      // 75% abzubauen
  if (count==4) return(c/2);      // 50% abzubauen
  if (count==5) return(c*3/4);    // 25% abzubauen
                return(c*9/10);   // 10% abzubauen
}

public func IsFulfilled()
{
  // noch gar nicht gezählt?
  var pix = MatPixelCount();
  if (pix == -1) return(0);
  // speichern, wieviel jeweils übrig bleiben darf
  if (!pixels)
  {
    // Materialpixel
    pixels = Percentage(pix) + 150;
    // Materialstücke
    objs = Percentage(MatObjsCount());
  }
  // noch zu viel?
  if (pix > pixels)          return(0);
  if (MatObjsCount() > objs) return(0);
  return(1);
}

protected func Activate(player)
{
  if (IsFulfilled())
   return(MessageWindow(Format("Genügend %s abgebaut.",MatName()), player));
  // noch nicht erfüllt
  var restobjs = Max(MatObjsCount()-objs, 0);
  if (restobjs == 1)
    MessageWindow(Format("Es sind noch %d Materialpixel|und ein Stück %s abzubauen.",
                         Max(MatPixelCount()-pixels,0), MatName()), player);
  else
    MessageWindow(Format("Es sind noch %d Materialpixel|und %d Stücke %s abzubauen.",
                         Max(MatPixelCount()-pixels,0), restobjs, MatName()), player);
}

/* Funktionen zum Überladen */* <br/><br/>private MatObjsCount:&#160; return(ObjectCount(GOLD));<br/>private MatPixelCount: return(GetMaterialCount(Material(&quot;Gold&quot;)));<br/>private MatName:&#160; &#160; &#160;&#160; return(&quot;Gold&quot;);<br/><br/></i><br/><br/><b>Dazu noch das includete GOAL, welches &quot;Timer=250&#160; TimerCall=CheckTime&quot; im DefCore hat:</b><br/><br/><i>/*-- Spielzielsteuerung --*/<br/><br/>#strict<br/><br/>local unfinished;&#160;&#160; // Anzahl der Spielziele, die NICHT erfüllt werden müssen<br/><br/>/* Initialisierung */<br/><br/>protected func Initialize()<br/>{<br/>&#160; // ist das hier GOAL selber? (also nicht #included)<br/>&#160; if (GetID() == GOAL)<br/>&#160; {<br/>&#160; &#160; // dringend benötigte Objekte erstellen<br/>&#160; &#160; CreateObject(SFXM,0,0,-1);&#160;&#160; // Effektmanager<br/>&#160; &#160; CreateObject(STWL,0,0,-1);&#160;&#160; // Warenliste für Handelssystem<br/>&#160; &#160; // Warteaktion<br/>&#160; &#160; return(SetAction(&quot;Init&quot;));<br/>&#160; }<br/>&#160; // GOAL-Objekt mit Timer erstellen<br/>&#160; if (!FindObject(GOAL))<br/>&#160; &#160; CreateObject(GOAL,0,0,-1);<br/>}<br/><br/>protected func PostInit()&#160;&#160; // Nachinitialisierung für GOAL<br/>{<br/>&#160; // alle Spielziele müssen erfüllt werden<br/>&#160; unfinished = 0;<br/>&#160; // ein CheckFulfilled-Broadcast an alle<br/>&#160; var goal;<br/>&#160; while (goal = FindObject(0, 0,0,0,0, 0, 0,0, 0, goal))<br/>&#160; &#160; if (GetCategory(goal) &amp; C4D_Goal())<br/>&#160; &#160; &#160; goal-&gt;~IsFulfilled();<br/>}<br/><br/>/* Timer */<br/><br/>private func EnoughGoals(player)<br/>{<br/>&#160; // Alle Spielziele für einen Spieler überprüfen<br/>&#160; var goal, count, restgoals;<br/>&#160; while (goal = FindObject(0, 0,0,0,0, 0,0,0,0, goal))<br/>&#160;&#160; if (GetCategory(goal) & C4D_Goal())`
      {
        ++count;
        if (!(goal->~IsFulfilled(player)))
          ++restgoals;
      }
  // Mindestanzahl der Spielziele erfüllt?
  return((restgoals <= unfinished) && count);
}

protected func CheckTime()
{
  // alle Spieler überprüfen
  var i, bool;
  var j = GetPlayerCount();
  for (i; i < j; ++i)
    if (EnoughGoals(GetPlayerByIndex(i)))
    {
      // da hat einer genug Spielziele erfüllt
      bool = 1;
      break;
    }
  if (!bool) return(1);
  // Ziel erfüllt: Vom Szenario abgefangen?
  if (GameCall("OnGoalsFulfilled"))
    return(RemoveObject());
  // alle "Verlierer" rausschmeissen
  for (i; i < j; ++i)
    if (!EnoughGoals(GetPlayerByIndex(i)))
      EliminatePlayer(GetPlayerByIndex(i));   // tja, leider verloren
  // die restlichen haben gewonnen!
  Sound("Trumpet",1);
  // jetzt ein wenig warten, und dann GameOver
  SetAction("Wait4End");
}

protected func RoundOver()
{
  // Das wars :confused:
  GameOver();
  return(RemoveObject());
}

/* Object-Call /

public func SetGoal_Unfinished(unf)
{
  unfinished = unf;
}

/
überladbare Defaultfunktionen */

public func IsFulfilled()
{
  return(1);
}

protected func Activate(player)   // Defaultnachrichten
{
  if (IsFulfilled())
    return(MessageWindow("Spielziel erfüllt!", player));
  return(MessageWindow(GetDesc(), player));
}



Wie gesagt ist das ganze auch zu finden im Star Empire Pack unter General/Goals

Du könntest probieren in CheckTime zu überprüfen, ob die Goldregel erfüllt wurde, und dann die Monsterregel erstellen.
Allerdings bin ich mir nicht ganz sicher ob das funktioniert, ist eine Idee, die auch falsch sein könnte.

protected func CheckTime()
{
  // alle Spieler überprüfen
  var i, bool;
  var j = GetPlayerCount();
  for (i; i < j; ++i)
    if (EnoughGoals(GetPlayerByIndex(i)))
    {
      // da hat einer genug Spielziele erfüllt
      bool = 1;
      break;
    }
  if (!bool) return(1);
  // Ziel erfüllt: Vom Szenario abgefangen?
  if (GameCall("OnGoalsFulfilled"))
    return(RemoveObject());
  CreateObject(ID, 0, 0, -1);
}


Das könntest du in einem appendto auf GOAL erreichen, wenn ich das richtig verstanden hab.

Denk aber daran, dass bool das Schlüsselwort eines Datentyps ist. Die Variable sollte also irgendwie anders benannt werden.
*nörgel nörgel nörgel*

Das bool stammt nicht von mir! Das war schon so! Mir wurde sowas nie passieren!

okay…

also meinst du, sollte es klappen, wenn ich eine Regel erstelle, welche im DefCore den TimerCheck enthält und im Script eig alles exakt genauso steht, wie im Goldmine Script , nur das zusätzlich noch deine Checktime Funktion reingeschrieben wird, welche dann die eigentliche CheckTime von GOAL überläd, richtig?

Ich teste das mal eben so und editiere dann hier… aber es kommt mir noch zu einfach, bzw. zu wenig geändert vor ^^

ach und zu "bool"  ich habe es jetzt in "boool" umbenannt.  Aber warum haben es die Star Empire entwickler denn bool genannt? Die werden sich ja schon iwas dabei gedacht haben, oder nicht?

edit:
soweit das testergebnis: bei achtmaliger aktivierung der Regel musste ich irgendwie trzd. alles Godl abbauen (teste ich gleich nochmal mit 5mal). Danach stand im Log, dass es gespeichert und ausgewertet, aber nicht beendet wird. Und schließlich wurden auch meine Monster gespawnt. Allerdings schien es so, als würde die Regel Monsterangriff nun alle 250 Frames (die Timerzahl) gespawnt werden, wodurch es letzlich unendlich viele Monster werden.  Besser ists da natürlich, wenn man das noch besser löst… entweder eine if Formulierung, die dafür sorgt, dass die Angriffsregel maximal x mal hierdurch aufgerufen werden kann, oder einfach ein Beenden des Timers.

Auch dieses Problem ist gelöst.

Als ich das Problem gepostet habe, hatte ich noch nicht das nötige Wissen, um die Funktionsweise zu verstehen (z.b dass Funktionen in den Klammern Werte weitergeben können). Mittlerweile verstehe ich es aber ganz gut und konnte mir mein eigenes komplexes Skript basteln, bei der nun bei jedem weiteren 5% abgebautem Material ein Ereignis abhängig vom technischen Fortschritt ausgelöst wird :slight_smile: (z.b monsterangrif, Katastrophen, alieninvasion usw)