Not logged inClonkspot Forum
Forum Home Help Search Register Login
Up Topic Deutsch / Hilfestellung / [Gelöst] "AddLight" abändern, weil sonst Gebäude
1 2 Previous Next  
Parent - - By Serpens66 (More than 200 posts.) Date 16.09.2014 16:01
okay, danke :)  jetzt weiß ich endlich auch, warum da mal #strict und mal #strict 2 steht =)   Wenn ich dann "==" verwende, muss ich immer darauf achten, dass es sich um strict 2 handelt und gegebenenfalls die 2 hinzufügen, richtig?
Parent - - By Luchs (More than 1000 posts.) Date 16.09.2014 18:03
Ich glaube, `==` müsste immer funktionieren. Es ist aber nie eine schlechte Idee, die 2 hinzuzufügen. Du musst dann aber auch noch beachten, dass Konstanten wie für die Kategorien (also z.B. `C4D_StaticBack`) und `this` keine Klammern hintendran haben dürfen.
Parent - By Serpens66 (More than 200 posts.) Date 16.09.2014 18:46
hm.. so ein mist. Dann muss ich ja echt aufpassen, was ich schreibe, je nach dem, ob strict oder strict 2?
habe in unserem Beispiel kurz strict 2 draus gemacht und promt gab es sehr sehr viele syntax fehler... also lasse ich es strict.
- - By Serpens66 (More than 200 posts.) Date 18.09.2014 23:44
Wie passe ich folgendes an, damit es in den neuen Findobject2 Befehl reinpasst?
if (!FindObject(DSTR,0,0,0,0,0,"Destruct",obj))

es soll hierein:

FindObject2(Find_Distance(90), , Find_Or(Find_Func("GetDefCoreVal", "Construction", "DefCore"), !FindObject(DSTR,0,0,0,0,0,"Destruct",obj)))

Also so ist es natürlich falsch, wie füge ich es richtig ein. Diese Bedingung darf im gegensatz zu construction nicht erfüllt sein.

Und ich merke gerade, dass ich in meinem fertigen Skript nur "FindObjects(...) verwendet habe, also die 2 vergessen habe. Es funktioniert aber soweit, was ist der Unterschied?
Parent - - By alex (More than 200 posts.) Date 19.09.2014 00:44
Wenn ich es richtig verstanden habe, dann:
FindObject2(Find_Distance(90), Find_Func("GetDefCoreVal", "Construction", "DefCore"), Find_Not(FindObject(DSTR,0,0,0,0,0,"Destruct",obj)))

Falls das nicht funktioniert, dann vielleicht das hier:
FindObject2(Find_Distance(90), Find_Func("GetDefCoreVal", "Construction", "DefCore"), Find_Not(Find_And(Find_ID(DSTR), Find_Action("Destruct"), Find_ActionTarget(obj))))

-------------------

FindObject2 gibt nur das erste Object zurück, dass alle Kriterien erfüllt.
FindObjects gibt alle Objekte zurück, die die Bedingungen erfüllen. (in einem Array)
Parent - - By Serpens66 (More than 200 posts.) Date 19.09.2014 13:38
danke, vermutlich ist das obere richtig, aber ich kam nicht wirklich weit genug, um das beurteilen zu können. 
Wir haben hier in dem Thread ja dafür gesorgt, dass auch Fundamente repariert werden können. Dasselbe wollte ich nun auch für das abreißen machen. Das Problem bei dem jetzigen Skript ist halt, dass das Suchfenster offensichtlich auf alles hinter dem Clonk beschränkt ist. Da sich das Fundament aber unter dem Clonk befindet, kann es nicht erfasst werden. Das skript sieht folgendermaßen aus:

/* Gebäude-Abriss */

public func ContextDestruction()
{
  [Abreißen|Image=SYF1|Condition=BackAnything]
  var obj = BackAnything();
  if (!obj) return(1);
  CreateMenu(SYF1);
  AddMenuItem("%s abreißen","DoDestruction",GetID(obj),0,0,obj);
  AddMenuItem("Zurück","NoDestruction",SYCC);
}

private func BackBuilding()
{
  var obj;
  while (obj = FindObjectOwner(0,GetOwner(), -1,+9,0,0, GetDefCoreVal("Construction", "DefCore",GetID(obj)), 0,0,obj))
//    if (GetCategory(obj) & C4D_Structure())
//      if (GetCon(obj) >= 100)
        if (GetDefCoreVal("Construction", "DefCore",GetID(obj)) != 0)
        if (!FindObject(DSTR,0,0,0,0,0,"Destruct",obj))
          return(obj);
  return(0);
}

