Construction Set Skriptthread zum Construction Set

Was mir als erstes aufgefallen ist, Du nutzt die Variable fQuestDelayTime, aber sie wird im Skript nicht gesetzt, ist also wirkungslos. Ich halte es auch für unnötig das Questskript zu beschleunigen, in diesem Fall ist es ja wirklich egal, ob die Stage nun 5 Sekunden früher oder später gesetzt wird. Die Variable Timer hat auch keine Funktion im Skript.

Das Skript soll ja feststellen, ob ein Tag, also 24 Stunden vergangen ist. GamedaysPassed ist da schon mal richtig, nur es fehlt die Uhrzeit. Ich habe mal schnell was geschrieben, aber ohne Gewähr - bin gerade erst aufgestanden und der Kaffee hat seine Wirkung noch nicht voll entfacht. :lol:


Code:
Scn A67HQ01Warten

short Tag
float Zeit
short Start      ; 1 = Zum Starten der 24-Stunden Abfrage
short Auswahl  ; Wert der Stage die hochgesetzt werden soll

Begin GameMode

     if Start == 1
        set Zeit to GameHour
        set Tag to GameDaysPassed
        set Start to 2
     endif

     if Start == 2

            if GameDaysPassed > Tag
               
                   if GameHour > Zeit
                        set Start to 0
                        set Auswahl to 0
                        SetStage A67HQ01 Auswahl
                  endif
           endif
    endif

End


Du musst hier eben zwei Variablen setzen um eine Stage hochzusetzen. Einmal Start und die Auswahl, also set QuestID.Start to 1 und set QuestID.Auswahl to 67, oder 210, oder welche auch immer. Ein aufploppendes Questlog kann in manchen Situationen unschön sein - in einem Kampfes beispielsweise. Einfach das Skript dann nach Belieben ergänzen. :)

Code:
     if Start == 2

            if GameDaysPassed > Tag
               
                   if GameHour > Zeit

                          if Player.IsInCombat == 0

                                   if Player.IsSleeping == 0

                                            if Player.GetInSameCell DieScharfeMaria == 0
                                                set Start to 0
                                                set Auswahl to 0
                                                SetStage A67HQ01 Auswahl
                                             endif
                                  endif
                           endif
                  endif
           endif
    endif
 
  • Like
Reaktionen: Andy1967
Du hast sicher recht was das QuestDelay und die Timer short angeht. Die schleppe ich mit seit ich mein erstes "nächster Tag Abfrage" Script aus irgendeiner Queste abgekupfert und mir angepasst hab. Da hab ich mich schon gefragt welchen Sinn es hat (auch da nämlich wahrscheinlich keinen), aber da es auch keinen für mich erkennbaren Schaden angerichtet hat hab ich es irgendwie immer weitergeschleppt. :D

Die Sache mit der Uhrzeit ist ein guter Hinweis. Muss mal drüber schlafen ob das in jeder Situation Sinn macht, aber ich denk ich nehm es wohl mit rein.

Die zu setzenden Stage auf dem Weg Teil des Scripts zu machen hat definitv Charme. Werd ich so machen, nur mit der kleinen Änderung vielleicht erst die Auswahl Short im SetStage zu verwenden und erst anschließend auf 0 zurück zu stellen. ;)

Vielen herzlichen Dank, Beolo.
 
Werd ich so machen, nur mit der kleinen Änderung vielleicht erst die Auswahl Short im SetStage zu verwenden und erst anschließend auf 0 zurück zu stellen.


Das "set Auswahl to 0" ist natürlich totaler Schwachsinn. Den Fehler sehe ich jetzt erst. Diese Zeile muss gelöscht werden, sonst funktioniert das Skript nicht. Auswahl braucht nie auf 0 zurückgesetzt werden. Diese Variable dient lediglich dazu, damit man dem Skript sagen kann, welche Stage hochgesetzt werden soll. Bevor die nächsten Questupdates ausgelöst werden, überschreibt man Auswahl sowieso mit dem Wert der neuen Stage.

