Construction Set Skriptthread zum Construction Set

Zugegeben, bei diesem Handler steht in der Dokumentation auch etwas Verwirrendes. Zum einen werden als Parameter der Schaden und Angreifer angegeben, andererseits steht in der Beschreibung, dass man den geschädigtem Actor mit "object" addressiert, also als dritten Parameter. Kann natürlich sein, dass ich da was falsch verstanden habe.

Habe jetzt aber mal in den Quellcode dieser Funktion reingesehen und da stehen als Parameter ein Float- und ein Ref-Wert. Also hat das mit dem "object" in der Bemerkung wohl doch eine andere Bedeutung...

Auf jeden Fall registrierst du den Handler an der selben Stelle, an der du auch den ersten registiert hast. Das dürfte so aussehen:
Code:
setEventHandler "OnHealthDamage" ZweitesHandlerSCRIPT

Dann erstellst du wie beim ersten Mal das Handler-Script:
Code:
scn ZweitesHandlerSCRIPT

float damage
ref attacker

Begin Function { damage , attacker }

if getIsReference playerRef == 0
  return
elseif isBlocking == 0
  return
endif

if getAV health <= damage
  ;wenn der Spieler sterben würde, werden vorher genug HP wiederhergestellt
  ;andernfalls erst nach dem Schlag -> im anderen Handler-Script die Variable <Quest>.rest überprüfen

  set <Quest>.rest to 1
  modAV2 health damage
endif

end
 
  • Like
Reaktionen: robinH
Wiedermal vielen Dank. Nun kann ich am WE mein Glück weiter versuchen. Hatte absolut keinen Plan wie ich da überhaupt anfange.

...................Habe jetzt aber mal in den Quellcode dieser Funktion reingesehen und da stehen als Parameter ein Float- und ein Ref-Wert.
...................

Wo kann man denn in den Code reinsehen?
 
Den findest du im "src"-Ordner von OBSE unter obse/obse/EventManager.cpp

Ist zwar nicht dierekt der Quellcode, da es ja keine reine Funktion sondern was komplexeres ist, aber in ca. Zeile 700 sieht man, was für Argumente die Funktion benötigt.
 
Zuletzt bearbeitet:
  • Like
Reaktionen: robinH
Tja also, erstmal sah es so aus , als wenn allles klappt, dann stellte sich heraus das dem nicht so ist.

Zwar werden die Hp immer schön wieder ausgeglichen, doch wenn der Player sich später mal heilt, hat er plötzlich mehr HPs als zuvor. Siehe Screen. Schwer zu erklären.


Nicht die GrundHP sind höher sondern die anderen. Sehr seltsam.
Mit der Ausdauer verhält es sich genau umgekehrt.

Hier bleiben die Grund Ausdauerpunkte nach wie vor auf 233Punkte, doch sobald der Abzug erfolgt lässt die Ausdauer sich nicht mehr auf 233 Heilen. Stattdessen ist nur der dann geringere Wert möglich. Wie in meinem Testlauf waren das 72 Ausdauerpunkte.

Ich habe da unspielbar, diese Zeile erstmal auskommentiert. Deshalb ist im Screen und in der Console davon nichts zu sehen.

Auch die Zwischenspeicherung der HP (In der Console zu sehen)- Im Script nicht dabei- da der Effect der selbe war- hat nichts gebracht.

Hier das Script
PHP:
scn A0EventBlockingPlayerHealth
;Das Event OnHealthdamage fragt ab, wie viel HP der Player bei einem Treffer eines Angreifers verliert

ref rAngreifer
float fDamage
float fPStrength
float fPHealthdamage
float fPFatiguedamage

;----Benutzte Quest Globale---
;A00EVENTS.fSchildGewicht

;;;;;;;;;;;;;;;;;;;;;;;;;;;;Player benutzt Schild;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Begin Function { fDamage , rAngreifer }

if player.GetEquippedObject 13
	
	if getIsReference playerRef == 0	
		return		
	elseif isBlocking == 0
	return	
	endif
		
;===========Player blockt===================================
	
set fPHealthdamage to  (fDamage * -1)
set fPStrength to player.getAV Strength		
		
set fPFatiguedamage to (fDamage * A00EVENTS.fSchildGewicht)
set fPFatiguedamage to (fPFatiguedamage / fPStrength)

