Portal-Zone Gothic-Zone Gothic II-Zone Gothic 3-Zone Gothic 4-Zone Modifikationen-Zone Download-Zone Foren-Zone RPG-Zone Almanach-Zone Spirit of Gothic

 

Ergebnis 1 bis 12 von 12
  1. Beiträge anzeigen #1 Zitieren
    Kämpfer
    Registriert seit
    Feb 2016
    Ort
    Dresden
    Beiträge
    349
     
    gladi1994 ist offline

    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)

  2. Beiträge anzeigen #2 Zitieren
    Ritter Avatar von Kirides
    Registriert seit
    Jul 2009
    Ort
    Norddeutschland
    Beiträge
    1.781
     
    Kirides ist offline
    Zitat Zitat von gladi1994 Beitrag anzeigen
    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)

  3. Beiträge anzeigen #3 Zitieren
    Kämpfer
    Registriert seit
    Feb 2016
    Ort
    Dresden
    Beiträge
    349
     
    gladi1994 ist offline
    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.

  4. Beiträge anzeigen #4 Zitieren
    Ritter Avatar von Kirides
    Registriert seit
    Jul 2009
    Ort
    Norddeutschland
    Beiträge
    1.781
     
    Kirides ist offline
    Code:
    rdyweapon = Npc_GetReadiedWeapon(hero);
    
         if(Npc_IsPlayer(attackerNpc))
        {
            return dmg;
        } 
        else
        {
            /// ...
    
        };
    Da haben wir dein Problem.

  5. Beiträge anzeigen #5 Zitieren
    Kämpfer
    Registriert seit
    Feb 2016
    Ort
    Dresden
    Beiträge
    349
     
    gladi1994 ist offline
    Wie machst du das so schnell?

    Ich bin ein Idiot.. Danke

  6. Beiträge anzeigen #6 Zitieren
    Ritter Avatar von Kirides
    Registriert seit
    Jul 2009
    Ort
    Norddeutschland
    Beiträge
    1.781
     
    Kirides ist offline
    Zitat Zitat von gladi1994 Beitrag anzeigen
    Wie machst du das so schnell?

    Ich bin ein Idiot.. Danke
    Ich drücke F5

  7. Beiträge anzeigen #7 Zitieren
    Kämpfer
    Registriert seit
    Feb 2016
    Ort
    Dresden
    Beiträge
    349
     
    gladi1994 ist offline
    Zitat Zitat von Kirides Beitrag anzeigen
    Ich drücke F5
    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.
    Geändert von gladi1994 (30.07.2020 um 16:11 Uhr)

  8. Beiträge anzeigen #8 Zitieren
    Ritter Avatar von Kirides
    Registriert seit
    Jul 2009
    Ort
    Norddeutschland
    Beiträge
    1.781
     
    Kirides ist offline
    Zitat Zitat von gladi1994 Beitrag anzeigen
    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)

  9. Beiträge anzeigen #9 Zitieren
    Kämpfer
    Registriert seit
    Feb 2016
    Ort
    Dresden
    Beiträge
    349
     
    gladi1994 ist offline
    Zitat Zitat von Kirides Beitrag anzeigen
    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?

  10. Beiträge anzeigen #10 Zitieren
    Dea
    Registriert seit
    Jul 2007
    Beiträge
    10.447
     
    Lehona ist offline
    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)

  11. Beiträge anzeigen #11 Zitieren
    Ritter Avatar von Kirides
    Registriert seit
    Jul 2009
    Ort
    Norddeutschland
    Beiträge
    1.781
     
    Kirides ist offline
    Zitat Zitat von gladi1994 Beitrag anzeigen
    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 Zitat von Lehona Beitrag anzeigen
    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)

  12. Beiträge anzeigen #12 Zitieren
    Dea
    Registriert seit
    Jul 2007
    Beiträge
    10.447
     
    Lehona ist offline
    Zitat Zitat von Kirides Beitrag anzeigen
    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
Impressum | Link Us | intern
World of Gothic © by World of Gothic Team
Gothic, Gothic 2 & Gothic 3 are © by Piranha Bytes & Egmont Interactive & JoWooD Productions AG, all rights reserved worldwide