[Modding] Wie weise ich konfliktfrei einer Original-cre ein Override-Script zu?

Acifer

Senior Member
Registriert
27.04.2019
Beiträge
2.169
Ich habe die Problematik, dass ich einigen Kreaturen aus dem Originalspiel ein Script zuweisen muss. Leider haben diese Wesen bisher kein eigenes Script.

Der Hintergrund: In der Abyss funktionieren Beschwörungszauber für Wesen der inneren Ebenen nur mit entsprechenden Hilfsmitteln. Das bedeutet, dass Elementare nicht ohne weiteres herbeigerufen werden können. Das möchte ich in meiner Mod umsetzen.

Problem: Viele der Wesen haben kein eigenes Script.
Beispiel: ELFIRPR.cre (Feuerelementar, der durch Druiden beschworen wird) hat nur unter Default Script WTASIGHT.BCS. Ich würde ihm gerne das Override-Script ELFIRPR.BCS zuweisen, falls nicht vorhanden, erstellen, und folgenden Scriptblock anhängen:
Code:
IF
    OR(21)
        AreaCheck("AC#W40")
        AreaCheck("AC#W41")
        AreaCheck("AC#W42")
        AreaCheck("AC#W43")
        AreaCheck("AC#W44")
        AreaCheck("AC#W45")
        AreaCheck("AC#W46")
        AreaCheck("AC#W47")
        AreaCheck("AC#W48")
        AreaCheck("AC#W49")
        AreaCheck("AC#W50")
        AreaCheck("AC#W51")
        AreaCheck("AC#W52")
        AreaCheck("AC#W53")
        AreaCheck("AC#W54")
        AreaCheck("AC#W60")
        AreaCheck("AC#W61")
        AreaCheck("AC#W80")
        AreaCheck("AC#W81")
        AreaCheck("AC#W90")
        AreaCheck("AC#W91")
    !HasItem("AC#WIPSK",LastSummonerOf(Myself))
THEN
    RESPONSE #100
        DisplayStringHead(LastSummonerOf(Myself),85574)  // Ohne entsprechende Hilfsmittel könnt Ihr in der Abyss keine Elementarwesen herbeirufen.
        DestroySelf()
END

Das Script funktioniert einwandfrei. Nur: Wie mache ich das bei einem non-existenden Script? Ich habe gesehen, dass @Jastey im G3-Forum einen entsprechenden Thread führt, in welchem Veränderungen an Original-cres aufgelistet sind.
Wie sähe der WeiDU-Code dafür aus?
 

Jastey

Matron Modderholic
Registriert
16.05.2004
Beiträge
12.921
Um eine existierende cre mit Skript zu patchen, wäre dies der Standrad-tp2-Code:
Code:
COPY_EXISTING ~imoen.cre~ ~override~
      WRITE_EVALUATED_ASCII 0x248 ~%IMOEN_BCS%~ #8  // override script
      BUT_ONLY_IF_IT_CHANGES

Ich hoffe, ich habe Deine Frage verstanden. :o
 

Acifer

Senior Member
Registriert
27.04.2019
Beiträge
2.169
Um eine existierende cre mit Skript zu patchen, wäre dies der Standrad-tp2-Code:
Danke! Ich habe versucht, das einmal in meine tp2 zu integrieren:

Code:
COPY_EXISTING ~ELFIRPR.cre~ ~override~
      WRITE_EVALUATED_ASCII 0x248 ~%ELFIRPR_BCS%~ #8  // override script
      BUT_ONLY_IF_IT_CHANGES
EXTEND_TOP ~%ELFIRPR_BCS%~ ~godcall/scripts/abyss_inner_planes_summon_failure.baf~