private func BackConstruct()
{
  var obj;
  while (obj = FindObjectOwner(0,GetOwner(), -20,+8,40,5, OCF_Construct(), 0,0,obj))
//   if (GetCategory(obj) & C4D_Structure())
      if (!FindObject(DSTR,0,0,0,0,0,"Destruct",obj))
        return(obj);
  obj = 0;
  while (obj = FindObjectOwner(0,GetOwner(), -1,+9,0,0, OCF_Construct(), 0,0,obj))
//    if (GetCategory(obj) & C4D_Structure())
      if (!FindObject(DSTR,0,0,0,0,0,"Destruct",obj))
        return(obj);
  return(0);
}

private func BackAnything()
{
  var obj = BackBuilding();
  if (obj) return(obj);
  return(BackConstruct());
}

private func DoDestruction(par0, target)
{
  CreateObject(DSTR)->DoDestruction(target);
}

private func NoDestruction() {}


Wenn ich "FindObject(..." verwende, dann gibt es wie schon von alex geschrieben ein array aus. Allerdings wird ein Objekt erwartet. Deswegen wollte ich "Findobject2(..." draus machen, das geht aber nur, wenn das skript in strict2 geschrieben ist, was nicht der Fall ist und viele Fehler verursacht, wenn ich es einfach zu strict 2 mache.
Also fallen mir nun 3 Optionen ein:
1. Ich ändere das alles so, dass es auch mit einem array umgehen kann und muss dafür vermutlich alles neu machen.
2. ich lagere dieses Abriss Skript aus, sodass ich strict2 daraus machen kann, ohne allen vorhergien zu Schaden.
3. Ich lasse es so wie es ist und ändere nur den Suchradius, sodass auch Fundamente erfasst werden können.

Mir persönlich wäre die dritte Variante am liebsten, weil sie am unkompliziertesten ist und am schnellsten geht und ich eure Zeit nicht weiter mit diesem kleinen Thema rauben muss und wir zu "wichtigeren" Dingen kommen könne.
Wie ändere ich in dem vorhandenen Script also, dass nicht nur hinter, sondern auch etwas über/unter/neben dem Clonk gesucht wird?
Parent - - By Serpens66 (More than 200 posts.) Date 29.09.2014 18:49 Edited 29.09.2014 18:53
Push

nochmal kürzer formuliert: ich habe den Befehl:
FindObjectOwner(0,GetOwner(), -1,+9,0,0, GetDefCoreVal("Construction", "DefCore",GetID(obj)), 0,0,obj)

Der Befehl ist ja hier erklärt:
http://www.clonk.de/docs/de/sdk/script/fn/FindObjectOwner.html

Aber ich komme trotzdem nicht weiter, weil ich die Logik hinter den Zahlen nicht verstehe. Die fettgedruckten Zahlen sind die, die evtl wichtig sind. Ich möchte ganz einfach nur den Suchradius erweitern, sodass durch den Befehl auch Gebäude gefunden werden, welche sich ein paar Schritte entfernt befinden. Aktuell ists so, dass man direkt vor dem Gebäude stehen muss, was aber bei Fundamenten nicht möglich ist.

Dass man Fundamente abreißen kann, wenn man direkt davor steht, weiß ich, weil ich noch ein baubares Fundament habe, welches nicht in den boden eingerückt wird und die Clonks  nach dem Bauen einklemmt. Dieses kann ich wieder abreißen, da ich sozusagen in dem Objekt drin stehe.
Parent - By Serpens66 (More than 200 posts.) Date 30.09.2014 11:50
ich würde mich auch über eine Erklärung der fettgedruckten Zahlen freuen, oder über ein
"geht nicht, egal welche Zahlen du dort eintippst, es geht maximal so weit, wie man vor dem Objekt steht".

Es ist nämlich schon recht wichtig, dass ich einzeln gebaute Fundamente auch abreißen kann. Z.b wenn ich alles mit Fundamenten zukleistere, aber dann doch einen Fahrstuhl bauen will.  Falls es mit den fettgedruckten Zahlen nicht geht, muss ich es halt anders lösen. Aber mit den Zahlen wäre es am unkompliziertesten.
Parent - - By Luchs (More than 1000 posts.) Date 30.09.2014 14:16
Es macht keinen Sinn, da GetDefCoreVal reinzupacken. Du solltest auch diesen Suchaufruf lieber nach FindObjects() umwandeln.
Parent - - By Serpens66 (More than 200 posts.) Date 30.09.2014 15:27 Edited 30.09.2014 15:32
Danke dir für deine Antwort :)

