Construction Set Skriptthread zum Construction Set

Ja das ist richtig. Soweit klappte das schon. Wenn auch viel zu komplex da ohne die Event Handler.
Nur der Schildschaden sollte sich mit weiteren Treffern erhöhen. Ab einem bestimmten Unterschreiten des Schildwertes sollte das Script den Spieler drauf hinweisen, dass es repariert werden müsste.
Soweit so gut.
Nur wenn man das Schild nun nicht repariert wurde, sondern einfach das nächste Schild zum Einsatz kam, stand das Script noch an der selben Stelle und hat dem dann benutztem heilem Schild keinen Schaden zugefügt.

Und du hast wahrscheinlich recht ich verstehe noch immer nicht, wie die Event Handler funktionieren. Zwar habe ich Ihn starten können und auch die Abfrage ob der Gegner eine Hiebwaffe benutzt hat soweit geklappt, doch weiter bin ich halt noch nicht gekommen.

Hier das funktionierende Zwischenergebnis noch ohne Eventhandler
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.


Hier der Scriptanfang mit den Event Handler
PHP:
Der Event Handler wird über eine Quest gestartet.
Das Script diente zum Testen, um die Event Handler zu verstehen

scn A0ItemBlockingPlayer

ref target
ref weapon
short WeaponType
short Schild; EDIT Falsch muss eine REF sein

;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 ; EDIT Muss 13 heissen und als REF deklariert werden
;message $Schild + wid zum Blocken genutzt" ;funktioniert nicht
PrintToConsole "Object16= %.0f"schild
	
;--------------Keine Hiebwaffe------------------------	
else
PrintToConsole "Waffentyp kein Hieb= %.0f"weaponType		
endif
		
end

Ich bin zuversichtlich das wir irgendwann diese Modifikation in Funktion sehen werden.

Im Grunde wollte ich einfach nur die Skilländerung, die der Player im Blocken ab der Stufe Journeyman erhält wieder umkehren. Ich finde es einfach langweilig, dass die Schilde dann nicht mehr kaputt gehen.

Allerdings ist das jetzt auch gut so und müsste von Anfang an so laufen. Ich meine es ist viel besser, wenn ein Schild nur Schaden nimmt wenn der Gegner Hiebwaffen nutzt.
Der Clou des Ganzen und damit die Krönung wenn die Höhe des Schildschadens sogar noch mit bestimmten Wafffen zusätzlich geändert werden würde. Sprich je mehr Gewicht die Hiebwaffe umso mehr Schaden beim Auftreffen. Wäre doch cool. Man stelle sich vor ein mächtiger Gegner kommt angeprecht und zerschmettert mit einem einzigen oder wenigen Hieben das Schild. Oh ha. So bekommen mächtige Gegner ein ganz neues Nivau.
 
Zuletzt bearbeitet:
Du machst da sehr seltsame Schadensberechnungen. Du registrierst doch bestimmt den EventHandler in irgendeinem Questscript, nehme ich an. Diesem Questscript fügst du jetzt noch folgende Zeilen hinzu:
Code:
short hits
ref shield
Deinen anderen Gamemode Script, der auf dem Item liegt, brauchst du gar nicht. Stattdessen kommt die Logik in den EventHandler. Das sparrt Performance und ist zudem auch sinnvoller.
Code:
scn A0ItemBlockingPlayer

ref target
ref weapon
ref shield
float damage

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

;----------Player blockt-------------------------
set shield to target.GetEquippedObject 13
if ( [QUEST].shield != shield )
    set [QUEST].hits to 0
    set [QUEST].shield to shield
endif
    
let [QUEST].hits += 1
set damage to shield.getObjectHealth * ([QUEST].hits / 100)

if (damage > target.GetEquippedCurrentHealth 13)
    set damage = target.GetEquippedCurrentHealth 13
set damage to damage * -1
PrintToConsole "Dein Schild nimmt %.0f Schaden" damage
target.ModEquippedCurrentHealth damage 13

if (target.GetEquippedCurrentHealth 13 < shield.getObjectHealth * 0.4 )
    Message "Mein Schild macht es nicht mehr lange"

end

Ich habe den Script etwas simplifiziert, sollte aber so funktionieren. Die Schadensberechnung setzt jeden weiteren hit einem Prozent gleich. Sprich erste hit = 1% Schaden, zweiter hit 2% schaden und so weiter. Das kannst du später natürlich anpassen, aber wichtig ist erst mal, dass das Grundgerüst klappt, bevor man komplizierte Logik implementiert.
 
Zuletzt bearbeitet:
  • Like
