Construction Set Skriptthread zum Construction Set

....................
Charakter der Blocken noch nicht so hoch hat, schau wie viele Angriffe es dauert bis der Schild kaputt ist, und rechne aus wie viel Health der Schild im Schnitt pro Treffer verloren hat. Dann nimm das als feste Punktzahl die ein Schild pro Block verlieren sollte und modifizier es evtl. noch mit dem Level des Charakters, da höherstufige Chars im Spiel auch auf härtere Gegner treffen die mehr austeilen können. Auf der anderen Seite kann man natürlich auch mit einem festen Wert arbeiten, da hochstufige Chars ja i.d.R. auch besser im Blocken sein sollten und damit den Schild nicht so sehr beschädigen..............

Interessanter Gedankengang. Soweit dachte ich garnicht. Das scheint mir hochkompliziert. keine Ahnung wie das abgefragt werden könnte. Erst mal die Grundabfrage überhaupt hinbekommen. ich weiss nicht mal ob die Engine das bevor der Skill so bescheuert gesetzt wird vorher so gamacht hat.


Hier das funktionierende Zwischenerbgebnis
PHP:
Das Script liegt auf beliebigen Gegenstand im Inventar.

scn A0ItemBlockingDamage

float fWeaponHealthBasis
float fWeaponHealth
float fSchaden
short sTreffer
short sDamage


;===================================================
BEGIN GAMEMODE

If player.IsAnimGroupPlaying BlockHit && sTreffer <1
		
set fWeaponHealthBasis to player.getEquippedCurrentHealth 13
		
printToConsole "Schildwert = %.0f"fWeaponHealthBasis
endif


If player.IsAnimGroupPlaying BlockHit && sTreffer <12
	set fWeaponHealth to player.getEquippedCurrentHealth 13 		
	set sTreffer to sTreffer+1
printToConsole "Trefferzähler = %.0f"sTreffer

	;2 Treffer sind erfolgt
	if sTreffer >5 && sDamage !=1
	set sDamage to 1
	endif			

	;4 Treffer sind erfolgt	
	if sTreffer >10 && sDamage !=3
	set sDamage to 3
	endif
			
Message "Trefferzähler:%.0f und Zustand des Schildes:%.0f"sTreffer, fWeaponHealth
endif

	
;===================Schadensberechnung 1=======================================	
if sTreffer >5 && sTreffer <=6 && sDamage ==1
	set fWeaponhealth to player.getEquippedCurrentHealth 13
printToConsole "WaffenzustandA1= %.0f"fWeaponhealth

	;10% Schaden
	set fSchaden to 0.1		
	set fWeaponHealth to fWeaponHealth - (fWeaponhealth*fSchaden)
	player.SetEquippedCurrentHealth fWeaponHealth 13
		
printToConsole "Damage =1 WaffenzustandA2= %.0f"fWeaponhealth
Message "Mein Schild hat Schaden davon getragen!"
set sDamage to 2		
endif	

	
	
;===================Schadensberechnung 2=======================================
if sTreffer >10 && sTreffer <=11 && sDamage ==3
	set fWeaponhealth to player.getEquippedCurrentHealth 13
		
printToConsole "WaffenzustandB1= %.0f"fWeaponhealth

	;weitere 15% Schaden
	set fSchaden to fSchaden*1.5		
	set fWeaponHealth to fWeaponHealth - (fWeaponhealth*fSchaden)
	player.SetEquippedCurrentHealth fWeaponHealth 13
		
printToConsole "Damage =1 WaffenzustandB2= %.0f"fWeaponhealth
Message "Mein Schild hat sehr viel Schaden davon getragen!"
set sDamage to 4        
endif    

	
	
;===============ENDE der Abfragen da Gesundheit zu gering======================    
If player.IsBlocking==1 && sDamage ==4 && fWeaponHealth <10	
	set fWeaponhealth to player.getEquippedCurrentHealth 13

printToConsole "WaffenZustand= %.0f"fWeaponhealth
Message "Mein Schild macht es nicht mehr lang"			
set sDamage to 5        
endif    