Allerdings weist WeiDU der Cre jetzt %ELFIRPR.BCS zu und das Script wird nicht gepatcht. :(
 

Maus

Senior Member
Registriert
07.08.2002
Beiträge
9.379
Das individuelle Skripte der cre kannst du nicht patchen, sondern nur ersetzen. In deinem Fall könntest du das default-Skript einfach normal ergänzen (APPEND meine ich). Aber dann haben alle Kreaturen die das Skript haben, diese Ergänzung und das ist suboptimal.

Oder eben du schreibst denen nicht nur dein Skript rein, sondern generierst erst ein Skript in dem WSIGHT um deinen Skriptblock ergänzt wird und weist das dann der cre zu.

Oder du schaust mal, ob die Kreatur nicht einen leeren Skriptslot hast (override, class, weiß gerade auch nicht, meine aber es sind insgesamt 4 Skript möglich, mind. aber 3) und packst dein Skript da rein. Kann aber sein, dass das Skript dann zu nachrangig für deinen Zweck behandelt wird.

Wenn ich mir deinen Skriptblock anschaue, dann ist der nur in der Hölle gefährlich, von daher würde ich sagen: Skript ergänzen und umbenennen und dann das neue Skript zuweisen (alte ersetzen). Ist zwar bisserl Aufwand, aber im Wesentlichen c&p.
 

Acifer

Senior Member
Registriert
27.04.2019
Beiträge
2.169
Oder du schaust mal, ob die Kreatur nicht einen leeren Skriptslot hast (override, class, weiß gerade auch nicht, meine aber es sind insgesamt 4 Skript möglich, mind. aber 3) und packst dein Skript da rein.
Ja, das möchte ich machen. Meine Sorge: Was, wenn eine andere Mod (z.B. ein Fixpack) da schon ein Script reingepatcht hat?

Deshalb würde ich gerne folgendes Vorgehen WeiDU sagen:
"Guck' mal, ob die Kreatur bereits ein Override-Script zugewiesen hat.
- Wenn ja: hänge meinen Scriptblock hintendran.
- Wenn nein: Weise der Kreatur ein Override-Script zu (Name der Kreatur als .bcs) und hänge dann meinen Scriptblock dran"


Nur das in WeiDU-Code zu übersetzen klappt nicht.

Kann aber sein, dass das Skript dann zu nachrangig für deinen Zweck behandelt wird.
Genau das ist es. Im Override-Script ist die Kreatur so gut wie nicht zu sehen, weil das sofort losgeht. Alles andere dauert zu lange (die Kreatur ploppt auf, guckt doof und ist dann wieder weg), deshalb sollte es das Override-Script sein.
 

Jastey

Matron Modderholic
Registriert
16.05.2004
Beiträge
12.921
@Acifer Ich bitte um Entschuldigung, mein Beispiel war Grütze. Es liest für den Skriptnamen eine Variable ein, deswegen sind da noch %%.
Wenn Du das Skript direkt als Namen angibst, dann fallen die weg:
Code:
COPY_EXISTING ~ELFIRPR.cre~ ~override~
      WRITE_EVALUATED_ASCII 0x248 ~ELFIRPR~ #8  // override script
      BUT_ONLY_IF_IT_CHANGES
EXTEND_TOP ~ELFIRPR.bcs~ ~godcall/scripts/abyss_inner_planes_summon_failure.baf~
Das individuelle Skripte der cre kannst du nicht patchen, sondern nur ersetzen.
Hä? Natürlich kann man individuelle Skripte patchen, man muss halt nur wissen, wie sie heißen.
Sollte es noch nicht existieren, wird es bei EXTEND_TOP/BOTTOM erzeugt, da kann man also nichts falsch machen.
 

Jastey

Matron Modderholic
Registriert
16.05.2004
Beiträge
12.921
Deshalb würde ich gerne folgendes Vorgehen WeiDU sagen:
"Guck' mal, ob die Kreatur bereits ein Override-Script zugewiesen hat.
- Wenn ja: hänge meinen Scriptblock hintendran.
- Wenn nein: Weise der Kreatur ein Override-Script zu (Name der Kreatur als .bcs) und hänge dann meinen Scriptblock dran"
Da könntest Du mal in Ascalons Mods reinschauen, Breagar oder im Questpack. Der hat es glaube ich so gemacht: ist OVERRIDE Skript vorhanden, wenn ja nimm das und patche es, ansonsten nenne es soundso. Ist auf alle Fälle eleganter und besser für Kompatibilität.
 

Maus

Senior Member
Registriert
07.08.2002
Beiträge
9.379
"Hä? Natürlich kann man individuelle Skripte patchen, man muss halt nur wissen, wie sie heißen." Ne, aber das ist glaube ich ein Definitions-Problem (was man mit individuell bezeichnet).

Du kannst z.B. bei einem Elementar das WTASIGHT-Skript ergänzen und damit patchen. Aber das ist dann auch bei allen anderen Kreaturen, die das Skript verändertn, geändert. Du kannst nur das Skript ergänzen, umbenennen und dann neu zuweisen.

Oder ich habe was grundlegend nicht verstanden.
 

Jastey

Matron Modderholic
Registriert
16.05.2004
Beiträge
12.921
Für mich ist individuelles skript = Skript das nur diese cre hat.
Du meinst da glaube ich was anderes mit, dann verstehe ich Deine Aussage. Wenn die cre ein generelles Skript hat, dann kann man dieses Skript nicht nur für diese cre patchen. Die Änderungen sind dann im Skript und damit auch bei allen andren dres, die es nutzen, logisch.
Das war aber auch nicht Acifers Frage, soweit ich weiß.

Man kann individuelle cres trotzdem ansprechen, indem man die Death Variable abfragt, oder halt wie Du schon meintest, in einer bestimmten Area nur eine bestimmte cre dieses Skript verwendet und dann einen AreaCheck macht.

Ist trotzdem immer noch besser, wenn man einen freien Skriptslot hat und ein eigenes Skript patchen kann.
 

Acifer

Senior Member
Registriert
27.04.2019
Beiträge
2.169
Wenn Du das Skript direkt als Namen angibst, dann fallen die weg:
So klappt es jetzt, Danke! :up:
Jetzt haben die cres wenigstens ein eigenes Override-Script zugewiesen.

Du kannst z.B. bei einem Elementar das WTASIGHT-Skript ergänzen und damit patchen. Aber das ist dann auch bei allen anderen Kreaturen, die das Skript verändertn, geändert. Du kannst nur das Skript ergänzen, umbenennen und dann neu zuweisen.
Davor schrecke ich ein wenig zurück. Ich habe in meiner modfreien BG2-ToB-Version nachgesehen, 1932 Kreaturen nutzen dieses Script (inklusive meiner eigenen). Ich fürchte, dass ich da von den WeiDU-Cracks Haue bekomme, wenn ich in dieses Script wild hineinpatche.
Eleganter wäre es, das nicht existente Override-Script per WeiDU abzufragen und meinen Code einzufügen.

Da könntest Du mal in Ascalons Mods reinschauen, Breagar oder im Questpack. Der hat es glaube ich so gemacht
Ich habe bei Breagar ein patching der DV gefunden:
Code:
//Patch Existing Creatures
COPY_EXISTING ~%tutu_var%TAEROM.CRE~ ~OVERRIDE~
READ_ASCII 0x280 ~DV~
PATCH_IF ((~%DV%~ STRING_EQUAL ~~) OR (~%DV%~STRING_EQUAL_CASE ~none~)) BEGIN
WRITE_ASCII 0x280 ~TAEROM~
END
BUT_ONLY

Ich versuche mich einmal daran entlangzuhangeln, ob ich das mit dem Override-Script auch hinbekomme.

Wo es natürlich auch vorkommt ist in SCS:
Code:
////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////// // check if a golem script is installed
////////////////////////////////////////////////////////////////////////////////////////////////

DEFINE_PATCH_FUNCTION has_golem_script RET value BEGIN
       SET value=0
       PATCH_FOR_EACH arguments IN golcly01 golsto01 goliro01 golice01 golbra01 BEGIN
          LPF CRE_match_script STR_VAR arguments RET value_here=value END
          SET value=value=1? 1: value_here
       END
END

Leider bräuchte ich dazu 2w6 Leitfäden des klaren Denkens, um da durchzusteigen...
 

Maus

Senior Member
Registriert
07.08.2002
Beiträge
9.379
Du hast mich falsch verstanden. Nimm das WTASIGHT-Skript. Benenne es um in ACI_BLA-Skript. Ergänze deinen Skriptblock im ACI_BLA-Skript. Weise der Kreatur ACI_BLA als Override-Skript zu (mit dem Syntax von Jastey). Und vorne das PATCH_FOR_EACH für alle Elementare, die du patchen willst.

Dann haben die Elementare alle das Skript, das sie auch vorher hatten, plus deine Ergänzung. Und alle anderen sind raus.
 

Jastey

Matron Modderholic
Registriert
16.05.2004
Beiträge
12.921
@Maus warum sollte man das so machen? Die cres haben ja extra mehrere Skript slots, damit man mehrere Skripte zuweisen kann. Was bringt es, eins zu machen, dass den Inhalt eines existierenden Skripts beinhaltet? Dann lieber das originale auf dem Slot lassen und ein eigenes auf den Override. Oder sprichst Du von cres, bei denen alle Slots belegt sind?
Prinzipiell ist das Reinkopieren bestehenden Inhalts in Skripte/Dialoge ungünstig und veraltete Vorgehensweise. Dann wird das nämlich nicht mehr gepatcht, wenn SCS et al da was ändern, zum Beispiel.

Leider bräuchte ich dazu 2w6 Leitfäden des klaren Denkens, um da durchzusteigen...
Die habe ich leider auch nicht.. Stimmt, bei Breagarwar das die DV, nicht das Skript.

Am besten fragst Du nach elegantem Code bei G3 oder wartest, bis Taimon vorbeikommt. :-)

