Construction Set Der Scriptthread

Ich möchte, dass einige Kreaturen den Spieler so wie NSCs grüßen, wenn er ihnen nahekommt.
begin Skriptname

float timer
short doonce

if ( MenuMode == 1 )
return​
endif

if ( doonce == 0 )
if ( GetDistance, Player <= 140 )
PlaySound3D "Sound"
MessageBox "Begrüßungstext"
set doonce to 1​
endif​

else
set timer to timer + GetSecondsPassed
if ( timer > 47 )
set doonce to 0
set timer to 0​
endif​
endif

end
Gedacht ist das Skript so, dass an der Position der Kreatur der Satz abgespielt wird. Wenn sie sich bewegt, sollte der Ton ihr folgen. Die Begrüßung soll nicht andauernd abgespielt werden, daher die Abklingzeit von 47 Sekunden. Soweit, meine ich, funktioniert das Skript auch schon.
  • Der abgespielte Ton ist ziemlich leise. PlaySound3DVP erlaubt keine Verstärkung. Hat jemand eine Idee, wie man den abgespielten Ton lauter hinbekommt?
  • Man könnte auf den Befehl Player->Say zurückgreifen, verliert dadurch aber den "3D-Effekt". (Könnte es nicht auch zu Problemen kommen, wenn eine Kreatur Say auslöst, während die Tondatei einer anderen Kreatur noch abgespielt wird? Demfalls müsste man wohl noch eine Abfrage SayDone hinzufügen, sodass nur eine Kreatur auf einmal die Begrüßung abspielen kann.)
  • Es wäre natürlich wunderbar, wenn die Kreatur sich für die Begrüßung so wie ein NSC zum Spieler dreht. Ich habe den Befehl "Face X Y ( Player->GetPos X ) ( Player->GetPos Y )" versucht, aber der Befehl scheint so nicht zu funktionieren – zumindest nicht bei Kreaturen. Kann man da etwas über Rotate oder SetAngle hinbekommen? Da es sich um einen offenen Raum handelt und die Kreaturen auch durch den Raum laufen werden, müsste man variable Werte einsetzen, die sowohl auf Spieler- als auch auf Kreaturenkoordinaten zurückgreifen und daraus die Z-Achsen-Rotation (SetAngle) oder die Rotationsdauer (Rotate) ermitteln.
  • Es ist nicht schlimm, dass der Spieler auch gegrüßt wird, wenn er schleicht oder unsichtbar ist. Wenn ich das aber verhindern wollte, könnte ich das doch mit einer Abfrage "if ( GetDetected Player == 1 )" eine Ebene unter der Distanzabfrage?
  • Habt ihr sonst noch Verbesserungsvorschläge für das Skript?
 
Hi, hab hier bissel rumprobiert, aber viel hab ich noch nicht gelernt :)
Ich bräuchte ein Script für eine Tür, die nur einmal ein ein Journal ausgibt, und die Tür sollte sich danach wie eine normale Tür verhalten.

Danke
 
Du kannst es hiermit probieren, aber ich kann dir nicht versprechen, dass es genau so funktioniert wie gedacht.

begin VD_DoorJournalScript

short DoOnce

if ( OnActivate == 1 )
if ( DoOnce == 0 )
journal VD_DoorJournal 10
activate
set DoOnce to 1
else
activate
endif
endif

end

Die Tür müsste nun beim ersten Aktivieren den Tagebucheintrag VD_DoorJournal bei Stage 10 geben und sich öffnen bzw. durchtreten werden. Soll beim ersten Mal nur der Tagebucheintrag erfolgen, die Tür aber nicht geöffnet werden, entferne nach dem Tagebucheintrag die Zeile 'activate'.
 
Zuletzt bearbeitet:
So wird das leider nicht funktionieren. Probier es mal so:

Code:
begin kf_sk_door_journalblock_script

if ( OnActivate == 1 )
    if ( GetJournalIndex, "kf_testthema" >= 10 )
        if ( GetJournalIndex, "kf_testthema" < 20 )
            Journal, "kf_testthema", 20
        endif
        Activate
    endif
endif

end

Genau das war sogar eine Beispielaufgabe aus dem Scriptkurs ;)
 
  • Like
Reaktionen: VDMap
So wird das leider nicht funktionieren. Probier es mal so:
Dein Script funktioniert, setzt aber dank des ersten GetJournalIndex >= 10 eine aktive Quest bzw. einen vorherigen Journaleintrag voraus ohne den die Tür nicht funktioniert. Also müsste man das Öffnen der Tür durch Setzen eines passenden Journaleintrags erlauben. Sofern das gewollt ist, gut. Geht es aber darum, beim ersten Öffnen einen Journaleintrag zu erhalten, zum Beispiel, weil das Öffnen der Tür die Quest starten soll, wäre eine gekürzte Version geeigneter:

