[Modding] Scripting Fragen

Maus

Senior Member
Registriert
07.08.2002
Beiträge
9.379
Korrekt, das DisplayStringHead rausnehmen funktioniert auch ;)
 

Maus

Senior Member
Registriert
07.08.2002
Beiträge
9.379
Frage zu
Code:
Continue()
am Ende eines ACTION-Blocks im Skript: Machen soll man das, damit das Skript weiterläuft und nicht in dem Skriptblock looped (willkommen meine Freunde, die bei DAY/NIGHT-Wechseln permanent laufende Skriptblöcke haben), aber wenn ich eine Variable im ACTION-Block hochzähle, wird der ja nicht mehr ausgeführt und ich könnte mir Continue sparen. Die Frage: ist es irgendwie schädlich, wenn ich trotzdem ein Continue einfüge?
 

Maus

Senior Member
Registriert
07.08.2002
Beiträge
9.379
Und noch eine ganz andere Frage hinterher:
Code:
IF
    G("Chapter",18)
    Global("FWAerieImmyInUD","GLOBAL",1)
    InParty(Myself)
    InParty("Imoen2")  // Imoen
    CombatCounter(0)
    !See([ENEMY])
THEN
    RESPONSE #100
        SetGlobal("FWAerieImmyInUD","GLOBAL",2)
        DisplayStringHead(Myself,485871)  // Running block 5 of AERIE.BCS
        RealSetGlobalTimer("FWAerieImmyUD","LOCALS",500)
END

Kann man das Abfragen von Global wirklich einfach mit "G" abkürzen oder ist das ein Skriptfehler?? Oder geht das nur bei Chapter? Und keine Ahnung, wer das Kürzel FW ist...
 

Taimon

Infinity Engineer
Registriert
25.11.2001
Beiträge
1.501
Kann man das Abfragen von Global wirklich einfach mit "G" abkürzen
Ja, wenn ein entsprechender Eintrag in der trigger.ids vorhanden ist. (In BG2 sollte der da sein, in BG1 wahrscheinlich eher nicht.)
Bei solchen Abkürzungen würde ich aber immer auch auf die Lesbarkeit achten.
(Generelle Empfehlung: Code so schreiben, dass er einfach zu lesen ist und nicht einfach zu schreiben.)

Die Frage: ist es irgendwie schädlich, wenn ich trotzdem ein Continue einfüge?
Das Skript läuft dann weiter, kann also weitere Aktionen auslösen. Ob das "schädlich" ist, hängt stark vom konkreten Fall ab.
 

Maus

Senior Member
Registriert
07.08.2002
Beiträge
9.379
Generell wäre es aber von Vorteil, wenn das Skript bis zum Ende läuft, weil es dann nicht neu von vorne laden muss. Bei Skripten, in denen die Reihenfolge der Abfrage wichtig ist (Kämpfe denke ich mal, kann das ja gewünscht sein), ist das gut. Aber ansonsten hätte ich immer gesagt: durchlaufen lassen... Aber solange es mal nicht prinzipiell schädlich ist, lasse ich es mal bei den einmal-Ereignissen mit Continue weiterlaufen.
 

Maus

Senior Member
Registriert
07.08.2002
Beiträge
9.379
Und noch eine Frage hinterher:
Sind NPC irgendwie per se GLOBAL oder sollte ich vorsichtshalber ein MakeGlobal für einen NPC einführen? Ich könnte mir vorstellen, dass die erst GLOBAL werden, wenn sie mal aufgenommen worden sind?
Wie kommt ein Eintrag automatisch in die GAM-Datei? Also ohne MakeGlobal...
 

Jastey

Matron Modderholic
Registriert
16.05.2004
Beiträge
12.920
NPCs sind erst global wenn sie in der Gruppe waren, korrekt. Für NPCs für original BG1 gab's mal ein Tutorial, wie man die GAM patcht - das ist aber nicht nörig, Du kannst einfach so wie in SoD gleich nach dem Erstellen des NPCs im selben Skriptblock ein MakeGlobal() setzen und gut ist.

Continue() habe ich mir mal gemerkt ist wichtig, wenn im Skript eventuell noch einBlock ist, der OnCreation(?) abfragt, da der wohl nur direkt nach dem betreten wahr ist und durch einen Skriptblock davor dann blockiert werden könnte. Daher Continue() immer dazusetzen, wenn man ein Skript mit EXTEND_TOP erweitert.
Ansonsten gibt es den Trick, dass eine Variable erst gesetzt wird, wenn ein Skriptblock beendet ist - das Continue() führt dazu, dass mehrere durchlaufen, als wären sie "einer". SoD nutzt das an mehreren Stellen, um für eine Variable = 0 Aktionen auszuführen, die Variable wird dann erst im letzten Block nach den ganzen mit Continue() hochgezählt und das klappt ohne Loopen der davor stehenden.
Das wäre also eine Gefahr wenn Du allen Blöcken ein Continue() gibst, dass Variablen eventuell nicht gleich so hochgesetzt werden, wie Du das geplant hast.
 

Maus

Senior Member
Registriert
07.08.2002
Beiträge
9.379
Hm, das ist ein gutes Argument. Dann nehme ich Continue() nur, wenn ich nicht Triggervariablen hochzähle (mache ich aber in der Regel fast immer).
 

Maus