;==============Reparaturabfrage================================================
if SDamage>1
set fWeaponhealth to player.getEquippedCurrentHealth 13
	
	if fWeaponHealth == fWeaponHealthBasis
	Message "Zustand des Schildes ist Neu:%.0f"fWeaponHealth
	set sTreffer to 0		
	set sDamage to 0
	endif			
endif
	
End 

Zur info:
2 Schadensberechnungen und auch die Hitpoints dienen nur des Tests. Wenn alles funtkioniert sind es weitere Berechnungen und die nötigen Hitpoints werden auch erhöht.

Soweit so gut. Aber.....
Wirft man ein kaputtes Schild ohne es zuvor zureparieren weg. So läuft das Script auf dem Neuen heilen Schild nicht. Wie denn auch. Das Script weiss ja nicht welches Schild gemeint ist und denkt das momentan benutzte ist immer noch kaputt.

Wäre es möglich die Abfrage über getSelf irgendwie zu nutzen?

Sprich das Script liegt dann auf dem jeweiligem Schild, deren Healthpunkte werden nicht über
set fWeaponhealth to player.getEquippedCurrentHealth 13
abgefragt sondern über die REF auf der das Script liegt. Nur wie lässt sich die Ref in diesem Falle dann abfragen?


Da würden mir spontan nur EventHandler einfallen. Da gibt es das Event "onHitWith", das du auf den Spieler wirken lassen kannst und in einer Variable kannst du dann die ID der Waffe speichern. Dann kannst du mit "getWeaponType" die Art der Waffe abfragen. Du könntest zusätzlich auch checken, wie viel Schaden der Spieler genommen hat, damit du daraus einen dynamischen Schadenswert für den Schild errechnen kannst.

Eine mit OnHIT ID-zuweisung wäre glaube ich zu Aufwendig. Schliesslich sollen ja alle Hiebwaffen und Bögen am Schild Schaden verursachen.
Als Kompromiss könnte jedoch die Einhand und Zweihandwaffe verschiedenen Schaden verursachen.
2: Blunt1H
3: Blunt2H

ref weapon
short weapontype
set weapon to player.GetEquippedObject 16
set weapontype to GetWeaponType weapon

Wie lässt sich abfragen welche Waffe der Angreifer benutzt. Das obengenannte läuft ja nur über die Abfrage welche Waffe der Player benutzt.
 
Zuletzt bearbeitet:
Interessanter Gedankengang. Soweit dachte ich garnicht. Das scheint mir hochkompliziert. keine Ahnung wie das abgefragt werden könnte. Erst mal die Grundabfrage überhaupt hinbekommen. ich weiss nicht mal ob die Engine das bevor der Skill so bescheuert gesetzt wird vorher so gamacht hat.
Du misverstehst mich. Ich meinte beobachte einfach mal im Spiel mit einem entsprechend ungeschulten Charakter wie viele Treffer ein Schild aushält, schau im CS wieviel Health der Schild hat und strick Dir daraus einen festen Wert per einfacher Division den Du als feste Größe in Dein Skript einbaust. :D

Wenn's nur drum geht, daß der Schild Schaden nimmt, warum nicht einfach den Schadenswert selber festlegen? ;)
 
Eine mit OnHIT ID-zuweisung wäre glaube ich zu Aufwendig. Schliesslich sollen ja alle Hiebwaffen und Bögen am Schild Schaden verursachen.
Als Kompromiss könnte jedoch die Einhand und Zweihandwaffe verschiedenen Schaden verursachen.
2: Blunt1H
3: Blunt2H

ref weapon
short weapontype
set weapon to player.GetEquippedObject 16
set weapontype to GetWeaponType weapon

Wie lässt sich abfragen welche Waffe der Angreifer benutzt. Das obengenannte läuft ja nur über die Abfrage welche Waffe der Player benutzt.

Nein, dafür sind die EventHandler ja da. Du definierst ein externes Skript das immer dann läuft, wenn das gewünschte Ereignis eintritt. In diesem Fall, wann immer der Spieler getroffen wird. In diesem Skript kannst du dann, je nachdem, welchen Befehl du benutzt, abfragen, wer den Angriff ausgeführt hat und dann abfragen, welcher Waffentyp benutzt wurde oder du kannst gleich die Waffen-ID erhalten und gucken welchem Waffentyp sie zugehört.
 
  • Like