Reaktionen: robinH
Ich glaub es nicht, so geht das! Unglaublich diese Handler. Wenn ich diese doch nur verstehen könnte.

Du setzt dort den Begriff [Quest] überall ein. Kannst du das genauer erklären. Steht der für den Namen der Quest und dient hier als Dummy.

Leider habe ich das nun Folgende und fürs erste ziemlich gut funktionierende Script schon vor dem Lesen deiner neuen Zeilen geschrieben.

Deine Methode scheint mir aber noch besser. Werde ich als nächstes ausprobieren. Hab Dank.

Anbei das Script.

PHP:
scn A0ItemBlockingPlayer

ref Rtarget
ref Rweapon
ref RSchild
float fSchaden
float fWeaponHealth
short SWeaponType

;Target speichert die Zielref (Also das Object welches zum Blocken benutzt wird)
;Weapon speichert die Waffenwerte mit der der Player getroffen wird

;========================================================
Begin Function {Rtarget Rweapon}
	
if Rtarget.isBlocking ==0
return

;----------Player blockt-------------------------		
else
		
messageEX $Rtarget + "-M1-?????" + $RWeapon

PrintToConsole "Begin Function {Rtarget Rweapon} Ausdruck1= %.0f, Ausdruck2= %.0f"Rtarget, Rweapon		
endif
	
set SWeaponType to getWeaponType Rweapon
PrintToConsole "Waffentyp Hieb= %.0f"SweaponType

set RSchild to player.GetEquippedObject 13
PrintToConsole "Object13 Schild= %.0f"Rschild
		
set fWeaponHealth to player.getEquippedCurrentHealth 13		
printToConsole "Schildwert = %.0f"fWeaponHealth			;Testschild =400 Healthpunkte


;-----Hiebwaffenabfrage-----1H,2H----------------	
if SWeaponType ==2 || SWeaponType ==3		
	
	;10% Schaden
	set fSchaden to 10		
	
	;Eingabewert 100	
	;1  Treffer Schildwert auf 300HP	300/4 =75%
	;2  Treffer Schildwert auf 200HP	200/4 =50%
	;3  Treffer Schildwert auf 100HP	100/4 =25%
	;4  Treffer Schild kaputt.   0HP

	;Eingabewert 10
	;1  Treffer Schildwert auf 390HP	390/4 =97%
	;10 Treffer Schildwert auf 300HP	300/4 =75%
	;40 Treffer Schild kaputt.   0HP

	;Eingabewert 20
	;1  Treffer Schildwert auf 390HP	300/4 =97%
	;10 Treffer Schildwert auf 200HP	200/4 =50%
	;20 Treffer Schild kaputt.   0HP
	
	;1H	
	if SweaponType ==2
	Rtarget.ModEquippedCurrentHealth -10 13		; es lässt sich keine Variable (fSchaden) einsetzen ??
	endif

	;2H	
	if SweaponType ==3
	Rtarget.ModEquippedCurrentHealth -20 13		
	endif
			
;--------------Bladeabfrage----1H,2H----------------	
elseif SWeaponType ==0 || SWeaponType ==1		
				
	;Eingabewert 1	
	;1   Treffer Schildwert auf 399HP	399/4 =99%
	;10  Treffer Schildwert auf 390HP	390/4 =97%
	;400 Treffer Schild kaputt.   0HP

	;Eingabewert 2
	;1   Treffer Schildwert auf 398HP	398/4 =99%
	;10  Treffer Schildwert auf 380HP	390/4 =95%
	;200 Treffer Schild kaputt.   0HP		
	
	;1H	
	if SweaponType ==0
	Rtarget.ModEquippedCurrentHealth -1 13		
	endif

	;2H	
	if SweaponType ==1
	Rtarget.ModEquippedCurrentHealth -2 13		
	endif
		
;--------------Bogenabfrage-------------------------	
elseif SWeaponType ==5	
		
	;Eingabewert 0.8	
	;1   Treffer Schildwert auf 399HP	399/4 =99%
	;10  Treffer Schildwert auf 392HP	392/4 =98%
	;500 Treffer Schild kaputt.   0HP

	;1H	
	if SweaponType ==0
	Rtarget.ModEquippedCurrentHealth -0.8 13		
	endif

else		
PrintToConsole "Waffentyp schadet dem Schild nicht= %.0f"SweaponType
			
endif

	
;Schild unbrauchbar
if player.GetEquippedCurrentHealth 13 <=0
player.unequipitem RSchild				; Wie lässt sich das Schild zu Boden fallen lassen?
endif
	
end