Die Uhrzeit macht halt insofern Sinn, wenn Du auch wirklich 24 Stunden Zeit vergehen lassen willst. Ich kenne ja den Questverlauf nicht. Angenommen der Spieler bekommt einen Auftrag von einem NPC und der Spieler hat einen Tag Zeit das zu erledigen. Würde man die Uhrzeit weglassen und nur GameDaysPassed verwenden, könnte das sehr knapp werden. Nämlich dann, wenn sich das Ganze kurz vor Mitternacht ereignet. Wäre schon etwas sonderbar, wenn der Spieler um 23:59 den Auftrag annimmt und eine Minute später ploppt das Questlog auf: Ihr habt zu lange herumgetrödelt und deswegen den Auftrag versemmelt! :lol:
 
Hallo
Ich habe versucht ein einfache skript zu schreiben , doch es funktioniert nicht und zwar will ich wenn der spieler unterwasser ist und es regnet ein sound abgespielt wird doch es funktioniert nicht.
Scn 0521sa

Begin Gamemode




if


IsRaining == 1
IsUnderwater ==1
PlaySound 00SOund


endif
end
 
Wenn du mehrere "if"-Bedingungen hast, verknüpfst du diese entweder mit "&&" oder du schreibst sie in verschiedene hintereinander ausgeführte "if"s.

Code:
if isRaining && isUnderwater
  playSound ...
endif
 
  • Like
Reaktionen: tommi
Das Problem ist nur, der Sound wird dabei in jedem Frame gestartet. Du hörst also nur die ersten Millisekunden, also praktisch nichts wenn es ein Objektskript ist. Bei einem Questskript würde er 5 Sekunden laufen, dann abgewürgt und von vorne starten. Du musst das mit einer Bedingung versehen, damit PlaySound nur einmal ausgeführt wird.
IsUnderwater? Diese Funktion ist mir nicht bekannt, ist vermutlich von OBSE. Doch bei einer solchen Funktion sollte das Skript schon auch wissen, wer unter Wasser ist. Wenn Du das so schreibst, dann wird eben das Objekt abgefragt, auf dem das Skript läuft - ich nehme nicht an, dass Du das Skript dem Player zuordnen willst.

Was den Sound betrifft, kommt es eben ganz darauf an, was der machen soll. Ohne zu wissen was Du vorhast, kann man da schlecht weiterhelfen. Es gibt viele Arten um einen Sound abzuspielen, dabei kommt es schon darauf an, was das für ein Sound ist. Ist er Stereo, oder Mono, läuft er im Loop, oder soll er nur einmal abgespielt werden? Soll er im Spiel ortbar sein, also von einer Referenz aus erklingen? Ist er nur für eine ganz bestimmte Stelle gedacht, oder soll er global in allen Gewässern der Spielwelt verwendet werden? Je nach Anforderungen, wird ein Skript völlig anders aussehen.
 
Hallo Meister des geskripteten Wortes

Ich möchte ein Spript machen, dass den Playercharakter per Spell in ein Haus und danach wieder zurück an den Ausgangspunkt schickt. Da man das Haus auch durch die Tür verlassen kann, soll in diesem Falle der Player erst ins Haus zurückteleportiert werden und danach an den Zielort. Ich habe es mit nachfolgendem Skript versucht, aber es funktioniert nicht korrekt.Nachdem der Homereturnmarker einmal von seinem Ausgangspunkt an einen Zielpunkt verschoben wurde, bewegt er sich nicht mehr.

Die Rückführung des Homereturnmarkers zum Returnmarker2 funktioniert nicht, wobei ich beim Homereturnmarker einen XMarkerheading und als Returnmarker2 einen XMarker benutze.
Scriptname DHReturnToDruidhome

;DHHomeMarker
;DHHomeReturnMarker
;DHReturnMarker2

short Start
ref target


Begin ScriptEffectStart


set target to GetSelf


if ( Player.GetInCell aaaDruidhome == 1 ) && (DHHomeReturnMarker.GetInCell aaaDruidhome != 1)

set Start to 2

endif


