Not logged inClonkspot Forum
Forum Home Help Search Register Login
Up Topic Deutsch / Hilfestellung / [Gelöst] x% Material abgebaut
- - By Serpens66 (More than 200 posts.) Date 24.09.2014 16:32
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(c)
{
  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 */*

private MatObjsCount:  return(ObjectCount(GOLD));
private MatPixelCount: return(GetMaterialCount(Material("Gold")));
private MatName:       return("Gold");



Dazu noch das includete GOAL, welches "Timer=250  TimerCall=CheckTime" im DefCore hat:

/*-- Spielzielsteuerung --*/

`#strict`

local unfinished;   // Anzahl der Spielziele, die NICHT erfüllt werden müssen

/* Initialisierung */

protected func Initialize()
{
  // ist das hier GOAL selber? (also nicht #included)
  if (GetID() == GOAL)
  {
    // dringend benötigte Objekte erstellen
    CreateObject(SFXM,0,0,-1);   // Effektmanager
    CreateObject(STWL,0,0,-1);   // Warenliste für Handelssystem
    // Warteaktion
    return(SetAction("Init"));
  }
  // GOAL-Objekt mit Timer erstellen
  if (!FindObject(GOAL))
    CreateObject(GOAL,0,0,-1);
}

protected func PostInit()   // Nachinitialisierung für GOAL
{
  // alle Spielziele müssen erfüllt werden
  unfinished = 0;
  // ein CheckFulfilled-Broadcast an alle
  var goal;
  while (goal = FindObject(0, 0,0,0,0, 0, 0,0, 0, goal))
    if (GetCategory(goal) & C4D_Goal())
      goal->~IsFulfilled();
}

/* Timer */

private func EnoughGoals(player)
{
  // Alle Spielziele für einen Spieler überprüfen
  var goal, count, restgoals;
  while (goal = FindObject(0, 0,0,0,0, 0,0,0,0, goal))
   ` 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 :/
  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
Parent - - By Alx (More than 15 posts.) Date 27.09.2014 08:41
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.
Parent - - By Pitri (More than 200 posts.) Date 27.09.2014 16:42
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\*
Parent - By Alx (More than 15 posts.) Date 27.09.2014 17:37
Das bool stammt nicht von mir! Das war schon so! Mir wurde sowas nie passieren!
Parent - - By Serpens66 (More than 200 posts.) Date 29.09.2014 19:19 Edited 29.09.2014 20:13
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.
Parent - By Serpens66 (More than 200 posts.) Date 21.10.2014 16:19
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 :) (z.b monsterangrif,, Katastrophen, alieninvasion usw)
Up Topic Deutsch / Hilfestellung / [Gelöst] x% Material abgebaut

Powered by mwForum 2.29.7 © 1999-2015 Markus Wichitill