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. Homepage besuchen Beiträge anzeigen #1 Zitieren
    Team Velen
    Registriert seit
    Aug 2015
    Beiträge
    952
     
    Bloodfly91 ist offline

    NPC Leben pro Sekunde abziehen

    Hi,
    ich habe mal wieder ein kleines Problemchen, bei dem ich leider selbst nicht weiter weiß. Und zwar habe ich versucht, einen Giftpfeil zu erstellen. Dazu habe ich erstmal das hier ganz oben in die B_AssessDamage() geschrieben:

    Code:
        var int rnd; rnd = Hlp_Random (100);
        var C_ITEM DistanceWeapon; DistanceWeapon = Npc_GetReadiedWeapon(other);
        
        if (DistanceWeapon.munition == ItRw_DIV_Arrow_Special_03)
        {
            if (rnd <= 75)
            {
                var oCViewStatusBar bar_focus; bar_focus = MEM_PtrToInst (MEM_GAME.focusBar);
                var int bar_tex; bar_tex = bar_focus.value_bar;
    
                ViewPtr_SetTexture(bar_tex, "BAR_HEALTH_POISONED.TGA");
    
                FF_ApplyOnceExt(DIV_SetPoisonHealth, 1000, 10);
    
            } else {
    
                return;
            };
        };
    Die Textur des Lebensbalkens des getroffenen NPCs soll sich also ändern und dann soll die DIV_SetPoisonHealth Funktion aufgerufen werden, die so aussieht:

    Code:
    func void DIV_SetPoisonHealth ()
    {
        Npc_ChangeAttribute (self, ATR_HITPOINTS, -10);
        
        FF_ApplyOnceExt(DIV_SetNormalHealthbarAgain, 10000, 1);
    };
    So weit funktioniert das auch. Aber das Leben wird bei dem getroffenen NPC nicht abgezogen. Die Funktion wird aber aufgerufen, denn wenn ich self mit hero tausche (also Npc_ChangeAttribute (hero, ATR_HITPOINTS, -10); ), verliert der Held 10 Sekunden lang pro Sekunde 10 Lebenspunkte. Auch mit victim habe ich es schon probiert, aber das funktioniert genau so wenig. Was müsste ich also machen, damit der getroffene NPC die 10 HP verliert?

    (PS: Ich weiß, dass der Lebensbalken im moment noch bei allen NPCs geändert wird. Weiß nur noch nicht genau, wie ich das nur für den getroffenen NPC ändern kann. ^^)

  2. Beiträge anzeigen #2 Zitieren
    Ehrengarde Avatar von mud-freak
    Registriert seit
    Dec 2005
    Beiträge
    2.199
     
    mud-freak ist offline
    Was das Abziehen der Lebensenergie angeht, solltest du es lösen können, wenn du einfach die Instanz-ID des NPC mitgibst.
    Code:
    if (!FF_ActiveData(DIV_SetPoisonHealth, Hlp_GetInstanceID(self))) {
        FF_ApplyExtData(DIV_SetPoisonHealth, 1000, 10, Hlp_GetInstanceID(self));
    };
    Code:
    func void DIV_SetPoisonHealth(slfInstID)
    {
        var C_NPC slf; slf = Hlp_GetNpc(slfInstID);
        Npc_ChangeAttribute(slf, ATR_HITPOINTS, -10);
        
        FF_ApplyOnceExt(DIV_SetNormalHealthbarAgain, 10000, 1);
    };


    EDIT: Für ApplyData gibt es keine "Once"-Funktion. Daher solltest du selbst abfragen, ob die FF schon läuft. Siehe Änderungen im Code.
    Geändert von mud-freak (29.04.2017 um 15:45 Uhr)

  3. Homepage besuchen Beiträge anzeigen #3 Zitieren
    Team Velen
    Registriert seit
    Aug 2015
    Beiträge
    952
     
    Bloodfly91 ist offline
    Zitat Zitat von mud-freak Beitrag anzeigen
    Was das Abziehen der Lebensenergie angeht, solltest du es lösen können, wenn du einfach die Instanz-ID des NPC mitgibst.
    Code:
    if (!FF_ActiveData(DIV_SetPoisonHealth, Hlp_GetInstanceID(self))) {
        FF_ApplyExtData(DIV_SetPoisonHealth, 1000, 10, Hlp_GetInstanceID(self));
    };
    Code:
    func void DIV_SetPoisonHealth(slfInstID)
    {
        var C_NPC slf; slf = Hlp_GetNpc(slfInstID);
        Npc_ChangeAttribute(slf, ATR_HITPOINTS, -10);
        
        FF_ApplyOnceExt(DIV_SetNormalHealthbarAgain, 10000, 1);
    };


    EDIT: Für ApplyData gibt es keine "Once"-Funktion. Daher solltest du selbst abfragen, ob die FF schon läuft. Siehe Änderungen im Code.
    Super, vielen Dank.

    Allerdings meckert Gothic jetzt, dass in der Zeile 128 eine Klammer ')' fehlt:

    Code:
    func void DIV_SetPoisonHealth (slfInstID)

  4. Beiträge anzeigen #4 Zitieren
    Ehrengarde Avatar von mud-freak
    Registriert seit
    Dec 2005
    Beiträge
    2.199
     
    mud-freak ist offline
    Da hab ich was vergessen.

    Code:
    func void DIV_SetPoisonHealth(var int slfInstID)

  5. Homepage besuchen Beiträge anzeigen #5 Zitieren
    Team Velen
    Registriert seit
    Aug 2015
    Beiträge
    952
     
    Bloodfly91 ist offline
    Zitat Zitat von mud-freak Beitrag anzeigen
    Da hab ich was vergessen.

    Code:
    func void DIV_SetPoisonHealth(var int slfInstID)
    Danke, jetzt funktioniert es genau so, wie ich es mir vorgestellt habe.

    Nur jetzt wäre da noch das Problem mit dem Balken, dass die Textur sich bei allen NPCs ändert. Ich kenne mich mit LeGo leider immer noch so gut wie gar nicht aus. Könntest du mir noch sagen, wie ich das anstelle, dass die sich nur beim getroffenen NPC ändert? Ich hab nämlich keine Idee was ich da im Skript ändern muss.

  6. Beiträge anzeigen #6 Zitieren
    Ehrengarde Avatar von mud-freak
    Registriert seit
    Dec 2005
    Beiträge
    2.199
     
    mud-freak ist offline
    Ich selbst würde das auf eine wahrscheinlich etwas kompliziertere Art und Weise machen (mit Hooks, wenn die Engine die Healthbar anzeigt). Eine einfachere Variante wäre, das mit einer FrameFunction zu machen. Ich habe gerade keine Skripte hier, hier also nur ein halb-richtiger Gedankenanstoss.
    Diese Funktion hier muss als FrameFunction durchgängig aufgerufen werden und aktualisiert die Fokusbar je nach NPC:

    Code:
    func void DIV_UpdatePoisonHealthbar() {
        // Standardtextur
        var string correctTex; correctTex = "BAR_HEALTH.TGA"; // Ich weiss nicht genau wie die heisst
    
        // Überprüfe den aktuellen Fokus auf einen NPC
        var oCNpc her; her = Hlp_GetNpc(hero);
        if (Hlp_Is_oCNpc(her.focus_vob)) {
            var C_NPC focusNpc; focusNpc = _^(her.focus_vob);
    
            // Ist der NPC im Fokus vergiftet?
            if (FF_ActiveData(DIV_SetPoisonHealth, Hlp_GetInstanceID(focusNpc)))
                correctTex = "BAR_HEALTH_POISONED.TGA";
            };
        };
    
        // Hole die Healthbartextur
        var oCViewStatusBar focusBar; focusBar = _^(MEM_GAME.focusBar);
        var int focusBarTex; focusBarTex = focusBar.value_bar;
    
        // Muss die Textur aktualisiert werden?
        if (!Hlp_StrCmp(ViewPtr_GetTexture(focusBarTex), correctTex)) {
            ViewPtr_SetTexture(focusBarTex, correctTex);
        };
    };
    Geändert von mud-freak (29.04.2017 um 18:43 Uhr)

  7. Homepage besuchen Beiträge anzeigen #7 Zitieren
    Team Velen
    Registriert seit
    Aug 2015
    Beiträge
    952
     
    Bloodfly91 ist offline
    Zitat Zitat von mud-freak Beitrag anzeigen
    Ich selbst würde das auf eine wahrscheinlich etwas kompliziertere Art und Weise machen (mit Hooks, wenn die Engine die Healthbar anzeigt). Eine einfachere Variante wäre, das mit einer FrameFunction zu machen. Ich habe gerade keine Skripte hier, hier also nur ein halb-richtiger Gedankenanstoss.
    Diese Funktion hier muss als FrameFunction durchgängig aufgerufen werden und aktualisiert die Fokusbar je nach NPC:

    Code:
    func void DIV_UpdatePoisonHealthbar() {
        // Standardtextur
        var string correctTex; correctTex = "BAR_HEALTH.TGA"; // Ich weiss nicht genau wie die heisst
    
        // Überprüfe den aktuellen Fokus auf einen NPC
        var oCNpc her; her = Hlp_GetNpc(hero);
        if (Hlp_Is_oCNpc(her.focus_vob)) {
            var C_NPC focusNpc; focusNpc = _^(her.focus_vob);
    
            // Ist der NPC im Fokus vergiftet?
            if (FF_ActiveData(DIV_SetPoisonHealth, Hlp_GetInstanceID(focusNpc)))
                correctTex = "BAR_HEALTH_POISONED.TGA";
            };
        };
    
        // Hole die Healthbartextur
        var oCViewStatusBar focusBar; focusBar = _^(MEM_GAME.focusBar);
        var int focusBarTex; focusBarTex = focusBar.value_bar;
    
        // Muss die Textur aktualisiert werden?
        if (!Hlp_StrCmp(ViewPtr_GetTexture(focusBarTex), correctTex)) {
            ViewPtr_SetTexture(focusBarTex, correctTex);
        };
    };
    Scheint perfekt zu funktionieren, danke.

    Jetzt muss ich das ganze nur auch noch irgendwie für den Helden machen. Aber das krieg ich schon irgendwie hin.. hoffe ich.

  8. Beiträge anzeigen #8 Zitieren
    Ehrengarde Avatar von mud-freak
    Registriert seit
    Dec 2005
    Beiträge
    2.199
     
    mud-freak ist offline
    Ich bin ein bisschen überrascht, dass es direkt funktioniert. Für den Spieler sollte das ganze genauso funktionieren. Anstatt einer weitere FrameFunction, kannst du die Färbung der Healthbar vom Spieler natürlich in die bestehende hinzufügen, damit es übersichtlich bleibt.
    Wenn du alles zum Laufen gebracht hast, könntest du den Code vielleicht hier noch einmal in seiner Gesamtheit posten. Ich bin sicher, das Skript könnte für andere auch von Interesse sein. (Ich habe schon von Implementierungen gehört, die die gesamten Healthbars komplett entfernen und selbst neu erstellen. Da ist dein Ansatz um Längen besser, einfacher und performanter.)

  9. Homepage besuchen Beiträge anzeigen #9 Zitieren
    Team Velen
    Registriert seit
    Aug 2015
    Beiträge
    952
     
    Bloodfly91 ist offline
    Zitat Zitat von mud-freak Beitrag anzeigen
    Ich bin ein bisschen überrascht, dass es direkt funktioniert. Für den Spieler sollte das ganze genauso funktionieren. Anstatt einer weitere FrameFunction, kannst du die Färbung der Healthbar vom Spieler natürlich in die bestehende hinzufügen, damit es übersichtlich bleibt.
    Wenn du alles zum Laufen gebracht hast, könntest du den Code vielleicht hier noch einmal in seiner Gesamtheit posten. Ich bin sicher, das Skript könnte für andere auch von Interesse sein. (Ich habe schon von Implementierungen gehört, die die gesamten Healthbars komplett entfernen und selbst neu erstellen. Da ist dein Ansatz um Längen besser, einfacher und performanter.)
    Veröffentlichen wollte ich es sowieso, sobald alles funktioniert.

    Aber es gibt noch ein Problem: Anscheinend wird die B_AssessDamage() gar nicht für den Helden aufgerufen. Wie mache ich das jetzt also mit dem?

  10. Beiträge anzeigen #10 Zitieren
    Ehrengarde Avatar von mud-freak
    Registriert seit
    Dec 2005
    Beiträge
    2.199
     
    mud-freak ist offline
    Zitat Zitat von Bloodfly91 Beitrag anzeigen
    Anscheinend wird die B_AssessDamage() gar nicht für den Helden aufgerufen. Wie mache ich das jetzt also mit dem?
    Schau dir dazu am besten mal den Post ganz unten (und den darin verlinkten) an. Vielleicht solltest du den Fall für NPCs auch so behandeln.
    Das könnte dann so aussehen (InitDamage wie LeGo in der INIT_Global eintragen):
    Code:
    func int DMG_OnDmg(var int victimPtr, var int attackerPtr, var int dmg) { 
    	// Diese Funktion anpassen, wenn ihr den Schaden verändern wollt! 'dmg' ist der von Gothic berechnete Schaden.
    
            // Hole die betroffenen (N)PCs, hier gesetzt wie in der B_AssessDamage
            var C_NPC slf; slf = _^(victimPtr);
            var C_NPC oth; oth = _^(attackerptr);
    
            // Überprüfe die benutzte Waffe wie gehabt (dein Auszug aus der B_AssessDamage)
            // { ...
    
                // Starte die FrameFunction. Dabei spielt es keine Rolle ob das Opfer der Spieler ist oder nicht
    
            // };
    
            // Damage unberührt zurückgeben
    	return dmg;
    };
    	
    	
    func void _DMG_OnDmg() {
    	EDI = DMG_OnDmg(EBP, MEM_ReadInt(MEM_ReadInt(ESP+644)+8), EDI);
    };
    func void InitDamage() {
    	const int dmg = 0;
    	if (dmg) { return; };
    	HookEngineF(6736583/*0x66CAC7*/, 5, _DMG_OnDmg);
    	dmg = 1;
    };
    Dann musst du nur noch die FF DIV_UpdatePoisonHealthbar um die Healthbar des Spielers erweitern.

  11. Homepage besuchen Beiträge anzeigen #11 Zitieren
    Team Velen
    Registriert seit
    Aug 2015
    Beiträge
    952
     
    Bloodfly91 ist offline
    Zitat Zitat von mud-freak Beitrag anzeigen
    Schau dir dazu am besten mal den Post ganz unten (und den darin verlinkten) an. Vielleicht solltest du den Fall für NPCs auch so behandeln.
    Das könnte dann so aussehen (InitDamage wie LeGo in der INIT_Global eintragen):
    Code:
    func int DMG_OnDmg(var int victimPtr, var int attackerPtr, var int dmg) { 
        // Diese Funktion anpassen, wenn ihr den Schaden verändern wollt! 'dmg' ist der von Gothic berechnete Schaden.
    
            // Hole die betroffenen (N)PCs, hier gesetzt wie in der B_AssessDamage
            var C_NPC slf; slf = _^(victimPtr);
            var C_NPC oth; oth = _^(attackerptr);
    
            // Überprüfe die benutzte Waffe wie gehabt (dein Auszug aus der B_AssessDamage)
            // { ...
    
                // Starte die FrameFunction. Dabei spielt es keine Rolle ob das Opfer der Spieler ist oder nicht
    
            // };
    
            // Damage unberührt zurückgeben
        return dmg;
    };
        
        
    func void _DMG_OnDmg() {
        EDI = DMG_OnDmg(EBP, MEM_ReadInt(MEM_ReadInt(ESP+644)+8), EDI);
    };
    func void InitDamage() {
        const int dmg = 0;
        if (dmg) { return; };
        HookEngineF(6736583/*0x66CAC7*/, 5, _DMG_OnDmg);
        dmg = 1;
    };
    Dann musst du nur noch die FF DIV_UpdatePoisonHealthbar um die Healthbar des Spielers erweitern.
    Ok, dann werd ich mal versuchen das einzubauen. Vielen Dank schon mal.

  12. Homepage besuchen Beiträge anzeigen #12 Zitieren
    Team Velen
    Registriert seit
    Aug 2015
    Beiträge
    952
     
    Bloodfly91 ist offline
    So, hier nochmal das komplette Skript (das hoffentlich funktioniert, hat es jedenfalls, als ich es getestet habe. ).

    Code:
    func int DMG_OnDmg(var int victimPtr, var int attackerPtr, var int dmg) 
    {
        var C_NPC slf; slf = _^(victimPtr);
        var C_NPC oth; oth = _^(attackerptr);
            
        var int rnd; rnd = Hlp_Random (100);
    
        // Hier wird eingetragen, was vergiften kann. In diesem Fall nur Blutfliegen.
        // Man könnte hier aber auch noch Waffen etc. eintragen.
        if (Hlp_GetInstanceID(oth) == Hlp_GetInstanceID(Bloodfly))
        || (Hlp_GetInstanceID(oth) == Hlp_GetInstanceID(YBloodfly))
        {
            if (rnd <= 55)
            {
                if (!FF_ActiveData(SetPoisonHealth, Hlp_GetInstanceID(slf))) 
                {
                    // Die Funktion wird insgesamt 10 mal aufgerufen und 1 mal pro Sekunde.
                    // Kann auch geändert werden.
                    FF_ApplyExtData(DIV_SetPoisonHealth, 1000, 10, Hlp_GetInstanceID(slf));
                };
            };
        };
        return dmg;
    };
        
    func void _DMG_OnDmg() 
    {
        EDI = DMG_OnDmg(EBP, MEM_ReadInt(MEM_ReadInt(ESP+644)+8), EDI);
    };
    
    func void InitDamage() 
    {
        const int dmg = 0;
        if (dmg) 
        { 
            return; 
        };
        
        HookEngineF(6736583/*0x66CAC7*/, 5, _DMG_OnDmg);
        dmg = 1;
    };
    Code:
    func void SetPoisonHealth (var int slfInstID)
    {
        var C_NPC slf; slf = Hlp_GetNpc(slfInstID);
        Npc_ChangeAttribute(slf, ATR_HITPOINTS, -10); // Schaden (pro Sekunde). Kann beliebig verändert werden.
    };
    
    func void UpdatePoisonHealthbar() 
    {
        // Standardtextur
        var string correctTex; correctTex = "BAR_HEALTH.TGA"; // Lebensbalken des NPCs
        var string correctTexPlayer; correctTexPlayer = "BAR_HEALTH.TGA"; // Lebensbalken des PCs
    
        // Falls der PC vergiftet ist
        var oCNpc her; her = Hlp_GetNpc(hero);
        
        if (FF_ActiveData(SetPoisonHealth, Hlp_GetInstanceID(her)))
        {
            correctTexPlayer = "BAR_HEALTH_POISONED.TGA";
        };
        
        // Überprüfe ob sich ein NPC im Fokus befindet
        if (Hlp_Is_oCNpc(her.focus_vob)) 
        {
            var C_NPC focusNpc; focusNpc = _^(her.focus_vob);
    
            // Falls der NPC im Fokus vergiftet ist
            if (FF_ActiveData(SetPoisonHealth, Hlp_GetInstanceID(focusNpc)))
            {
                correctTex = "BAR_HEALTH_POISONED.TGA";
            };
        };
    
        // Hole die Healthbartextur
        var oCViewStatusBar focusBar; focusBar = _^(MEM_GAME.focusBar);
        var oCViewStatusBar hpBar; hpBar = _^(MEM_GAME.hpBar);
        
        var int focusBarTex; focusBarTex = focusBar.value_bar;
        var int hpBarTex; hpBarTex = hpBar.value_bar;
    
        // Muss die Textur des NPCs aktualisiert werden?
        if (!Hlp_StrCmp(ViewPtr_GetTexture(focusBarTex), correctTex)) 
        {
            ViewPtr_SetTexture(focusBarTex, correctTex);
    
        // Muss die Textur des PCs aktualisiert werden?
        } else if (!Hlp_StrCmp(ViewPtr_GetTexture(hpBarTex), correctTexPlayer)) {
        
            ViewPtr_SetTexture(hpBarTex, correctTexPlayer);
        };
    };

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