Ich würde sowas versuchen:
Code:
COPY_EXISTING ~ELFIRPR.CRE~ ~OVERRIDE~
READ_ASCII 0x248 ~override~
PATCH_IF ((~%override%~ STRING_EQUAL ~~) OR (~%override%~STRING_EQUAL_CASE ~none~)) BEGIN
WRITE_EVALUATED_ASCII 0x248 ~ELFIRPR~ #8
END
BUT_ONLY


Das funktioniert (wenn überhaupt...) aber nur, wenn kein Skript zugewiesen ist. idealerweise würde man, wenn eins zugewiesen ist, dieses einlesen und dann patchen. Ich könnt schwörn, das mal irgendwo gesehen zu haben. Ich suche mal.
 

Jastey

Matron Modderholic
Registriert
16.05.2004
Beiträge
12.921

Acifer

Senior Member
Registriert
27.04.2019
Beiträge
2.169

Taimon

Infinity Engineer
Registriert
25.11.2001
Beiträge
1.501
SCS hat einige Hilfsfunktionen in lib_cre.tpa, z. B. CRE_insert_script_high.
Ohne den Teil mit dem Mergen von zwei Skripten, falls kein freier Platz ist, sähe das so aus:
Code:
DEFINE_PATCH_FUNCTION CRE_insert_script_high
     STR_VAR
         arguments=""