;let fPFatiguedamage := (fDamage * A00EVENTS.fSchildGewicht) / fPStrenght 	;diese Zeile lässt sich nicht abspeichern		
			
	;---Healthanpassung--
			
	if fPHealthdamage >0
	player.modAV Health fPHealthdamage	;Passt nicht, die Hp wird immer höher als die Grund HP

	;---Ausdaueranpassung--
	;player.modAV Fatigue fPFatiguedamage	;Passt nicht, die Ausdauer wird immer niedriger als die Grundpunkte
	endif	
		
endif			

END

Aus irgendeinem Grund möchte der CS meine "Let Syntax" nicht haben.
EDIT: Busstabendreher : gth nicht ght

Wer kann zu der anderen Tatsache etwas sagen?

Ich bin echt langsam ratlos. Das darf doch nicht wahrsein. Warum geht das denn nicht?
EDIT: So wie es aussieht ist wohl ModAV nicht der richtige Befehl. Werde mal die anderen 2 durchprobieren umzu sehen was welcher macht.

SETAV, FORCEAV,
 
Zuletzt bearbeitet:
Guckst du eigentlich manchmal ins Wiki?
Bei "modAV" steht da:
If you use ModActorValue in a script, the Script Modifier is adjusted, and ONLY a script can adjust it back. In other words, if you have a script do "player.modav health 100" you are also responsible for doing "player.modav health -100" or that 100 points will *always* be in the script modifier.
Gibts ja aber auch in der deutschen Übersetzung im Ei-der-Zeit.

Der "Let"-Befehl wird wahrscheinlich nicht kompiliert, weil du die Variable "fPStrength" dort falsch geschrieben hast. Ich nehme an, in der Fehlermeldung stand etwas von "unknown expression fPStrenght"?
 
  • Like
Reaktionen: robinH
Hi, ich suche eine Möglichkeit ein Projektil abzufangen (Blitzzauber)
Leider scheint eine Collisionbox dies nicht hinzubekommen....
Die Collisionbox lässt zwar keine Npcs durch allerdings fliegen zauber und so munter weiter durch die Box durch.
Oder liegt es vielleicht doch am Skript ?(Deswegen poste ich es ja hier)
Das Skript bewegt eine Collisionbox mit der RefId NmBarriereBox vor den Caster (in diesem Fall vor einen NPC).

Das Enable/disable Problem nach SetPos habe ich bereits bedacht....

Solltet ihr vielleicht noch eine andere Idee haben wie man Projektile abfangen kann wäre ich euch sehr dankbar.


SCRIPT:

Code:
scn NmBarriereSCRIPT


ref self


float frontXFinal
float FrontYfinal
float posx
float posy
float posz
float angle
float cosangle
float sinangle
float time
short once


Begin ScripteffectStart


    set self to getself
    NmBarrierebox.moveto self 




    set angle to self.getangle z
    set cosangle to cos angle
    set sinangle to sin angle


    set posx to self.getpos x 
    set posy to self.getpos y
    set posz to 350 + self.getpos z 


    set frontxfinal to posx + sinangle * 400 
    set frontyfinal to posy + cosangle * 400 




    NmBarriereBox.setpos x frontxfinal
    NmBarriereBox.setpos y frontyfinal
    NmBarriereBox.SetPos z posz
    NmBarriereBox.disable ;wegen setpos disable im updateblock wieder enable.

     
end


Begin ScripteffectUpdate


    set time to time + scripteffectelapsedseconds


    if time > 0.5  && once == 0
        set once to 1
        NmBarrierebox.enable
        Message "TEST"
    endif




    if time >0.8 && once==1
        set once to 2
        NmBarrierebox.pms effectatronachstorm
    endif






end 




Begin Scripteffectfinish


;NmBarrierebox.disable


end


EDIT:Sorry ich habe den Beitrag geschrieben und war angeblich nicht eingeloggt , daher war die Formatierung nicht mehr da.
 