Das "GetDefCoreVal" ist da bei meinen unzähligen Versuchen, dafür zu sorgen, dass das Licht nicht abreißbar ist hineingeraten. Zusätzlich steht das aber auch nochmal in einer if Bedingung, weshalb es dann letzlich so klappte wie ich es wollte und nicht daran dachte, dass "GetDefCoreVal" an der hier genannten Stelle wohl nicht funktioniert.
Habe die Stelle jetzt mal freigelassen, also steht da nun:
  while (obj = FindObjectOwner(0,GetOwner(), -1,+9,0,0, , 0,0,obj))

das vollständige Abriss Script (zumindest das appendto für den Clonk) habe ich ja hier gepostet:
https://clonkspot.org/forum/topic_show.pl?tid=298;pg=2#pid5480

Ich hab mich schon mehrmals daran versucht, daraus was neues zu machen. Erst mit findobject2, aber das hat irgendwie nicht funktioniert, weiß garnicht mehr, was das Problem war. Mit FindObjects() wäre es natürlich am besten gelöst, weil ich dann eine Liste anstelle eines einzelnen Objekts bekomme.
Das dumme ist nur, dass ich dafür das komplette Abriss Skript neu schreiben muss... und ich verändere lieber, als komplett neu zu schreiben, weil man so weniger Fehler macht.

Ich kann mich nachher nochmal dransetzen und versuchen es umzuschreiben. Dann poste ich hier mein Ergebnis und wenns nicht funktioniert, frag ich nach den Fehlern ^^

Edit:
ach kannst du mir noch erklären, warum "GetDefCoreVal" nicht in FindObjectowner funtkioniert? Woher weiß ich denn, wann ich "GetDefCoreVal" nutzen kann und wann ich diese OCF Dinger verwenden muss? Oder kann man beides verwenden nur andere Schreibweise? Woher weiß ich die Schreibweise?
Parent - - By Luchs (More than 1000 posts.) Date 30.09.2014 18:30
OCF kannst du nur für exakt die Dinge verwenden, die in der Liste auftauchen. Mit `FindObjects`/`FindObject2` kannst du für andere Kriterien (wie etwa `GetDerCoreVal`) `Find_Func` verwenden, ansonsten musst du manuell mit einem `if` filtern.

In deinem Fall wäre das entsprechend so: `FindObjects(Find_Owner(GetOwner()), Find_AtPoint(-1, 9))`
Parent - - By Serpens66 (More than 200 posts.) Date 30.09.2014 18:51 Edited 30.09.2014 18:54
okay danke.
Mit

> Woher weiß ich denn, wann ich "GetDefCoreVal" nutzen kann und wann ich diese OCF Dinger verwenden muss?


meinte ich eher, woher ich weiß, dass ich bei FindObjectOwner kein "GetDefCoreVal" nutzen kann ,dafür aber bei FindObject2. Und ob ich die OCF Dinger auch in FindObjects2 verwenden kann, und ob diese dann trzd noch so aussehen "GetOCF(objekt) & OCF_Living", oder ob ich da auch ein Find_.... davorsetzen muss.

Dennoch wären wir dann wieder bei dem Problem mit den Zahlen -1 und 9 ^^  (wobei man auch Find_Distance verwenden kann, aber besser ich weiß auch wie das andre funktioniert)
Kannst du mir da sagen, wie genau sich das auswirkt? Ich sehe gerade beim Befehl Find_AtPoint sind die Zahlen besser beschrieben =)
Suchkriterium: sucht alle Objekte, deren Grafikbereich (Shape) den angegebenen Punkt überlappt.
Okay, das würde erklären, warum es nicht besser wird, wenn ich die Zahlen sehr weit auseinander, sehr hoch, oder sehr niedrig setze.
Aber das würde doch auch heißen, dass wenn ich dort 0 und 0 hinschreibe, dass dann nur in der Objektmitte gesucht wird, wodurch jedes Objekt gefunden wird...
Habe das mal gemacht, aber dann wird an jedem Ort jedes Objekt gefunden...  Nur verstehe ich dann nicht, wie -1 und 9 dafür sorgen, dass ein Objekt nur gefunden werden kann ,wenn man direkt davorsteht...
Parent - - By Luchs (More than 1000 posts.) Date 30.09.2014 20:15