BEGIN
     FOR (i=0x248;i<0x270;i=i + 8) BEGIN
        READ_ASCII i ~test~
        SET blank=0
        PATCH_IF ~%test%~ STRING_EQUAL_CASE ~~ OR ~%test%~ STRING_EQUAL_CASE ~none~ BEGIN
           SET blank=i
           SET i=0x270
        END
     END
     PATCH_IF blank=0 BEGIN // merge the first two scripts, but check both exist first!
     // Hier ist der Merge-Teil. Kann potentiell zu Problemen führen, wenn Mods, die später installiert werden, Änderungen an dem gemergten Skript vornehmen.
     END ELSE BEGIN
           FOR (i=blank;i>0x248;i=i - 8) BEGIN
              READ_ASCII i - 8 ~move~
              WRITE_ASCIIE i ~%move%~ (8)
           END
           WRITE_ASCIIE 0x248 ~%arguments%~ (8)
     END
END

Alternativ könnte ich mir auch vorstellen, die Funktionalität in den Area-Skripten umzusetzen. (Der Effekt ist ja sowieso auf bestimmte Areas beschränkt.)
 

Maus

Senior Member
Registriert
07.08.2002
Beiträge
9.379
Weil Acifer ja geschrieben hatte, dass nur das Override schnell genug ausgeführt wird. Und weil es sowas wie SCS gibt, das aus Prinzip alle Script-Slot belegt, wobei das eigentlich irrelevant ist, weil SCS genau deswegen erst am Schluss installiert wird. Aber ich meine schon, dass der Override-Slot in aller Regel belegt ist.
 