Reaktionen: robinH
Jetzt bin ich total verwirrt.

Der Spieler wird doch garnicht getroffen, sondern das Schild welches der Spieler zur Abwehr benutzt.
ONHIT "Only works on NPCs and Creatures, and will not work on items" steht in der Wiki

Wie meinst du das jetzt genau.

Ich erstelle also eine Quest, welche nun welchen Eventhändler abfragt?

Wie kann ich denn abfragen, welche Waffe der Gegner benutzt. Hast du mal ein Beispiel wie so ein Script aussehen müsste.

Ich steig da einfach nicht durch. Habe mir das im Wiki sehr lange angeschaut und versucht zu verstehen. Doch wie ich das jetzt umsetzte weiss ich beim Besten Willen nicht. Gibt es eine Mod zum nachsehen, in der so was ähnliches schon mal abgefragt wurde?
 
Zuletzt bearbeitet:
So, jetzt hätte ich auch mal zwei Fragen. Bitte seht mir nach wenn das absolute noob Fragen sind, da ich mit Skripten noch ganz am Anfang stehe.

1 - Wie kann ich abfragen ob ein NSC mit dem ich grade rede männlich oder weiblich ist?

2 - Wie kann - in Abhängigkeit von 1 - bestimmte Werte des NSCs (oder meines eigenen Char, falls das einfacher ist) ändern, solange das Gespräch dauert?

Hinweise auf passende Tutorials sind auch jederzeit als Antwort willkommen. Wenn ich erst mal ein, zwei Startpunkte habe kann ich mich vielleicht auch selber durchhangeln. :)

(Hintergrund der Frage, falls es hilft: Ich dachte mir es könnte ganz witzig sein manche der eher freizügigen Kleidung aus Mods mit einem Skript zu belegen, das bestimmte Reaktionen bei NSCs auslöst, je nach dem welches Geschlecht sie haben.)
 
Am besten wäre es erst mal sich mit dem Grundprinzip der Nutzung des Questmanagements und der Topics vertraut zumachen. Eventuell sogar das Idelmanegement noch dazu nehmen. Damit die NPC Ihre Texte auch mit entsprechenden Körperreaktionen unterstreichen.

http://www.ei-der-zeit.com/wiki/index.php?title=Oblivion:Gescriptete_Konversation_zwischen_NPCs
Ist jedoch nicht ganz Einfach. Ich habe auch mehrere Versuche gebraucht bis ich ein Gespräch hinbekommen habe. Das Idelmanegement ist recht komplex. Nimm dir am Anfang nicht allzuviel vor.

Mit
http://www.ei-der-zeit.com/wiki/index.php?title=Oblivion:GetIsSex
lässt sich das Geschlecht abfragen.
Bei den Conditions in den Topics gibt es jedoch auch direkt dort einen Befehl ohne das noch zu scripten.

Doch wer kann mir nun weiter helfen mit dem Eventhändler.

Jemand mal ein Beisspiel wie so ein Script in meinem Fall aussehen müsste. Die Anfänge davon würden mir schon helfen.
 
Zuletzt bearbeitet:
@Andy: Für den Gesprächspartner kannst du "getActiveMenuRef" benutzen. Dann wie beschrieben "getIsSex". Es sollte aber auch über das Result Script im Dialog gehen:
Code:
set <Referenzvariable> to getSelf
Im Result Script kannst du auch die Werte des NPCs ändern, mit "setAV".


@robin: Für die EventHandler registrierst du einfach irgendwann (der Zeitpunkt, ab dem es gelten soll) sozusagen eine externe Funktion. Das machst du mit
Code:
setEventHandler "onHitWith" SpielerWirdGetroffen ref::playerRef

Nun wird jedes Mal, wenn der Spieler getroffen wird, das Skript "SpielerWirdGetroffen" ausgeführt. Du kannst auch die "playerRef" durch eine beliebige andere ersetzen, oder ganz weglassen. Letzteres bewirkt jedoch, dass die Handler-Funktion immer ausgeführt wird, wenn irgendjemand getroffen wird.
Die Handler-Funktion musst du auch noch erstellen:
Code:
scn SpielerWirdGetroffen   ; das Skript muss genau so heißen, wie du es in der Handler-Registrierung genannt hast