>woher ich weiß, dass ich bei FindObjectOwner kein "GetDefCoreVal" nutzen kann


Weil nichts dazu in der Dokumentation steht. Die alte `FindObject`-Funktion kann nur nach genau den Kriterien suchen, die als Parameter in der Dokumentation stehen.

>dafür aber bei FindObject2


Mit FindObject2 kannst du deine Kriterien beliebig zusammenstellen, wobei eben Find_Func das mächtigste Kriterium ist, da es beliebig erweiterbar ist durch eigene Funktionen.

>und ob diese dann trzd noch so aussehen "GetOCF(objekt) & OCFLiving", oder ob ich da auch ein Find.... davorsetzen muss


Da hilft ein Blick in die [Dokumentation](http://www.clonk.de/docs/de/search.php?func=Find_): Wenn dein Kriterium dort dabei ist, dann verwendest du das (also für den OCF-Fall eben `Find_OCF(OCF_Living)`), ansonsten musst du dir etwas mit Find_Func zusammenbasteln. Direkt verwenden kannst du da sonst keine Funktionen.

>Nur verstehe ich dann nicht, wie -1 und 9 dafür sorgen, dass ein Objekt nur gefunden werden kann ,wenn man direkt davorsteht...


Diese Koordinaten sind relativ zu dem aufrufenden Objekt. Also wenn die Suche beispielsweise vom Clonk aus ausgeführt wird, dann wird an den Punkt geguckt, der ein Pixel links und neun Pixel unter dem Mittelpunkt des Clonks liegt. [Siehe Zappers Zeichnung unten.](https://clonkspot.org/forum/topic_show.pl?pid=5617#pid5617)
Parent - By Serpens66 (More than 200 posts.) Date 30.09.2014 20:39
Danke für die Erläuterung, mir war nicht ganz bewusst, dass all diese Find_... Befehle zum FindObject2 bzw. FindObjects Befehl gehören, jetzt weiß ich es :)
Parent - - By Zapper (More than 500 posts.) Date 30.09.2014 20:04 Edited 30.09.2014 20:08
Nochmal zu den Koordinaten:

In Clonk musst du in Pixeln denken. Die Koordinaten geben ein Suchrechteck an. Die ersten beiden platzieren das Rechteck relativ zum Mittelpunkt vom Clonk und die anderen beiden bestimmten die Größe des Rechteckes.
Hier ein Beispiel für **-1,+9,8,4**


Weil du `wdt` und `hgt` beide auf Null hast, wird nur an einem Punkt gesucht und nicht in einem Rechteck.

Ich empfehle dir immer die alten `FindObject` und `FindObjectOwner` und so mit den aktuellen `FindObject2` und `FindObjects` zu ersetzen

PS:
zB `while (obj = FindObjectOwner(0,GetOwner(), -1,+9,0,0, , 0,0,obj))` ersetzen durch `for (var obj in FindObjects(Find_AtPoint(-1,9), Find_Owner(GetOwner())))`

PPS: Die Werte -1 und 9 sehen relativ willkürlich aus. 0, 0 müsste genauso gut gehen. Oder gleich `Find_Distance(30)` um alles in einem Radius zu finden (was ungefähr das gleiche wäre wie *-30, -30, 60, 60* beim alten Dings).
Parent - - By Serpens66 (More than 200 posts.) Date 30.09.2014 20:38
danke, auch besonders für die zeichnung :)

>PPS: Die Werte -1 und 9 sehen relativ willkürlich aus. 0, 0 müsste genauso gut gehen.


0,0 hatte ich ja bereits ausprobiert und es wurde mir jedes Gebäude angezeigt (bzw. dadurch dass es noch keine Liste ist, wurde mir ständig dasselbe Gebäude angezeigt, egal wo ich stand und nachdem ich es abgerissen habe, kam dann das nächste möglicherweise zufällige Gebäude egal wo ich stand usw.)
Also warum sucht 0,0,0,0 nicht nur direkt in der mitte des clonks?