Acifer

Senior Member
Registriert
27.04.2019
Beiträge
2.169
Aber ich meine schon, dass der Override-Slot in aller Regel belegt ist.
Ja, diese Gefahr sehe ich auch. Ich muss mir einmal SCS genauer ansehen. Blöd wäre nämlich, wenn eine andere Mod ein ebenfalls alltägliches Script in den override-slot legt und ich anstelle der WTASIGHT.BCS dann das SHOUT.BCS patche. :hae:

Ohne den Teil mit dem Mergen von zwei Skripten, falls kein freier Platz ist, sähe das so aus:
Cool! Vielen Dank! Das ist genau das, was ich brauche. Ich werde sicher noch einige Zeit brauchen, um das Code-technisch auch zu verstehen. ;)

Alternativ könnte ich mir auch vorstellen, die Funktionalität in den Area-Skripten umzusetzen. (Der Effekt ist ja sowieso auf bestimmte Areas beschränkt.)
Mein Problem ist, dass die Area-Scripts auch schon voll sind und dementsprechend langsam "feuern".

In der Abyss gibt es mehrere Einschränkungen für Zauberwirker:
- Zauber, die Wesen von den inneren Existenzebenen beschwören, wirken nur mit entsprechendem Zauberschlüssel: Möchte ich im Creature-Script umsetzen (das ist das, was ich im Thread anspreche; betrifft Elementarwesen, aber auch Ifrits, Dschinn und Unsichtbare Pirscher)

- Klerikerzauber schlagen mit einer gewissen %-Chance fehl, je weiter entfernt sich die Machtbasis des Klerikergottes von der Abyss befindet (das heißt, gute Kleriker haben eine höhere Misserfolgschance als böse Kleriker): Das habe ich in den Area-Scripten mit rundenbasiertem Timer und einem Zauber ähnlich in Zonen toter Magie umgesetzt. Hat der Kleriker einen passenden Machtschlüssel, kann er seine Zauber fehlerfrei wirken.

- Zauber der Schule "Verwandlung" haben zu 50% einen negativen Effekt auf den Zauberwirker, wenn dieser keinen passenden Zauberschlüssel hat. Das habe ich für die meisten Veränderungszauber in den Area-Scripts umgesetzt, z.B. recht drastisch (aber regelgetreu) bei Steinhaut:
Code:
IF
    SpellCast([PC],WIZARD_FLESH_TO_STONE)  // SPWI604.SPL (Fleisch zu Stein)
    !HasItem("AC#W_SK1",LastTrigger)  // Zauberschlüssel: Veränderung
THEN
    RESPONSE #50
        DisplayStringHead(LastTrigger,84851)  // Euer Zauber wurde in der Abyss korrumpiert.
        ApplySpell(LastTrigger,WIZARD_FLESH_TO_STONE)  // SPWI604.SPL (Fleisch zu Stein)
END

- Zauber, die Monster beschwören, beschwören in einer gewissen Wahrscheinlichkeit feindlich gesinnte Dämonen: das möchte ich ebenfalls in den cre-Scripten umsetzen