Mit welchem Befehl lässt sich das Schild zu Boden fallen lassen und warum lässt sich keine Variable für die 10 einsetzten? Der CS meckert immer sobald ich das tue.
Rtarget.ModEquippedCurrentHealth -10 13
Das mit MessageEx gibt auch wieder kein richtiges Ergebnis. Bis auf die Weapontype und die Schildhealth haben alle Werte immer eine 0 in der Ausgabe. Das Schecke ich überhaupt nicht. Ist wohl so.
 
Zuletzt bearbeitet:
Den Schild fallen lassen, kannst du wahrscheinlich mit "dropMe".

Für die Messages musst du auch andere Stringformatierer benutzen. "%.0f" zeigt den Zahlenwert einer numerischen Variable an. Für den Namen des Objekt musst du "%n" benutzen.
 
  • Like
Reaktionen: robinH
--------------
Code:
scn A0ItemBlockingPlayer

----------------------------

;----------Player blockt-------------------------
set shield to target.GetEquippedObject 13
if ( [QUEST].shield != shield )
    set [QUEST].hits to 0
    set [QUEST].shield to shield
endif
    
let [QUEST].hits += 1
set damage to shield.getObjectHealth * ([QUEST].hits / 100)

if (damage > target.GetEquippedCurrentHealth 13)
    set damage = target.GetEquippedCurrentHealth 13
set damage to damage * -1
PrintToConsole "Dein Schild nimmt %.0f Schaden" damage
target.ModEquippedCurrentHealth damage 13
............

end
................

Wird das let in die obere If -Bedingung mit eingesetzt so alleine darf das doch nicht stehen.
Allerdings weiss ich auch nicht was das Let überhaupt macht. Ist das ein Listenbefehl?

Was wird hier genau gemacht?
let [QUEST].hits += 1

???? Questname.Hitvariable +??? =1

Ich verstehe leider diesen Ausdruck nicht?
 
"Let" ist im Grunde das gleiche wie "set". Es bietet allerdings noch ein paar zusätzliche Möglichkeiten und ist beispielsweise der standardmäßige Ausdruck um Arrays zu bearbeiten ("set" funktioniert standardmäßig nicht, soweit ich weiß).

Hier bedeutet "let [QUEST].hits += 1": "set [QUEST].hits to ( [QUEST].hits + 1 )".

Mehr dazu findest du auch in der OBSE-Dokumentation: Link (Abschnitt "Expression Statements").
 
  • Like
Reaktionen: robinH
Da mir soeben aufgefallen ist, dass ich weiter oben ein paar Syntax Fehler gemacht habe (1 Jahr Modding Auszeit schlägt sich nieder :p), habe ich nun selbst mal eine esp zum Testen erstellt. Es ist am Ende komplizierter ausgefallen, als ich dachte.

Download

Was mich verwundert hat war, dass "GetEquippedObject" keine Referenz im eigentlich Sinne, sondern die Base ID zurückgibt. Und das bringt mehr oder weniger wenig. Kurz: Du kannst nicht 100% zuverlässig abfragen, ob er das Schild tatsächlich wechselt. Ich habe es so gelöst, dass bei jedem Ausrüsten eines Schildes die hits zurückgesetzt werden. Sprich, man könnte das Schild ablegen, wieder anlegen und es würde die hits zurücksetzen. Sehr viel schöner gehts aber nicht. Die Mod ist getestet und funktioniert, wie gesagt, kannst die esp gerne mal testen. Einfach ein Schild in die Hand nehmen und dich treffen lassen, Ausgaben zum Debuggen befinden sich danach in der Konsole (^). Das Ganze sieht am Ende so aus:

Code:
scn GDShieldQuestScript

short hits
ref shield

Begin GameMode
	if getGameRestarted
		printc "GDShieldQuest enabled"
		SetEventHandler "OnHit" GDFnShieldModifier ref::PlayerRef
		SetEventHandler "OnActorEquip" GDFnShieldChange ref::PlayerRef
	endif
End

Code:
scn GDFnShieldChange

ref target
ref item
short slot

;========================================================
Begin Function {target, item}
	let item := CreateTempRef item
	let slot := item.GetEquipmentSlot
	if (slot == 13)
		let GDShieldQuest.hits := 0
		printc "resetting hits"
	endif
end

Code:
scn GDFnShieldModifier