Zuletzt bearbeitet:
Zauber werden doch von Hindernissen, wie Wänden etc. aufgehalten, sonst würden ja Feuerbälle kreuz und quer durch die Dungeons schießen. Wenn eine reine Kollision das nicht verhindert, braucht es vermutlich noch eine NiTriStrips in der Nif dazu. Stell doch einfach eine Wand dahin, mit unsichtbarer Textur - vielleicht funktioniert das ja.
Ich nutze solche Flächen für allerlei Kram und kann dir eine solche "Wand" gern zukommen lassen, musst nur die Ausmasse angeben. Ob es als Projektil-Kollision taugt, kann ich allerdings nicht sagen - hab das für diesen Zweck noch nie gebraucht.
 
  • Like
Reaktionen: robinH und nevs44
Guckst du eigentlich manchmal ins Wiki?
Bei "modAV" steht da:
...............................


So habe alles rauf und runter probiert. Ich checks nicht, was mache ich da falsch?

Wenn ich die Health am Ende wieder abziehe, wie es in der Wiki steht. Gibt es einen Funktionsfehler.
Siehe Screen


Setzte ich diesen Abzug in das andere Script mit dem Blockevent, kommt zwar kein Fehler, jedoch erfolgt der Abzug dann erst beim nächsten Schlag. Heilt man sich vorher so hat man wieder mehr HP.

Gibt es eine Möglichkeit das Ende einer Funktion abzufragen und dann den Wert abzuziehen.

Jedoch weiss ich nicht was der Sinn ist, Erst setzte ich den Wert rauf um so den Schutz des Schildes darzustellen und dann wird der Wert wieder abgezogen. Also irgendwie muss ich dich Diarrhoe und die Wiki falsch verstanden haben. So kann das nicht richtig sein.

Hier mein dummes Script
PHP:
scn A0EventBlockingPlayerHealth

;Das Event OnHealthdamage fragt ab, wie viel HP der Player bei einem Treffer eines Angreifers verliert

ref rAngreifer

;TESTS------------
float fBaseHealth
float fBaseFatique
;float fForceHealth
;------------------
float fDamage
float fPStrength
float fPHealth
float fPFatigue

;----Benutzte Quest Globalen---
;A00EVENTS.sDebug
;A00EVENTS.sModAVReturn
;A00EVENTS.fSchildGewicht
;A00EVENTS.fPHealthdamage
;A00EVENTS.fPFatiguedamage

Begin Function { fDamage , rAngreifer }
		
	if getIsReference playerRef == 0	
		return		
	elseif isBlocking == 0
	return	
	endif
	
;-------------------------TESTS-------------------------------
;setzt den Wert Health runter auf 10		
;set fForceHealth to Player.ForceAV Health 10	
;printC "B: ForceHP:%.0f" fForceHealth

set fBaseHealth to Player.GetBaseAV Health
set fBaseFatique to Player.GetBaseAV Fatigue
printC "A: BaseHP:%.0f BaseFatigue:%.0f" fBaseHealth, fBaseFatique		
;-------------------------------------------------------------
	
set A00EVENTS.fPHealthdamage to  (fDamage * -1)

;----------Ausdauerschadensberechnung-------------------------	
set fPStrength to player.getAV Strength
let A00EVENTS.fPFatiguedamage := (fDamage * A00EVENTS.fSchildGewicht) / fPStrength	
		

	if A00EVENTS.sDebug ==1
	printC "EVENT-HP: 0) HPSchaden=%0f, Schildgewicht=%.0fkg, Playerstärke=%.0f" fDamage, A00EVENTS.fSchildGewicht, fPstrength 		
	PrintC "EVENT-HP: 1) (%n) sorgt für Abzüge: HP=-%0f, Ausdauer=%0f" rAngreifer, A00EVENTS.fPHealthdamage, A00EVENTS.fPFatiguedamage
	endif		
		
	;--------------Healthanpassung------------------------
			
	if A00EVENTS.fPHealthdamage >0
	set fPHealth to player.getAV Health
			
		if A00EVENTS.sDebug ==1	
		printC "EVENT-HP: 2) [HP=%.0f / %.0f] HP um %0f erhöhen" fPHealth, A00EVENTS.fPHealthRestore, A00EVENTS.fPHealthdamage
		endif
		
	player.modAV Health A00EVENTS.fPHealthdamage				
	set A00EVENTS.sModAVReturn to 1		

		if A00EVENTS.sDebug ==1	
		set fPFatigue to player.getAV Fatigue	
		printC "EVENT-HP: 5) Ausdauerneu=%.0f" fPFatigue
		endif

	endif	

	;Player.modAV Health fdamage
	
	if A00EVENTS.sModAVReturn ==1
		let A00EVENTS.fPHealthdamage *=(-1)	
		Player.modAV Health A00EVENTS.fPHealthdamage
	set A00EVENTS.sModAVReturn to 0
	endif		