Deshalb möchte ich das Area-Script nicht noch mehr belasten. Mein Wunsch wäre, dass die beschworenen Cre's gar nicht erst erscheinen, alles andere sähe immersionsbrechend aus. Derzeit bekomme ich das nicht hin, im Cre-Script ist die Latenz aber weniger als in den Area-Scripts.Ich hatte auch schon überlegt, das spl-file zu patchen, habe dabei aber keine Möglichkeit gefunden, das entsprechend umzusetzen.
Jetzt ist es so, dass die cre kurz aufpoppt und dann wieder verschwindet (das Script hierbei ist das WIZELSU2.BCS):
Baldr002.jpg
Baldr003.jpg
Baldr004.jpg
 

Taimon

Infinity Engineer
Registriert
25.11.2001
Beiträge
1.501
Ich hatte auch schon überlegt, das spl-file zu patchen, habe dabei aber keine Möglichkeit gefunden, das entsprechend umzusetzen.
Wird schwierig.
Spontan fällt mir nur der Weg über eine unsichtbare CRE als Mittelsmann ein.
Der originale Spruch beschwört dann diese CRE, welche in einem OnCreation()-Block die jeweiligen Bedingungen prüft, das eigentliche Wesen beschwört und sich selbst zerstört.
Dürfte aber nicht ganz einfach werden, das fehlerfrei umzusetzen. Schließlich soll der ursprüngliche Caster ja weiterhin der Summoner von dem Wesen sein.
 

Jastey

Matron Modderholic
Registriert
16.05.2004
Beiträge
12.921
Und wenn Du in die Areas einen Areatriggr patchst (unsichtbar), der ein Skript hat? Ich habe mal gelesen, Areatrigger führenihre Skripte aus wie Charaktere, es sind sozusagen 2d-Charaktere in der Beziehung. :-)
Das wäre dann nicht so laggy wie das Areaskript.
EDIT: unsichtbare cre war nämlich auch mein erster Gedanke, aber die stehen halt irgendwo rum, können von Zaubern getroffen werden etcpp.
 

Acifer

Senior Member
Registriert
27.04.2019
Beiträge
2.169
Und wenn Du in die Areas einen Areatriggr patchst (unsichtbar), der ein Skript hat?
Das ist eine gute Idee. Mit einer unsichtbaren Cre habe ich es gestern abend schon versucht, auch das läuft. Wenn ich die cre in einen Bereich stelle, der in der Searchmap ausgeblockt (=schwarz) ist, läuft diese auch nicht Gefahr, von Zaubern etc. getroffen zu werden.
An sich wäre mir eine Cre etwas lieber, weil der Aufwand nicht so groß ist, anstatt in jeder Area einen Area-Trigger hineinzupatchen. Ich berichte, wenn ich mit den Tests weiter fortgeschritten bin.

Der originale Spruch beschwört dann diese CRE, welche in einem OnCreation()-Block die jeweiligen Bedingungen prüft, das eigentliche Wesen beschwört und sich selbst zerstört.
Dürfte aber nicht ganz einfach werden, das fehlerfrei umzusetzen. Schließlich soll der ursprüngliche Caster ja weiterhin der Summoner von dem Wesen sein.
Ja, das klingt kompliziert. Dann müsste ich mit LastSummonerOf(LastSummonerOf(Myself())) arbeiten, oder? Ich müsste mir einmal ansehen, welche Mods beschworene Kreaturen verändern.

SCS hat einige Hilfsfunktionen in lib_cre.tpa, z. B. CRE_insert_script_high.
Hier hänge ich auch noch fest. Den Schritt Hilfsfunktion -> patchen zahlreicher Cre's habe ich noch nicht hinbekommen. Ich werde mir einmal SCS auf BG2EE installieren und mir den Code dort genauer ansehen müssen.

Puh, alles ein ziemlicher Aufwand. Die Frage ist, ob der Spielspaß überhaupt in einem Verhältnis zu der ganzen Programmiererei steht. :hae:
 
Oben