ref target
ref attacker
ref shield
float damage

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

	;----------Player blockt-------------------------
	let GDShieldQuest.hits += 1
	
	let shield := target.GetEquippedObject 13
	let shield := CreateTempRef shield		
	let damage := shield.getObjectHealth * (GDShieldQuest.hits / 100)

	if (damage > target.GetEquippedCurrentHealth 13)
	    let damage := target.GetEquippedCurrentHealth 13
	endif
	PrintToConsole "Dein Schild nimmt %.0f Schaden" damage
	let damage *= -1
	target.ModEquippedCurrentHealth damage 13

	if (target.GetEquippedCurrentHealth 13 < shield.getObjectHealth * 0.3 )
	    Message "Mein Schild macht es nicht mehr lange"
	endif

end
 
Zuletzt bearbeitet:
  • Like
Reaktionen: robinH
Wofür soll den überhaupt die Ref-ID benutzt werden? Es kann doch einfach der Schaden davon abhängen wie der momentane Zustand des Schildes noch ist. Wofür der Hit-Counter?
 
  • Like
Reaktionen: robinH
Der Schaden ist inkrementell abhängig von den maximalen Lebenspunkten des Schildes und immer 1% mehr. Sprich, bei einem Schild mit 300 Lebenspunkten macht der erste Schlag 3 Extraschaden, der nächste 6, der nächste 9 etc. Die Formel ist natürlich nicht perfekt und wahrscheinlich sollte man noch eine maximale Schadensgrenze einbauen, vlt. 10% und nicht mehr. Aber letztendlich dienen diese Scripte ja nur als Fundament und als Beispiel, falls er prozentual zu den Maximallebenspunkten des Schildes rechnen will.
 
  • Like
Reaktionen: robinH
Dank Dir Gildur für diese tolle Arbeit die du dir gemacht hast. Wie du schon sagst es ist doch komplexer als angenommen.
Und wenn man diese Schrittweise Schadenserhöhung einfach weglassen würde. Dann wäre es doch egal ob das Schild gewechselt wird. Oder? Dann würde jedes Schild beschädigt oder komplett neu bei jedem Treffer den selben Schaden erhalten.
So ähnlich funktioniert es ja mit dieser von mir mit deiner Hilfe davor genutzten Methode.

PHP:
scn A0ItemBlockingPlayer

ref Rtarget
ref Rweapon
ref RSchild
float fWeaponHealth
short SWeaponType
;========================================================
Begin Function {Rtarget Rweapon}
	
if Rtarget.isBlocking ==0
return
;----------Player blockt-------------------------		
else
	
set SWeaponType to getWeaponType Rweapon
PrintToConsole "Waffentyp Hieb= %.0f"SweaponType

set RSchild to player.GetEquippedObject 13
PrintToConsole "Object13 Schild= %.nf"Rschild
		
set fWeaponHealth to player.getEquippedCurrentHealth 13		
printToConsole "Schildwert = %.0f"fWeaponHealth			;Testschild =400 Healthpunkte

;-----Hiebwaffenabfrage-----1H,2H----------------	
if SWeaponType ==2 || SWeaponType ==3		
	
	;Eingabewert 10
	;1  Treffer Schildwert auf 390HP	390/4 =97%
	;10 Treffer Schildwert auf 300HP	300/4 =75%
	;Eingabewert 20
	;1  Treffer Schildwert auf 380HP	300/4 =95%
	;10 Treffer Schildwert auf 200HP	200/4 =50%
	
	;1H	
	if SweaponType ==2
	Rtarget.ModEquippedCurrentHealth -10 13
	endif
	;2H	
	if SweaponType ==2
	Rtarget.ModEquippedCurrentHealth -20 13
	endif
...............
...........		
endif
	
;Schild unbrauchbar
if player.GetEquippedCurrentHealth 13 <=0
player.unequipitem RSchild
;dropme RSchild ---Syntax noch nicht getestet
endif
	
end

Nur wie lässt sich dort einbauen, das der Schaden im oberen Beisspiel -10 und bei 2Hand Hiebwaffen -20 sich noch um ein Faktor verändern lässt?

Könnte das so gehen?
PHP:
float fSchadengewicht
float fdamage

if Gewicht der Waffe  >=0 && <10        ; Syntax hier nur Dummy, genauen Abfragebefehl kenn ich nicht.
        set fSchadengewicht =0.1
else
        set fSchadengewicht =0.2
endif

;1H	
if SweaponType ==2
       let fdamage = -10 - (10 *fSchadengewicht)            ;ist das von der Syntax so Richtig? -10-1 =-11
       Rtarget.ModEquippedCurrentHealth fdamage 13
endif

;2H	
if SweaponType ==3
      let fdamage = -10 - (10 *fSchadengewicht)
      Rtarget.ModEquippedCurrentHealth fdamage 13
endif

Ideal wäre es, wenn man über die Ref "Rweapon" den Wert des Gewichts der Waffe erhält und dann zB. Faktoren zum Addieren nutzen könnte.

