ok Scripteffeckt wäre schlecht da der Skript ja auch bei verzauberten sachen funktionieren soll
Könntest du mir das mit den Quest Skript vieleicht genauer erklären
sry das ich so blöd frage aber hatte mit Quest´s noch nicht viel am Hut
Druckbare Version
ok Scripteffeckt wäre schlecht da der Skript ja auch bei verzauberten sachen funktionieren soll
Könntest du mir das mit den Quest Skript vieleicht genauer erklären
sry das ich so blöd frage aber hatte mit Quest´s noch nicht viel am Hut
Um ein QuestScript wirst du nie herumkommen. Entweder um den NPCs die Eigenschaft hinzuzufügen (macht übrigens keinen Unterschied, ob die Rüstung verzaubert wurde oder nicht), oder um den Effekt gleich dort zu erledigen.
QuestScripts unterscheiden sich von sonstigen Scripten nur darin, dass sie keine Referenz haben (sprich: wenn eine Funktion einen CallingActor benötigt muss der angegeben werden), sie mittels StopQuest/StartQuest gestoppt/gestartet werden können und mittels der (lokalen) Variable fQuestDelayTime kontrolliert wird, wie oft ein Gamemode/Menumode-Block läuft.
Ansonsten ist so ziemlich alles gleich: stelle den Typ auf Quest, erstelle eine neu Quest und füge dein Script als das Script der Quest ein. Hin und wieder ist es auch sinnvoll den Haken bei SetGameEnabled zu entfernen (hier wahrscheinlich nicht).
bedeuted das nicht das der skript dadurch Global wird
und das wen ich für jede rüssi ein passenden Skript erstelle das sehr an die performence
geht?
zu scripteffektstart : dadurch muss ich doch automatisch jede rüssi die den skript benutzt verzaubern was ja blöd währ wenn ich den skript für jede rüssi im Spiel benutzen will
Nö, nicht die Rüstung verzaubern, sondern den NPCs eine Eigenschaft (!= Verzauberung) hinzufügen die das entsprechende erledigt. ;)
Performance dürfte hauptsächlich dadurch beeinträchtigt werden, dass du immer jeden NPC neu durchgehen musst. Mehrere Rüstungen (lassen sich btw. auch in einem Script erledigen) machen da den Braten auch nicht mehr fett.
Scripte sind allgemein nicht so Performance-lastig, dass sollte also weniger das Problem sein.
Die umstehenden NPCs kannst du auf mehreren Wegen bekommen:
Zauber mit großer Reichweite auf den Spieler abfeuern (z.B. von einem Activator der vorher über dem Spieler platziert wird). Das Ziel in dem ScriptEffect (GetSelf) ist dann alles, was sich in der Reichweite befindet.
Mittels OBSE-Funktionen GetFirst/NextRef in einem Loop.
Alles muss in regelmäßigen Abständen überprüft werden, da die NPCs ja wandern.
ok wenn ich den skript in einen Questskript umwandeln will
sagt cs folgendes
scripterror "aaarmorbroken" on line 10
reference function "getcontainer" requieres explicit reference in quest script
getContainer funzt also nich Getself geht ine einem GameMode block ja auch net gibt sonst noch was das ich überprüfen kann
das mit den callingActor verstehe ich jetzt net so ganz ^^"
wie füge ich ein Activator über den Spieler ein ??
das mit den zauber ist iwie nich so toll wollte ja nicht immer ein dicken zauber wirken lassen (oder geht das alles auch automatisch ganz ohne visualen Effekten)
Edit: weiss jetzt aber net so ganz wie ich mehrere rüssies in einem skript erlediegen soll
Mäh, keine Lust mehr.
Hier eine Eigenschaft-Verteil-Quest aus einem meiner Mods:
Code:scn LPUSfEQuDistributionScript
;Global: short LPUSfEGlbEnableNPC ; set LPUSfEGlbEnableNPC to 0 if you want to deactivate the NPC-component of this Plugin
;Global: float LPUSfEGlfVersion ; Version of "Unarmored Skill for Everyone"
long lCount
long lNumber
float fQuestDelayTime
ref rCell
ref rNPC
ref rScript
Begin Gamemode
set rScript to LPUSfEQuDistributionScript
;------------------------------------------------------------------------
; Conditions
;------------------------------------------------------------------------
if ( LPUSfEGlfVersion == 0 ) || ( LPUSfEGlbEnableNPC == 0 ) || ( LPUSfEQuInitialization.iShutDown )
Return
endif
if ( rCell != ( Player.GetParentCell ) )
set rCell to ( Player.GetParentCell )
set lNumber to -1
endif
if ( lNumber != ( GetNumRefs 35 1 ) )
set lNumber to ( GetNumRefs 35 1 )
set lCount to 0
While ( lCount < lNumber )
if ( lCount )
set rNPC to ( GetNextRef )
else
set rNPC to ( GetFirstRef 35 1 )
endif
let lCount += 1
if ( rNPC.GetDead )
PrintD ( ASCIIToChar 2 ) + "LPUSfE (" + ( GetFormIDString rScript ) + "):" + ( ASCIIToChar 3 ) + " " + ( rNPC.GetName ) + " (" + ( rNPC.GetFormIDString ) + ") is dead.%r" + ( ASCIIToChar 2 ) + "LPUSfE (" + ( GetFormIDString rScript ) + "):" + ( ASCIIToChar 3 ) + " NPC " + ( ToString lCount ) + " / " + ( ToString lNumber )
elseif ( rNPC.GetIsReference Player )
PrintD ( ASCIIToChar 2 ) + "LPUSfE (" + ( GetFormIDString rScript ) + "):" + ( ASCIIToChar 3 ) + " " + ( rNPC.GetName ) + " (" + ( rNPC.GetFormIDString ) + ") is the Player.%r" + ( ASCIIToChar 2 ) + "LPUSfE (" + ( GetFormIDString rScript ) + "):" + ( ASCIIToChar 3 ) + " NPC " + ( ToString lCount ) + " / " + ( ToString lNumber )
elseif ( rNPC.HasSpell LPUSfEAbMain )
PrintD ( ASCIIToChar 2 ) + "LPUSfE (" + ( GetFormIDString rScript ) + "):" + ( ASCIIToChar 3 ) + " " + ( rNPC.GetName ) + " (" + ( rNPC.GetFormIDString ) + ") already has the Unarmored Skill.%r" + ( ASCIIToChar 2 ) + "LPUSfE (" + ( GetFormIDString rScript ) + "):" + ( ASCIIToChar 3 ) + " NPC " + ( ToString lCount ) + " / " + ( ToString lNumber )
else
rNPC.AddSpell LPUSfEAbMain
PrintD ( ASCIIToChar 2 ) + "LPUSfE (" + ( GetFormIDString rScript ) + "):" + ( ASCIIToChar 3 ) + " Added Unarmored Skill to " + ( rNPC.GetName ) + " (" + ( rNPC.GetFormIDString ) + ").%r" + ( ASCIIToChar 2 ) + "LPUSfE (" + ( GetFormIDString rScript ) + "):" + ( ASCIIToChar 3 ) + " NPC " + ( ToString lCount ) + " / " + ( ToString lNumber )
endif
Loop
PrintD ( ASCIIToChar 2 ) + "LPUSfE (" + ( GetFormIDString rScript ) + "):" + ( ASCIIToChar 3 ) + " Cell " + ( GetName rCell ) + " (" + ( GetFormIDString rCell ) + ": %q" + ( GetEditorID rCell ) + "%q) tested.%r" + ( ASCIIToChar 2 ) + "LPUSfE (" + ( GetFormIDString rScript ) + "):" + ( ASCIIToChar 3 ) + " NPCs: " + ( ToString lNumber )
endif
End
Begin Menumode
;------------------------------------------------------------------------
; Conditions
;------------------------------------------------------------------------
if ( LPUSfEGlfVersion == 0 ) || ( LPUSfEGlbEnableNPC == 0 ) || ( LPUSfEQuInitialization.iShutDown )
Return
endif
if ( IsPlayerMovingIntoNewSpace ) || ( rCell != ( Player.GetParentCell ) )
set rCell to ( Player.GetParentCell )
set lNumber to -1
endif
End
Der Effekt der Eigenschaft wäre dann folgender:
Code:scn aaarmorbrokenc
short next
short EquipDelay
long objecthealth
Begin ScriptEffectUpdate
if ( GetEquipped aamodiamelion ) && ( next == 0 )
if ( ( getEquippedCurrentHealth 2 ) / ( getObjectHealth aamodiamelion ) >= 0 ) && ( ( getEquippedCurrentHealth 2 ) / ( getObjectHealth aamodiamelion ) <= 0.75 )
message "Rüstung ist beschädigt!"
set next to 1
set objecthealth to ( getEquppedCurrentHealth 2 )
addItem aamodiamelionbroken 1
set EquipDelay to 1
endif
elseif next == 1
if EquipDelay >= 1
set EquipDelay to EquipDelay - 1
elseif EquipDelay == 0
set next to 0
UnEquipItem aamodiamelion
EquipItem aamodiamelionbroken
setEquippedCurrentHealth objecthealth 2
RemoveItem aamodiamelion 1
endif
endif
end
Mäh, kann ich verstehen :DZitat:
Mäh, keine Lust mehr.
o_ojetzt verstehe ich erst wie sowas aufgebaut ist
auf jedenfall großes danke für alle zeit und müh http://www.multimediaxis.de/images/s.../respekt_2.gif
2 kleine frage habe ich jedoch noch
ich müsste getFirstRef 69(Actor) 1
nehmen wen ich Player mit einbeziehen will richtig?
was ist Loop? ich vermute ma das ist das für while was endif füt if
//Edit
habe das jetzt so probiert
jetzt sagt er mir allerdingsPHP-Code:
scn aavictimsofbroken
long Count
long Number
float fQuestDelayTime
ref victim
ref Cell
begin GameMode
set fQuestDelayTime to 1
if ( Cell != ( Player.GetParentCell ) )
set Cell to ( Player.GetParentCell )
set Number to -1
endif
if ( Number != ( GetNumRefs 69 1 ) )
set Number to ( GetNumRefs 69 1 )
set Count to 0
While ( Count < Number )
if ( Count )
set victim to ( GetNextRef )
else
set victim to ( GetFirstRef 69 1 )
endif
set Count to Count +1
if victim.getEquippedObject 2 > 0
if getIsID aamodiamelion
victim.addSpell
elseif getIsID aamodiamelionbroken
victim.addSpell
endif
endif
loop
endif
end
reference function getIsID requires explicit reference in questSkript
sry das ich dich weiter belästige
Actor bedeutet NPCs & Kreaturen.
Wenn du den Spieler mit einbeziehen willst mach den einfach am Schluss, wenn der Rest schon durch ist. ;)
Die Fehlermeldung kommt, weil der nicht weiß für welche Referenz er GetIsID überprüfen soll. Für deine Zwecke sollte es ein einfaches == tun. ;)
Code:scn aavictimsofbroken
long Count
long Number
float fQuestDelayTime
ref victim
ref Object
ref Cell
begin GameMode
set fQuestDelayTime to 1
if ( Cell != ( Player.GetParentCell ) )
set Cell to ( Player.GetParentCell )
set Number to -1
endif
if ( Number != ( GetNumRefs 35 1 ) )
set Number to ( GetNumRefs 35 1 )
set Count to 0
While ( Count <= Number )
if ( Count )
set victim to ( GetNextRef )
elseif ( Count == Number )
set victim to Player
else
set victim to ( GetFirstRef 35 1 )
endif
set Count to Count + 1
if Eval ( Object := ( victim.getEquippedObject 2 ) )
if Object == aamodiamelion || Object == aamodiamelionbroken
victim.addSpell <ID>
endif
endif
loop
endif
end
ok leider passiert nichts
ich habe das folgendermaßen probiert
quest einstellung
priority 60
skript aavictimsofbroken (habe da aus if Object == aamodiamelion || Object == aamodiamelionbroken
if Object == aamodiamelion
victim.addspell aamodiamelionbrokenSP
elseif object == aamodiamelionbroken
viktim.addspell aamodiamelionhealthSP
endif
gemacht sollen ja 2 verschiedene Effekte auftreten sonst habe ich aber nichts geändert ;)
häkchen start game enable
zauber einstellung
type eigenschaft
häkchen Auto-calculate
Effects
effect Skript Effekt
range selbst
school Veränderung
skript aamodiamelionbrokenspell
häkchen Effect is hostile
alles nicht erwähnte habe ich nicht geändert (nur name u ID habe ich jetzt nicht immer angegeben)
muss in game eigendlich die eigenschaft da sichtbar werden wo z.B. anfälligkeit feuer etc steht
edit: ok bei quest hab ich dir Priority auf 0 gesetzt
fuktioniert allerdings immer noch nicht:(PHP-Code:
scn aavictimsofbroken
long Count
long Number
float fQuestDelayTime
ref victim
ref Object
ref Cell
begin GameMode
set fQuestDelayTime to 1
if ( Cell != ( Player.GetParentCell ) )
set Cell to ( Player.GetParentCell )
set Number to -1
endif
if ( Number != ( GetNumRefs 35 1 ) )
set Number to ( GetNumRefs 35 1 )
set Count to 0
while ( Count <= Number )
if ( Count )
set victim to ( GetNextRef )
elseif ( Count == Number )
set victim to Player
message "player hat object"
else
set victim to ( GetFirstRef 35 1 )
endif
set Count to Count + 1
if Eval ( Object := ( victim.getEquippedObject 2 ) )
if Object == aamodiamelion
victim.addSpell aamodiamelionbrokenSP
elseif Object == aamodiamelionbroken
victim.addSpell aamodiamelionhealthSP
endif
endif
Loop
endif
end
message taucht nur auf wenn kein NPC in der cell ist
in der ich bin
frage: was macht if (count)?
ok habe es hinbekommen
Alle Jahre wiederhttp://www.multimediaxis.de/images/s.../old/s_065.gif
so nach dem ja so ein Jahr vergangen ist habe ich mal meinen Skript wieder Ausgegraben.
Der sich im laufe der Zeit ein wenig verändert hat und jetzt so Aussieht.
Jetzt habe ich da 2 ProblemPHP-Code:
Scriptname aaTestcuirassa
short next
short EquipDelay
long objecthealth
ref Actor
ref britem
Begin GameMode
if Actor == 0
set Actor to GetContainer
elseif ( Actor.GetEquipped aaTestcuirass ) && ( next == 0 )
if getCurrentHealth / getObjectHealth >= 0 && getCurrentHealth / getObjectHealth <= 0.75
set next to 1
set objecthealth to getCurrentHealth
Actor.addItemNS aaTestcuirassb 1
Actor.addItemNS brTestcuirass1Splitter 1
set EquipDelay to 1
endif
elseif next == 1
if EquipDelay >= 1
set EquipDelay to EquipDelay - 1
elseif EquipDelay == 0
set next to 0
Actor.UnEquipItemNS aaTestcuirass
Actor.EquipItemNS aaTestcuirassb
Actor.setEquippedCurrentHealth objecthealth 2
Actor.Drop brTestcuirass1Splitter 1
set britem to brTestcuirass1Splitter
britem.moveto Actor 0,0,9
removeMe
endif
elseif Actor != 0
set Actor to 0
endif
end
1. Script wird wenn ich im Spiel bin und denn lade. (nicht wenn ich Obl gerade gestartet habe ) öfters mal ignoriert (nicht immer aber doch recht oft).
2. nachdem ich die sache mit den Drop eingefügt habe. löst der Script ein CTD in Exterior Bereichen aus, im interior funktioniert es so aber.
Ich nehme an brTestcuirass1Splitter ist ein base object id (sonst würde Drop auch nicht funktionieren).
Dadurch, dass duverwendest benötigst du aber die Referenz.Code:set britem to brTestcuirass1Splitter
britem.moveto Actor 0,0,9
Die einzige Möglichkeit diese zu bekommen wäre GetFirst/NextRef. Du solltest allerdings (mindestens) einen Frame warten, bis du sie auch verwendest.
Das erklärt zwar nicht den CTD, allerdings warum das Script nach dem ersten Durchlauf nicht mehr funktioniert (wird gestoppt, bis Oblivion neu gestartet wird).
habe mich mal im cswiki schlau gemacht da steht ja irgendwas von While Loop Schleifehttp://www.multimediaxis.de/images/s...1/nixweiss.gif, sorry wegen meiner Unwissenheit aber ich habe keine ahnung wie die funktioniert.:oZitat:
Die einzige Möglichkeit diese zu bekommen wäre GetFirst/NextRef. Du solltest allerdings (mindestens) einen Frame warten, bis du sie auch verwendest.
Jep ein Miscitem um´s Genauer zu sagenZitat:
Ich nehme an brTestcuirass1Splitter ist ein base object id
das der Script nach dem laden Gerne nicht funktioniert war schon bevor ich die sache mit Drop Reingenommen habe.Zitat:
Das erklärt zwar nicht den CTD, allerdings warum das Script nach dem ersten Durchlauf nicht mehr funktioniert (wird gestoppt, bis Oblivion neu gestartet wird).
Sprich als der Script noch so aussahPHP-Code:
Scriptname aaTestcuirassa
short next
short EquipDelay
long objecthealth
ref Actor
ref britem
Begin GameMode
if Actor == 0
set Actor to GetContainer
elseif ( Actor.GetEquipped aaTestcuirass ) && ( next == 0 )
if getCurrentHealth / getObjectHealth >= 0 && getCurrentHealth / getObjectHealth <= 0.75
set next to 1
set objecthealth to getCurrentHealth
Actor.addItemNS aaTestcuirassb 1
set EquipDelay to 1
endif
elseif next == 1
if EquipDelay >= 1
set EquipDelay to EquipDelay - 1
elseif EquipDelay == 0
set next to 0
Actor.UnEquipItemNS aaTestcuirass
Actor.EquipItemNS aaTestcuirassb
Actor.setEquippedCurrentHealth objecthealth 2
removeMe
endif
elseif Actor != 0
set Actor to 0
endif
end
Bei einer While-Schleife wird einfach alles zwischen dem While und Loop (angenommen Break/Continue wird nicht verwendet) so oft wiederholt, bis die While-Bedingung nicht mehr zutrifft. In dem Wiki-Beispiel ist das so lange der Fall, wie GetNextRef einen Wert != 0 ausgibt.
Warum das Script sonst anhält kann ich nur vermuten. Mein Ansatz wäre jetzt, dass ein unequip & equip, die den gleichen Slot betreffen nicht im selben Frame stehen dürfen. Ich würde dazu einfach das unequip weglassen.
Ich würde dir allerdings empfehlen ein paar Print(C)-Befehle einzufügen. Damit kannst du kontrollieren, wie weit das Script durchläuft. Der Fehler ist dann auf jeden Fall danach.
Habe mal versucht so ein While Loop einzubauen
Das war jetzt mein Erster versuch. Führt allerdings nur zum CTD :(PHP-Code:
Scriptname aaTestcuirassa
short next
short EquipDelay
long objecthealth
ref Actor
ref britem
Begin GameMode
if Actor == 0
set Actor to GetContainer
elseif ( Actor.GetEquipped aaTestcuirass ) && ( next == 0 )
if getCurrentHealth / getObjectHealth >= 0 && getCurrentHealth / getObjectHealth <= 0.75
set next to 1
set objecthealth to getCurrentHealth
Actor.addItemNS aaTestcuirassb 1
Actor.addItemNS brTestcuirass1Splitter 1
Actor.Drop brTestcuirass1Splitter 1
set britem to GetFirstRef 27 1
While ( britem != brTestCuirass1Splitter )
set britem to GetNextRef
Loop
set EquipDelay to 1
endif
elseif next == 1
if EquipDelay >= 1
set EquipDelay to EquipDelay - 1
elseif EquipDelay == 0
set next to 0
Actor.UnEquipItemNS aaTestcuirass
Actor.EquipItemNS aaTestcuirassb
Actor.setEquippedCurrentHealth objecthealth 2
britem.moveto Actor 0,0,150
removeMe
endif
elseif Actor != 0
set Actor to 0
endif
end
auf der CS Wiki steht ja irgendwas von ; do something with pDoor innerhalb der While Loop Schleife heißt das ich muss da jetzt noch was anderes machen als nur GetNextRef :confused:
Da britem eine Referenz ist (GetFirst/NextRef gibt nur Referenzen aus) wird es nie gleich dem base object brTestCuirass1Splitter sein. Versuch mal folgenden While-Loop:
Code:While ( britem.GetIsID brTestCuirass1Splitter )
Was den CTD betrifft:
Konsole lässt sich da ja schwer überprüfen, von daher musst du auf den (undokumentierten) Befehl dbg_echo zurückgreifen. Der verwendet die gleiche Syntax wie PrintC, schreibt den Inhalt aber nicht nur in die Konsole, sondern auch in die Datei obse.log im Oblivion-Verzeichnis.
Der Befehl sollte aber nur zum De-bugging (Fehlersuche) verwendet werden und aus der Release-Version wieder gelöscht werden.
Ok jetzt gibt es kein CTD mehr (auch nicht im Exterior 8))
allerdings Passieren jetzt andere Merkwürdige dinge o_O
1. Der Bildschirm wird für ein Bruchteil einer Sekunde Schwarz
2. Der Gegner Steckt danach die waffe weg und Zieht sie wieder erneut
3. Die Musik wird zurück gesetzt
und 4. bei 3 meiner 8 Versuche wurde das Wetter nach dem Blackscreen geändert:eek:
und Moveto scheint nicht zu Funktionieren (Der Gegenstand brTestcuirass1Splitter erscheint vor der Brust von Player und nicht ein Stück über´m Kopf so wie es bei moveto 0,0,150 ja eigendlich sein soll)
Hier der Script
und die Obse.logPHP-Code:
Scriptname aaTestcuirassa
short next
short EquipDelay
long objecthealth
ref Actor
ref britem
Begin GameMode
if Actor == 0
set Actor to GetContainer
dbg_echo "Actor to container frame 1", Actor
elseif ( Actor.GetEquipped aaTestcuirass ) && ( next == 0 )
if getCurrentHealth / getObjectHealth >= 0 && getCurrentHealth / getObjectHealth <= 0.75
set next to 1
set objecthealth to getCurrentHealth
Actor.addItemNS aaTestcuirassb 1
dbg_echo "if frame 2", Objecthealth
Actor.addItemNS brTestcuirass1Splitter 1
Actor.Drop brTestcuirass1Splitter 1
set britem to GetFirstRef 27 1
While ( britem.GetIsID brTestcuirass1Splitter )
set britem to GetNextRef
dbg_echo "While", britem
Loop
set EquipDelay to 1
endif
elseif next == 1
if EquipDelay >= 1
dbg_echo "EquipDelay frame 3", EquipDelay
set EquipDelay to EquipDelay - 1
elseif EquipDelay == 0
set next to 0
Actor.UnEquipItemNS aaTestcuirass
Actor.EquipItemNS aaTestcuirassb
Actor.setEquippedCurrentHealth objecthealth 2
britem.moveto Actor 0,0,150
dbg_echo " move to frame 4", britem
removeMe
endif
elseif Actor != 0
set Actor to 0
dbg_echo "Actor Reset frame 5"
endif
end
Zitat:
if frame 2
While
Error in script 42001ca0
Attempting to call a function on a NULL reference or base object
File: Brokenarmor.esp Offset: 0x0131 Command: <unknown>
Error in script 42001ca0
An expression failed to evaluate to a valid result
File: Brokenarmor.esp Offset: 0x0131 Command: <unknown>
EquipDelay frame 3
Actor Reset frame 5
Actor to container frame 1
Actor Reset frame 5
Actor to container frame 1
Actor Reset frame 5
Actor to container frame 1
Actor Reset frame 5
Actor to container frame 1
Actor Reset frame 5
Actor to container frame 1
Actor Reset frame 5
...usw...
Das weist auf einen Syntax-Fehler hin: Eine Funktion, die einen best. Wert benötigt wird mit einer Null-Referenz/base object aufgerufen.Zitat:
Error in script 42001ca0
Attempting to call a function on a NULL reference or base object
File: Brokenarmor.esp Offset: 0x0131 Command: <unknown>
Error in script 42001ca0
An expression failed to evaluate to a valid result
File: Brokenarmor.esp Offset: 0x0131 Command: <unknown>
Probier mal den ScriptViewer aus, da kannst du sehen, was die Offset-Werte bedeuten (stehen für eine Position im Script).
Ich vermute, dass es die While-Schleife selbst ist. Das passiert aber nur, wenn keiner der entsprechenden Werte brTestcuirass1Splitter als Base Object hat. Sicher, dass du den richtigen Filter bei GetFirstRef verwendest?