Code:
begin kf_sk_door_journalblock_script

if ( OnActivate == 1 )
   if ( GetJournalIndex, "kf_testthema" < 10 )
      Journal, "kf_testthema", 10
   endif
   Activate
endif

end
 
  • Like
Reaktionen: VDMap
Hallöchen,

ich habe mal wieder ein kleines Skriptproblem. Ich möchte, dass eine besiegte Kreatur bzw. NPC einen Spruch auf sich selbst castet (z.B. Spell "fireball"), um zu simulieren, dass sie nach dem Tod explodiert und der Spieler, wenn er zu Nahe ist Schaden erleidet. Danach soll der Leichnam verschwinden. Das Verschwinden bekomme ich hin, nur nicht diesen Explosionseffekt. Im folgenden mal meinen Skriptversuch:

Begin _ly_skript

short NPCdisable

if ( GetDeadCount "ID_NPC" == 1 )
if ( NPCdisable == 0 )
Cast "fireball" "ID_NPC"
"ID_NPC"->disable
Set NPCdisable to 1​
endif​
endif

End
 
Ich gehe davon aus, dass dieses Script auf der zu sprengenden Kreatur liegt. Damit das funktioniert, benötigst du einen speziellen Zauber. Der muss auf Touch, also Berührung, eingestellt sein und eine genügend große AoE und Schadenshöhe haben. Dann kannst du die Funktion:

ExplodeSpell "Spell ID"

benutzen, um den Effekt zu faken.
 
Ich habe versucht das anzupassen und habe auch den Spruch auf Berührung umgestellt. Das Skript liegt auf einem NPC, leider wird der Spruch nicht gecastet.
Hier das anpepasste Skript:

Begin _ly_skript

short NPCdisable

if ( GetDeadCount "ID_NPC" == 1 )
if ( NPCdisable == 0 )
ExplodeSpell "ID_Spell"
"ID_NPC"->disable
Set NPCdisable to 1​
endif​
endif

End
 
Ah, mein Fehler... funktioniert mit Leichen nicht :D

Okay, mach folgendes:
  1. erstelle zunächst einen Zauber [ID_EXPLOSION_SPL]
    -> Effect: FireDamage
    -> Settings: Range Touch, Area 20, Duration 5, Magnitude XX/YY
    -> setze die Kosten auf 5
    -> setze den Haken bei "Always Succeeds"

  2. Erstelle ein Script [ID_Detonator_SCR], wie folgt:
    Code:
    begin ID_Detonator_SCR
    DontSaveObject
    Short FrameCounter
    
    IF ( GetDisabled == 0 )
      IF ( FrameCounter < 5 )
        set FrameCounter to ( FrameCounter + 1 )
      ELSE
         ExplodeSpell "ID_EXPLOSION_SPL"
         Disable
      EndIF
    EndIF
    
    end
  3. Erstelle nun einen Activator, z.B. [ID_Detonator]
    -> Keine Bezeichnung vergeben
    -> Artfile: w\magic_target_dst.nif
    -> lege das [ID_Detonator_SCR] Script auf [ID_Detonator]

  4. Verwende folgenden Scriptblock für die NPC:
    Code:
    begin NPCID_SCR
    
    IF ( GetDisabled == 0 )
       IF ( GetHealth <= 0 )
         PlaceAtMe "ID_Detonator", 1, 0, 0
         Disable
       EndIF
    EndIF
    
    end
Das sollte dein Problem lösen.
 
Zuletzt bearbeitet:
  • Like
Reaktionen: VDMap und Lyali
Guten Morgen,

Hab hier mal was zusammen gebastelt, funzt aber leider nur die hälfte..

Das Script ist für eine Tür und soll bei bestimmten Journaleintrag eine Messagebox ausgeben, weil man den Schlüssel noch nicht hat, und eine Globale + 1 setzen.
Soweit so gut. Dann bei neuen Journaleintrag sollte man einen Schlüsselabdruck mit Wachs machen können mit Messagebox ja/nein.
Der erste Teil funktioniert, aber der Teil mit dem Wachs nicht. Was ist falsch?

Code:
begin _vdm_door_xyz_script

short done
short doonce

if (done == 1)
return
endif



if ( OnActivate == 1 )
if ( player->GetItemCount, "_vdm_key_xyz" < 1 )
MessageBox "no key!" "Ok"  
if(GetJournalIndex "_vdm_hf_init"  == 3)
        if(doonce == 0)
            set "_vdm_xy_status" to ("_vdm_xy_status" + 1)
            set doonce to 1
            MessageBox "xyz"
        endif
    endif