ZB: Das Gewicht beträgt bis 10 der Faktor würde dann *0.1 das heist die Hiebwaffe macht nicht 10 Schaden sondern 10+(10*0.1) =11
Das Gewicht wäre über 10 der Faktor könnte dann um 0.2 erhöht werden - dann wäre der Schaden 12

Wie würde man das Gewicht abfragen können?
Was ich auch noch nicht verstehe, wann sollte man "let" anstatt "set" benutzen?
 
Zuletzt bearbeitet:
Das Gewicht kannst du mit "getWeight" abfragen.

"Let" muss man bei der Verwendung von Arrays und Strings benutzen. Aber auch sonst bietet es ein paar Vorteile. Zum einen kannst du halt "set x to x+1" durch "let x += 1" abkürzen. Dieses Prinzip ist übrigens auch für die anderen Rechenoperatoren übertragbar ( -= , *= , /= , %= , ^= ). Außerdem kannst du so um Platz zu sparen mehrere Zuweisungen in einer Zeile ausführen.
Das heißt: "let a := b := c := d := 42" würde alle vier Variablen a, b, c und d auf den gleichen Wert setzen, wofür du normalerweise 4 Zeilen bräuchtest.
Es gehen auch kompliziertere Sachen wie: "let a := ( b *= c/3-5 ) - 6". Das wäre sowas wie:
Code:
set b to b*(c/3-5)
set a to b-6


@Gildur:
Was ich meinte ist die reine Kopplung des Schadens an den Zustand des Schildes, also sowas wie:
Code:
let Schild := player.getEquippedObject 13

let damage := bla * ( getObjectHealth Schild ) / ( player.getEquippedObjectHealth 13 )
 
  • Like
Reaktionen: robinH
Ideal wäre es, wenn man über die Ref "Rweapon" den Wert des Gewichts der Waffe erhält und dann zB. Faktoren zum Addieren nutzen könnte.

ZB: Das Gewicht beträgt bis 10 der Faktor würde dann *0.1 das heist die Hiebwaffe macht nicht 10 Schaden sondern 10+(10*0.1) =11
Das Gewicht wäre über 10 der Faktor könnte dann um 0.2 erhöht werden - dann wäre der Schaden 12

Ich würde es in etwa so machen:
Code:
scn GDFnShieldModifier

ref target
ref weapon
short weapontype
short basedamage
short additionalDamage
short damage

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

	;----------Player blockt-------------------------
	set weapontype to weapon.GetWeaponType

	let basedamage := 10
	if weapontype == 3
		let basedamage := 20
	endif
	
	let additionalDamage := GetWeight weapon * 0.1
	let damage := basedamage + additionalDamage
	
	if (damage > target.GetEquippedCurrentHealth 13)
	    let damage := target.GetEquippedCurrentHealth 13
	endif
	
	PrintToConsole "Dein Schild nimmt %.0f Schaden" damage
	let damage *= -1
	target.ModEquippedCurrentHealth damage 13

end



@Gildur:
Was ich meinte ist die reine Kopplung des Schadens an den Zustand des Schildes, also sowas wie:
Code:
let Schild := player.getEquippedObject 13

let damage := bla * ( getObjectHealth Schild ) / ( player.getEquippedObjectHealth 13 )

Stimmt, daran habe ich gar nicht gedacht. Ist in der Tat ein Schritt weniger.
 
  • Like
Reaktionen: robinH
Oh mein Gott- Ihr habt es voll drauf. Ich sitze an der Mod schon fast den ganzen Monat und Ihr habt das mal eben so fertig geschrieben.

Werde am WE erst mal versuchen diese Umdenken zwischen der verkürzten Form Let und dem ursprügnlichen set versuchen umzusetzten. Ich denke mal durch Übung wird das schon gehen. Dieses Rückwertsdenken lag mir noch nie, deshalb fällt es mir auch ungalublich schwer zu verstehen, was Ihr da genau berechnet. Danke Diarrhoe für die ausführliche Erklärung und den Beispielen dazu. Das hilft mir und bestimmt auch anderen.

@Gildur
Der Kompromiss Gildur ist ziemlich störend. Manchmal kommt es vor das ein Player zum nachschauen (Wie steht dem Char das Schild) das leicht beschädigte Schild mit einem anderen tauscht. Doch dann würde der Hit zurückgesetzt werden. Der Player bekommt es ohne Konsole nicht mit, ob der Schaden konstant oder steigernd erfolgt. Somit ist es besser das Prozentuale ansteigen, da es solche Probleme macht, wegzulassen. War halt eine Idee. Dafür sorgt dann das Gewicht für Abwechslung in der Schadensstärke.
.............
Code:
scn GDFnShieldModifier

