Construction Set Der Scriptthread

Na das ist ja mal seltsam... Wie verhält es sich jetzt wenn ein anderer NPC mit einer Armbrust schiesst während Du die Muskete gezogen/angelegt hast? Hört man da nun auch den Musketenschuss oder tatsächlich die Armbrust?
 
Hallo zusammen,

ich bräuchte mal wieder etwas Hilfe. Ich möchte, dass in einer bestimmten Interior-Zelle eine mp3-Datei abgespielt wird (mit ständiger Wiederholung). Bei meinen Skriptversuchen rattert die Datei jedoch, sobald ich die Interior-Zelle betrete. Verlasse ich die Zelle wieder, wird das Lied normal abgespielt. Ich habe darauf geachtet, dass die mp3-Datei mono und nur 64bit/s ist.

Hier mein Skriptversuch:
Begin _ly_musictavern

StreamMusic, "Ordnername/XY.mp3"

end

Für Hilfe wäre ich sehr dankbar, die Threadsuche hat mir leider nicht geholfen.
 
Das ist nicht das Problem. StreamMusic wird mit deinem Script ständig neu angestossen, also solange du in der Zelle bist, in welcher der Scriptholder steckt. Außerhalb läuft die Musik deshalb normal, weil das Script dann nicht mehr läuft. Du mußt also einen passenden IF-Block darum herum bauen, damit das Ding in der Zelle nicht ständig angeschoben wird, sondern nur wenn es nötig ist.

Beachte bitte, dass StreamMusic verbuggt ist und die Lautstärkeeinstellung des Spielers mit 100% überschreibt, egal was der vorher eingestellt hat und man es dann manuell über das Menu zurücksetzen darf.
 
  • Like
Reaktionen: Lyali
Du musst einen Timer einsetzen der das Stück erst wieder startet nachdem es vorbei ist.
Sagen wir das Musikstück ist 1:45 min lang, das wären 105 Sekunden...
Code:
Begin _ly_musictavern

float timer

if (CellChanged) 
  set timer to 0
  return
endif

if ( timer <= 0 )
  StreamMusic, "Ordnername/XY.mp3"
   set timer to 105
else
  set timer to timer - GetSecondsPassed
endif

end

Beim Zellwechsel (egal ob rein oder raus) wird die Uhr auf 0 gesetzt so das die Musik dann neu beginnt.
Die Musik wird - ohne das man's ändern könnte - unterbrochen sobald vom System andere Musik gestartet wird (z.B. bei einem Angriff).

Nebenbei bemerkt kannst Du in den Music\Explore oder \Attack-Unterordnern beliebige Musikstücke unterbringen die - ganz ohne Script - dann automatisch mit unter die vorhandene Musik gemischt wird.
 
Zuletzt bearbeitet:
  • Like
Reaktionen: Lyali
Danke euch beiden für die schnelle Antwort.
Ich habe das Skript angepasst und es läuft jetzt in der Taverne optimal. Gibt es aber eine Möglichkeit, mittels Skript das so einzustellen, dass die "normale" Musik wieder läuft, sobald ich einen Zellenwechsel vornehme? Falls das mit StreamMusic Probleme nicht möglich ist, ich könnte die mp3-Datei auch ins wav-Format konvertieren ( zwecks Befehl PlayLoopSound etc.)
 
Du kannst dazu in der Zelle das Script erweitern. Du benötigst lediglich eine klitzekleine mp3-Datei mit etwa 1 Sekunde Länge - ohne Geräusche natürlich. Ich nenn sie mal "SILENTIUM.mp3"

Das Script sähe etwa so aus:

Code:
Begin _ly_musictavern 

float timer 

if (CellChanged)    
   StreamMusic, "Ordnername/SILENTIUM.mp3"
   set timer to 0.2   
   return
 endif 
 
if ( timer <= 0 )   
  StreamMusic, "Ordnername/XY.mp3"    
  set timer to 105 
else   
  set timer to timer - GetSecondsPassed 
endif  

end
Das bewirkt beim Betreten und Verlassen der Zelle eine kurzes Anspielen des Stückes ohne Ton.
Wenn man in der Zelle ist beginnt nach 0.2 Sekunden die eigentliche Musik während draussen - wegen Ende des letzten Musikstückes einfach was Neues aus dem Standard-Repertoire gespielt wird.

Für eine gewisse Atmosphäre die mit Deiner Zelle verbunden sein soll, müsste es nicht mal ein tonloses Stück sein sondern könnte eine Art Jingle sein (eben eine kurze Melodie die beim Betreten und Verlassen erklingt). Dann müsstest Du nur den ersten Timer auf die Länge des Jingles abstimmen damit es danach in Deine eigentliche Musik übergeht.
 
Zuletzt bearbeitet:
Ich habe die Skriptanpassung vorgenommen und wenn ich von Exterior in die Zelle reingehe, bemerke ich eine kleine Verzögerung, bevor das Lied wie gewünscht abgespielt wird. Wenn ich allerdings dann wieder nach Exterior gehe, wird das Lied einfach weitergespielt, ohne Pause und somit ohne Unterbrechung des Skripts. Woran könnte das liegen?
 
