|
-
Manaentzug pro Schlag mit einem bestimmten Schwert
Huhu
Ich hab heute eine neue Idee umsetzen wollen, aber dabei schon wieder Schwierigkeiten..
Ich möchte gern für ein bestimmtes Schwert Manakosten einfügen. Dafür hab ich in die Dmg_OnDmg Funktion (wird jedes Mal aufgerufen, wenn irgendwo Schaden gemacht wird), die mir Lehona mal zur Verfügung gestellt hat, Folgendes hinzugefügt:
Code:
func int DMG_OnDmg(var int victimPtr, var int attackerPtr, var int dmg, var int dmgDescriptorPtr)
{
var oSDamageDescriptor dmgDesc; dmgDesc = _^(dmgDescriptorPtr);
// Diese Funktion anpassen, wenn ihr den Schaden verändern wollt! 'dmg' ist der von Gothic berechnete Schaden
// return dmg;
var c_npc victimNpc;
victimNpc = MEM_PtrToInst(victimPtr);
var c_npc attackerNpc;
attackerNpc = MEM_PtrToInst(attackerPtr);
var c_item rdyweapon;
rdyweapon = Npc_GetReadiedWeapon(hero);
if(Hlp_IsItem(rdyweapon, ItMw_Glamdring) == TRUE)
{
if(Npc_IsPlayer(attackerNpc))
{
if(hero.attribute[ATR_MANA] >= 20)
{
hero.attribute[ATR_MANA] -= 20;
return dmg;
} else {
dmg = 5;
return dmg;
};
} else {
return dmg;
};
};
};
Bekomme keine Fehler, aber es tut sich nichts beim Mana, wenn der Held mit dem Schwert zuschlägt (und trifft). Auch wenn der Held weniger als 20 Mana zur Verfügung hat, macht es noch den vollen Schaden, obwohl dann nur noch 5 Schaden fällig sein sollen.
Kann mir hier vielleicht nochmal jemand helfen?
Liebe Grüße,
Gladi
Geändert von gladi1994 (30.07.2020 um 15:46 Uhr)
-
Zitat von gladi1994
Huhu
...
Kann mir hier vielleicht nochmal jemand helfen?
Liebe Grüße,
Gladi
Vielleicht eine dumme frage - aber ...
Hast du das Schadens-Skript auch ordentlich initialisiert, damit es überhaupt wirklich angewandt wird?
also... irgendwo (Story.d INIT_GLOBAL funktion ) das Init ausgeführt?
Code:
func void InitDamage() {
const int dmg = 0;
if (dmg) { return; };
HookEngineF(6736583/*0x66CAC7*/, 5, _DMG_OnDmg_Post);
const int oCNpc__OnDamage_Hit = 6710800;
HookEngineF(oCNpc__OnDamage_Hit, 7, _DMG_OnDmg_Pre);
dmg = 1;
};
Nebenbei hast du am ende des Skripts kein "return dmg;" drin, das könnte mies in die Hose gehen...
Geändert von Kirides (30.07.2020 um 15:51 Uhr)
-
Wow, das ging ja schnell!
Ja, das passt, ich benutze es schon für eine andere Schadensberechnung bei Zaubern. Habe es nur gekürzt, vollständig sieht es so aus:
Code:
func int DMG_OnDmg(var int victimPtr, var int attackerPtr, var int dmg, var int dmgDescriptorPtr)
{
var oSDamageDescriptor dmgDesc; dmgDesc = _^(dmgDescriptorPtr);
// Diese Funktion anpassen, wenn ihr den Schaden verändern wollt! 'dmg' ist der von Gothic berechnete Schaden
// return dmg;
var c_npc victimNpc;
victimNpc = MEM_PtrToInst(victimPtr);
var c_npc attackerNpc;
attackerNpc = MEM_PtrToInst(attackerPtr);
var c_item rdyweapon;
rdyweapon = Npc_GetReadiedWeapon(hero);
if(Npc_IsPlayer(attackerNpc))
{
return dmg;
}
else
{
if(dmgDesc.spellID != 0)
{
if (PLAYER_TALENT_PERKS[7] == TRUE
&& ((dmgDesc.spellID == SPL_Firebolt)
|| (dmgDesc.spellID == SPL_InstantFireball)
|| (dmgDesc.spellID == SPL_ChargeFireball)
|| (dmgDesc.spellID == SPL_Firestorm)
|| (dmgDesc.spellID == SPL_Pyrokinesis)
|| (dmgDesc.spellID == SPL_Firerain)
|| (dmgDesc.spellID == SPL_MasterOfDisaster)))
{
dmg = ((spl_damage(dmgDesc.spellID) * 100) / 150);
dmg = ApplyMagicResistance(victimNpc, dmg);
};
if (PLAYER_TALENT_PERKS[8] == TRUE
&& ((dmgDesc.spellID == SPL_Icebolt)
|| (dmgDesc.spellID == SPL_IceLance)
|| (dmgDesc.spellID == SPL_IceCube)
|| (dmgDesc.spellID == SPL_IceWave)
|| (dmgDesc.spellID == SPL_Geyser)
|| (dmgDesc.spellID == SPL_WaterFist)
|| (dmgDesc.spellID == SPL_ZORNADANOS)))
{
dmg = ((spl_damage(dmgDesc.spellID) * 100) / 150);
dmg = ApplyMagicResistance(victimNpc, dmg);
};
if (PLAYER_TALENT_PERKS[10] == TRUE
&& ((dmgDesc.spellID == SPL_WindFist)
|| (dmgDesc.spellID == SPL_Whirlwind)
|| (dmgDesc.spellID == SPL_Thunderstorm)
|| (dmgDesc.spellID == SPL_Zap)
|| (dmgDesc.spellID == SPL_LightningFlash)
|| (dmgDesc.spellID == SPL_ChargeZap)))
{
dmg = ((spl_damage(dmgDesc.spellID) * 100) / 150);
dmg = ApplyMagicResistance(victimNpc, dmg);
};
return dmg;
}
else
{
return dmg;
};
};
if(Hlp_IsItem(rdyweapon, ItMw_Glamdring) == TRUE)
{
if(Npc_IsPlayer(attackerNpc))
{
if(hero.attribute[ATR_MANA] >= 20)
{
hero.attribute[ATR_MANA] -= 20;
return dmg;
} else {
dmg = 5;
return dmg;
};
} else {
return dmg;
};
};
};
Ich habe zwar am Ende kein return, aber in jeder Teilabfrage, soweit ich das sehe. Hat bisher für die Schadensberechnung bei den Zaubern auch keine Probleme gemacht.
-
Code:
rdyweapon = Npc_GetReadiedWeapon(hero);
if(Npc_IsPlayer(attackerNpc))
{
return dmg;
}
else
{
/// ...
};
Da haben wir dein Problem.
-
-
Zitat von gladi1994
Wie machst du das so schnell?
Ich bin ein Idiot.. Danke
Ich drücke F5
-
Geändert von gladi1994 (30.07.2020 um 16:11 Uhr)
-
Zitat von gladi1994
Hehe
Manchmal bin ich echt ein wenig blind, ich bitte um Entschuldigung.
Edit: Funktioniert perfekt! Gibt es noch die Möglichkeit, den Manabalken einzublenden, sobald das entsprechende Schwert gezogen ist? So, wie es bei Zaubern der Fall ist? Da ist es vermutlich in der Engine verankert, oder? Hab zumindest in den Skripten bisher noch nichts gesehen.
Wenn du diese Funktion entsprechend aufrufst wenn die Waffe gezogen wurde, oder on_equip oder, oder oder...
Dank geht dabei an @mud-freak, ich habe den Teil des Codes und die Idee davon aus seinem "setBarPositions" Beitrag aus dem Script-Bin.
Die Funktion überschreibt die Prüfung welche den Manabalken einblenden soll, sodass sie immer eingeblendet wird, oder setzt den wert auf den Ursprungswert zurück, was dazu führt das er wieder nur im Inventar und bei gezogener Magie eingeblendet wird.
Code:
func void X_Force_ManaBar(var int on) {
const int oCGame__UpdatePlayerStatus_manaBarJmp_G2 = 7091198; //0x6C33FE
const int overrideOnce = 1;
if (overrideOnce) {
MemoryProtectionOverride(oCGame__UpdatePlayerStatus_manaBarJmp_G2, 1);
overrideOnce = FALSE;
};
// Always show mana bar
if (on) {
MEM_WriteByte(oCGame__UpdatePlayerStatus_manaBarJmp_G2, 0);
} else {
MEM_WriteByte(oCGame__UpdatePlayerStatus_manaBarJmp_G2, 171);
};
};
Korrektur: Habe es gerade in einer FrameFunction getestet, funktioniert
Hier wird geprüft ob der Spieler gerade das "selbstgeschmiedete Schwert" Ausgerüstet und Herauszogen hat und dann der Manabalken eingeblendet.
Code:
var C_Item readiedWeapon; readiedWeapon = Npc_GetReadiedWeapon(hero);
if (Hlp_IsItem(readiedWeapon, ItMw_1H_Common_01)) {
X_Force_ManaBar(TRUE);
} else {
X_Force_ManaBar(FALSE);
};
Geändert von Kirides (30.07.2020 um 16:44 Uhr)
-
Zitat von Kirides
Wenn du diese Funktion entsprechend aufrufst wenn die Waffe gezogen wurde, oder on_equip oder, oder oder...
Dank geht dabei an @mud-freak, ich habe den Teil des Codes und die Idee davon aus seinem "setBarPositions" Beitrag aus dem Script-Bin.
Die Funktion überschreibt die Prüfung welche den Manabalken einblenden soll, sodass sie immer eingeblendet wird, oder setzt den wert auf den Ursprungswert zurück, was dazu führt das er wieder nur im Inventar und bei gezogener Magie eingeblendet wird.
Code:
func void X_Force_ManaBar(var int on) {
const int oCGame__UpdatePlayerStatus_manaBarJmp_G2 = 7091198; //0x6C33FE
const int overrideOnce = 1;
if (overrideOnce) {
MemoryProtectionOverride(oCGame__UpdatePlayerStatus_manaBarJmp_G2, 1);
overrideOnce = FALSE;
};
// Always show mana bar
if (on) {
MEM_WriteByte(oCGame__UpdatePlayerStatus_manaBarJmp_G2, 0);
} else {
MEM_WriteByte(oCGame__UpdatePlayerStatus_manaBarJmp_G2, 171);
};
};
Korrektur: Habe es gerade in einer FrameFunction getestet, funktioniert
Hier wird geprüft ob der Spieler gerade das "selbstgeschmiedete Schwert" Ausgerüstet und Herauszogen hat und dann der Manabalken eingeblendet.
Code:
var C_Item readiedWeapon; readiedWeapon = Npc_GetReadiedWeapon(hero);
if (Hlp_IsItem(readiedWeapon, ItMw_1H_Common_01)) {
X_Force_ManaBar(TRUE);
} else {
X_Force_ManaBar(FALSE);
};
Vielen Dank, das funktioniert wunderbar!
Hab mich jetzt dafür entschieden, es - wie zuerst von dir vorgeschlagen - über die Equip / UnEquip Funktionen der Waffe selbst zu machen, da man so auch ohne gezogene Waffe vor einem möglicherweise schwierigen Kampf sein Mana sehen kann. Nichts wäre ärgerlicher, als erst beim Ziehen der Waffe zu sehen, dass kein Mana mehr vorhanden ist.
Aber um meine Neugier zu befriedigen: habe den unteren Code von dir mal testweise in einen Scripttrigger eingefügt, schien auf die Schnelle nicht zu klappen. Hab vermutlich nur wieder was übersehen und über FrameFunctions wäre es vermutlich ohnehin besser, oder?
-
Das hier ist eventuell eine bessere Lösung, da sie nur 1x pro Session aufgerufen werden muss und nicht dauerhaft.
Edit: Ich sehe gerade, die FF ist nur nötig für das An-/Abschalten an Hand der ausgerüsteten oder gezogenen Waffe. Dann unterscheiden sich die beiden Skripte wohl doch nicht so wirklich.
Geändert von Lehona (30.07.2020 um 18:16 Uhr)
-
Zitat von gladi1994
Vielen Dank, das funktioniert wunderbar!
Hab mich jetzt dafür entschieden, es - wie zuerst von dir vorgeschlagen - über die Equip / UnEquip Funktionen der Waffe selbst zu machen, da man so auch ohne gezogene Waffe vor einem möglicherweise schwierigen Kampf sein Mana sehen kann. Nichts wäre ärgerlicher, als erst beim Ziehen der Waffe zu sehen, dass kein Mana mehr vorhanden ist.
Aber um meine Neugier zu befriedigen: habe den unteren Code von dir mal testweise in einen Scripttrigger eingefügt, schien auf die Schnelle nicht zu klappen. Hab vermutlich nur wieder was übersehen und über FrameFunctions wäre es vermutlich ohnehin besser, oder?
Framefunktions sind "teuer" im vergleich zu einem einmaligen ausführen bei "on_equip"/unequip da die FrameFunktions immer ausgeführt werden, bei jedem gezeichneten Bild.
Im Falle dieser Waffe macht es sinn, das Mana anzeigen zu lassen sobald man die Waffe "equipt" hat, da sie ja davon abhängt.
Zitat von Lehona
Das hier ist eventuell eine bessere Lösung, da sie nur 1x pro Session aufgerufen werden muss und nicht dauerhaft.
Inwiefern wäre das besser?
Soweit ich den Code verstehe, macht er das der Manabalken immer (im kampf) aktiv ist, unabhängig davon ob die Waffe Mana benötigt.
Geändert von Kirides (30.07.2020 um 18:16 Uhr)
-
Zitat von Kirides
Soweit ich den Code verstehe, macht er das der Manabalken immer (im kampf) aktiv ist, unabhängig davon ob die Waffe Mana benötigt.
Der verlinkte Code kann die Manabar auch gezielt an- oder ausschalten, aber wie ich gerade gemerkt habe, bezog sich der Kommentar zur FrameFunction nur auf das Reagieren auf die entsprechende Waffe, nicht um die Manabar an sich. Daher also kein wirklicher Unterschied.
Berechtigungen
- Neue Themen erstellen: Nein
- Themen beantworten: Nein
- Anhänge hochladen: Nein
- Beiträge bearbeiten: Nein
|
|