ref target
ref weapon
short weapontype
short basedamage
short additionalDamage
short damage
;========================================================
Begin Function {target, weapon}
    
	if target.isBlocking == 0
	    return
	endif

	;----------Player blockt-------------------------
	set weapontype to weapon.GetWeaponType

	let basedamage := 10
	if weapontype == 3
		let basedamage := 20
	endif
	
	let additionalDamage := GetWeight weapon * 0.1
	let damage := basedamage + additionalDamage
	
	if (damage > target.GetEquippedCurrentHealth 13)
	    let damage := target.GetEquippedCurrentHealth 13
	endif
	
	PrintToConsole "Dein Schild nimmt %.0f Schaden" damage
	let damage *= -1
	target.ModEquippedCurrentHealth damage 13
end
..........
Das sieht alles so schön kompakt aus. Doch die Abfrage ob das Gewicht der Waffe < 10 oder >10 ist fehlt. Oder ist das da irgendwo versteckt zu finden?

Gestern habe ich erst mal alles was Ihr so geschrieben habt umgesetzt. Allerdings erst noch mit der Syntax set- aus den oben genannten Gründen.
Es funktioniert tadellos und man kann jedes beliebige Schild ob kaputt oder heile tauschen ausrüsten und reparieren. Jedes Schild wird entsprechend wie das Script es vorgibt beschadigt. Der genannte Kompromiss ist nicht vorhanden. Auch die Waffentypen funktionieren.

Das mit dem Drop macht jedoch leider noch Schwierigkeiten.

PHP:
scn A0ItemBlockingPlayer

ref Rtarget
ref Rweapon
ref RSchild
float fSchaden
float fSchaden2H
float fWeaponHealth
short SWeaponType

;==============================================================
Begin Function {Rtarget Rweapon}

if Rtarget.isBlocking ==0
return
endif
	
;===========Player blockt======================================

if player.GetEquippedObject 13		;Der Player benutzt ein Schild zum Blocken, sonst läuft das Script auch bei anderen Blockarten
		
set SWeaponType to getWeaponType Rweapon
set RSchild to player.GetEquippedObject 13
set fWeaponHealth to player.getEquippedCurrentHealth 13		
	
	;-----Hiebwaffenabfrage-----1H,2H--------------------	
	if SWeaponType ==2 || SWeaponType ==3		
	
		set fSchaden 	to 10*-1
		set fSchaden2H 	to 20*-1		
		
		;Eingabewert 10  --40 Treffer Schild auf 0HP-
		;1  Treffer Schildwert auf 390HP	390/4 =97%
		;10 Treffer Schildwert auf 300HP	300/4 =75%	

		;Eingabewert 20  --20 Treffer Schild auf 0HP--
		;1  Treffer Schildwert auf 380HP	380/4 =95%
		;10 Treffer Schildwert auf 200HP	200/4 =50%
	
		if SweaponType ==2
		Rtarget.ModEquippedCurrentHealth fSchaden 13
		endif		
		if SweaponType ==3
		Rtarget.ModEquippedCurrentHealth fSchaden2H 13		
		endif
		
	;--------------Bladeabfrage----1H,2H----------------	
	elseif SWeaponType ==0 || SWeaponType ==1

		set fSchaden 	to 1*-1
		set fSchaden2H 	to 2*-1		
				
		;Eingabewert 1  --400 Treffer Schild auf 0HP--	
		;1   Treffer Schildwert auf 399HP	399/4 =99%
		;10  Treffer Schildwert auf 390HP	390/4 =97%

		;Eingabewert 2  --200 Treffer Schild auf 0HP--
		;1   Treffer Schildwert auf 398HP	398/4 =99%
		;10  Treffer Schildwert auf 380HP	390/4 =95%	
		
		if SweaponType ==0
		Rtarget.ModEquippedCurrentHealth fSchaden 13
		endif
		if SweaponType ==1
		Rtarget.ModEquippedCurrentHealth fSchaden2H 13
		endif
		
	;--------------Bogenabfrage-------------------------	
	elseif SWeaponType ==5
		
		set fSchaden 	to 0.8*-1
		
		;Eingabewert 0.8 --500 Treffer Schild auf 0HP--
		;1   Treffer Schildwert auf 399HP	399/4 =99%
		;10  Treffer Schildwert auf 392HP	392/4 =98%
	
		if SweaponType ==5
		Rtarget.ModEquippedCurrentHealth fSchaden 13
		endif
		
	else		
	;PrintToConsole "(Zauberstab) Typ=%.0f"SweaponType			
	endif

	;-----------Schild unbrauchbar---------------------
	
	;if fWeaponHealth >=5 && <10
	;message "Mein Schild ist nicht mehr zu gebrauchen"	;TEst: das Script läuft nicht weiter
	;endif

	if fWeaponHealth <=0
	player.unequipitemNS RSchild	;sonst behält der Player das Schild mit HP0% in der Hand
	;player.drop RSchild 1		;Drop OK, aber Schild am Boden hat HP100%
	playsound CWoodLarge		;Sonst hört man das Schild nicht kaput gehen		

		
	;dropme RSchild	;Player hat Schild weiter in der Hand, Drop OK, Schild drop HP100%, Inventaraufruf crash	
	;dropme		;wird ignoriert
	
	endif