Ich habe die Skriptanpassung vorgenommen und wenn ich von Exterior in die Zelle reingehe, bemerke ich eine kleine Verzögerung, bevor das Lied wie gewünscht abgespielt wird. Wenn ich allerdings dann wieder nach Exterior gehe, wird das Lied einfach weitergespielt, ohne Pause und somit ohne Unterbrechung des Skripts. Woran könnte das liegen?
Wundert mich nicht.

CellChanged triggert im Frame direkt nach dem Zellwechsel. Dies bedeutet, wenn ein Script auf einem Aktivator die Musik steuert, so würde dieses nicht mehr laufen, wenn der Zellwechsel detektiert werden kann - sprich nach dem Benutzen der Tür oder eines Teleports.

Wenn Du das machen willst, wirst du um ein Background Script nicht herum kommen. Dieses würde vom Aktivator, der das bisherige Script trägt, gestartet werden - mit so einem Script:

Code:
begin _ly_musictavern_ctrl

IF ( CellChanged )
  IF (ScriptRunning "_ly_musictavern" = 0 )
    StartScript "_ly_musictavern"
  EndIF
EndIF

end
... und das BackGround-Script sähe dann so aus:

Code:
Begin _ly_musictavern

float timer 

IF ( GetPCCell != "NAME DER ZELLE DER TAVERNE" )
  StreamMusic, "Ordnername/SILENTIUM.mp3"
  set timer to 0
  StopScript "_ly_musictavern"
ElseIF ( timer <= 0 )   
  StreamMusic, "Ordnername/XY.mp3"    
  set timer to 105 
Else   
  set timer to timer - GetSecondsPassed 
EndIF

end
Der Aktivator sollte ein Unique sein. Dann müßte es funktionieren. letzteres läßt sich erst kompilieren, wenn du einmal das StopScript mit einem ";" davor auskommentierst, sonst kommt Script not found.
 
Zuletzt bearbeitet:
@£exa: Ich habe deine Variante probiert, leider passiert gar nichts, d.h. wenn ich die Zelle betrete, wird das Lied nun nicht mehr abgespielt. Beim Verlassen das gleiche.
 
@£exa: Ich habe deine Variante probiert, leider passiert gar nichts, d.h. wenn ich die Zelle betrete, wird das Lied nun nicht mehr abgespielt. Beim Verlassen das gleiche.
Dann nimm die "IF ( CellChanged )" Bedingung um den ScriptRunning Block mal weg. Eigentlich hätte das funktionieren müssen, es kann aber bei hoher Scriptlast doch sein, dass es so nicht geht.

Wichtig ist, dass der Hintergrundtask für die Musik jeweils nur einmal beim Betreten angeschubst wird.
 
  • Like
Reaktionen: Lyali
Nimm das erste Script so wie es anfangs war.

Mach ein zweites, kleines Script welches Du an die Tür machst die nach draussen führt.
Code:
Begin Ausgangscript

if ( OnActivate )
streamMusic "silentium.mp3"
Activate
endif

end

Das ist ein sehr unfeines Script weil es einen Cellchanged-Event "klaut" - nämlich den der stattfinden würde wenn man nun durch diese Tür hinausgeht. Der ist bei Türen die ein "OnActivate" tragen nicht mehr registrierbar. Du musst also dran denken das beim Verlassen der Taverne kein "CellChanged" ausgelöst wird. Beim reinkommen schon...


Edit: Sorry, ich vergaß, man kann ja einen Raum auch anders verlassen und wäre jetzt dämlich wenn Du sieben Ausgänge hättest. Eine andere Lösung - wenn Du bereits ein einmaliges, persistentes Objekt welches eines Deiner Scripte trägt in der Zelle hast mach dort drei zusätzliche Scriptzeilen rein:

Code:
If ( ScriptRunning "NeuesScript" == 0 )
StartScript "NeuesScript"
endif

und das neue script (wie bereits beschrieben) erstmal speichern bevor Du den Namen verwenden kannst:

Code:
begin NeuesScript

short playsNow

if ( GetPCCell != "TAVERNE" )
  if ( playsNow == 0 )
    streamMusic "Silentium.mp3"
    set playsNow  to 1
  else
    stopScript "NeuesScript" 
  endif

endif

end
Die Variable playsNow sorgt dafür das das Script nachdem die "stille Music" gestartet wurde erst einen kompletten Frame durchläuft. Ansonsten wird "Silentium.mp3" wahrscheinlich nicht gespielt.
Um es auf Deutsch zu sagen: der Befehl würde erst garnicht in die Liste der noch zu erledigenden Dinge aufgenommen werden da der Zettel mit der Anweisung schon weg wäre wenn das Script bereits terminiert ist.
 
Zuletzt bearbeitet:
  • Like