ref target
ref weapon
short weaponType

Begin Function { target, weapon }
; hier werden automatisch die Variablen gesetzt
; "target" speichert die Ziel-Referenz, in diesem Fall den Spieler
; "weapon" speichert die ID der Waffe


if target.isBlocking == 0
; Spieler blockt nicht

  return
endif


set weaponType to getWeaponType weapon
; .....

end

Ps: Das Zitat aus dem Wiki meint, dass "onHit" nicht wirkt, wenn das Skript auf einem Activator oder ähnlichem liegt.
 
Zuletzt bearbeitet:
  • Like
Reaktionen: Andy1967 und robinH
Huh, das sieht echt kompliziert aus. Mal sehen wie weit ich da komme.

Aber wo kommen die beiden Scripte dann hin.

In eine Quest oder in ein Item im Inventar?


ref target
ref weapon
short weaponType

Begin Function { target, weapon }
; hier werden automatisch die Variablen gesetzt
; "target" speichert die Ziel-Referenz, in diesem Fall den Spieler
; "weapon" speichert die ID der Waffe

Kann anstatt der Weapon auch der Typ dort eingetragen werden?
Ich weiss ja nicht welche Waffe der Gegner schwingt. (Die Waffe wird durch eine Levelliste mit mehreren Hiebwaffen und Schwertwaffen erzeugt)

Das Schild soll ja nur zunächst bei Hiebwaffen, später (Wenn es dann mal funktioniert) auch bei Pfeiltreffer einen Schaden nehmen.

Wird der Target (der Player) mit getself definiert?
 
Zuletzt bearbeitet:
Die Handler-Registrierung ("setEventHandler") erfolgt da, wo du sie haben möchtest.
Den Handler selbst musst du einfach nur als Skript abspeichern.

Den Waffentyp kannst du doch mit "getWeaponType" abfragen... :huh:

Die Variablen "target" und "weapon" werden beim Ausführen des Handlers automatisch gesetzt. Du kannst ihnen auch andere namen geben, wichtig ist nur, dass in den geschwungenen Klammern zuerst die Variable für den getroffen Actor und als zweites für die Waffen-ID steht.
 
  • Like
Reaktionen: robinH
Ok ich werde mal sehen wie weit ich da am WE komme. Sorry, das ich dich so zur Verzweiflung bringe.

Das mit den Handlern habe ich noch nie verstanden und deshalb immer wieder aufgegeben. Eventuell wird es ja diesmal was.

Also kann ich den Handler über ein Script allein starten. Dieses Script benötigt keinen Gegenstand und keine Quest. Richtig?
Komisch wieso funktioniert es dann? Naja ist halt wohl so.

Und das andere Script lege ich dann am besten auf das Schild welches zum Blocken benutzt wird, oder ist eine Quest besser?
 
Zuletzt bearbeitet:
Ich würde es auf eine Quest legen, und den Befehl dann einmal ausführen, wenn du wie zu Beginn beschrieben eine gewissen Stufe (Experte??) im Blocken erreicht hast, Stichwort: "getAV".
 
  • Like
Reaktionen: robinH
Das mit den Handlern habe ich noch nie verstanden und deshalb immer wieder aufgegeben. Eventuell wird es ja diesmal was.

Also kann ich den Handler über ein Script allein starten. Dieses Script benötigt keinen Gegenstand und keine Quest. Richtig?
Komisch wieso funktioniert es dann? Naja ist halt wohl so.
Keine Ahnung ob es in der Praxis tatsächlich so funktioniert, aber ich stelle mir einen EventHandler als eine Art "Steno Version" für ein Skript vor das mit
beginn GameMode
eingeläutet wird und dann jeden Frame nichts anderes macht als vordefinierte Befehle ablaufen zu lassen die bestimmte "wenn - dann" Abfragen ersetzen die Du theoretisch auch von Hand skripten könntest, nur nimmt Dir der EventHandler diese Arbeit ab.

Skripts die Questen starten liegen ja auch nicht auf einem bestimmten Gegenstand, sondern warten nur im Hintergrund darauf, dass bestimmte Bedingungen erfüllt werden. Nur liegt der EventHandler nicht auf einer Queste sondern... na ja, denke quasi auf dem gesamten Spiel, ähnlich wie Veränderungen im Wetter oder das Fortschreiben der Kalendertage ja auch nicht an Gegenstände oder Questen gebunden sind.
 
Na der Robin lernt das noch mit den Funktionen.
Also die Funktion wird schon mal angesteuert allerdings nicht ganz so wie beschrieben

Code:
setEventHandler "onHitWith" SpielerWirdGetroffen ref::playerRef

gibt im CS folgende Fehlermeldung aus.

Keine Ahnung warum. Das Script ist ein Questscript und liegt auf einer Quest.

Nun gut, dafür funktioniert es so
setEventHandler "onHitWith" SpielerWirdGetroffen

Was ich nun nicht verstehe:
Warum hat die Messageangabe wie von mir beschrieben keine Angaben. Da steht nur
bei message $target + "?????" + $Weapon inGame folgendes:
"$target"
bei der anderen Message steht
"$Weapon"

Deshalb habe ich das auf herkömmliche Weise geschrieben

Doch warum sind beide Ausgaben der Funktion =0
und warum wird das Object16 (das Schild) nicht definiert? Dort steht auch =0
Siehe Consolenausgabe.


Was mache ich da falsch?

Anbei das Script welches ich zum Testen benutzt habe
PHP:
scn A0ItemBlockingPlayer

ref target
ref weapon
short WeaponType
short Schild

;Target speichert die Zielref
;Weapon speichert die ID der Waffe mit der der Player getroffen wird

;========================================================
Begin Function {target weapon}
	
if target.isBlocking ==0
return

;----------Player blockt-------------------------		
else
		
;message $target + "?????" + $Weapon ;funktioniert nicht
PrintToConsole "Begin Function {target weapon} Ausdruck1= %.0f, Ausdruck2= %.0f"target, weapon		
endif

set WeaponType to getWeaponType weapon
	
;-----Hiebwaffenabfrage-----1H,2H----------------	
if WeaponType ==2 || WeaponType ==3
		
;message $Weapon + "Typ Hieb 1Hand oder 2Hand" ;funktioniert nicht
PrintToConsole "Waffentyp Hieb= %.0f"weaponType ; funktioniert- siehe Ausgabe Console im Bild oben

set Schild to player.GetEquippedObject 16
;message $Schild + wid zum Blocken genutzt" ;funktioniert nicht
PrintToConsole "Object16= %.0f"schild
	
;--------------Keine Hiebwaffe------------------------	
else

PrintToConsole "Waffentyp kein Hieb= %.0f"weaponType
		
endif
		
end

Fazit:
Eine Abfrage ob der Gegner mit einer Hiebwaffe zuschlägt, bzw nicht zuschlägt funktioniert einwandfrei.

Doch wie lässt sich denn nun das eigentliche Grundproblem die Gesundheit des Schildes so steuern, das das Spiel auch erkennt, welches Schild kaputt ist und welches repariert wurde?
 
Zuletzt bearbeitet:
1. Die Schild-ID musst du in einer Ref-Variable speichern. Und außerdem wird der Schild über den Slot 13 abgefragt, 16 ist die Waffe.

2. Für die Messages musst du entweder "messageEx" oder "printToConsole" benutzen, natürlich jeweils mit den richtigen Stringformatierungen.

3. Weiß jetzt nicht, warum der den "ref"-Parameter nicht haben will. Du könntest es mal mit einem einzelnen Doppelpunkt versuchen, oder vor dem Blocktyp einen Unterstrich, also: "_GameMode". Wenn es trotz allem nicht geht, darfst du aber auf jeden Fall nicht vergessen, im Handler-Skript abzufragen, ob auch tatsächlich der Spieler getroffen wird.
 
  • Like
