|
-
Zitat von Moe
The polling rate of the function B_AssessDamage depends on the perception rate of PERC_ASSESSDAMAGE, which is equal to 1 second:
\Ai\Ai_intern\perception.d
Npc_SetPercTime(self,1); //1 second
Npc_PercEnable(self,PERC_ASSESSDAMAGE,B_AssessDamage);
Try check BS_PARADE in Trigger-Script or LeGo Loop function with more frequent polling.
-
Setzt sich eigentlich außer mir noch jemand mit diesem Blockschaden auseinander?
Ich komme da nicht wirklich weiter und wäre ja schon ein geiles Feature, praktisch die Revolution des Gothic 2 Kampfsystems sozusagen.
-
Hello. A lot of examples have been sorted out, but so far it has stopped as it is. I do not know how to configure the check so that if Hero hit by attaker hits, the output is of the same color, if attacker hit by hero, the output is of a different color. Now the whole conclusion is always the same color.
Code:
func void _DMG_OnDmg_Post() {
EDI = DMG_OnDmg(EBP, MEM_ReadInt(MEM_ReadInt(ESP+644)+8), EDI, _DMG_DmgDesc);
dmg3 = EDI;
var oCNpc her;
var oCNpc sel;
her = Hlp_GetNpc(hero);
sel = Hlp_GetNpc(self);
if(dmg3 != 0)
{
if(Npc_IsPlayer(her))
//if(Hlp_GetInstanceID(self) != Hlp_GetInstanceID(hero))
{
//this conclusion there is
PrintS_Ext(ConcatStrings("Урон (Damage): ",IntToString(dmg3)), RGBA(255, 215,0,255));
}
//else if(_^(self) == _^(hero))
else if(Npc_IsPlayer(sel))
{
//this conclusion is not
PrintS_Ext(ConcatStrings("Урон (Damage): ",IntToString(dmg3)), RGBA(255, 0,0,255));
};
};
};
Thanks for help.
-
Code:
her = Hlp_GetNpc(hero);
if(Npc_IsPlayer(her))
is always true?
You probably want to check for something along the lines of other?
-
Zitat von Milky-Way
Code:
her = Hlp_GetNpc(hero);
if(Npc_IsPlayer(her))
is always true?
Yes.
I tried to check the ID of the Hero himself, but it did not bring success.
I understand that any NPS fits the condition if(Hlp_GetInstanceID(self) == Hlp_GetInstanceID(her))
Code:
func void _DMG_OnDmg_Post(){
EDI = DMG_OnDmg(EBP, MEM_ReadInt(MEM_ReadInt(ESP+644)+8), EDI, _DMG_DmgDesc);
dmg3 = EDI;
var C_Npc her;
//var oCNpc sel;
her = Hlp_GetNpc(PC_HERO);
//sel = Hlp_GetNpc(self);
if(dmg3 != 0)
{
//if(Npc_IsPlayer(her))
//if(Npc_IsPlayer(hero) && (self.id == 0))
//if(her.id == 0)
//if(Hlp_GetInstanceID(self) != Hlp_GetInstanceID(hero))
if(Hlp_GetInstanceID(self) == Hlp_GetInstanceID(her))
{
PrintS_Ext(ConcatStrings("Урон: ",IntToString(dmg3)), RGBA(255, 215,0,255));
}
//else if(_^(self) == _^(hero))
//else if(Npc_IsPlayer(sel))
else
{
PrintS_Ext(ConcatStrings("Урон: ",IntToString(dmg3)), RGBA(255, 0,0,255));
};
}; };
-
The variable self doesn't point necessarily to the attacker. In fact it could point to any npc.
What you need:
var int attackerptr; attackerptr = MEM_ReadInt(MEM_ReadInt(ESP+644)+8); //pointer to attacker
var int victimPtr; victimPtr = EBP ; //pointer to victim
To get c_npc variables, use:
var c_npc slf; slf = _^(attackerptr);
var c_npc oth; oth = _^(victimPtr);
Of course, you can also cast to an oCNpc variable like this:
var oCNpc slf; slf = _^(attackerptr);
-
Zitat von Neconspictor
The variable self doesn't point necessarily to the attacker. In fact it could point to any npc.
What you need:
var int attackerptr; attackerptr = MEM_ReadInt(MEM_ReadInt(ESP+644)+8); //pointer to attacker
var int victimPtr; victimPtr = EBP ; //pointer to victim
To get c_npc variables, use:
var c_npc slf; slf = _^(attackerptr);
var c_npc oth; oth = _^(victimPtr);
Of course, you can also cast to an oCNpc variable like this:
var oCNpc slf; slf = _^(attackerptr);
I tried it, the result - it does not go beyond the first print. I tried to swap the pointers - the result is zero.
Code:
func void _DMG_OnDmg_Post() {
EDI = DMG_OnDmg(EBP, MEM_ReadInt(MEM_ReadInt(ESP+644)+8), EDI, _DMG_DmgDesc);
dmg3 = EDI;
var int attackerptr; attackerptr = MEM_ReadInt(MEM_ReadInt(ESP+644)+8);
var int victimPtr; victimPtr = EBP ;
if(dmg3 != 0)
{
if(victimPtr)
{
PrintS_Ext(ConcatStrings("Урон ваш (damage hero): ",IntToString(dmg3)), RGBA(255, 215,0,255));
}
else if(attackerptr)
{
PrintS_Ext(ConcatStrings("Урон по вам (damage by hero): ",IntToString(dmg3)), RGBA(255, 0,0,255));
};
};
};
-
victimPtr and attakerPtr should never be zero, so it is naturally that only the first Print is printed.
What do you mean with 'the result is zero' ?
-
Zitat von Neconspictor
victimPtr and attakerPtr should never be zero, so it is naturally that only the first Print is printed.
What do you mean with 'the result is zero' ?
That's not necessarily true, attackerPtr can be zero, iirc. if someone is hit by Firerain
-
Zitat von Kirides
That's not necessarily true, attackerPtr can be zero, iirc. if someone is hit by Firerain
Alright, thanks
-
Lehrling
Hi,
I wonder how can i use this fucntion to calculate dmg for Charge Spells, because If i put things like this:
Code:
if (dmgDescriptor.SpellID == SPL_FIRESTORM)
{
splDMG = (SPL_DAMAGE_FIRESTORM + slf2.name1 - oth.protection[PROT_FIRE]);
dmg = splDMG;
};
The spell damage will be always the same no matter if i charge it or not.
My question is how i can check the spell level or something like this to calculate charge dmg?
-
The DamageDescriptor contains the value
Code:
var int spellLevel; // zDWORD 0x20
which might be how often the player charged the spell. I'm not sure, though, so you will have to try it out.
-
Lehrling
Yes i tried it but it didnt work, maybe i dont know how to use it in my function .
Geändert von rezu93 (11.05.2020 um 17:15 Uhr)
-
Please write in English, foreign languages not understood by the moderators are generally frowned upon here (mostly for legal purposes).
And show exactly what you have tried, otherwise we can't help you any further.
-
Lehrling
Im sorry Lehona, my Google Chrome just translated my english words when i was editing, i didnt noticed
I tried this:
Code:
dmgDescriptor.spellLevel = Npc_GetActiveSpellLevel(slf);
then i printed it in game but it always show me "1" no matter if i charged or not
btw im working with G1 and spell firestorm looks like this:
Code:
func int Spell_Logic_Firestorm (var int manaInvested)
{
PrintDebugNpc (PD_MAGIC, "Spell_Logic_Firestorm");
if (manaInvested ==(SPL_SENDCAST_FIRESTORM*3)/10)
|| (manaInvested ==(SPL_SENDCAST_FIRESTORM*5)/10)
|| (manaInvested ==(SPL_SENDCAST_FIRESTORM*8)/10)
{ return SPL_NEXTLEVEL; };
if (manaInvested >= SPL_SENDCAST_FIRESTORM)
{ return SPL_SENDCAST; };
return SPL_RECEIVEINVEST;
};
So maybe this is the problem? Because i know this was bugged with manainvest in G1 and i want to changed it anyway but spellLevel?
Edit: I make it another way:
Code:
func int Spell_Logic_Firestorm (var int manaInvested)
{
skalowanie = self.name1;
PrintDebugNpc (PD_MAGIC, "Spell_Logic_Firestorm");
if (manaInvested ==(SPL_SENDCAST_FIRESTORM*3)/10)
{
splLevel = 2;
return SPL_NEXTLEVEL;
}
else if (manaInvested ==(SPL_SENDCAST_FIRESTORM*5)/10)
{
splLevel = 3;
return SPL_NEXTLEVEL;
}
else if (manaInvested ==(SPL_SENDCAST_FIRESTORM*8)/10)
{
splLevel = 4;
return SPL_NEXTLEVEL;
};
if (manaInvested >= SPL_SENDCAST_FIRESTORM)
{ return SPL_SENDCAST; };
return SPL_RECEIVEINVEST;
};
and in DmgOnDmg function:
Code:
if (dmgDescriptor.SpellID == SPL_FIRESTORM)
{
var string concatText;
concatText = ConcatStrings("Poziom czaru: ",IntToString(splLevel));
PrintS_Ext(concatText,RGBA(255, 255, 255, 255));
if (splLevel <= 1)
{
splDMG = (SPL_DAMAGE_FIRESTORM + slf2.name1 - oth.protection[PROT_FIRE]);
}
else if (spllevel == 2)
{
splDMG = (SPL_DAMAGE_FIRESTORM*2 + slf2.name1 - oth.protection[PROT_FIRE]);
}
else if (spllevel == 3)
{
splDMG = (SPL_DAMAGE_FIRESTORM*3 + slf2.name1 - oth.protection[PROT_FIRE]);
}
else if (spllevel == 4)
{
splDMG = (SPL_DAMAGE_FIRESTORM*4 + slf2.name1 - oth.protection[PROT_FIRE]);
};
dmg = splDMG;
if (splDMG < 5 && !(C_BodyStateContains(oth2, BS_MOD_BURNING)))
{
dmg = MinimalDMG;
PrintS_Ext("InstantFireStorm DMG MINIMAL",RGBA(255, 255, 255, 255));
};
splLevel = 1;
};
Geändert von rezu93 (11.05.2020 um 19:35 Uhr)
-
You're not supposed to set the spellLevel, you should just read it out.
Call
Code:
Print(IntToString(dmgDescriptor.spellLevel));
in your OnDmg-function and see what happens when you use a charged-up spell.
-
Lehrling
dmgDescriptor.spellLevel is always = 8 no matter if charge or not
Code:
if (dmgDesc.SpellID > 0)
{
if (dmgDesc.SpellID == SPL_FIRESTORM)
{
concatText = ConcatStrings("Poziom czaru: ",IntToString(dmgDesc.spellLevel));
PrintS_Ext(concatText,RGBA(255, 255, 255, 255));
splDMG = (SPL_DAMAGE_FIRESTORM + slf.name1 - oth.protection[PROT_FIRE]);
if (splDMG < 5 && !(C_BodyStateContains(oth, BS_MOD_BURNING)))
{
dmg = MinimalDMG;
PrintS_Ext("InstantFireStorm DMG MINIMAL",RGBA(255, 255, 255, 255));
};
};
};
Geändert von rezu93 (12.05.2020 um 21:16 Uhr)
-
Hallo, da der Thread noch nicht zu alt ist, bitte ich mal fix um Hilfe. Habe vor 2 Jahren oder so schonmal versucht die G1 Schadensberechnung zu modifizieren, nur damals erkannte das Programm sämtliche Rüstungswerte als -65.000 oder so an. Da hier aber einige gepostet haben, dass sie die Schadensberechnung in G1 erfolgreich geändert haben, möchte ich es nochmal neu versuchen.
Problem ist, dass das Spiel abstürzt, sobald ich einen Gegner treffe. Spiel startet, ich kann auch alles machen, bis die Schadensberechnung ausgeführt wird.
Ich vermute mal, dass der Fehler bei HookEngineF(7567329, 6, _DMG_OnDmg_Post); oder
const int oCNpc__OnDamage_Hit = 7541776; HookEngineF(oCNpc__OnDamage_Hit, 7, _DMG_OnDmg_Pre); liegt.
Habe damals Post 48/49 mal gefragt was man dort für G1 einsetzen müsse, hat glaube ich auch funktioniert. Aber vielleicht muss man dank Lego upgrade da jetzt was neues eintragen. Wie gesagt soll für G1 laufen, für G2 läuft es momentan noch Problemlos, wobei ich noch das alte script mit DMG_OnDmg(var int victimPtr, var int attackerPtr, var int dmg) benutze,
Edit:
hat sich erledigt, hab vergessen
EDI = DMG_OnDmg(EBP, MEM_ReadInt(MEM_ReadInt(ESP+644)+8), EDI, _DMG_DmgDesc); auf EAX = DMG_OnDmg(ECX, MEM_ReadInt(MEM_ReadInt(ESP+548)+4), EAX, _DMG_DmgDesc); umzuändern.
Aber selbes Problem bleibt wie ich auch damals schon hatte. Das Programm erkennt Rüstungswerte ab 30 oder so auf einmal als minus 100.000 oder so an. Ich verstehs nichts, wenn ich den Rüstungswert des Helden im Dialog oder so abfrage wird der richtige Rüstungswert erkannt.
Geändert von Teron Gorefiend (17.06.2020 um 13:27 Uhr)
-
Ich hatte jetzt das Problem, das ich einen Brandschaden-Effekt hinzufügen wollte, aber durch dieses Script gab es zu dem benötigten Zeitpunkt keinen "Angreifer" (attackerPtr leer)
Also habe ich mich hingesetzt und ... dabei kam die Klassendefinition für eine oCVisualFX raus.
Zauber wie Feuersturm machen Flächenschaden, aber der "Explosions-Effekt" hat keinen "attackerPtr". Diesen kann man aber über den VisualFX aus der DamageDescription auslesen:
"visFx.inflictor" ist hierbei derjenige der den Zaube gewirkt hat.
Code:
func int DMG_OnDmg(var int victimPtr, var int attackerPtr, var int dmg, var int dmgDescriptorPtr) {
// ...
var int dmgIsVFX; dmgIsVFX = FALSE;
if (!attackerptr && dmgDesc.visualFX) {
// z.B. Brandschaden
var oCVisualFX visFx; visFx = MEM_PtrToInst(dmgDesc.visualFX);
attackerptr = visFx.inflictor;
dmgIsVFX = TRUE;
};
// ...
};
Ich benutze es um der Feuersturm-Explosion den gleichen Brandschaden über Zeit wie dem Feuerstum zu geben. Das ist für die immersion wichtig (Warum brennt der angegriffene, aber die anderen getroffenen bekommen keinen Brandschaden über Zeit?)
oCVisualFX.d - Zugriff auf die Eigenschaften einer VisualFx (z.B. Feuer-Effekt durch Vobs)
( Die Klassendefiniton ist nur mit Gothic 2 Die Nacht des Raben kompatibel. )
Geändert von Kirides (02.02.2021 um 11:49 Uhr)
Grund: oCVisualFX aktualisiert
-
Falls jemand in seiner Schadensberechnun wissen möchte ob ein Treffer ein "Volltreffer" war, dann könnt ihr iesen Code hier verwenden (Gothic 2)
in der Konstante "Dmg_IsHit" steht dann ob der aktuelle Treffer ein Volltreffer ist. (1 = Volltreffer, 0 = Mindestschadens-berechnung)
Code:
/// Gibt an ob der aktuelle Treffer ein "Volltreffer" ist.
const int Dmg_IsHit = 0;
func int DMG_OnDmg(var int victimPtr, var int attackerPtr, var int dmg, var int dmgDescriptorPtr) {
// ...
};
func void _DMG_OnDmg_Post() {
Dmg_IsHit = MEM_ReadInt((ESP + 640) - 356 /*zBOOL bHasHit*/);
EDI = DMG_OnDmg(EBP, MEM_ReadInt(MEM_ReadInt(ESP+644)+8), EDI, _DMG_DmgDesc);
};
EDIT: In dem Script werden ja 2 Hooks verwendet, einmal um den oSDamageDescriptor zu bekommen und einmal für das setzen des Schadens für Npc->ChangeAttribute(...)
Ist es falsch/gefährlich wenn man statt der 2 Hooks nur einen verwenden würde, aber dafür den oSDamageDescriptor aus dem ESP+644 (280h +4) auslesen würde? (Soweit ich dem Zeug in IDA glauben kann, sollte das das Stack-Argument vom übergebenen &oSDamageDescriptor sein :/ )
Code:
func void _DMG_OnDmg_Post() {
Dmg_IsHit = MEM_ReadInt((ESP + 640) - 356 /* zBOOL bHasHit */);
EDI = DMG_OnDmg(EBP, MEM_ReadInt(MEM_ReadInt(ESP+644)+8), EDI, +MEM_ReadInt((ESP + 640) + 4));
};
Geändert von Kirides (22.08.2020 um 15:26 Uhr)
Berechtigungen
- Neue Themen erstellen: Nein
- Themen beantworten: Nein
- Anhänge hochladen: Nein
- Beiträge bearbeiten: Nein
|
|