Reaktionen: Lyali
@£exa: Die Entfernung der CellChanged-Bedingung brachte leider auch nichts.
@ReneMiner: Super, jetzt funktioniert es.
 
Spezielle Variable?

Hallo. Da ich kein Experte spezieller Morrowindfunktionen bin, frage ich besser mal hier.

Anscheinend gibt es eine Funktion/Variable "Dead", die für jeden Actor gesetzt wird, ohne dass sie deklariert wird oder per Skript gesetzt wird. Sie wird anscheinend nur einmal hochgesetzt, wenn der Actor stirbt und bleibt auch bei diesem Wert, wenn "resurrect" verwendet wird.
Diese Funktion/Variable habe ich bislang nur als Condition bei Dialogen gesehen. Da sie abgefragt wird, verhindert sie den weiteren Ablauf von Quests, da ja der Actor nach "resurrect" wieder lebt. Gibt es eine Möglichkeit, auch diese Variable wieder in den Grundzustand zu setzen? Ansonsten wäre die einzige Möglichkeit, die Bedingung zu löschen...
 
Äh, nein... hier handelt es sich nicht um eine Variable im eigentlichen Sinne... also ein frei setzbarer Wert. Vielmehr ist es ein Counter, der bei allen CSIDs der Art Actor (NPCs und Creatures) mitzählt, wie oft diese im Spiel gestorben sind. Du hast den Einsatz dessen bereits in Dialogen gesehen, es gibt sie aber auch in Scripts, da heißt sie nur anders. Klartext:

GetDeadCount (Script)
bzw.
Dead (Dialog)

gibt für eine ReferenzID zurück, wieviel mal ein Actor mit dieser ID gestorben ist. Es gibt also nicht etwa eine Variable pro Ingame Instanz, sondern jeweils einen Zähler für alle Referenzen einer ID. Und der wird in der Tat durch Resurrect nicht reduziert. Es gibt soweit ich weiß auch keinen Befehl dafür.

Mir ist nur ein Weg bekannt, um das wegzubekommen - Editieren des Savegames mit dem Enchanted Editor.
 
Hallo zusammen, ich bräuchte mal wieder Hilfe.
Ich möchte, dass einem Container in regelmäßigen Abständen (wie das geskriptet werden muss weiß ich) ein zufälliger Gegenstand aus einer Liste möglicher Gegenstände hinzugefügt wird. Könnte ich diesbzgl. AddItem mit einem Leveled Item verbinden oder wie muss ich das machen, wenn überhaupt möglich?

Edit: Ich hätte noch eine Frage: Gibt es eine Möglichkeit, bei dem Mannequin-Skript (die Variante mit SkipAnim und Health = 0) das so einzustellen, dass der NPC den Kopf nicht zu einem anderen NPC dreht, wenn der in die Nähe kommt?
 
Zuletzt bearbeitet:
Ich möchte, dass einem Container in regelmäßigen Abständen (wie das geskriptet werden muss weiß ich) ein zufälliger Gegenstand aus einer Liste möglicher Gegenstände hinzugefügt wird. Könnte ich diesbzgl. AddItem mit einem Leveled Item verbinden oder wie muss ich das machen, wenn überhaupt möglich?

Ja, das sollte funktionieren. Wenn es nicht klappt, könntest du den Zufallspart noch immer im Script selbst abhandeln, indem du eine Zufallszahl zuweist und entsprechend dieser eine Item hinzufügst.

Edit: Ich hätte noch eine Frage: Gibt es eine Möglichkeit, bei dem Mannequin-Skript (die Variante mit SkipAnim und Health = 0) das so einzustellen, dass der NPC den Kopf nicht zu einem anderen NPC dreht, wenn der in die Nähe kommt?

Das sollte bei SkipAnim eigentlich nicht passieren. Immerhin werden die Animationen unterdrückt. Auf jeden Fall ist es eine gute Idee, die Mannequins immer mal wieder an ihren ursprünglichen Platz zu setzen, da die sich langsam "wegruckeln".
 
  • Like
Reaktionen: Lyali
Hallo,

Ich bräuchte einen kleinen Script.
Er soll auf ein Aktivator gelegt werden.

Die Wirkung des script soll so sein:
Es soll eine bestimmte Anzahl eines Objekts, dass man bei sich trägt zb: Dwemer Münzen.
gegen ein anderes eintauschen.
Ungefähr so: 50 dwemer Münzen für ein XY Gegenstand.
Also eine art Tauschgeschäft.

MFG
 
Kein Problem:

begin my_script_1

if ( OnActivate == 1 )
if ( Player->GetItemCount, "misc_dwe_coin" >= 50 )
Player->RemoveItem, "misc_dwe_coin", 50
Player->AddItem, "my_item", xy
endif
endif

end

Das ist übrigens nicht die ID für Dwemermünzen, die kenn ich nciht auswendig ;)

Natürlich kann man das Script noch mit Abfragen, Messageboxen oder Sounds fast beliebig ausbauen.
 
  • Like
Reaktionen: Houdini