END

Wie würdet Ihr denn das Script schreiben, damit sich die HP entsprechend verhällt?

Ziel sollte sein. Das wenn beim Blocken ein Schaden dem Player zugefügt wird, dieser sofort rückgängig gemacht und anstatt dessen dieser der Ausdauer angelastet wird.
 
Zuletzt bearbeitet:
Benutze doch einfach "modAV2". Das ist ein OBSE-Befehl und wenn damit die HP geändert werden verhält sich das ziemlich genau so, wie wenn dafür ein Zauber benutzt wird.
"SetAV" ist nicht der richtige Befehl, weil der die Base-HP verändert und "forceAV" birgt mehr oder weniger die gleichen Probleme wie "modAV".
 
  • Like
Reaktionen: robinH
Dank dir, das wäre ja Klasse wenn es damit gehen würde.

EDIT: Es hat geklappt. Die Mod ist fertig (Beta).

Ich wollte sie auch hochladen, jedoch klappt das nicht mit der Ini. Keine Ahnung warum die nicht geladen wird. Ohne Ini ist es nur über die Console möglich entsprechende Werte anzupassen.

Die Defaultwerte beziehen sich auf meinen Einstellungen. Ich habe sämmtliche Waffen im Gewicht angepasst. Deshalb kann es bei denjenigen, die originale Waffenwerte nutzen, zu unmöglichen Ausdauerverlusten kommen. Je schwerer die Waffen umso mehr machen sich die Effekte bemerkbar.

Die ifBedingung wird abgearbeitet und es erscheint auch die Nachricht, dass die Ini Werte geladen wurden.

Trotzdem werden die Werte nicht gesetzt sondern stehen alle auf 0.
Deshalb habe ich die initialisierung der Iniwerte auskommentiert.

Wer möchte kann ja mal nachsehen, warum die ini nicht geladen wird.
BlockEvents.7z

PHP:
;Ini für BlockEffects

;Bei Nutzung des Schildes blockt dieses jeden Schlag. Je mächtiger die Waffe des Gegners dabei ist,
;umso mehr wird das benutzte Schild beschädigt. Jeder erfolgreiche Block kostet dafür Ausdauer.
;Zur Berechnung wird folgendes herangezogen.

; Die Stärke des Players. Umso stärker umso weniger Ausdauerverbrauch
; Das Gewicht der Waffe des Gegners. Je schwerer umso heftiger die Wirkung
; Das Gewicht des Schildes. Je schwerer umso mehr Ausdauerschaden

;Addierer für die Waffentypabhängige Schildbeschädigung. Höhere Werte schaden dem Schild mehr.
;---------------------------------------------------------------------------------------------
set A00EVENTS.fSchadenAddHieb to 	10			;default=10
set A00EVENTS.fSchadenAddHieb2H to 	20			;default=20
set A00EVENTS.fSchadenAddStich to 	1			;default=1
set A00EVENTS.fSchadenAddStich2H to 	2			;default=2
set A00EVENTS.fSchadenAddBow to 	0.8			;default=0.8

;Multiplikator für die Ausdauerschädigung (Gegnerabhängig). Höhere Werte verursachen mehr Ausdauerschaden. 1=off
;---------------------------------------------------------------------------------------------
set A00EVENTS.fFatigueMultipl to 	0.1			;default=0.01

;Multiplikator2 für die Ausdauerschädigung (Playerstärkeabhängig). Höhere Werte verursachen weniger Ausdauerschaden. 1=off
;---------------------------------------------------------------------------------------------
set A00EVENTS.fFatigueMultiplStr to 	1			;default=10

;Visueller Break des Schildes 1= On 0 =off
set A00EVENTS.sSchildBreak to		1			;default=1

;Effectereignisse und Berechnungen in der Console 1=On 0=Off
set A00EVENTS.sDebug to 		0			;default=0
 