Ansonsten müsste es ja heißen, dass ich mit 0,+11,0,0 ganz gute chancen haben sollte, ein fundament zu füßen des Clonks zu finden...
habe das jetzt mal getestet und tatsächlich finde ich mit 0,+11 das Fundament , yeah =)
Gut... eigentlich sollte sowohl das Gebäude, als auch das Fundament dann bei -2,-5,4,18 möglich sein, oder nicht?  Ich gehe 2 nach links und 5 nach oben, befinde mich nun also etwas oben links vom Clonk. Nun ziehe ich ein Rechteck, welches  2 links vom Clonk beginnt und 2 rechts vom Clonk endet. Nach unten geht es von 5 über Clonk, nach 13 unter Clonk, sollte also das Fundament mit einschließen. Dennoch erhalte ich hier garkeine Ziele, weder Gebäude noch Fundament, wenn ich direkt mittig vor dem Gebäude stehe =/
Parent - By Luchs (More than 1000 posts.) Date 30.09.2014 21:16
Alles 0 ist ein Spezialfall von FindObject. Mit FindObjects passiert das nicht.
Parent - - By Zapper (More than 500 posts.) Date 30.09.2014 21:39 Edited 30.09.2014 21:41

>Also warum sucht 0,0,0,0 nicht nur direkt in der mitte des clonks?


Ah, stimmt. Hatte ich vergessen.
* 0, 0, 0, 0 sucht tatsächlich die ganze Karte ab.
* x, y, -1, -1 sucht das naheste Objekt zur Position x|y
* x, y, 0, 0 findet alle Objekte, die an der Position x|y sind
* x, y, w, h findet alle Objekte, deren Mittelpunkt im Rechteck ist

Schon wegen der ganzen Sonderfälle und so würde ich `FindObject2` empfehlen bzw. für Schleifen `FindObjects`.

PS:

>Gut... eigentlich sollte sowohl das Gebäude, als auch das Fundament dann bei -2,-5,4,18 möglich sein, oder nicht?


Wenn du ein Rechteck angibst, dann muss der Mittelpunkt der Objekte in dem Rechteck liegen.
Versuch stattdessen `FindObjects` mit `Find_AtRect` (findet alle Objekte, die das Rechteck schneiden - `Find_InRect` gibt es aber auch)
Parent - - By Serpens66 (More than 200 posts.) Date 01.10.2014 10:56 Edited 01.10.2014 12:36
Vielen Dank euch beiden :)

Habe es jetzt mit FindObjects gelöst =) Nun wird mir eine Liste von abbreißbaren Dingen angezeigt. Leider sucht auch Find_Distance, nach dem Mittelpunkt. Das heißt, damit ein Schloss gefunden wird, muss ich den Wert ca. auf 80 stellen, wodurch aber auch andere Gebäude in der Nähe schon abgerissen werden können.

Aber dein "Find_AtRect" funtkioniert tadellos, perfekt :) Warum findet sich das hier nicht? http://www.clonk.de/docs/de/search.php?func=find_
(keine ahnung warum der Link so komisch aussieht, eigentlich ist da alles korrekt...)

Das fertige Skript sieht nun wie folgt aus:

/* Gebäude-Abriss */

public func ContextDestruction()
{
  [Abreißen|Image=SYF1|Condition=BackAnything]
  var obj = BackAnything();
  if (!obj) return(1);
  CreateMenu(SYF1,0,0,0,"Was soll abgerissen werden?",0,1);
for (var obj in FindObjects(Find_AtRect(-5,-5,10,20), Find_Owner(GetOwner()),Find_Func("GetDefCoreVal", "Construction", "DefCore")))
{
  AddMenuItem("%s abreißen","DoDestruction",GetID(obj),0,0,obj);}
  AddMenuItem("Zurück","NoDestruction",SYCC);
}

private func BackBuilding()
{
  var obj;
for (var obj in FindObjects(Find_AtRect(-5,-5,10,20), Find_Owner(GetOwner()),Find_Func("GetDefCoreVal", "Construction", "DefCore")))
       return(obj);
  return(0);
}

private func BackAnything()
{
  var obj = BackBuilding();
  if (obj) return(obj);
  return(0);
}

private func DoDestruction(par0, target)
{
  CreateObject(DSTR)->DoDestruction(target);
}

private func NoDestruction() {}
Parent - By Luchs (More than 1000 posts.) Date 01.10.2014 11:06
Die Funktion hat wohl niemand dokumentiert. In System.c4g/FindObject.c findest du alle definierten Funktionen.
Up Topic Deutsch / Hilfestellung / [Gelöst] "AddLight" abändern, weil sonst Gebäude
1 2 Previous Next  

Powered by mwForum 2.29.7 © 1999-2015 Markus Wichitill