if ( Player.GetInCell aaaDruidhome != 1 ) && (DHHomeReturnMarker.GetInCell aaaDruidhome == 1)
DHHomeReturnMarker.moveto Player
DHHomeReturnMarker.enable

set Start to 1

endif


if ( Player.GetInCell aaaDruidhome != 1 ) && (DHHomeReturnMarker.GetInCell aaaDruidhome != 1)
Message "Eine unwiderstehliche Kraft zieht euch ins Druidenhaus zurück", 10

set start to 1

endif


if ( Player.GetInCell aaaDruidhome == 1 ) && (DHHomeReturnMarker.GetInCell aaaDruidhome == 1)
Message "Der Zauber wirkt noch nicht", 10

return

endif


End


Begin ScriptEffectUpdate


End


Begin ScriptEffectFinish


if ( Start == 1 )
set Start to 0
Player.MoveTo DHHomeMarker


elseif ( Start == 2 )
set Start to 0
Player.MoveTo DHHomeReturnMarker
DHHomeReturnMarker.disable
DHHomeReturnMarker.moveto DHReturnmarker2


endif


End


Jemand eine Idee wie ich es richtig machen könnte?

Danke


Harvald
 
Zuletzt bearbeitet:
Du willst also einfach einen Teleport-Zauber, der dich in dein Haus bringen kann und wieder zurück zum Ausgangspunkt?
Sowas in die Richtung sollte gehen:

Code:
Scriptname <name>

short placed

Begin ScriptEffectStart

if(player.getInCell <homecell>)
    if(placed)
        player.moveTo <Ausgangsmarker>
    endif
else
    <AusgangsMarker>.moveTo player
    set placed to 1
    player.moveTo <HausMarker>
endif

End

Die placed-Variable ist dazu da, um zu versichern, dass der Ausgangsmarker schon einmal benutzt wurde.
 
  • Like
Reaktionen: Harvald
Danke für den Tip Kahmul, doch das ist nicht ganz das was ich wollte(ein Kkript in der Art hatte ich schon selbst geschafft), denn der Player kann ja die <homecell> auch durch die Tür verlassen und dann liegt der Zauber logischerweise brach, bis er in die <homecell> zurückkehrt. Was du mit placed machst mache ich mit start und den Werten 0 und 1.

Das Skript sollte die Funktionen haben.

1 ausser Haus und kein Rückkehrzauber aktiv: Rückkehr zum Haus
2 Rückkehr durch Zauber und nicht im Haus: Rückkehr zum Haus
3 Rückkehr durch Zauber und im Haus: Rückkehr zum Ausgangspunkt
4 keine Rückkehr zum Haus durch Zauber und im Haus: nichts passiert

Ws funktioniert auch soweit bis auf die Tatsache, das der marker nach einmaliger benutzung nicht weiter bewegt wird.

aber trotzden Danke für die Mühe.

Harvald
 
Code:
Player.MoveTo DHHomeReturnMarker
    DHHomeReturnMarker.disable
        DHHomeReturnMarker.moveto DHReturnmarker2

Dein Problem dürfte an der Reihenfolge der Befehle liegen. Ein MoveTo auf den Player angewendet wirkt wie ein "retun" im Skript, verhindert also die Ausführung der nachfolgenden Befehle.

Dazu wie man es allerdings am besten löst den Marker trotzdem zu verschieben fällt mir spontan nichts ein, da ich mich an einer solchen Materie bislang noch nie versucht habe. :(
 
  • Like
Reaktionen: Harvald
Magic-Scripts sind wohl nicht so geeignet, weil Du Variablen brauchst die persistent sind, um die jeweilige Situation festzuhalten. Also wenn ich das Szenario richtig verstanden habe, soll der Spieler von jedem x-beliebigen Ort in das Haus teleportieren können und beim zweiten Aufruf des Spells an den Ausgangspunkt zurück.
Du brauchst also min. eine Variable die festhält, ob der Spieler mit dieser Funktion in Haus reist und nicht etwa durch die Tür. Du kannst dazu schon Spells benutzen, solltest aber Variablen auslagern, weil die in Magic-Scripts beim Zellenwechsel zurückgesetzt werden.
Das Spell-Skript braucht zwei Teile, einmal für den Part ins Haus und der zweite für die Rückkehr zum Ausgangspunkt. Welcher Teil ausgeführt wird hängt von der Variable ab. In einem Questskript legst Du die Variable >Reise< oder was auch immer an. Im Magic-Script wird die als erstes abgefragt.

Code:
Begin ScriptEffectStart

   if MeineQuest.Reise == 0
      ZielMarkerRef.MoveTo Player
      set MeineQuest.Reise to 1
      Player.MoveTo NachHauseMarker
   endif

   if MeineQuest.Reise == 1
      set MeineQuest.Reise to 0
      Player.MoveTo ZielMarkerRef
   endif

End


Jetzt muss nur noch das Problem beseitigt werden, wenn der Spieler das Haus per Spell betreten hat, es aber normal über die Haustür verlässt. Eine einfache Lösung wäre ein Skript auf die Tür zu legen, das die Variable Reise auf 0 zurücksetzt. Eventuell noch mit Warnhinweis, dass der Rückkehrzauber beim Verlassen durch die Tür deaktiviert wird.

Code:
short Button
short Ablauf

Begin OnActivate

   if MeineQuest.Reise == 1
     set Ablauf to 1
   else
     Activate
   endif

End

Begin GameMode

    if Ablauf == 1
      set Ablauf to 2
      MessageBox "Der Rückkehrzauber funktioniert außerhalb des Hauses nicht! Wollt Ihr die Tür trotzdem benutzen?" "Ja!" "Nein!"
    endif

   if Ablauf == 2
     set Button to GetButtonPressed

         if Buttom == -1
           Return
         endif

         if Button == 0
           set MeineQuest.Reise to 0
           set Ablauf to 0
           Activate
         endif

         if Button == 1
           set Ablauf to 0
         endif
   endif

End


Das wäre eventuell eine Lösung, falls nicht noch irgendwelche Dinge in deiner Mod sind, die ich jetzt nicht berücksichtigt habe.
 
  • Like
Reaktionen: Harvald
Kurze Frage: Wenn ich mit StopQuest eine Quest beende wird ja wohl auch das Quest Script gestopt. Kann ich danach trotzdem noch von anderer Stelle die Variablen abfragen die in dem Quest Script gesetzt wurden während es lief (also z.B. mit "get MyQuestname.MyQuestVariable" in einem anderen Script)? Oder ist das Script dann quasi "versiegelt" und "unzugänglich"?
 
Ja, StopQuest beendet das Questskript und zudem alle Gespräche, die dieser Quest zugeordnet sind. Ein Questskript eignet sich sehr gut als reiner Variablen-Container. Es reichen Skriptname und die Variablen, mehr ist nicht erforderlich. Die Quest muss dazu nicht gestartet werden, so lange nur Variablen und kein ausführbarer Code im Skript steht.
Bei umfangreicheren Projekten macht es Sinn eine neue Quest zu erstellen, die nur das Skript mit den Variablen erhält. Man kann die Variablen dann nach und nach ergänzen und hat das Zeug dann aufgeräumt an einem Ort, wo man es später auch wiederfindet, ohne in zig Skripten herumwühlen zu müssen.

Get Questname.Variable geht aber nicht. In Skripten einfach wie jede Variable abfragen: "if Questname.Variable == x". In den Bedingungen von Packages, Topics etc. mit GetQuestVariable und dann die Quest aus der Liste picken und die gewünschte Variable aussuchen. Ingame-Überprüfung geht mit SQV Questname, da werden dann alle Variablen der Quest mit ihren jeweiligen Werten aufgelistet.
 
  • Like
Reaktionen: Andy1967
Hast natürlich recht was das "get" angeht. Da fehlte noch die dritte Tasse Kaffee bei mir und ich war gedanklich irgendwo zwischen Conditions und Scripts im Nirwana. :D Benutzten tue ich beides schon reichlich in der von dir beschriebenen Weise, nur hatte ich bislang nicht alle Variablen in einem einzigen "Variablenhalter Quest". So geht es halt wenn man als Anfänger bei einer Mod für den Eigenbedarf irgendwann beschließt das könnt ja auch mal veröffentlicht werden und die Mod dann wächst und wächst. Da ist halt beim ersten Mal noch nicht alles "best practice". :D
 
eine ziemlich einfache Sache aber irgendwie bin ich zu blöd sie zu lösen: Ein Zauber soll eine beschworenen Waffenkombi aus Bogen und 50 Pfeilen hinzufügen, so weit so einfach.

scn DHboudbow

ref self
short done


Begin ScriptEffectStart
set self to GetSelf
if ( done == 0 )
self.additem DHJaegerbogen 1
self.EquipItem DHJaegerbogen
self.additem DHFirearrows 50
self.EquipItem DHFirearrows 50
set done to 1
else
return
endif
End


Begin ScriptEffectUpdate


End


Begin ScriptEffectFinish
if ( done == 1 )
self.removeitem DHJaegerbogen 1
self.removeitem DHFirearrows 50
set done to 0
endif
End

Das Problem sind die Pfeile. Es wird statt der 50 nur einer angelegt, und im Inventar erscheinen 49 +1 Pfeil getrennt. Sie lassen sich auch nicht zusammenfügen und wenn man den einen abfeuert bleibt trotzdem einer gesondert im Inventar auch wenn man die 49 anlegt. hat irgendjemand ne Idee warum das so ist und wie man es wermeiden kann. Danke im Voraus.
 
Zuletzt bearbeitet:
Das Problem ist, dass equipItem als Argument nicht die Anzahl der Items nimmt, sondern stattdessen, ob das Item abgelegt werden kann oder nicht.
Habe ein wenig im Internet gesucht und das hier scheint die Lösung zu sein:

Code:
player.equipItem <arrow>
player.addItem <arrow> 49

Da equipItem automatisch eine Instanz des Pfeiles hinzufügt, kann man das so aufrufen. Wenn man nun mehr Pfeile dem Inventar hinzufügt, werden sie den ausgerüsteten Pfeilen automatisch hinzugefügt.
 
  • Like
Reaktionen: Harvald
Ich bin beim stöbern im CS Wiki auf den Befehl "sv_replace" gestoßen. Soweit ich das verstanden habe, kann man mithilfe dieses Befehls einen Text im Spiel durch einen anderen ersetzten. Leider verstehe ich nicht, wie ich diesen Befehl anwenden muss. Mit der Syntax komme ich nicht zurecht. Kann mir da jemand ein Beispiel geben?
 
Der Befehl ersetzt in einer String-Variable einen von dir festgelegten Teil mit einem anderen. Sollte so aussehen:

Code:
sv_replace "<wirdErsetzt>|<wirdEingefügt>" <stringVariable>

Du kannst dann noch festlegen, ob nur in einem bestimmten Abschnitt des Strings gesucht werden soll, ob auf Groß- und Kleinschreibung geachtet werden soll und ob nur eine bestimme Anzahl an Vorkommnissen des zu ersetzenden Teils ersetzt werden sollen (standardmäßig alle).

Für OBSE-Commands würde ich immer die offizelle Dokumentation zu Rate nehmen und nicht das CS-Wiki.
 
  • Like
Reaktionen: bjoernret
Danke für deine Antwort. Also kann ich damit nicht z.B. alle "Septime" in "Goldmünzen" umbenennen (auch in Dialogen, Questlogs, etc.). Schade, gibt es dafür auch einen Befehl?
 
Das müsstest du dann wohl eher im CS machen. Ich kenne nämlich keinen Befehl, der zum Beispiel den Inhalt von Dialogen oder Questeinträgen ausliest. Für Bücher gibt es immerhin "getBookText".

Man müsste außerdem aufpassen, dass man nicht "Septime" in "Goldmünzen" ändert, wenn von der Familie der Septime die Rede ist... :D
 
  • Like
Reaktionen: bjoernret