Zuletzt bearbeitet:
Hallo zusammen,

ich möchte einer Companion den Befehl geben, mir ohne Rüstung zu folgen. Ich weiß schon mal so viel, dass es über die Dialogoptionen geht. Ich muss also dafür sorgen, dass sie ihre aktuelle Rüstung unequipped, um ein Standardkleid zu equippen. Das muss ich ihr wohl vorher in ihre Inventar-Truhe legen, richtig?
Wie würde der Skriptbefehl lauten, den ich im ResultScript-Fenster eintragen muss?
Etwa so?:

NPCRef.RemoveAllWeapons
NPCRef.RemoveAllArmor
NPCRef.equipitem (?????aus ihrer Truhe.Ref????)
 
Ich kenn mich leider mit den Scripten zu wenig aus um zu wissen ob das geht was mir als erster Gedanke kommt, aber meine Idee wäre ein Follow Package zu verwenden (mit "unequip armor"), das an an eine Funktion geknüpft ist die durch die Dialogoption angesteuert wird. In den Packages lässt sich ja die Verwendung von Rüstung - und das Follow - setzen, also warum nicht das verwenden? Wäre dann nur die Frage wie man es aktiviert und deaktiviert. Aber vielleicht ist das ja auch völlig abwägig. Bin da, wie gesagt, nicht der Expert. Aber was Du als Script einbauen willst ist ja an sich schon in den Packages als Option vorhanden.
 
Das kommt doch ganz darauf an, wie bei dir die Begleitersteuerung aufgebaut ist. Ein Dialog wird ja irgendwie die Bedingungen für die Packages auf dem Begleiter schalten müssen.
Ich würde das mit einer einzigen Variablen steuern. Z.B. Package "Follow mit Rüstung" hat die Bedingung Variablenwert 1, Package "Follow ohne Rüstung" den Wert 2, Package "In der Nase bohren" hat Wert 3 und Package "Was weiss ich" hat Wert 4 usw, das kann ja beliebig erweitert werden. Im jeweiligen Result eines Topics wird dann nur der Variablenwert verändert.
 
OK, ich glaube ich blicke langsam durch.

Schritt 1:
In ihrem Questscript ergänze ich eine short Variable. Die könnte so aussehen:
short step
;step == 10 Follow Player without armor


Schritt 2:
Ich erstelle ein Follow-Package, bei Conditions "GetQuestVariable" "Questname", bei Variable Name schreibe ich "step" und ganz rechts == 10
Kann ich gleich hier bei den Flags "armor unequipped" und "Weapons unequipped" anhaken, oder muss ich das im Topic-Fenster bei Result-Script unequippen?

Das führt mich gleich zu
Schritt 3:
Einen entsprechenden Dialog im Reiter Topic erstellen, bei Result Script schreibe ich
"setNPC-Name.step to 10

Ist das richtig so? Ich sehe noch nicht den Befehl, dass sie ein Kleid und Schuhe anziehen soll.
 
Wenn sie normalerweise Rüstung trägt, aber zusätzlich ein Kleid und normale Schuhe im Inventar hat sollte sie automatisch das Kleid anziehen, sobald ein Package startet bei dem Du "armor uneqipped" gesetzt hast. Wüsste nicht, dass Du dafür noch irgendwo sonst einen extra Befehl verwenden müsstest. Hauptsache ist, dass das Kleid definitiv keinen Rüstungswert hat, sprich im CS unter Clothing gelistet ist, dann sollte das klappen.

zu 2.: M.E. müsste es ausreichen wenn Du das "unequipped" einfach an der üblichen Stelle im Package ankreuzt. Sobald dann ein anderes Package startet bei dem der Haken nicht gesetzt ist müsste sie dann das Kleid automatisch wieder ausziehen und die Rüstung anlegen.
 
Hallo,
ich möchte folgendes über ein Script steuern:
Wenn drei Gegner getötet wurden soll dem Avatar ein Gegenstand zugeordnet werden.
Ist dies so möglich? Lege ich dann diesen Script auf alle drei NPC’s?
Danke
 