Reaktionen: robinH
Ok Danke also 13, jedoch hat er ja auch über die 16 nur eine 0 ausgegeben. Hätte da nicht ein Wert von dem Schwert welches der Player in der Hand hat (siehe Screenshot oben) erscheinen müssen?
 
Ach klar, hatte da nicht richtig gelesen. Es muss eine REF sein. Hattest du ja gesagt.
Mal sehen wie weit ich dieses WE komme.

Doch wenn ich dann die ID habe wie lässt sich diese speichern sodas Ingame erkannt wird, das das Schild wenn nicht repariert noch kaputt ist?

Sprich der Player nimmt einfach ein anderes Heiles Schild. Mit meiner alten Methode weiss das Game nicht das das Schild nicht repariert wurde, und denkt das jetzige ist ebenfalls kaputt.

Sprich das Script würde nicht laufen und das neue Schild bekommt solange keinen Schaden, bis das Alte (das heisst wenn es nicht weggeworfen wurde, denn dann müsste man es erst wieder suchen) repariert wurde.
 
Was meinst du? Du musst nur die Lebenspunkte des Schildes runtersetzen:

Code:
scn A0ItemBlockingPlayer

ref target
ref weapon
short WeaponType

;========================================================
Begin Function {target weapon}
    
if target.isBlocking == 0
    return
endif

;----------Player blockt-------------------------        

set WeaponType to getWeaponType weapon
    
;-----Hiebwaffenabfrage-----1H,2H----------------    
if WeaponType ==2 || WeaponType ==3
    PrintToConsole "Waffentyp Hieb= %.0f"weaponType ; funktioniert- siehe Ausgabe Console im Bild oben
    target.ModEquippedCurrentHealth -100 13
   
    
;--------------Keine Hiebwaffe------------------------    
else

PrintToConsole "Waffentyp kein Hieb= %.0f"weaponType
        
endif
        
end
 
Zuletzt bearbeitet:
Gildur, ich glaube das hilft ihm nicht. Das Script an dem Robin im Moment arbeitet dient nur dazu abzufragen mit welcher Waffe der Spieler angegriffen wird. Die Funktionen die er - an das Abfrageresultat angepasst - abarbeiten will hat er schon vor zwei oder drei Seiten gepostet. Keine Ahnung wie weit Du die älteren Posts zu diesem Thema gelesen hast?

Robin, Ich denke mal das Spiel wird sich schon merken wie viele Lebenspunkte ein Gegenstand aktuell hat. Tut es ja sonst auch. Vielleicht lässt sich das Problem mit dem Schildwechsel lösen in dem Du Dein Script bei einem "OnUnequip" deaktivierst und als erste Startbedingung ein "OnEquip" (verbunden mit Abfrage der gegenwärtigen Lebenspunkte) einbaust, bevor Du die "OnHit" Sequenz überhaupt startest? Hab allerdings keine Ahnung ob sich das "OnEquip" auch für den Shieldslot als solchen machen lässt, oder nur für einzelne Gegenstände. Aber damit müsstest Du doch theoretisch das Script davon überzeugen können wie gut oder schlecht ein Schild repariert ist der grade ausgerüstet ist ... denk ich mal.
 
Zuletzt bearbeitet:
Entweder verstehe ich nicht, was genau ihr machen wollt oder ihr versteht nicht, wie Event Handler funktionieren.

Diese Funktion wird jedes mal aufgerufen, wenn der Spieler blockt und er angegriffen wird, sprich der Schild getroffen wird. Dann wird das Schild um 100 Health beschädigt. Muss man eventuell noch anpassen und verringern den Schaden, oder man kann ihn gleich variabel halten. Allerdings bisher auch nur mit der Einschränkung, wenn man von einer Hiebwaffe getroffen wird. Aber die Bedingungen kann man ja beliebig anpassen. Wichtig ist einfach nur diese Zeile:
Code:
target.ModEquippedCurrentHealth -100 13
Denn diese beschädigt das Schild, wenn es getroffen wird. Und ich dachte das wäre das Ziel des Ganzen. Irgendwelche IDs oder Referenzen muss man nicht abspeichern, da du das Schild direkt per Script beschädigst.
 
  • Like
Reaktionen: robinH