;================Consolenausgabe======================================================	
Print"-------------------------------------------------------------------------------"		
PrintToConsole "Target (%n), Object (%n) wird getroffen mit (%n)"Rtarget, Rschild, Rweapon
PrintToConsole "Waffentyp=%.0f (Stich1H=0, 2H=1, Hieb1H=2, 2H=3, Bogen=5)"SweaponType
printToConsole "SchildHP=%.0f, Sfaktor=%.0f, Sfaktor2H=%.0f"fWeaponHealth, fschaden, fSchaden2H	

else
print "Kein Schild in der Hand"		
endif
	
end

Wie gesagt das mit dem Drop funktioniert noch nicht richtig.

player.drop
Sobald das Schild gedropt wird, liegt am Boden ein komplett neues Schild. Das heisst das Zerstörte ist nicht mehr da. Das neue lässt sich benutzen.

dropme
Das selbe wie vorher, nur das sobald das Neue aufgenommen wird, ein Crash beim Aufruf des Inventars kommt.

Gibt es einen Weg das gedroppte als kaputtes Schild zu definieren,
oder das das wirklich defekte Schild zu Boden fällt?


Weiter funktioniert die vorzeitige Meldung, das das Schild bald kaputt ist, nicht. Warum ich habe keine Ahnung. Das Script stoppt an der Stelle.

Bestimmt lässt sich das was ich da geschrieben habe mit der Syntax let verkürzen, das mache ich dann am WE. Anregungen dazu wären schön.
 
Zuletzt bearbeitet:
Das sieht alles so schön kompakt aus. Doch die Abfrage ob das Gewicht der Waffe < 10 oder >10 ist fehlt. Oder ist das da irgendwo versteckt zu finden?

Ist "versteckt":
Code:
let additionalDamage := GetWeight weapon * 0.1
Müsste man aber eigentlich noch anpassen und +1 am Ende addieren. was das Script ohne +1 macht ist folgendes:

Gewicht < 10 = 0 extra damage
Gewicht < 20 = 1 extra damage
Gewicht < 30 = 2 extra damage
... und so weiter.

Wenn du am Ende einfach 1 addierst, kannst du es erhöhen. Ich dachte es wäre realistischer, wenn es für jede 10 Gewichteinheiten mehr auch Extraschaden gibt und nicht nur zwischen <10 und >10 unterschieden wird. Kannst du natürlich auch anpassen.

Das Drop hingegen funktioniert nicht so, wie du es dir wünschst, weil du nicht die exakte Referenz des Schildes hast und diese auch nicht so einfach kriegen kannst. Ich würde wahrscheinlich das Inventar durchschleifen und das ausgerüstete Schild finden und anschließend droppen. Ich glaube einfacher gehts nicht.
 
  • Like
Reaktionen: robinH
Dank dir, da ist das also wirklich versteckt gewesen. Da kann man mal wieder sehen das ich rein garnichts bisher verstanden habe. Doch die Sache wird immer klarer.

Ja du hast recht es ist schöner den Schaden bei höherer Gewichtsklasse zu erhöhen.

Ist "versteckt":
Code:
let additionalDamage := GetWeight weapon * 0.1
Müsste man aber eigentlich noch anpassen und +1 am Ende addieren. was das Script ohne +1 macht ist folgendes:

Gewicht < 10 = 0 extra damage
Gewicht < 20 = 1 extra damage
Gewicht < 30 = 2 extra damage
... und so weiter.

.................für jede 10 Gewichteinheiten mehr auch Extraschaden gibt ..........................
........

Wo setze ich denn die Variable 10 ein? Welcher Wert müsste geändert werden um dieses Ergebnis zu erhalten?
Gewicht < 5 = 0 extra damage
Gewicht < 8 = 1 extra damage
Gewicht < 11 = 2 extra damage