Senior Member
Registriert
07.08.2002
Beiträge
9.379
Timer-Frage:
Aus der IESDP: 115 SetGlobalTimer(S:Name*,S:Area*,I:Time*Gtimes)
Warum muss ich bei einem Timer die Area angeben? Läuft der Timer nicht eben Global? Ich dachte immer, dass ich nur den Namen und die Dauer angebe...

edit: hab die Lösung gefunden:
0x4040 GlobalTimerExpired(S:Name*,S:Area*)
Returns true only if the timer with the name specified and of the type in the 2nd parameter has run and expired.

Das heißt, dass mit "Area" hier "GLOBAL" gemeint ist...
 
Zuletzt bearbeitet:

Taimon

Infinity Engineer
Registriert
25.11.2001
Beiträge
1.501
Warum muss ich bei einem Timer die Area angeben? Läuft der Timer nicht eben Global?
Die Timer werden mit Hilfe von Variablen umgesetzt.

Beim Aufruf wird einfach die aktuelle Zeit und der angegebene Zeitwert addiert und als Wert der Variable gespeichert. (Der Wert ändert sich dann nicht mehr.)
Um zu überprüfen, ob der Timer abgelaufen ist, muss nur die aktuelle Zeit mit dem Variablenwert verglichen werden.

Timer können also überall dort gespeichert werden, wo es auch Variablen gibt. (GLOBAL, LOCALS, MYAREA, ...)
 

Maus

Senior Member
Registriert
07.08.2002
Beiträge
9.379
Ok, dann sind es für LOCALS und MYAREA aber nicht wirklich globale Timer wie der Name nahelegt... gerade weil es ja auch "normale" Timer gibt, die nur lokal wirksam sind, war ich da verwirrt. Wobei die "normalen" wohl nicht im SaveGame gespeichert werden, es da also wirklich einen Unterschied gibt.
 

Jastey

Matron Modderholic
Registriert
16.05.2004
Beiträge
12.920
Naja, die lokalen Variablen heißen ja auch "Global()".
 

Maus

Senior Member
Registriert
07.08.2002
Beiträge
9.379
Noch eine Frage zum Unterschied zwischen SetGlobalTimer und RealSetGlobalTimer. Beide beziehen sich ja auf Angaben aus der GTIMES.IDS um die Zeitdauer festzulegen. Ich würde jetzt sicherheitshalber bei RealSet nicht X_ROUNDS angeben. Aber ansonsten müssten die doch gleich laufen mit der Ausnahme, dass der Set-Timer bei Reisen läuft, aber nicht bei Spielpausen und es beim Real-Timer umgekehrt ist.
Im IESDP wird angegeben, dass der RealSet-Timer in Sekunden läuft. Daher bin ich ein wenig irritiert.
 

Jastey

Matron Modderholic
Registriert
16.05.2004
Beiträge
12.920
RealSetGlobalTimer ist ein Timer in Echtsekunden. Er läuft wie Du schon selbst gesagt hast auch, wenn Pause gedrückt ist.
SetGlobalTimer ist ein timer in Spiel-Zeit, und läuft nicht, wenn Pause gedrückt ist.
Wenn Du dem RealSetGlobalTimer eine Angabe in HOURS, ROUNDS oder DAYS gibts weiß ich nicht, was er daraus macht. Normalerweise einfach in Sekunden: 3600 für eine Echtzeit-Stunde.
 

Maus

Senior Member
Registriert
07.08.2002
Beiträge
9.379
Frage zu dem Skript, das in einer Area laufen soll:
Code:
IF
    Global("M8MECreateErik","LOCALS",0)
THEN
    RESPONSE #100
        SetGlobal("M8MECreateErik","LOCALS",1)
        CreateCreature("M8MEERIK",[4313.1762],SE)  // Erik - Erik the Wyrmslayer
        Continue()
END

Es funktioniert nicht. Kann das daran liegen, dass ich "LOCALS" verwendet habe und das bei Areas nicht funktioniert und ich stattdessen den Namen der Area verwenden sollte?
 

Maus

Senior Member
Registriert
07.08.2002
Beiträge
9.379
Aber ist LOCALS da falsch? Ich meine, dass es früher funktioniert hat, bin mir aber da nicht sicher...
 

Maus

Senior Member
Registriert
07.08.2002
Beiträge
9.379
Und die nächste Frage, die mit dlg verknüpft ist: kann ich LeaveAreaLUA nicht aus einer dlg raus als Action benutzen? Geht das nur in Skripten? Kann ich überhaupt einen NPC aus seiner dlg heraus bewegen oder muss ich in der dlg eine Variable setzen und das dann über das Skript des NPC laufen lassen?
 

Jastey

Matron Modderholic
Registriert
16.05.2004
Beiträge
12.920
LOCALS ist nur für cres, soweit ich weiß.
Das mit dem LeaveAreaLUA weiß ich nicht, MoveBetweenAreas geht jedenfalls im Dialog - außer der Spieler verlässt zu schnell die Area, dann wird es nicht zu Ende ausgeführt und der Charakter ist weg.
 

Taimon

Infinity Engineer
Registriert
25.11.2001
Beiträge
1.501
LOCALS ist nur für cres, soweit ich weiß.
Ja, LOCALS funktioniert nur bei Akteuren vom Typ 0x31 (CRE), der Akteur für das Areascript hat Typ 0x61.

kann ich LeaveAreaLUA nicht aus einer dlg raus als Action benutzen?
Sollte eigentlich funktionieren.
Zumindest ist die Action als INSTANT deklariert, was darauf hindeutet, dass sie auch ausgeführt werden kann, wenn die Zeit stillsteht.
 
Oben