else
set done to 1
Activate
endif

endif

if ( OnActivate == 1 )
if (GetJournalIndex "_vdm_xyz_init"  == 4)
if ( player->GetItemCount, "ingred_dreugh_wax_01" < 1 )
        MessageBox "imprint wax?", "Yes", "No"
        set doonce to 2
endif
endif
endif


if ( doonce == 2 )
    set button to GetButtonPressed
    if ( button == -1 )
            return  
    elseif ( button == 0 )
        if ( player->getitemcount "ingred_dreugh_wax_01" < 1 )
                messagebox "no wax"
                set doonce to 3  
            else
                messagebox "key imprint wax"
                player->removeitem, "ingred_dreugh_wax_01", 1
                player->additem, "_vdm_xy_imprint", 1
                set doonce to 4
            endif
    elseif ( button == 1 )
        set doonce to 3
    endif
endif

End

Danke, und einen schönen Tag ;)
 
Zuletzt bearbeitet:
Versuch das mal - aber ohne Gewähr, da ich es ohne CS umgeschrieben habe:

Code:
begin _vdm_door_xyz_script
short MessageOn
short Button

IF ( MenuMode )
   return
EndIF

IF ( MessageOn != 1 )

   IF ( OnActivate == 1 )
     IF ( MessageOn > -1 )
       IF ( player->GetItemCount, "_vdm_key_xyz" < 1 )
         MessageBox "no key!" "Ok"
         IF (GetJournalIndex "_vdm_hf_init"  == 3)
           set "_vdm_xy_status" to ("_vdm_xy_status" + 1)
           Journal "_vdm_hf_init", 4
          ;hier besser auch einen Journaleintrag setzen, ersetzt das lokale DoOnce
          ;falls "4" schon belegt ist, alle Einträge verschieben und "4" neu einfügen!
         ElseIF (GetJournalIndex "_vdm_xyz_init"  == 4)
           IF ( player->GetItemCount, "ingred_dreugh_wax_01" >= 1 )
             MessageBox "imprint wax?", "Yes", "No"
             set MessageOn to 1
           EndIF
         EndIF
         return
       ELSE
         set MessageOn to -1
       EndIF
     EndIF
     Activate
   EndIF

ELSE

   set Button to GetButtonPressed
   IF ( button >= 0 )
     IF ( Button == 0 )
       IF ( player->getitemcount "ingred_dreugh_wax_01" < 1 )
         messagebox "no wax"
       ELSE
         IF ( player->getitemcount "_vdm_xy_imprint" > 0 )
           messagebox "Already got Imprint"
         ELSE
           player->removeitem, "ingred_dreugh_wax_01", 1
           player->additem, "_vdm_xy_imprint", 1
           messagebox "key imprint wax"
         EndIF
       EndIF
     EndIF
     set MessageOn to 0
   EndIF

EndIF

end
Man könnte es auch umschreiben, so dass die Tür im Script ständig mit "Lock, 1000" bombensicher versiegelt und erst entriegelt wird, wenn der Spieler einmal mit dem Schlüssel daher kommt.
 
  • Like
Reaktionen: VDMap
Hallo, brauch ma wieder Hilfe.. :)

Wie kann ich den "furn_dwrv_dynamo" Activator ohne Animation benutzen, und später wieder anstellen?
SkipAnim geht schon mal nicht.

Danke
 
Gar nicht - jedenfalls nicht mit Hausmitteln.

SkipAnim funktioniert nur bei Meshes mit Animation Groups. Das Drehen des Dynamos ist aber keine Animation Group, sondern eine permanente Rotation und hart in the Mesh eingebaut. Wenn du mit Blender animieren kannst, könntest du die Mesh umstricken, das ist allerdings keine triviale Sache, da du mit der Aktion die Partikel-Emitter zerstörst.

Da die dann nur schwer wieder zum Laufen zu bringen sind, solltest du davon Abstand nehmen. Ich selbst habe das vor langer Zeit mal für alle Dwemer Maschinen folgendermaßen umgangen:

Als Behelfslösung kannst du eine Kopie der Dynamo-Mesh erstellen und in der dann mit NifSkope sämtliche Animationen entfernen. Das ist allerdings auch nicht ganz ohne, z.B. müssen alle NiBSAnimationNodes durch normale NiNodes ersetzt werden, ohne die Struktur der Mesh zu verändern, heißt du wirst Transformationen manuell nachbauen und die Mesh komplett auseinandernehmen und wieder zusammensetzen müssen. Wenn das fertig ist, erstellst du zwei persistente Ingame Referenzen (z.B. Dynamo_active, und Dynamo_dead) und die kannst du dann nach Bedarf via Script auf einem Aktivator aktivieren bzw. deaktivieren, um ein Ein- und Ausschalten der Maschine zu faken.
 
  • Like
Reaktionen: VDMap
Hab es grad mit NifSkope probiert, sämtliche AnimationNodes in NiNodes konvertiert, und PartikelSystem gelöscht. War gar nicht so tricky :)
 
Guten Abend, hab hier ein Zergen Kurbel Skript editiert, leider funktioniert es nicht richtig. Status 1 funktioniert, bei 2 keine Reaktion. :confused:

Code:
begin _vdm_dwrv_doors_01

float timer
short start

if ( MenuMode == 1 )
    return
    ;don't run time in Menu Mode. Very bad.
endif

if ( OnActivate == 1)
    if ( "_vdm_dwemer_status" == 0 )
        Playsound "Dwemer Door Open"
        MessageBox "no power!" 
    endif
endif


if ( OnActivate == 1)
    if ( "_vdm_dwemer_status" == 1 )
    if ( start == 0 )
        set start to 1
        Playsound "Dwemer Door Open"
    endif
    endif
endif

if ( start == 0 )
    return
    ;if we have't started, stop here for speed
endif

if ( timer < 9 )
    if ( timer > 1 )
        if ( start == 1 )
            PlaySound "Door Stone Open"
            Set start to 2
        endif
    endif
    Rotate X 20
    ;above line rotates the crank itself
    "_vdm_dwrv_door_00"->Rotate Z -10
    "_vdm_dwrv_door_01"->Rotate Z 10
    ;above two lines open the doors.
    ;you may need to adjust the times or the rotate value.
    ;right now they open over 9 seconds to about 100 degrees.
endif

if ( timer > 14 )
    if ( start == 2 )
        PlaySound "Door Stone Open"
        Set start to 3
    endif
    "_vdm_dwrv_door_00"->Rotate Z 10
    "_vdm_dwrv_door_01"->Rotate Z -10
    ;these lines close the doors 14 seconds after you activate
    ;or 5 seconds after the doors are fully open
endif

if ( timer > 23 )
    set start to 0
    set timer to 0
    "_vdm_dwrv_door_00"->SetAngle Z 205.3
    "_vdm_dwrv_door_01"->SetAngle Z 295.3
    ;after 9 more seconds, the doors are back to their original position
    ;reset timer and start
endif

set timer to ( timer + GetSecondsPassed )
;above line increments the timer... should be last here outside if
;statements
;otherwise bad things can happen

end

Was ist da falsch? Zwei mal if ( OnActivate == 1) ?

Und noch was anderes.
Ich hab vier verschiedene persistent misc items, die gehören zu dem jeweilig richtigen Activator. Wenn man die aktiviert, und das richtige misc item im Inventar hat, wird das misc item entfernt, und ein anderer Activator und Light enabled sich am aktivierten Activator.., plus ein Static bewegt sich noch nach unten, oben etc..,funktioniert alles wie es sollte. Kommt auch fancy.. :)

Das Problem ist das wenn ich danach eine NPC anspreche bekomme ich immer die Meldung das mir die vier misc items schon wieder aus dem Inventar entfernt wurden..., was kann man da machen?
 
Die Variable "OnActivate" wird einmalig in jedem Frame auf 1 gesetzt, wenn eine Referenz wie auch immer geartet aktiviert wird. Nach dem Abfragen setzt das System sie auf 0 zurück. Wie du also schon selbst richtig erkannt hast, sollte man doppeltes Abfragen in einem Frame vermeiden, doch genau das tut dein Script. Somit sollte der Teil dann eher so geschrieben werden:

Code:
IF ( OnActivate == 1)
  IF ( start == 0 )
    IF ( "_vdm_dwemer_status" == 0 )
      Playsound "Dwemer Door Open"
      MessageBox "no power!"
    Else
      set start to 1
    EndIF
  EndIF
EndIF
Wie man sieht, habe ich ein PlaySound entfernt. Grund dafür ist, dass dieses sonst, falls der Strom aktiviert ist, beim Starten des Hebels immer doppelt aufgerufen würde.

Den Rest habe ich mir nicht angesehen, probier das erstmal aus.

Was das zweite Problem angeht - keine Ahnung. Ich würde mir Scripts für diese Activatoren mal genauer ansehen, da muss irgendein Bug drin sein. Oder die NPC hat irgendwo in einem Greet- oder Dialogresult irgendwas stehen, was da nicht hingehört. Ohne das Plugin zu sehen, kann ich da nur raten.
 
  • Like
Reaktionen: VDMap