Wenn Du die Steuervariable in ein Questskript legst, lautet das Result im Dialog-Topic "set QuestID.Variable to Wert". Die Bedingung für die Packages sind dann "GetQuestVariable SkriptID == Wert".
Liegt die Variable hingegen auf dem Skript des Begleiters, dann sollte die Bedingung GetScriptVariable sein.
Dazu würde dein "set NPC-Name.step to 10" wieder passen.

Wie Andy schon schrieb, Du brauchst normalerweise nur zwei Follow-Packages, einmal mit gesetztem unequipped Flag und einmal ohne. Dieses Flag wird ja auch bei Sleep-Packages verwendet, damit sich die NPC nicht in voller Montur ins Bett legen.

@ Meclaton

Du kannst jedem NPC eine Skript verpassen, der einen OnDeath-Block hat. Dann erstellst Du in einem Questskript die Variable "Tot", oder was dir beliebt.
Im Objektskript für die NPC schreibst Du set.QuestID.Tot to QuestID.Tot + 1. Bei jedem Ableben eines NPC´s der das Skript hat, erhöht sich dann die Variable Tot. So genügt ein Skript für alle NPC. Im Questskript kannst Du dann auch die Auswertung vornehmen. Z.B.
If Tot == 3
Player.AddItem WasAuchImmer 1
 
Zuletzt bearbeitet:
  • Like
Reaktionen: Meclaton
Aha, deswegen wollte das Result-Script nicht angenommen werden, weil ich die ganze Zeit die NPC-ID anstatt der QuestID eingetippt habe. Aber nun steht alles.

1. Im Questskript steht jetzt

short step
;step == 50 Follow Player without armor (ich habe die 50 nehmen müssen, weil step 10 - 40 schon vergeben sind)

2. Im Follow-Package habe ich die unequipped-Flags und auch Offers Service angehakt, dann bei Conditions die GetQuestVariable Questname == 50, bei Target selbstverständlich den Player mit Count 1

3. Dialog erstellt mit ResultScript set Questname.step to 50, bei den entsprechenden Greetings dieses Topic bei choices eingefügt.

4. In ihre Truhe habe ich letztendlich das upper shirt und upper shoes eingefügt.

Resultat: das Topic ist ingame da, man kann es anwählen, sie folgt auch, wechselt aber ihre Kleidung nicht.
Hab ich irgendwas vergessen?



Edit: OK, sie tut's, aber erst nachdem man nochmal ihr Inventar geöffnet und wieder geschlossen hat. Das kann's aber nicht sein, da muss es doch eine bessere Lösung für geben.
 
Zuletzt bearbeitet:
Vermutlich wird das neue Package beim ersten Mal nicht evaluiert. Ein normales Dialogende sollte aber automatisch die Packages des NPC evaluieren. Was passiert, wenn Du im Result noch ein NPC-ID.evp zusätzlich reinschreibst?
Eine andere Möglichkeit wäre, den Klamottenwechsel über einen Skript zu erledigen. Das würde ich dann über einen Objektskript auf dem Begleiter machen.
Dem Begleiter erstmal nur die Rüstung geben und mit AddItem die Klamotte dem NPC geben. Dann mit UnequipItem und RemoveItem die Rüstung entfernen und mit EquipItem die Klamotte anlegen. Falls Du da ne Vorlage brauchst, ich hab mehrere solche Klamottenwechselskripts in meiner Mod.
 
4. In ihre Truhe habe ich letztendlich das upper shirt und upper shoes eingefügt.
...
Edit: OK, sie tut's, aber erst nachdem man nochmal ihr Inventar geöffnet und wieder geschlossen hat. Das kann's aber nicht sein, da muss es doch eine bessere Lösung für geben.
Nur damit wir uns nicht misverstehen: Meinst Du mit Truhe den Inventory Tab in ihrem CS Eintrag, oder weist Du ihr ihre Ausrüstung irgendwie anders zu? Wenn Du die Sachen einfach per drag-and-drop in ihr Inventory gezogen hast sollte es eigentlich funktionieren. Hat sie irgendwelche Packages die nicht per Dialog angesteuert werden, z.B. ein Eat oder Sleep Package? Dann könntest Du dort auch mal "unequip armor" ankreuzen und testen ob es dort funktioniert. Falls ja hat Beolo sicher recht, dass das Package am Dialogende nicht richtig evaluiert wird.