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

 

Seite 3 von 6 « Erste 123456 Letzte »
Ergebnis 41 bis 60 von 117
  1. Beiträge anzeigen #41 Zitieren
    research Avatar von NicoDE
    Registriert seit
    Dec 2004
    Beiträge
    7.410
     
    NicoDE ist offline
    Zitat Zitat von Lehona Beitrag anzeigen
    Which is probably too late if you cleanly want to change the damage
    Yes, and it's tricky enough anyway (the registered perception (none by default) is used instead of PLAYER_PERC_ASSESSMAGIC if a script state is active on the player).
    "Unter diesen schwierigen Umständen bin ich mir sicher, daß diese guten Menschen meinen augenblicklichen Bedarf an deren Gold verstehen werden." -- Connor

  2. Beiträge anzeigen #42 Zitieren
    Ranger Avatar von Demondays
    Registriert seit
    Feb 2015
    Beiträge
    173
     
    Demondays ist offline
    I think I managed to get what I needed other way. Instead editing damage formula I added aditional damage with B_MagicHurtNpc function placed in C_CanNpcCollideWithSpell. It seems to be working for now, although further testings will show if there is no problems with it. Well, thanks everyone for help

  3. Beiträge anzeigen #43 Zitieren
    Ranger Avatar von Demondays
    Registriert seit
    Feb 2015
    Beiträge
    173
     
    Demondays ist offline
    Can this function be used in Gothic 1? I need Ikarus, not Lego for it right?

  4. Homepage besuchen Beiträge anzeigen #44 Zitieren
    General Avatar von Dada
    Registriert seit
    Jan 2007
    Ort
    Krefeld
    Beiträge
    3.729
     
    Dada ist offline
    It uses the HookEngine, so it depends on LeGo

  5. Beiträge anzeigen #45 Zitieren
    Dea
    Registriert seit
    Jul 2007
    Beiträge
    10.447
     
    Lehona ist offline
    Zitat Zitat von Demondays Beitrag anzeigen
    Can this function be used in Gothic 1? I need Ikarus, not Lego for it right?
    While HookEngine is conceptionally very similar to Ikarus, it was developed and maintained by Gottfried and me.

    Splash posted a version with G1-specific addresses/offsets on TheModders.org:
    Code:
    func int DMG_OnDmg (var int victimPtr, var int attackerPtr, var int dmg) 
    { 
        return dmg;
    };
        
    func void _DMG_OnDmg () 
    {
        EAX = DMG_OnDmg (ECX, MEM_ReadInt (MEM_ReadInt (ESP+548)+4), EAX);
    };
    
    func void InitDamage () {
        const int dmg = 0;
        if (dmg) { return; };
        HookEngineF(7567329, 6, _DMG_OnDmg);
        dmg = 1;
    };
    So if you can find a standalone version of HookEngine for Gothic 1 (It definitely has been posted somewhere before...) you can get it to work for G1.

    LeGo for G1 is currently under development and maybe I will release some sort of alpha version until I get some tests running.

  6. Beiträge anzeigen #46 Zitieren
    Ranger Avatar von Demondays
    Registriert seit
    Feb 2015
    Beiträge
    173
     
    Demondays ist offline
    Thanks for the answer, but Im afraid I will not manage implement myself hookengine to G1. I found this but since im noob I dont know what to do with it:
    https://github.com/Outlander1210/got...Engine_Hooks.d
    I see its part of the Lego for G1 so I suppose it wouldnt work if I used only this hookengine part in my scripts?
    Also found this, its from polish modification:
    https://github.com/orcwarrior/Czas_Z...kEngineForCZ.d

    Edit. Oh well, I used LeGo from first link then initialized only part with the hookengine and it worked. Now I can finally have G2 dmg formula in G1

    Geändert von Demondays (25.01.2017 um 16:54 Uhr)

  7. Beiträge anzeigen #47 Zitieren
    Dea
    Registriert seit
    Jul 2007
    Beiträge
    10.447
     
    Lehona ist offline
    Ich habe eine neue Version geschrieben, die die Funktion DMG_OnDmg um einige weitere nützliche Informationen bereichert. Gerade wer akkurat und einfach mit Magie umgehen möchte wird es damit simpler haben.

    Code:
    // Look for the function "DMG_OnDmg" to modify
    
    class oSDamageDescriptor {
    	var int validFields; 		// zDWORD 0x00
    	
    	var int attackerVob; 		// zCVob* 0x04
    	var int attackerNpc; 		// oCNpc* 0x08
    	var int hitVob; 			// zCVob* 0x0C
    	var int hitPfx;				// oCVisualFX* 0x10
    	var int itemWeapon; 		// oCItem* 0x14
    		
    	var int spellID;			// zDWORD 0x18
    	var int spellCat; 			// zDWORD 0x1C
    	var int spellLevel;			// zDWORD 0x20
    	
    	var int dmgMode;			// zDWORD 0x24
    	var int weaponMode;			// zDWORD 0x28
    	
    	var int dmgArray[8];	 	// zDWORD[8] 0x2C Vermutlich vor Abzug der Rüstungswerte
    	var int dmgTotal;			// zREAL 0x4C // Nach Abzug der Rüstungswerte?
    	var int dmgMultiplier;		// zREAL 0x50
    	
    	var int locationHit[3]; 	// zVEC3 0x54
    	var int directionFly[3];	// zVEC3 0x58
    	
    	var string visualFXStr;		// zSTRING 0x5C
    	
    	var int duration;			// zREAL 0x60
    	var int interval; 			// zREAL 0x64
    	var int dmgPerInterval;		// zREAL 0x68
    	var int dmgDontKill;		// zBOOL 0x6C
    	
    	var int bitfield; // 1 -> Once, 2 -> finished, 4 -> isDead, 8 -> isUnconscious
    	
    	var int azimuth;			// zREAL 0x74
    	var int elevation;			// zREAL 0x78
    	var int timeCurrent;		// zREAL 0x7C
    	var int dmgReal;			// zREAL 0x80
    	var int dmgEffective;		// zREAL 0x84
    	var int dmgArrayEffective[8]; // zDWORD[8] 0x104 // Vermutlich nach Abzug der Rüstungswerte, ohne Mindestschaden
    	var int vobParticleFX;		// zCVob* 0x108
    	var int particleFX;			// zCParticleFX* 0x10C
    	var int visualFX;			// zCVisualFX* 0x110
    };
    
    
    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 int _DMG_DmgDesc;
    
    func void _DMG_OnDmg_Post() {
    	EDI = DMG_OnDmg(EBP, MEM_ReadInt(MEM_ReadInt(ESP+644)+8), EDI, _DMG_DmgDesc);
    };
    
    func void _DMG_OnDmg_Pre() {
    	_DMG_DmgDesc = ESI; // I'm preeeeetty sure it won't get moved in the meantime...
    };
    
    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;
    };
    Nicht alle Änderungen am DamageDescriptor-Objekt werden in der DMG_OnDmg auch wirksam sein, da sie eventuell bereits verarbeitet wurden. Da heißt im Zweifelsfall nur testen. Einige Änderungen können auch schon in der _DMG_OnDmg_Pre() durchgeführt werden, zu diesem Zeitpunkt sollte noch keines der Werte verarbeitet worden sein.
    Geändert von Lehona (20.02.2018 um 03:07 Uhr)

  8. Beiträge anzeigen #48 Zitieren
    Held Avatar von Teron Gorefiend
    Registriert seit
    Nov 2006
    Ort
    im Alchemielabor
    Beiträge
    5.120
     
    Teron Gorefiend ist offline
    wie muss ich das script verändern, wenn ich es für G1 verwenden möchte?

    HookEngineF(6736583/*0x66CAC7*/, 5, _DMG_OnDmg_Post); muss bestimmt durch
    HookEngineF(7567329, 6, _DMG_OnDmg_Post);

    ersetzt werden. Aber was ich für
    const int oCNpc__OnDamage_Hit = 6710800;
    HookEngineF(oCNpc__OnDamage_Hit, 7, _DMG_OnDmg_Pre);

    ersetzen wenn es für G1 funktionieren soll.

  9. Homepage besuchen Beiträge anzeigen #49 Zitieren
    General Avatar von Dada
    Registriert seit
    Jan 2007
    Ort
    Krefeld
    Beiträge
    3.729
     
    Dada ist offline
    Versuchs mal mit 7541776.
    Bin mir wohl mit der Länge nicht sicher

    Edit:
    7 müsste auch für die Länge stimmen

    Nochmal Edit:
    Vielleicht wäre es nützlich diesen Post irgendwie im LeGo-Thread zu verlinken
    Geändert von Dada (05.03.2018 um 16:53 Uhr)

  10. Beiträge anzeigen #50 Zitieren
    Veteran Avatar von Atariar
    Registriert seit
    May 2016
    Beiträge
    570
     
    Atariar ist offline
    Hallo Lehona,

    vielen Dank für das tolle Script!

    In ZSpy kommt es vor, dass durch Zauber/Magieschaden ein Stacktrace getriggert wird. Das Spiel stürzt nicht ab. Kennt jemand diese Fehlermeldung und kann diese reproduzieren?

    Momentan kommt es in meiner Mod/Testversion vor, dass bei Ladevorgängen das Spiel abstürzt. Die Fehlermeldungen sind nicht eindeutig und ich kann die Abstürze auf keinen konkreten Scripteingriff zurückführen. Deshalb suche ich an allen Stellen.

    Getestet habe ich das unter den Bedingungen:
    • frische Gothic-Installation, keine weiteren Scriptveränderungen
    • Ikarus 1.2
    • Lego 2.5
    • B_DmgOnDmg.d

    im Fallbeispiel: Held trifft Ork-Krieger mit einem Feuerball.
    Ereignisse: Stacktrace-Meldung in ZSpy. Die Schadensberechnung wird korrekt ausgeführt, auch unter Eingriffen bei den Spells über den dmgDesc.

    Auszug der Stacktrace-Meldung:
    Code:
    [w] 02:33 Warn:  0 C:     SCRIPT: Hlp_IsItem(): illegal param: "C_ISITEMBELIARSWEAPON.WEAP" is NULL. .... <oGameExternal.cpp,#252>[w] 02:33 Warn:  0 C:     SCRIPT: last parser func-name: B_MM_ASSESSDAMAGE .... <oGameExternal.cpp,#262>
    [w] 02:33 Warn:  0 C:     SCRIPT: Hlp_IsItem(): illegal param: "C_ISITEMBELIARSWEAPON.WEAP" is NULL. .... <oGameExternal.cpp,#252>
    [w] 02:33 Warn:  0 C:     SCRIPT: last parser func-name: B_MM_ASSESSDAMAGE .... <oGameExternal.cpp,#262>
    [w] 02:33 Warn:  0 C:     SCRIPT: Hlp_IsItem(): illegal param: "C_ISITEMBELIARSWEAPON.WEAP" is NULL. .... <oGameExternal.cpp,#252>
    [w] 02:33 Warn:  0 C:     SCRIPT: last parser func-name: B_MM_ASSESSDAMAGE .... <oGameExternal.cpp,#262>
    [w] 02:33 Warn:  0 C:     SCRIPT: Hlp_IsItem(): illegal param: "C_ISITEMBELIARSWEAPON.WEAP" is NULL. .... <oGameExternal.cpp,#252>
    [w] 02:33 Warn:  0 C:     SCRIPT: last parser func-name: B_MM_ASSESSDAMAGE .... <oGameExternal.cpp,#262>
    [w] 02:33 Warn:  0 C:     SCRIPT: Hlp_IsItem(): illegal param: "C_ISITEMBELIARSWEAPON.WEAP" is NULL. .... <oGameExternal.cpp,#252>
    [w] 02:33 Warn:  0 C:     SCRIPT: last parser func-name: B_MM_ASSESSDAMAGE .... <oGameExternal.cpp,#262>
    [w] 02:33 Warn:  0 C:     SCRIPT: Hlp_IsItem(): illegal param: "C_ISITEMBELIARSWEAPON.WEAP" is NULL. .... <oGameExternal.cpp,#252>
    [w] 02:33 Warn:  0 C:     SCRIPT: last parser func-name: B_MM_ASSESSDAMAGE .... <oGameExternal.cpp,#262>
    [w] 02:33 Warn:  0 C:     zSndMSS(zCSndSys_MSS::LoadSoundFXByIdentifier): Sound Identifier "SVM_18_AARGH_1" unknown ! .... <zSndMss.cpp,#1155>
    [i] 02:34 Info:  5 C:     SND: Creating Sound DrawSound_ME.wav   (single)  .... <zSndMss.cpp,#1126>
    [f] 02:34 Fault: 0 Q:     [start of stacktrace]
    [f] 02:34 Fault: 0 Q:             MEMINT_HANDLEERROR(2, 'MEM_PtrToInst: ptr is NULL. Use MEM_NullToInst if that's what you want.') +   62 bytes
    [f] 02:34 Fault: 0 Q:             MEM_WARN('MEM_PtrToInst: ptr is NULL. Use MEM_NullToInst if that's what you want.') +   21 bytes
    [f] 02:34 Fault: 0 Q:             MEM_PTRTOINST(306877232)                                       +  128 bytes
    [f] 02:34 Fault: 0 Q:             DMG_ONDMG(509465092, 0, 0, 506594012)                          +   34 bytes
    [f] 02:34 Fault: 0 Q:             _DMG_ONDMG_POST()                                              +   47 bytes
    [f] 02:34 Fault: 0 Q:             MEM_CALLBYID(37338)                                            +  224 bytes
    [f] 02:34 Fault: 0 Q:             _HOOK(318399192, 0, 506594012, 509465092, 20313164, -1, 0, 509465092, 0) +  498 bytes
    [f] 02:34 Fault: 0 Q:             [UNKNOWN]                                                      +-1623096441 bytes
    [f] 02:34 Fault: 0 Q:     [end of stacktrace]
    [w] 02:34 Warn:  0 Q:     MEM_PtrToInst: ptr is NULL. Use MEM_NullToInst if that's what you want.
    [i] 02:34 Info:  3 B:     GMAN: Entering Menu-Section .... <oGameManager.cpp,#1350>
    [i] 02:34 Info:  3 B:     VID: Videomode found .... <oGameManager.cpp,#1112>
    [i] 02:34 Info:  4 B:     GMAN: Menu started (ingame) .... <oGameManager.cpp,#1396>
    [i] 02:34 Info:  5 B:     GAM: Game paused .... <oGame.cpp,#2744>
    [i] 02:37 Info:  5 B:     GAM: Game unpaused .... <oGame.cpp,#2767>
    [i] 02:37 Info:  4 B:     GMAN: Menu finished .... <oGameManager.cpp,#1410>
    [i] 02:37 Info:  4 B:     MENU: LEAVE_GAME .... <oGameManager.cpp,#1430>
    [i] 02:37 Info:  4 B:     GMAN: Menu-Selection "exit" .... <oGameManager.cpp,#1437>
    [i] 02:37 Info:  3 B:     OPT: Applying settings ... .... <oGameManager.cpp,#1178>
    [i] 02:37 Info:  3 B:       OPT: Lookaround inverse = 0 .... <oGameManager.cpp,#1221>
    Ikarus, Lego und B_Dmg_OnDmg parsen in der Gothic.src
    Spoiler:(zum lesen bitte Text markieren)

    Code:
    _INTERN\CONSTANTS.D
    _INTERN\CLASSES.D
    
    
    _INTERN\Ikarus_Const_G2.d
    _INTERN\EngineClasses_G2\*.d
    _INTERN\Ikarus.d
    _INTERN\float.d
    
    
    _INTERN\LeGo\Header.src
    
    
    AI\AI_INTERN\AI_CONSTANTS.D
    
    ...
    
    STORY\B_Story\B_ENTER_DRAGONISLAND.d
    
    _INTERN\B_Dmg_OnDmg.d
    
    STORY\Startup.d

    Init in der Startup.d, InitGlobal
    Spoiler:(zum lesen bitte Text markieren)

    Code:
    func void INIT_GLOBAL()
    {
        // wird fuer jede Welt aufgerufen (vor INIT_<LevelName>)
        Game_InitGerman();
        LeGo_Init(LeGo_All & ~LeGo_Bloodsplats);
        InitDamage();
    };

    unveränderte B_Dmg_OnDmg.d
    Spoiler:(zum lesen bitte Text markieren)
    Code:
    // Look for the function "DMG_OnDmg" to modify
    
    class oSDamageDescriptor {
        var int validFields;         // zDWORD 0x00
        
        var int attackerVob;         // zCVob* 0x04
        var int attackerNpc;         // oCNpc* 0x08
        var int hitVob;             // zCVob* 0x0C
        var int hitPfx;                // oCVisualFX* 0x10
        var int itemWeapon;         // oCItem* 0x14
            
        var int spellID;            // zDWORD 0x18
        var int spellCat;             // zDWORD 0x1C
        var int spellLevel;            // zDWORD 0x20
        
        var int dmgMode;            // zDWORD 0x24
        var int weaponMode;            // zDWORD 0x28
        
        var int dmgArray[8];         // zDWORD[8] 0x2C Vermutlich vor Abzug der Rüstungswerte
        var int dmgTotal;            // zREAL 0x4C // Nach Abzug der Rüstungswerte?
        var int dmgMultiplier;        // zREAL 0x50
        
        var int locationHit[3];     // zVEC3 0x54
        var int directionFly[3];    // zVEC3 0x58
        
        var string visualFXStr;        // zSTRING 0x5C
        
        var int duration;            // zREAL 0x60
        var int interval;             // zREAL 0x64
        var int dmgPerInterval;        // zREAL 0x68
        var int dmgDontKill;        // zBOOL 0x6C
        
        var int bitfield; // 1 -> Once, 2 -> finished, 4 -> isDead, 8 -> isUnconscious
        
        var int azimuth;            // zREAL 0x74
        var int elevation;            // zREAL 0x78
        var int timeCurrent;        // zREAL 0x7C
        var int dmgReal;            // zREAL 0x80
        var int dmgEffective;        // zREAL 0x84
        var int dmgArrayEffective[8]; // zDWORD[8] 0x104 // Vermutlich nach Abzug der Rüstungswerte, ohne Mindestschaden
        var int vobParticleFX;        // zCVob* 0x108
        var int particleFX;            // zCParticleFX* 0x10C
        var int visualFX;            // zCVisualFX* 0x110
    };
    
    
    
    
    func int DMG_OnDmg(var int victimPtr, var int attackerPtr, var int dmg, var int dmgDescriptorPtr) {
        var oSDamageDescriptor dmgDesc; dmgDesc = _^(dmgDescriptorPtr);
        var c_npc attackerNpc; attackerNpc = _^(attackerptr);
            var c_npc victimNpc; victimNpc = _^(victimPtr);
    
    
        // Diese Funktion anpassen, wenn ihr den Schaden verändern wollt! 'dmg' ist der von Gothic berechnete Schaden
        return dmg;
    };
        
    
    
    var int _DMG_DmgDesc;
    
    
    func void _DMG_OnDmg_Post() {
        EDI = DMG_OnDmg(EBP, MEM_ReadInt(MEM_ReadInt(ESP+644)+8), EDI, _DMG_DmgDesc);
    };
    
    
    func void _DMG_OnDmg_Pre() {
        _DMG_DmgDesc = ESI; // I'm preeeeetty sure it won't get moved in the meantime...
    };
    
    
    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;
    };

  11. Beiträge anzeigen #51 Zitieren
    Knight
    Registriert seit
    Aug 2009
    Ort
    Hessen
    Beiträge
    1.487
     
    Cryp18Struct ist offline
    Code:
    var c_npc attackerNpc; attackerNpc = _^(attackerptr);
    das ist einfach eine Abgekürzte Schreibweise für:
    Code:
    var c_npc attackerNpc; attackerNpc = MEM_PTRTOINST(attackerptr);
    Die Warnung sagt dir also das du versuchst aus einem ungültigen pointer eine Instanz zu basteln.

    attackerptr kann hier ungültig sein. Beispielsweise wenn du den hero in eine Stachelfalle steuerst. Da nimmt er zwar Schaden, aber es gibt keinen Schadensverursacher.
    Warum in deinem "Held trifft Ork-Krieger mit einem Feuerball"-Szenario einer der pointer ungültig ist weiß ich jetzt aus dem Stegreif nicht.

    Ganz platt gesagt: Solange es funktioniert kannst du die Warnung ignorieren.
    Du solltest dir aber bewusst sein das die c_npc Variablen eventuell nicht auf einen validen NPC zeigen.
    Falls du auf irgendwelche Eigenschaften vom attackerNpc zugreifen willst solltest du also Hlp_IsValidNPC benutzen um abzufragen ob da überhaupt was brauchbares drinsteht.

    Wenn dich einfach nur die Warnung stört müsstest du das auch so machen können:
    Code:
    func int DMG_OnDmg(var int victimPtr, var int attackerPtr, var int dmg, var int dmgDescriptorPtr) {
        var oSDamageDescriptor dmgDesc; dmgDesc = _^(dmgDescriptorPtr);
        
        var c_npc attackerNpc;
        if(Hlp_Is_oCNpc(attackerptr)){
            attackerNpc = _^(attackerptr);
        } else{
            attackerNpc = MEM_NullToInst();
        };
    
        var c_npc victimNpc;
        if(Hlp_Is_oCNpc(victimptr)){
            victimNpc = _^(attackerptr);
        } else{
            victimNpc = MEM_NullToInst();
        };
    
    
        // Diese Funktion anpassen, wenn ihr den Schaden verändern wollt! 'dmg' ist der von Gothic berechnete Schaden
        return dmg;
    };
    MEM_NullToInst() ist halt gezielt dazu da.

    Wenn du aber dann sowieso Hlp_Is_oCNpc benutzt könntest du das auch so strukturieren das du in der Funktion erst Sachen machst bei denen attackerNpc egal ist, dann aus der Funktion springst falls !Hlp_Is_oCNpc(attackerptr) und erst danach attackerNpc eine Instanz zuweist und Abfragen machst bei denen du auf Eigenschaften von attackerNpc zugreifen willst.
    Geändert von Cryp18Struct (07.05.2018 um 23:17 Uhr)

  12. Beiträge anzeigen #52 Zitieren
    Apprentice Avatar von Rayzer
    Registriert seit
    Sep 2014
    Ort
    Poland
    Beiträge
    44
     
    Rayzer ist offline
    That's because in some cases there is no attacker (hitting the ground after falling from the ledge for example). Before you assign pointer to instance, check if variable returns pointer instead null.

    Code:
    if (attackerPtr) {
        var c_npc attacker; attacker = _^(attackerPtr);
    };

  13. Beiträge anzeigen #53 Zitieren
    Veteran Avatar von Atariar
    Registriert seit
    May 2016
    Beiträge
    570
     
    Atariar ist offline
    Zitat Zitat von Cryp18Struct Beitrag anzeigen
    Spoiler:(zum lesen bitte Text markieren)
    Code:
    var c_npc attackerNpc; attackerNpc = _^(attackerptr);
    das ist einfach eine Abgekürzte Schreibweise für:
    Code:
    var c_npc attackerNpc; attackerNpc = MEM_PTRTOINST(attackerptr);
    Die Warnung sagt dir also das du versuchst aus einem ungültigen pointer eine Instanz zu basteln.

    attackerptr kann hier ungültig sein. Beispielsweise wenn du den hero in eine Stachelfalle steuerst. Da nimmt er zwar Schaden, aber es gibt keinen Schadensverursacher.
    Warum in deinem "Held trifft Ork-Krieger mit einem Feuerball"-Szenario einer der pointer ungültig ist weiß ich jetzt aus dem Stegreif nicht.

    Ganz platt gesagt: Solange es funktioniert kannst du die Warnung ignorieren.
    Du solltest dir aber bewusst sein das die c_npc Variablen eventuell nicht auf einen validen NPC zeigen.
    Falls du auf irgendwelche Eigenschaften vom attackerNpc zugreifen willst solltest du also Hlp_IsValidNPC benutzen um abzufragen ob da überhaupt was brauchbares drinsteht.

    Wenn dich einfach nur die Warnung stört müsstest du das auch so machen können:
    Code:
    func int DMG_OnDmg(var int victimPtr, var int attackerPtr, var int dmg, var int dmgDescriptorPtr) {
        var oSDamageDescriptor dmgDesc; dmgDesc = _^(dmgDescriptorPtr);
        
        var c_npc attackerNpc;
        if(Hlp_Is_oCNpc(attackerptr)){
            attackerNpc = _^(attackerptr);
        } else{
            attackerNpc = MEM_NullToInst();
        };
    
        var c_npc victimNpc;
        if(Hlp_Is_oCNpc(victimptr)){
            victimNpc = _^(attackerptr);
        } else{
            victimNpc = MEM_NullToInst();
        };
    
    
        // Diese Funktion anpassen, wenn ihr den Schaden verändern wollt! 'dmg' ist der von Gothic berechnete Schaden
        return dmg;
    };
    MEM_NullToInst() ist halt gezielt dazu da.

    Wenn du aber dann sowieso Hlp_Is_oCNpc benutzt könntest du das auch so strukturieren das du in der Funktion erst Sachen machst bei denen attackerNpc egal ist, dann aus der Funktion springst falls !Hlp_Is_oCNpc(attackerptr) und erst danach attackerNpc eine Instanz zuweist und Abfragen machst bei denen du auf Eigenschaften von attackerNpc zugreifen willst.
    Hallo Cryp18Struct,

    danke für die schnelle Antwort! Das hatte ich mir gedacht, dass der Schadenverursacher in einigen Fällen nicht bekannt ist und damit auf einen ungültigen (leeren) Pointer verwiesen wird.
    Dein Input und die zwei Lösungsansätze haben mir direkt geholfen, ich konnte meine Scripte jetzt korrekt einbauen!

    Vielen Dank nochmal!

    Zitat Zitat von Rayzer Beitrag anzeigen
    That's because in some cases there is no attacker (hitting the ground after falling from the ledge for example). Before you assign pointer to instance, check if variable returns pointer instead null.

    Code:
    if (attackerPtr) {
        var c_npc attacker; attacker = _^(attackerPtr);
    };
    Thank you Rayzer! That does work out for me.

  14. Beiträge anzeigen #54 Zitieren
    banned
    Registriert seit
    Jan 2009
    Ort
    Oberösterreich
    Beiträge
    2.393
     
    Moe ist offline
    Ist es möglich in G2 die Schadensberechnung auf die G1 Schadensberechnung umzustellen, aber nicht zur Gänze?

    Also normaler Treffer soll im Nahkampf bedeuten Schaden = Stärke + Waffenschaden - Rüstungsschaden und Volltreffer = Doppelter Schaden.
    Im Fernkampf auch so, nur halt das anders als in G1 auch das Geschick zum Schaden addiert wird.

  15. Beiträge anzeigen #55 Zitieren
    Dea
    Registriert seit
    Jul 2007
    Beiträge
    10.447
     
    Lehona ist offline
    Zitat Zitat von Moe Beitrag anzeigen
    Ist es möglich in G2 die Schadensberechnung auf die G1 Schadensberechnung umzustellen, aber nicht zur Gänze?

    Also normaler Treffer soll im Nahkampf bedeuten Schaden = Stärke + Waffenschaden - Rüstungsschaden und Volltreffer = Doppelter Schaden.
    Im Fernkampf auch so, nur halt das anders als in G1 auch das Geschick zum Schaden addiert wird.
    Der Post scheint irgendwie untergegangen zu sein, sorry.

    Möglich ist es auf jeden Fall. Du müsstest herausfinden, ob es sich um Nah- oder Fernkampf handelt (im dmgDescriptor steht ein Pointer auf die Waffe, das solltest du prüfen können) und dann eigentlich nur den entsprechenden Schaden berechnen. Falls du es nach so langer Zeit doch noch versuchst, kannst du ja mal berichten, was dir konkret Probleme bereitet

  16. Beiträge anzeigen #56 Zitieren
    banned
    Registriert seit
    Jan 2009
    Ort
    Oberösterreich
    Beiträge
    2.393
     
    Moe ist offline
    Zitat Zitat von Lehona Beitrag anzeigen
    Der Post scheint irgendwie untergegangen zu sein, sorry.

    Möglich ist es auf jeden Fall. Du müsstest herausfinden, ob es sich um Nah- oder Fernkampf handelt (im dmgDescriptor steht ein Pointer auf die Waffe, das solltest du prüfen können) und dann eigentlich nur den entsprechenden Schaden berechnen. Falls du es nach so langer Zeit doch noch versuchst, kannst du ja mal berichten, was dir konkret Probleme bereitet
    Coole Sache, danke für Rückmeldung.

    Ich trau mich da irgendwie nicht so ganz drüber, es hätte nicht zufällig jemand Lust das für mich zu machen?


  17. Beiträge anzeigen #57 Zitieren
    Serima Avatar von Fisk2033
    Registriert seit
    Dec 2010
    Ort
    Dresden
    Beiträge
    5.803
     
    Fisk2033 ist offline
    Zitat Zitat von Moe Beitrag anzeigen
    Coole Sache, danke für Rückmeldung.

    Ich trau mich da irgendwie nicht so ganz drüber, es hätte nicht zufällig jemand Lust das für mich zu machen?

    Du könntest dich ja zumindest erstmal trauen anzufangen und bei Fragen/Problemen wird dir hier sicher geholfen!

  18. Beiträge anzeigen #58 Zitieren
    banned
    Registriert seit
    Jan 2009
    Ort
    Oberösterreich
    Beiträge
    2.393
     
    Moe ist offline
    So ich hab jetzt angefangen und Ikarus und LeGo mitsamt diesem Damage Skript installiert.

    Jetzt stehe ich allerdings schon an, da ich leider keinerlei Ahnung habe wie ich diese Funktion nun modizifieren soll/muss, damit der Gothic 1 Damage statt dem Gothic 2 Damage berechnet wird oder die kritischen Treffer doppelten Schaden machen.

    Code:
    func int DMG_OnDmg(var int victimPtr, var int attackerPtr, var int dmg, var int dmgDescriptorPtr) {
    	var oSDamageDescriptor dmgDesc; dmgDesc = _^(dmgDescriptorPtr);
    	var c_npc attackerNpc; attackerNpc = _^(attackerptr);
            var c_npc victimNpc; victimNpc = _^(victimPtr);
    
    	// Diese Funktion anpassen, wenn ihr den Schaden verändern wollt! 'dmg' ist der von Gothic berechnete Schaden
    	return dmg;
    };



    Könnte mir bitte jemand der schon erfolgreich eine neue Schadensberechnung gemacht, paar Tipps geben?

  19. Beiträge anzeigen #59 Zitieren
    Knight Commander Avatar von Neconspictor
    Registriert seit
    Jan 2009
    Beiträge
    2.749
     
    Neconspictor ist offline
    Mach dir doch erst einmal klar, wie die Schadensberechnung in Gothic 1 überhaupt funktioniert.
    Zweitens solltest du dir überlegen, wie sich die Schadensberechnung in Gothic 2 verhält.

    Es gibt Insgesamt Ohne Waffe, Einhand, Zweihand, Fernkampf und Magie. Du wirst für jede Waffenart eine andere Berechnung durchführen müssen (Tipp: Verwende if, else if, else ). Magieschaden dürfte gleich sein, kannst du also ignorieren. Ich weiß aber gerade nicht, ob der Mindestschaden in Gothic 2 auch für Magie gilt. Da du eh deine eigene Schadensberechnung machst, kannst du den Mindestschaden aber auch ausschalten: NPC_MINIMAL_DAMAGE = 0 in AI_Constants.d


    Der Einfachheit solltest du erst einmal nur eine Waffenart implementieren. Das verringert die Komplexität beim Implementieren enorm.

    Für Einhand wäre die Formel (kein Volltreffer): Stärke + Waffenschaden - Rüstungsschutz
    Die Stärke nimmst du vom Angreifer, den Rüstungsschutz vom Opfer und um den Waffenschaden zu bestimmen, musst du erst einmal die gezogene Waffe des Angreifers ermitteln:
    Code:
    var int weapon; weapon = Npc_GetReadiedWeapon(attackerNpc);
    Wir wissen an dieser Stelle noch nicht, ob der Angreifer überhaupt eine Waffe in Händen hält, also ein Sicherheitscheck mit Hlp_IsValiditem.

    Als nächstes müssen wir noch prüfen, ob die Waffe eine Einhandwaffe ist. Das geht, indem wir schauen ob das ITEM_KAT_NF flag gesetzt ist und entweder ITEM_SWD oder ITEM_AXE gesetzt ist:
    Code:
    var int isOneHand; 
    isOneHand = weapon.flags & ITEM_KAT_NF;
    isOneHand = isOneHand  && (weapon.flags & ITEM_SWD || weapon.flags & ITEM_AXE);
    Die Bedingung, die wir brauchen, um die Einhandschadensberechung durchführen zu können, sieht also so aus:

    Code:
    var int isOneHand; 
    isOneHand = weapon.flags & ITEM_KAT_NF;
    isOneHand = isOneHand  && (weapon.flags & ITEM_SWD || weapon.flags & ITEM_AXE);
    
    if (Hlp_IsValidItem(weapon) && isOneHand) {
    // Hier berechnest du den Schaden für Einhandwaffen
    };
    Der Schaden lässt sich jetzt ganz einfach berechnen.
    EDIT: Man muss allerdings noch berücksichtigen, dass Äxte Blunt-Schaden machen, während Schwerter Edge verwenden!
    Code:
    if (weapon.flags & ITEM_SWD) {
        dmg = attackerNpc.attribute[ATR_STRENGTH] + weapon.damage[DAM_EDGE] - victimNpc.protection[PROT_EDGE];
    } else {
        dmg = attackerNpc.attribute[ATR_STRENGTH] + weapon.damage[DAM_BLUNT] - victimNpc.protection[PROT_BLUNT];
    };
    Zusammengefasst sieht das ganze so aus:

    Code:
    func int DMG_OnDmg(var int victimPtr, var int attackerPtr, var int dmg, var int dmgDescriptorPtr) {
    	var oSDamageDescriptor dmgDesc; dmgDesc = _^(dmgDescriptorPtr);
    	var c_npc attackerNpc; attackerNpc = _^(attackerptr);
            var c_npc victimNpc; victimNpc = _^(victimPtr);
    
    	// Diese Funktion anpassen, wenn ihr den Schaden verändern wollt! 'dmg' ist der von Gothic berechnete Schaden
            
           var int weapon; weapon = Npc_GetReadiedWeapon(attackerNpc);
    
           var int isOneHand; 
           isOneHand = weapon.flags & ITEM_KAT_NF;
           isOneHand = isOneHand  && (weapon.flags & ITEM_SWD || weapon.flags & ITEM_AXE);
           
           if (Hlp_IsValidItem(weapon) && isOneHand) {
               if (weapon.flags & ITEM_SWD) {
                   dmg = attackerNpc.attribute[ATR_STRENGTH] + weapon.damage[DAM_EDGE] - victimNpc.protection[PROT_EDGE];
               } else {
                   dmg = attackerNpc.attribute[ATR_STRENGTH] + weapon.damage[DAM_BLUNT] - victimNpc.protection[PROT_BLUNT];
               };
           };
    
           return dmg;
    };
    Ich denke damit hast du jetzt genügend Material, um Volltreffer für Einhandwaffen und die restlichen Waffenarten selbst zu implementieren.

    Ich sollte noch dazu sagen, dass ich den Code nicht getestet habe (Fehler können also möglich sein)
    Geändert von Neconspictor (11.10.2018 um 19:15 Uhr)

  20. Beiträge anzeigen #60 Zitieren
    now also in your universe  Avatar von Milky-Way
    Registriert seit
    Jun 2007
    Beiträge
    15.244
     
    Milky-Way ist offline
    Du möchtest vermutlich entscheiden können, ob es Nahkampf, Fernkampf, Magie oder anderer Schaden war. Wenn du nur Nahkampf und Fernkampf anpassen möchtest, dann könntest du z.B. abfragen, ob der attackerNpc eine Nahkampf oder Fernkampfwaffe gezogen hat oder im Fistmode (letzteres vielleicht ausprobieren) ist. Wenn nicht (else) dann einfach mit return dmg; den von Gothic errechneten Schaden zurückgeben / anwenden / verwenden.

    Du kannst dir ja die Stärke-, Rüstungs- und Waffenwerte schnappen, die in dmgDesc, attackerNpc, victimNpc stehen.
    Falls in der Tat Nah- oder Fernkampf, dann mit diesen Werten den Schaden so berechnen, wie du ihn haben möchtest. Anschließend z.B. mit einer Zufallszahl (Hlp_Random) entscheiden, ob es ein Volltreffer gibt und ggf. den Schaden verdoppeln.

    Am Ende dann return deine_variable;, wobei deine_variable den Wert des errechneten Schadens hat.

Seite 3 von 6 « Erste 123456 Letzte »

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