Das mit dem Drop klappt recht gut, auch das automatische entfernen aus dem Inventar klappt. Nur nicht das das neue gedroppte Schild erstmal 0% HP hat. Lässt sich das denn nicht vor dem Drop per Script ebenfalls auf 0% stellen.

Warum das Ganze. Es ist irgendwie lustig, wenn da mitten Im Kampf, der Player weiss ja nicht wann das Schild zerbricht, dieses noch eben genannte Schild während des Blockens mit einem Krachen zu Boden fällt. Das klappt ja auch so weit. Nur das das zu Boden fallende Schild nicht das eben gehaltende sondern ein komplett Neues ist.

Das muss doch irgend wie gehen.
 
Zuletzt bearbeitet:
Du könntest es mit "setCurrentHealth" versuchen, aber vielleicht klappt das nur, wenn der Gegenstand im Inventar ist... Um die Referenz des gedropten Schildes abzufragen, musst du wahrscheinlich notgedrungen "getFirstRef/getNextRef" benutzen und dann abfragen, wie weit das Item vom Spieler entfernt ist.
Drop bietet leider auch den Nachteil, dass man nicht vorhersehen kann, welcher Gegenstand aus dem Inventar entfernt wird, wenn es mehrere der betreffenden Base-ID im Inventar gibt. Das würde beispielsweise "dropMe" ermöglichen.
 
  • Like
Reaktionen: robinH
Wo setze ich denn die Variable 10 ein? Welcher Wert müsste geändert werden um dieses Ergebnis zu erhalten?
Gewicht < 5 = 0 extra damage
Gewicht < 8 = 1 extra damage
Gewicht < 11 = 2 extra damage

Das würde wie folgt aussehen:
Code:
let additionalDamage := ((GetWeight weapon - 5) / 3) + 1

Nur das das zu Boden fallende Schild nicht das eben gehaltende sondern ein komplett Neues ist.

Das muss doch irgend wie gehen.

Diarrhoe hat schon alles wichtige gesagt und die Gründe genannt, weswegen ich diese Funktion auch weglassen würde. Wenn du es aber trotzdem versuchen willst empfehle ich dir GetPCLastDroppedItemRef in Kombination mit Diarrhoe's genanntem Befehl SetCurrentHealth.
 
  • Like
Reaktionen: robinH
Das würde wie folgt aussehen:
Code:
let additionalDamage := ((GetWeight weapon - 5) / 3) + 1

Gewicht < 5 = 0 extra damage
Gewicht < 8 = 1 extra damage
Gewicht < 11 = 2 extra damage
Kann das jemand erklären. Wo befindet sich die > oder das < ist das das negative und positive Vorzeichen. Wo ist die 8 und wo die 11?
Wofür steht das geteilt? Warum verstehe ich das bloss nicht. Wie Kreuz und Quer muss man denn da denken?

Ich zeige mal meinen Gedankengang.

Extraschaden um ein Punkt erhöht, wenn das Gewicht der Waffe kleiner 5 oder ???? drei
Hm.

Das heisst wenn ich die 3 Zeile nicht um 1 sondern um 2 erhöhen möchte, muss das wieder anders geschrieben werden.
Das +1 steht doch für 1 Schaden extra oder? Wie hoch wäre hier denn der Extraschaden bei einem Gewicht von 20?

Und wie würde das zB aussehen bei
Gewicht < 5 = 0 extra damage
Gewicht < 8 = 1 extra damage
Gewicht < 11 = 3 extra damage

-----------------------------------------------------------------------------------------------

Zur Dropschwierigkeit
Ich denke mal das ich das mit dem Drop ganz anders löse.

In Wirklichkeit ist ein total zerstörtes Schild auch nicht reparierpar. Warum also in diesem Game.

Ich werde einfach ein Dummyobject nehmen und dieses dann zu Boden fallen lassen. Als Schild ist das dann nicht zu gebrauchen. Wenn man es aufnimmt, dann ist es ein Schrottgegenstand der nur unötiger Balast ist.

Das sorgt auch dafür, das der Player, den Zustand eines besonderen Schildes öfters überprüft und es halt nicht bis zum 0% Zustand kommen lässt. Bei Schilden die der Gegner nutzt oder die öfters auftauchen ist es dann egal. Da lässt man es halt in Stücke hauen.

Doch ich denke das ist ein guter Kompromiss und vereinfacht das Ganze.

Jetzt muss ich nur noch ein geeignetes Dummyobject finden. Jemand eine Idee?
 
Zuletzt bearbeitet: