Skriptthread zum Creation Kit

Eldarie

Hausvetter
Hier könnt ihr Skripts vorstellen oder nachfragen, wenn ihr ein Skript benötigt.

Skriptanfrage:

  • Was soll durch das Skript bewirkt werden?
  • An welches Mesh wird es angehängt? (Optional)

Skriptvorstellung:

  • Autor
  • Was bewirkt das Skript?
  • Für welche Art von Typ (Creature, Activator, etc.) soll das Script sein
  • Wurde das Script getestet?
Viel Spaß beim Skripten. :)
 
Scriptbefehle zum setzen der Respwan- und Essential-Flag

Der Titel sagt eigentlich schon alles: Wie lauten die Scriptbefehle für das setzen der Respawn- und Essential-Flag? Vermutlich geht das nur mit SKSE, ist aber auch egal, solang jemand die Befehle kennt.
 
Das ist das Script:
Code:
Scriptname DrReEsEssential   

Event OnEffectStart(Actor akTarget)
	if (akTarget.IsEssential())
		akTarget.SetEssential(False)
		Debug.Notification("Dieser NPC ist nicht mehr Essential")
	else
		akTarget.SetEssential()
		Debug.Notification("Dieser NPC ist nun Essential")
	endif
endEvent
Bitte nicht schlagen, ist mein erstes :oops:
 
Hmmm ich erkenne da gerade überhaupt keinen Fehler...
Du kannst aber mal versuchen False komplett klein zu schreiben.
Anders kann ich mir dort keinen Fehler erklären. Es kann bspw. nicht am Objekt akTarget liegen, da die Methode IsEssential() ja funktioniert und die Methode ja zur selben Klasse wie SetEssential gehört. Außerdem wurde deine Fehlermeldung auch nirgends dokumentiert (http://www.creationkit.com/Papyrus_Runtime_Errors). Aber wie auch immer versuchs mit false statt False.
 
Nein, funktioniert leider immer noch nicht, hier die volle Meldung:
Starting 1 compile threads for 1 files...
Compiling "DrReEsEssential"...
c:\program files (x86)\steam\steamapps\common\skyrim\Data\Scripts\Source\DrReEsEssential.psc(5,11): SetEssential is not a function or does not exist
c:\program files (x86)\steam\steamapps\common\skyrim\Data\Scripts\Source\DrReEsEssential.psc(8,11): SetEssential is not a function or does not exist
No output generated for DrReEsEssential, compilation failed.

Batch compile of 1 files finished. 0 succeeded, 1 failed.
Failed on DrReEsEssential
 
Solche Meldungen hatte ich auch bei meinem ersten Script, das einen hübschen Imagespace-Modfier als Ersatz für ENB per Quest startet. Nach mehrmaligem Neustart des Quest-Dialogs, gutem zureden und wiederholtem Neuspeichern des Scripts klappte es plötzlich. Ich schätze, dass manche Scripte zuerst im System registriert werden müssen, bevor man auf sie zugreifen kann.
Und den Mod möchte ich jetzt ausfeilen, um zwar geht es darum, per Message-Box ein verschachteltes Menu zu haben, indem man Sättigung, Kontrast, Helligkeit, DoF, Bloom und Farbverschiebungen wählen kann.
In Fallout gab es da super Beispiele auf der GECK-Seite, sowas könnte ich jetzt auch brauchen, denn in den GECKs war ein dreifach verschachteltes Menu so in etwa das komplexeste, was man tun konnte.
 
Ich wollte mich in den Skripteditor einarbeiten aber Ich bin mit meinem kleinen Skript schon gescheitert. Ich hoffe es lag an mir und nicht an evtl fehlenden Möglichkeiten sowas umzusetzen.

Was soll das Skript machen?

Verzauberte Waffen von NPCs (in der Umgebung/im Kampf) oder dem Spieler automatisch aufladen (die Verzauberungspunkte auf 100% setzen), entweder bei Auslösung eines Events aka "OnHit" o.ä. oder jedes xte Zeitintervall.

Was habe ich bisher getan:

- Mich ins CK Wiki eingelesen
- Notepad++ Papyrus fähig gemacht
- die als zur Verfügung stehenden und relevanten psc-Scripte durchgeschaut

Das Problem liegt weniger im Syntax/Aufbau, der ja sehr an Java bzw. C++ erinnert sondern eher an nachfolgendenden zwei Problemen

Probleme:

1. Im Spiel selbst und im ConstructionKit besitzen Waffen Aufladungen. Um auf diese zuzugreifen bzw. den Status dieser abzufragen habe ich nach Funktionen gesucht, aber keine gefunden. "Weapons"- und "Forms"-Script besitzen dazu keine get/set-Funktion und auch in den anderen Skripten konnte ich nichts finden, lediglich verschiedene Wege um an die Waffe selbst zu kommen (evtl. über das OnHit-Event oder über die Abfrage "GeEquippedWeapon" beim Actor-Skript. Das führt jedoch gleich zum zweiten Problem

2. Wie erstelle ich ein globales Skript, also ein Skript welches ich nicht an spezifische Referenzen im Editor (sei es Waffen oder Actors) dranhängen muss. Denn es ist nicht praktikabel dass manuell an jegliche Actors/Waffen dranzuhängen, da das a) zu umständlich ist und lange dauern würde und b) nicht nützlich ist denn vllt erstellt man selbst oder andere neue Waffen oder NPCs für die das dann ja nicht gilt. Das einzige was ich gefunden habe sind Funktionen die periodisch dauerhaft oder einmalig eine Funktion ausführen, aber das macht sie ja nicht global.
 
Suche ein Script welches die Schnellreisefunktion abschaltet oder aber kostenpflichtig macht. (ka wo das rein müsste) und ein Script welches die Wartefunktion abschaltet oder aber dafür sorgt, dass wartende spieler von einem tödlichem Feind überfallen werden.
 
Suche ein Script welches die Schnellreisefunktion abschaltet oder aber kostenpflichtig macht. (ka wo das rein müsste) und ein Script welches die Wartefunktion abschaltet oder aber dafür sorgt, dass wartende spieler von einem tödlichem Feind überfallen werden.
Guck mal für schnellreise abschaltung hier.
http://www.creationkit.com/EnableFastTravel
Zur zweiten Frage: mit dieser Methode sollte das gehen.
http://www.creationkit.com/SetInChargen_-_Game
1. Im Spiel selbst und im ConstructionKit
Es heißt nun CreationKit ;)
(...) Funktionen (...)
Da alle "Funktionen" in Papyrus einer Klasse zugeordnet sind spricht man von Methoden statt von Funktionen.

Um auf diese zuzugreifen bzw. den Status dieser abzufragen habe ich nach gesucht, aber keine gefunden. "Weapons"- und "Forms"-Script besitzen dazu keine get/set-Funktion und auch in den anderen Skripten konnte ich nichts finden, lediglich verschiedene Wege um an die Waffe selbst zu kommen (evtl. über das OnHit-Event oder über die Abfrage "GeEquippedWeapon" beim Actor-Skript. Das führt jedoch gleich zum zweiten Problem
Gibt es soweit ich weiß nichts. Zumindest besitzt die Klasse Weapon keine derartige Methode. (http://www.creationkit.com/Weapon_Script)
2. Wie erstelle ich ein globales Skript, also ein Skript welches ich nicht an spezifische Referenzen im Editor (sei es Waffen oder Actors) dranhängen muss. Denn es ist nicht praktikabel dass manuell an jegliche Actors/Waffen dranzuhängen, da das a) zu umständlich ist und lange dauern würde und b) nicht nützlich ist denn vllt erstellt man selbst oder andere neue Waffen oder NPCs für die das dann ja nicht gilt. Das einzige was ich gefunden habe sind Funktionen die periodisch dauerhaft oder einmalig eine Funktion ausführen, aber das macht sie ja nicht global.
Wenn ich dich richtig verstehe möchtest du ein Skript haben was immer und überall läuft. Ich kann dir leider nur sagen wie es im CS ging. Da musste man einfach dem Skript als Quest Skript deklarieren und einer Quest zuordnen.

 
Zuletzt bearbeitet:
Finde die Phase immer interessant, wenn man das erste Mal ein neues Script in das Spiel pastet, hofft, dass man das zum Kompilieren kriegt und dass es im Spiel auch läuft.

Hier also mal meine zwei Rumpfscripte, die Imagespace Modifier aus einem Buch wählbar machen sollen.

Scriptname DRWEffectsQuestScript extends Quest
Code:
; DOF-Einstellungen
ImageSpaceModifier[] DRWImadDof = new ImageSpaceModifier[6]
DRWImadDof[0] = DRWImadDof0
DRWImadDof[1] = DRWImadDof1
DRWImadDof[2] = DRWImadDof2
DRWImadDof[3] = DRWImadDof3
DRWImadDof[4] = DRWImadDof4
DRWImadDof[5] = DRWImadDof5

int dofIndex = 0
bool dofEnabled = true
int property DofLevel
  int function get()
	if dofEnabled == false
		return 0
	else
		return dofIndex + 1
	endif
  endFunction
endProperty

; DoF-Methoden
function ApplyDof (int fxIndex)
	dofIndex = fxIndex
	dofEnabled = true
	applyEffect(DRWImadDof, dofIndex)
endfunction
function EnableDof ()
	dofEnabled = true
	applyEffect(DRWImadDof, dofIndex)
endfunction
function DisableDof ()
	dofEnabled = false
	clearEffect(DRWImadDof)
endfunction

; Utility-Funktionen
; Wendet einen Effekt an und verwirft den letzten des Bereichs
function applyEffect (ImageSpaceModifier[] objects, int fxIndex)
	clearEffect(objects)
	objects[fxIndex].Apply()
endfunction

; Deaktiviert alle Effekte eines Bereichs
function clearEffect(ImageSpaceModifier[] objects)
   int currentElement = 0
   while (currentElement < objects.Length)
     objects[currentElement].Remove()
     currentElement += 1
   endwhile
endfunction

Scriptname DRWEffectsControllerScript extends ObjectReference

Code:
Book Property MySelf auto
Quest Property DRWEffectsQuest auto
Message Property DRWEffectsMsgMain auto
Message Property DRWEffectsMsgSaturation auto
Message Property DRWEffectsMsgColors auto
Message Property DRWEffectsMsgBloom auto
Message Property DRWEffectsMsgDof auto
Message Property DRWEffectsMsgBrightness auto
Message Property DRWEffectsMsgContrast auto


Function ReadMySelf(bool fromWorld)
    int    dofLevel = 0
    int dofSelection = DRWEffectsMsgDof.Show(DRWEffectsQuest.DofLevel)

    if(dofSelection == 0)
        ; Return
    elseif (dofSelection == 1)
        ; Effekt deaktivieren
        DRWEffectsQuest.DisableDof()
    elseif (dofSelection > 1 && dofSelection < 7)
        ; Effekt aktivieren
        dofLevel = dofSelection - 2
        DRWEffectsQuest.ApplyDof(dofSelection)    
    else
        ; Return
    endif
EndFunction


Event OnEquipped(Actor reader)
    if (reader != Game.GetPlayer())
        return
    endif
    Utility.WaitMenuMode(2.0)
    ReadMySelf(false)
EndEvent

Event OnActivate(ObjectReference reader)
    if (reader != Game.GetPlayer() || IsActivationBlocked())
        return
    endif
    Utility.WaitMenuMode(2.0)
    ReadMySelf(true)
EndEvent

Wie man vielleicht sieht, ist das Script darauf ausgerichtet, in einer späteren Version um haufenweise Optionen in verschachtelten Menus erweitert zu werden, z.B. dass Sättigung unabhängig von Dof eingestellt werden kann.
Aber für Testzwecke und um den Mod in einer ersten Version in vernünftiger Frist online bringen zu können, mache ich mal ein einfaches flaches Menu.
 
Zuletzt bearbeitet:
Es sieht so aus, wie wenn das meiste jetzt funktionieren würde. Buch wird hinzugefügt, beim Öffnen erscheint die Messagebox und wenn ich drauf klicke wird etwas geändert.


Scriptname DRWEffectsQuestScript extends Quest
Code:
Actor Property Player  Auto  
ImageSpaceModifier[] Property DRWImadDof  Auto
Book Property DRWEffectsBookController  Auto
GlobalVariable Property DRWEffectsDofLevel  Auto  
GlobalVariable Property DRWEffectsDofEnabled Auto

; DoF-Methoden
function ApplyDof (int fxIndex)
    DRWEffectsDofLevel.SetValueInt(fixRange(fxIndex, 9))
    DRWEffectsDofEnabled.SetValueInt(1)
    applyEffect(DRWImadDof, DRWEffectsDofLevel.GetValueInt())
endfunction
function EnableDof ()
    DRWEffectsDofEnabled.SetValueInt(1)
    applyEffect(DRWImadDof, DRWEffectsDofLevel.GetValueInt())
endfunction
function DisableDof ()
    DRWEffectsDofEnabled.SetValueInt(0)
    clearEffect(DRWImadDof)
endfunction

; Utility-Funktionen
; Wendet einen Effekt an und verwirft den letzten des Bereichs
function applyEffect (ImageSpaceModifier[] objects, int fxIndex)
    clearEffect(objects)
    objects[fxIndex].Apply()
endfunction

; Deaktiviert alle Effekte eines Bereichs
function clearEffect(ImageSpaceModifier[] objects)
   int currentElement = 0
   while (currentElement < objects.Length)
     objects[currentElement].Remove()
     currentElement += 1
   endwhile
endfunction

; Begrenzt Input fuer Arrays
int function fixRange(int indexNumber, int maxRange)
    if (indexNumber < 0)
        return 0
    elseif (indexNumber > maxRange)
        return maxRange
    endif
    return indexNumber
endfunction

; Quest Init
Event OnInit ()
    Utility.Wait(5)
    Player = Game.GetPlayer()
    if (Player.GetItemCount(DRWEffectsBookController) == 0)
        Player.AddItem(DRWEffectsBookController)
    endIf
     EnableDof()
EndEvent

Scriptname DRWEffectsControllerScript extends ObjectReference
Code:
Book Property MySelf  Auto
GlobalVariable Property DRWEffectsDofLevel  Auto  
GlobalVariable Property DRWEffectsDofEnabled Auto
Message Property DRWEffectsMsgDof  Auto
Message Property DRWEffectsMsgMain Auto
Message Property DRWEffectsMsgSaturation Auto
Message Property DRWEffectsMsgColors Auto
Message Property DRWEffectsMsgBloom Auto
Message Property DRWEffectsMsgBrightness Auto
Message Property DRWEffectsMsgContrast Auto
DRWEffectsQuestScript Property EffectQuest  Auto

Function ReadMySelf(bool fromWorld)
    int    dofLevel = DRWEffectsDofLevel.GetValueInt()
    int dofSelection = DRWEffectsMsgDof.Show(dofLevel + 1)

    if(dofSelection == 0)
        ; Return
    elseif (dofSelection == 1)
        ; Effekt deaktivieren
        EffectQuest.DisableDof()
        ReadMySelf(fromWorld)
    elseif (dofSelection == 2)
        ; Effekt aktivieren
        EffectQuest.EnableDof()
        ReadMySelf(fromWorld)
    elseif (dofSelection == 3)
        ; Effekt verringern
        dofLevel -= 1
        EffectQuest.ApplyDof(dofLevel)
        ReadMySelf(fromWorld)
    elseif (dofSelection == 4)
        ; Effekt vergroessern
        dofLevel += 1
        EffectQuest.ApplyDof(dofLevel)
        ReadMySelf(fromWorld)
    else
        ; Return
    endif
EndFunction

Event OnEquipped(Actor reader)
    if (reader != Game.GetPlayer())
        return
    endif
    Utility.WaitMenuMode(2.0)
    ReadMySelf(false)
EndEvent

Event OnActivate(ObjectReference reader)
    if (reader != Game.GetPlayer() || IsActivationBlocked())
        return
    endif
    Utility.WaitMenuMode(2.0)
    ReadMySelf(true)
EndEvent

Jetzt habe ich aber den Verdacht, dass es da noch Probleme gibt.

Kann es sein, dass in dem System nur drei Buttons angezeigt werden können? Ich hoffe nicht, dass das wirklich eine Beschränkung ist.

Kann es sein, dass GlobalValue.SetValueInt(x) nicht einen Wert setzt oder GlobalValue.GetValueInt() nicht die geänderte Zahl holt?

Funktioniert das eigentlich nicht, dass man mit einer Button-Condition QuestVariabeln abfrufen kann? Ich kann zwar die Quest wählen, aber keine Property abrufen. Das ist ja auch der Grund, wieso ich mit den Globals gebastelt habe, damit ich Conditions setzen kann.

Übrigens: das Spiel ist schon ein graues Entlein, wenn man sich mal an ENB gewöhnt hat, mir kommen die Herbstwälder, die ich vorher immer so hübsch gefunden habe, nur noch reizlos vor.
 

Anhänge

  • TESV-303.jpg
    TESV-303.jpg
    156,5 KB · Aufrufe: 540
  • TESV-304.jpg
    TESV-304.jpg
    163,3 KB · Aufrufe: 509
  • TESV-305.jpg
    TESV-305.jpg
    197,9 KB · Aufrufe: 484
  • TESV-306.jpg
    TESV-306.jpg
    111,7 KB · Aufrufe: 568
Zuletzt bearbeitet:
Kann es sein, dass es Probleme mit rekursiv aufgerufenen Methoden gibt? Ich habe das Problem, dass die Globals nicht geupdatet werden, obwohl jeder Klick auf Filter+ die Global um 1 erhöhen sollte.

Code:
Function ReadMySelf(bool fromWorld)
    int    dofLevel = DRWEffectsDofLevel.GetValueInt()
    int dofEnabled = DRWEffectsDofEnabled.GetValueInt()
    int dofSelection = DRWEffectsMsgDof.Show(dofLevel + 1, dofEnabled)

    if(dofSelection == 0)
        ; Return
    elseif (dofSelection == 1)
        ; Effekt deaktivieren
        EffectQuest.DisableDof()
        ReadMySelf(fromWorld)
    elseif (dofSelection == 2)
        ; Effekt aktivieren
        EffectQuest.EnableDof()
        ReadMySelf(fromWorld)
    elseif (dofSelection == 3)
        ; Effekt verringern
        dofLevel -= 1
        EffectQuest.ApplyDof(dofLevel)
        ReadMySelf(fromWorld)
    elseif (dofSelection == 4)
        ; Effekt vergroessern
        dofLevel += 1
        EffectQuest.ApplyDof(dofLevel)
        ReadMySelf(fromWorld)
    else
        ; Return
    endif
EndFunction

Es gibt da einen Beitrag auf der Creation Kit-Seite zu Threading. Könnte das was mit dem Problem zu tun haben?

Der Grund, wieso ich nicht mit eingebauten Zählern im Quest-Script arbeite, die wahrscheinlich Thread-sicher wären, ist eben der, dass ich per Condition auf den Buttons keine QuestVariable aufrufen kann. Das ist sehr wahrscheinlich ein Bug im CK, denn es kommt jeweils eine Fehlermeldung, dass Definition X für die Dialog-Box fehlt.

Edit:
-----------------
Habe mal das Controller-Script umgeschrieben, sodass es mit internen Variablen arbeitet und ja, so wird alles korrrekt hochgezählt. Nur: wenn ich das Buch öffne, werden wieder die Default-Werte der Globals eingelesen, es ist wie wenn SetValutInt(x) keinerlei Auswirkungen hätte. Die Global hat den richtigen Daten-Typ Int und ist keine Konstante.
Im Quest-Script:
Code:
function ApplyDof (int fxIndex)
    DRWEffectsDofLevel.SetValueInt(fixRange(fxIndex, 9))
    DRWEffectsDofEnabled.SetValueInt(1)
    applyEffect(DRWImadDof, DRWEffectsDofLevel.GetValueInt())
endfunction

Wenn der Wert für fxIndex richtig hochgezählt wird und das wird es, dann müsste beim nächsten Mal auf jeden Fall eine geänderte Global eingelesen werden, wird es aber nicht.
 
Zuletzt bearbeitet:
LichtschalterScript die Papyrus-Edition

Ahoi, Leute. Kann mir mal einer schnell sagen, wie man z.B. einen Lichtschalter in Papyrus scriptet?
Da ist ja alles ein bisschen anders und da "Find Text" bei Scripten irgendwie nicht funktioniert, kann ich auch nicht in bestehenden Scripten nach Ähnlichkeiten suchen.

Intention: Aktivierung von Activator "enabled" ein (initally disabled) Objekt (wie z.B. eine Lichtquelle); nochmalige Aktivierung schaltet wieder ab.

Also mit der alten Scriptsprache aus Morrowind, hätte ich das so ausgedrückt:

Code:
Start XXXX

short state

if (OnActivate == 1)
  if state == 1
    disable [Objektreferenz]
    set state to 0
  else
    enable [Objektreferenz]
    set state to 1
  endif
endif

End

Kann mir das bitte jemand kurz in Papyrus übersetzen? :oops:
 
Hallo

kann mir jemand sagen wie ein Script aussehen müsste das dem Spieler beim Anziehen eines Ringes einen bestimmten Perk gibt
ich hab ein bischen rumprobiert, habs aber nicht geschafft

Danke
 
Zuletzt bearbeitet:
@Zipacna: Probiere es mal hiermit. Das/der (?) Property ist dann immer das Licht, das der Activator aktivieren soll.

Code:
ScriptName <ScriptNameEinfügen> extends ObjectReference

ObjectReference Property Light

Event OnActivate(ObjectReference akActor)

if(light.isdisabled())
   light.enable()
else
   light.disable()
endif

EndEvent

EndProperty

@Draconis: Das OnUpdate-Event sollte das sein.

@adinsx: Auf den Ring:

Code:
ScriptName <ScriptNameEinfügen> Extends ObjectReference

Event OnEquipped(Actor akActor)
  if(akActor == game.getplayer())
    akActor.addperk(<PerkName>)
  endif
EndEvent

Event OnUnEquipped(Actor akActor)
  if(akActor == game.getplayer())
    akActor.removeperk(<PerkName>)
  endif
EndEvent




Fehler können überall enthalten sein, ich arbeite mich selbst noch in die Skriptsprache ein.
 
Danke
ich bekomme immerhin jetzt weniger Fehlermeldungen als vorher. Allerdings bekomme ich immer wieder diesen Fehler angezeigt:

Starting 1 compile threads for 1 files...
Compiling "zoomscriptleon1"...
c:\program files (x86)\steam\steamapps\common\skyrim\Data\Scripts\Source\temp\zoomscriptleon1.psc(5,20): variable EagleEye30 is undefined
c:\program files (x86)\steam\steamapps\common\skyrim\Data\Scripts\Source\temp\zoomscriptleon1.psc(11,23): variable EagleEye30 is undefined
No output generated for zoomscriptleon1, compilation failed.

Batch compile of 1 files finished. 0 succeeded, 1 failed.
Failed on zoomscriptleon1