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 16 von 16
  1. Homepage besuchen Beiträge anzeigen #1 Zitieren
    Apprentice Avatar von Migos
    Registriert seit
    Mar 2016
    Beiträge
    45
     
    Migos ist offline

    [Skript][Tutorial] Pfeilsorten-Auswahl | Mutli Arrow System

    Grüße Community

    Wollte mal zeigen, wie man unterschiedliche Pfeilsorten auswählen kann und mit demselben Bogen verschießen kann. Analog dazu kann man das Skript auch für Bolzen und Armbrüste übertragen.

    Also, fangen wir direkt an:
    Zuerst habe ich mir folgende Konstanten und Variablen in der Tuning_Ranged_Weapons.d angelegt
    Code:
    //Bögen
    //Pfeilsorten Schadensbonus
    const int Damage_Eisenpfeil            = 10;
    const int Damage_Feuerpfeil            = 15;
    const int Damage_Magiepfeil            = 20;
    //Variablen für die Funktionen
    const int Munition                     = 0;
    const int Bogen                     = 0;
    Erklärung: Die Damage Konstanten geben an, wieviel zusätzlicher Schaden die Pfeile machen sollen (Gesamtschaden = Basis-Schaden des Bogens + Pfeilbonus).
    Danach die beiden Integer 'Munition' und 'Bogen' brauche ich zur Unterscheidung zwischen den verschiedenen Iteminstanzen.

    Als nächstes kommen die folgenden Funktionen ganz an den Anfang der IT_Ranged_Weapons.d:
    Code:
    //     ****************
    //         Munition
    //     ****************
    
    // Munitionswechsel
    // die allgemeine Schadensaenderungs-Funktion, item ist global
    FUNC VOID MunniwechselPfeil() 
    {
         // In der Equip-Funktion des Bogens steht: 
         // Bogen = <Instanz des Bogens>;
         // Npc_GetInvItem (self, Bogen);  
         // Npc_GetInvItem füllt die globale Variable 'item' mit dem entsprechendem Bogen
        
        // Npc_HasItems kann auch verwendet werden, aber Achtung:
        // die Funktion ist nicht GMP tauglich! Man kann den Munitionstyp ueber Talente abfangen, 
        // also zB Tiere ausweiden auf 0,1,2 oder 3 setzen.
        
        // Hier wird abgefragt, ob man den Alternativen Munitionstyp dabei hat
        if (Munition == 3) // Magische Pfeile
        {
            item.munition = ItRw_MagicArrow; // hier wird die Munitionsart festgelegt
            item.damageTotal += Damage_Magiepfeil;
            // Beim magischen Pfeil koennte man den Schadensbonus auch bei 
            // DAM_INDEX_MAGIC hinzufuegen (nicht abziehen vergessen! ;) )
            item.damage[DAM_INDEX_BLUNT] = 0;
            item.damage[DAM_INDEX_EDGE] = 0;
            item.damage[DAM_INDEX_FLY] = 0;
            item.damage[DAM_INDEX_MAGIC] = 0; 
            item.damage[DAM_INDEX_POINT] += Damage_Magiepfeil;
            item.damage[DAM_INDEX_FIRE] = 0;
        }
        else if (Munition == 2) // Feuerpfeile
        {
            item.munition = ItRw_FireArrow; 
            item.damageTotal += Damage_Feuerpfeil;
            item.damage[DAM_INDEX_BLUNT] = 0;
            item.damage[DAM_INDEX_EDGE] = 0;
            item.damage[DAM_INDEX_FLY] = 0;
            item.damage[DAM_INDEX_MAGIC] = 0;
            item.damage[DAM_INDEX_POINT] += Damage_Feuerpfeil;
            item.damage[DAM_INDEX_FIRE] = 0;
        }
        else if (Munition == 1) // Eisenpfeile
        {
            item.munition = ItRw_ironArrow; 
            item.damageTotal += Damage_Eisenpfeil;
            item.damage[DAM_INDEX_BLUNT] = 0;
            item.damage[DAM_INDEX_EDGE] = 0;
            item.damage[DAM_INDEX_FLY] = 0;
            item.damage[DAM_INDEX_MAGIC] = 0;
            item.damage[DAM_INDEX_POINT] += Damage_Eisenpfeil;
            item.damage[DAM_INDEX_FIRE] = 0;
        }
        //Falls Munition = 0 ist, wird einfach wieder der normale Pfeil gesetzt
        else // normale Pfeile
        {
            item.munition = ItRw_Arrow; 
            // kein Schadensbonus
        };
    };
    
    // Und die Funktion, die beim Pfeil- oder Bogenwechsel den Schaden zuruecksetzt
    // analog zu MunniwechselPfeil()
    FUNC VOID MunniresetPfeil() 
    {
    
         if (Munition == 3) // Magische Pfeile 
        {
            item.munition = ItRw_MagicArrow; 
            item.damageTotal -= Damage_Magiepfeil;
            item.damage[DAM_INDEX_BLUNT] = 0;
            item.damage[DAM_INDEX_EDGE] = 0;
            item.damage[DAM_INDEX_FLY] = 0;
            item.damage[DAM_INDEX_MAGIC] = 0;
            item.damage[DAM_INDEX_POINT] -= Damage_Magiepfeil;
            item.damage[DAM_INDEX_FIRE] = 0;
        }
        else if (Munition == 2) // Feuerpfeile
        {
            item.munition = ItRw_FireArrow; 
            item.damageTotal -= Damage_Feuerpfeil;
            item.damage[DAM_INDEX_BLUNT] = 0;
            item.damage[DAM_INDEX_EDGE] = 0;
            item.damage[DAM_INDEX_FLY] = 0;
            item.damage[DAM_INDEX_MAGIC] = 0;
            item.damage[DAM_INDEX_POINT] -= Damage_Feuerpfeil;
            item.damage[DAM_INDEX_FIRE] = 0;
        }
        else if (Munition == 1) // Eisenpfeile
        {
            item.munition = ItRw_ironArrow; 
            item.damageTotal -= Damage_Eisenpfeil;
            item.damage[DAM_INDEX_BLUNT] = 0;
            item.damage[DAM_INDEX_EDGE] = 0;
            item.damage[DAM_INDEX_FLY] = 0;
            item.damage[DAM_INDEX_MAGIC] = 0;
            item.damage[DAM_INDEX_POINT] -= Damage_Eisenpfeil;
            item.damage[DAM_INDEX_FIRE] = 0;
        }
        else // normale Pfeile
        {
            item.munition = ItRw_Arrow; 
        };
        Munition = 0;
    };
    Jetzt müssen wir nur noch bei den Munitionsarten und Bögen die Variablen Munition und Bogen mit den entsprechenden Werten füllen. Das machen wir mit on_equip Funktionen.
    Bei den Pfeilen hab ich mir überlegt das Flag ITEM_AMULET zu setzen, da man immer nur ein Amulett gleichzeitig tragen kann und man so nicht mehrere Pfeilsorten gleichzeitig ausrüsten kann. Ich wette das lässt sich an dieser Stelle auch noch verbessern, indem man sich ein eigenes Flag definiert und so nicht den Amulett Slot mit Pfeilen belegt. Sobald ich mal Zeit dafür finde, werde ich das Skript hier updaten. Oder jemand weiß schon wie das geht und postet es als Kommentar, dann editiere ich das mit Credits auch hier rein

    Also, so werden die Pfeilinstanzen gemacht:
    Code:
    // Munitionsarten
    
    INSTANCE ItRw_Arrow(C_Item)
    {
        name                 =    "Pfeil";
    
        mainflag             =    ITEM_KAT_MAGIC;
        flags                 =    ITEM_AMULET|ITEM_MULTI; 
    
        value                 =    Value_Pfeil;
    
        visual                 =    "ItRw_Arrow.3ds";
        material             =    MAT_WOOD;
        
        on_equip            =    Equip_Arrow;
        on_unequip            =    Unequip_Arrow;
    
        description            = name;
    
        TEXT[4]                =     "Die Spitze ist aus Krallen oder Zähnen.";    
        TEXT[5]                =     "+0 Schaden";    
        
        INV_ZBIAS            = INVCAM_ENTF_AMULETTE_STANDARD;
    };
    FUNC VOID Equip_Arrow()
    {
        Munition = 0; // Munition Variable wird gesetzt
        Npc_GetInvItem (self, Bogen); //füllt die globale Variable 'item' mit dem entsprechendem Bogen
        MunniwechselPfeil(); // Aufruf der Schadensaenderungsfunktion
    };
    // analog zu Equip_Arrow()
    FUNC VOID Unequip_Arrow()
    {
        Npc_GetInvItem (self, Bogen); 
        MunniresetPfeil(); // wichtig: Schaden wird zurueckgesetzt
    };
    Die anderen Pfeilsorten werden ganz analog dazu erstellt.
    Spoiler:(zum lesen bitte Text markieren)

    Code:
    INSTANCE ItRw_ironArrow(C_Item)
    {
        name                 =    "Pfeil mit Eisenspitze";
    
        mainflag             =    ITEM_KAT_MAGIC;
        flags                 =    ITEM_AMULET|ITEM_MULTI;
        
        wear                =     WEAR_EFFECT;
        effect                =    "SPELLFX_ITEMGLIMMER";
        
        value                 =    Value_Pfeil;
    
        visual                 =    "ItRw_Arrow.3ds";
        material             =    MAT_WOOD;
        
        on_equip            =    Equip_ironArrow;
        on_unequip            =    Unequip_ironArrow;
    
        description            = name;
    
        TEXT[4]                =     "Die Spitze ist aus Eisen.";    
        TEXT[5]                =     "+10 Schaden";    
        
        INV_ZBIAS            = INVCAM_ENTF_AMULETTE_STANDARD;
    };
    FUNC VOID Equip_ironArrow()
    {
        Munition = 1;
        Npc_GetInvItem (self, Bogen); 
        MunniwechselPfeil();
    };
    FUNC VOID Unequip_ironArrow()
    {
        Npc_GetInvItem (self, Bogen); 
        MunniresetPfeil();
    };
    
    instance ItRw_FireArrow (C_Item)
    {
        name                 =    "Feuerpfeil";
    
        mainflag             =    ITEM_KAT_MAGIC;
        flags                 =    ITEM_AMULET | ITEM_MULTI;
    
        wear                =    WEAR_EFFECT;
        effect                =    "SPELLFX_FIREARROW";
    
        value                 =    Value_Pfeil;
    
        visual                 =    "ItRw_Arrow.3ds";
        material             =    MAT_WOOD;
        
        on_equip            =    Equip_FireArrow;
        on_unequip            =    Unequip_FireArrow;
    
        description            = name;
    
        TEXT[4]                =     "Vorsicht, der Pfeil brennt.";    
        TEXT[5]                =     "+15 Schaden";    
        
        INV_ZBIAS            = INVCAM_ENTF_AMULETTE_STANDARD;
    };
    FUNC VOID Equip_FireArrow()
    {
        Munition = 2;
        Npc_GetInvItem (self, Bogen); 
        MunniwechselPfeil();
    };
    FUNC VOID Unequip_FireArrow()
    {
        Npc_GetInvItem (self, Bogen); 
        MunniresetPfeil();
    };
    
    instance ItRw_MagicArrow (C_Item)
    {
        name                 =    "Magischer Pfeil";
    
        mainflag             =    ITEM_KAT_MAGIC;
        flags                 =    ITEM_AMULET | ITEM_MULTI;
    
        wear                =    WEAR_EFFECT;
        effect                =    "SPELLFX_ARROW";
    
        value                 =    Value_Pfeil;
    
        visual                 =    "ItRw_Arrow.3ds";
        material             =    MAT_WOOD;
        
        on_equip            =    Equip_MagicArrow;
        on_unequip            =    Unequip_MagicArrow;
    
        description            = name;
    
        TEXT[4]                =     "Der Pfeil ist magisch.";    
        TEXT[5]                =     "+20 Schaden";    
        
        INV_ZBIAS            = INVCAM_ENTF_AMULETTE_STANDARD;
    };
    FUNC VOID Equip_MagicArrow()
    {
        Munition = 3;
        Npc_GetInvItem (self, Bogen); 
        MunniwechselPfeil();
    };
    FUNC VOID Unequip_MagicArrow()
    {
        Npc_GetInvItem (self, Bogen); 
        MunniresetPfeil();
    };


    Und zu guter Letzt noch die Funktionen für die Bögen:
    Hier gebe ich nur ein Beispiel an, wie es am Kurzbogen gemacht wird. Die Funktionen kann man sich ganz analog zu den anderen Bögen schreiben.
    Code:
    instance ItRw_kurzbogen (C_Item)
    {
        name     = "Kurzbogen";
        
        mainflag    = ITEM_KAT_FF;
        flags     = ITEM_BOW;
        material    = MAT_WOOD;
        
        value     = Value_Kurzbogen;
        
        damageTotal   = Damage_Kurzbogen;
        damagetype   = DAM_POINT;
        munition   = ItRw_Arrow;
        
        on_equip        =    Equip_Kurzbogen;
        on_unequip        =    UnEquip_Kurzbogen;
        
        cond_atr[2]     =  ATR_DEXTERITY;
        cond_value[2]   =  Condition_Kurzbogen;
            
        visual             = "ItRw_Bow_L_01.mms";
        
        
        description = name;
        TEXT[1]        = NAME_Damage;     COUNT[1] = damageTotal;
        TEXT[2]        = NAME_Dex_needed;    COUNT[2] = cond_value[2];
    };
    FUNC VOID Equip_Kurzbogen()
    {
        Bogen = ItRw_kurzbogen; // Belege die Bogen-Variable mit der Iteminstanz
        MunniwechselPfeil(); // Update Schaden
    };
    FUNC VOID Unequip_Kurzbogen()
    {
        Npc_GetInvItem (self, Bogen); 
        MunniresetPfeil(); // Resette Schaden
    };
    Vielleicht findet man das Skript ja in der ein oder anderen Mod wieder. Würde mich freuen.
    [Bild: spineSignature.php?name=Migos]
    Entwickler von Jharkendar-Online Deathmatch & Roleplay (zu finden in Spine).
    Komm doch auf unseren Discord und lerne unsere nette Community kennen.
    Mal gucken, was gerade entwickelt wird? Hier ist unsere Roadmap.

  2. Beiträge anzeigen #2 Zitieren
    Schwertmeister Avatar von Noraser
    Registriert seit
    Jun 2007
    Ort
    im Osten
    Beiträge
    937
     
    Noraser ist offline
    Hi Milgo,
    Wir haben uns ja viel mit unseren Multi-Pfeil System versucht.
    Bei deiner Version sollte man beachten, das der Pfeil nur gewechselt wird, wenn der Bogen nicht angelegt ist.
    Ansonsten wirft die Engine den ein oder anderen Pfeil in die Gegend, oder der Held steht mit einen Pfeil in der Hand da, weigert sich aber den abzuschiessen.
    Die Engine ist sehr eigenwillig wenn es um Pfeile geht.
    Selbst in unsere aktuellen Version, wird der Bogen kurzfristig weggesteckt, wenn der Pfeil bei angelegten Bogen gewechselt wird.

    Noraser
    MOD: JURAN 1.4.6 Juran 1.5 Fertig: Sprachdateien 99%, Videos 50%, Weg der Magie (done), Weg des Geschicks (90%)

  3. Beiträge anzeigen #3 Zitieren
    Legend of Ahssûn Avatar von TheEternal
    Registriert seit
    Jun 2013
    Ort
    Frankfurt
    Beiträge
    4.540
     
    TheEternal ist offline
    Man könnte vllt. mit nem Overlay die Bogen Zieh- und Wegsteck-Animation auf 0 oder 1 frame überladen, sodass man höchstens ein kurzes Flackern sieht. Aber der Npc den Bogen "gefühlt" nicht wegsteckt.
    [Bild: LoA_Banner_Skyline2.jpg]
    LoA Website
    Checkout Cloudevo: unlimited Cloud-Drive


  4. Beiträge anzeigen #4 Zitieren
    Legende der Amazonen Avatar von Bisasam
    Registriert seit
    Dec 2006
    Ort
    Meine Faust in Sinis Gesicht
    Beiträge
    9.635
     
    Bisasam ist offline
    Hallo Migox, überrascht dich hier zu sehen.
    Hast du die Pfeilsorten im GMP umgesetzt? Da müsste es doch mordsmäßige Synchronisationsprobleme geben, weil die gestreamten Spieler mit Standardmunition dargestellt werden.


    "Das erinnert doch sehr erfreulich an das, was man sich als Gothicfan wünscht!"
    -Korallenkette

  5. Homepage besuchen Beiträge anzeigen #5 Zitieren
    Team Velen
    Registriert seit
    Aug 2015
    Beiträge
    952
     
    Bloodfly91 ist offline
    Super, genau so etwas habe ich gebraucht. Wollte das vor einiger Zeit auch schon mal in Velen einbauen, wusste nur nicht genau wie. Danke.

    Aber ich habe dazu auch gleich mal eine Frage, bei der ich mir nicht sicher war, ob ich einen extra Thread dafür aufmachen soll, weil das ja so gut dazu passt:
    Ich wollte einen Gothic 3 ähnlichen "Kopfnuss" Pfeil skripten, der also nicht tötet, sondern den Gegner nur bewusstlos machen soll. Ich habe schon einiges probiert, z.B. einfach den damagetype des Bogens per Skript (bzw. der Funktion MunniwechselPfeil()) in DAM_BLUNT zu ändern (item.damagetype = DAM_BLUNT) oder das mainflag zu ändern (item.mainflag = XXX). Aber nichts davon hat funktioniert. Beim mainflag hab ich verschiedenes getestet, z.B. ITEM_KAT_NF und ITEM_KAT_RUNE, was aber beides nicht funktioniert hat (ist ja eigentlich klar. ^^). Wäre so ein nicht tödlicher Pfeil überhaupt möglich? Weil ich denke, dafür müsste ich ja ein neues mainflag erstellen (geht das überhaupt so einfach?) und dann per Pfeilskript das item.mainflag ändern?

  6. Homepage besuchen Beiträge anzeigen #6 Zitieren
    Apprentice Avatar von Migos
    Registriert seit
    Mar 2016
    Beiträge
    45
     
    Migos ist offline
    Zitat Zitat von Noraser Beitrag anzeigen
    Bei deiner Version sollte man beachten, das der Pfeil nur gewechselt wird, wenn der Bogen nicht angelegt ist.
    Das stimmt. Da die Pfeile hier das Amulett-Flag haben, muss man aber sowieso in das Inventar gehen, wenn man die Pfeile wechseln möchte. Sobald man in das Inventar geht, geht man ja automatisch aus der Kampfstellung heraus. Daher dürfte das deine beschriebenen Bugs vermeiden.

    Zitat Zitat von Bisasam Beitrag anzeigen
    Hallo Migox, überrascht dich hier zu sehen.
    Hast du die Pfeilsorten im GMP umgesetzt? Da müsste es doch mordsmäßige Synchronisationsprobleme geben, weil die gestreamten Spieler mit Standardmunition dargestellt werden.
    Ja, die Pfeilsorten sind umgesetzt. Aktuell lassen die sich nur auf CK bewundern, aber unser Deathmatch und zukünftiger RP Server werden die bald auch haben.
    Synchronisationsprobleme mit dem Schaden gab es keine. Allerdings hat der GMP allgemein ein Problem mit der Darstellung von Munition bei anderen Spielern. Egal ob Standard Pfeile oder eigene Munition, sie werden nicht angezeigt.

    Zitat Zitat von Bloodfly91 Beitrag anzeigen
    Super, genau so etwas habe ich gebraucht. Wollte das vor einiger Zeit auch schon mal in Velen einbauen, wusste nur nicht genau wie. Danke.

    Aber ich habe dazu auch gleich mal eine Frage, bei der ich mir nicht sicher war, ob ich einen extra Thread dafür aufmachen soll, weil das ja so gut dazu passt:
    Ich wollte einen Gothic 3 ähnlichen "Kopfnuss" Pfeil skripten, der also nicht tötet, sondern den Gegner nur bewusstlos machen soll. Ich habe schon einiges probiert, z.B. einfach den damagetype des Bogens per Skript (bzw. der Funktion MunniwechselPfeil()) in DAM_BLUNT zu ändern (item.damagetype = DAM_BLUNT) oder das mainflag zu ändern (item.mainflag = XXX). Aber nichts davon hat funktioniert. Beim mainflag hab ich verschiedenes getestet, z.B. ITEM_KAT_NF und ITEM_KAT_RUNE, was aber beides nicht funktioniert hat (ist ja eigentlich klar. ^^). Wäre so ein nicht tödlicher Pfeil überhaupt möglich? Weil ich denke, dafür müsste ich ja ein neues mainflag erstellen (geht das überhaupt so einfach?) und dann per Pfeilskript das item.mainflag ändern?
    Freut mich zu hören, dass das Skript direkt Anklang findet
    Du könntest bei deinem Kopfnuss Pfeil item.damageTotal = 0 setzen, dann macht der Bogen zumindest schonmal keinen Schaden. Dann musst du nur noch herausfinden, wie man den Attributs-Schaden vom Hero selbst eliminiert und anschließend einen Weg finden, wie man deinen gewünschten Stun/Knockout-Effekt scriptet. Dafür kenne ich mich aber zu wenig mit Daedalus aus.
    [Bild: spineSignature.php?name=Migos]
    Entwickler von Jharkendar-Online Deathmatch & Roleplay (zu finden in Spine).
    Komm doch auf unseren Discord und lerne unsere nette Community kennen.
    Mal gucken, was gerade entwickelt wird? Hier ist unsere Roadmap.

  7. Homepage besuchen Beiträge anzeigen #7 Zitieren
    Team Velen
    Registriert seit
    Aug 2015
    Beiträge
    952
     
    Bloodfly91 ist offline
    Zitat Zitat von Migos Beitrag anzeigen
    Freut mich zu hören, dass das Skript direkt Anklang findet
    Du könntest bei deinem Kopfnuss Pfeil item.damageTotal = 0 setzen, dann macht der Bogen zumindest schonmal keinen Schaden. Dann musst du nur noch herausfinden, wie man den Attributs-Schaden vom Hero selbst eliminiert und anschließend einen Weg finden, wie man deinen gewünschten Stun/Knockout-Effekt scriptet. Dafür kenne ich mich aber zu wenig mit Daedalus aus.
    Eigentlich keine schlechte Idee. Aber dann macht der Bogen/Pfeil ja gar keinen Schaden mehr? Eigentlich soll er ja schon noch normalen Schaden machen, nur nicht töten. Ich glaube ich werde dafür trotzdem nochmal einen extra Thread aufmachen. ^^

    Mir ist auch noch ein Bug aufgefallen: Wenn man einen Spielstand lädt und einen Bogen mit Pfeil angelegt hatte, muss man immer beides nochmal ablegen und wieder anlegen in der Reihenfolge: Bogen --> Pfeil. Sonst zieht der Held den Bogen nicht mehr.

    Edit: Gleiches Problem wenn man erst die Pfeile anlegt und dann erst den Bogen.
    Geändert von Bloodfly91 (01.05.2017 um 01:20 Uhr)

  8. Homepage besuchen Beiträge anzeigen #8 Zitieren
    Team Velen
    Registriert seit
    Aug 2015
    Beiträge
    952
     
    Bloodfly91 ist offline
    Zitat Zitat von Bloodfly91 Beitrag anzeigen
    Mir ist auch noch ein Bug aufgefallen: Wenn man einen Spielstand lädt und einen Bogen mit Pfeil angelegt hatte, muss man immer beides nochmal ablegen und wieder anlegen in der Reihenfolge: Bogen --> Pfeil. Sonst zieht der Held den Bogen nicht mehr.

    Edit: Gleiches Problem wenn man erst die Pfeile anlegt und dann erst den Bogen.
    Hat da vielleicht noch jemand eine Idee?

  9. Beiträge anzeigen #9 Zitieren
    Abenteurer Avatar von Maximus93
    Registriert seit
    Feb 2016
    Ort
    Braunschweig
    Beiträge
    68
     
    Maximus93 ist offline
    Zitat Zitat von Bloodfly91 Beitrag anzeigen
    Hat da vielleicht noch jemand eine Idee?
    Ich wollte den Thread nochmal aus der Versenkung holen. Ich will ein System zur Auswahl von Pfeilsorten gerne in meine private Mod einbauen.
    Hat jemand in den letzten Jahren ggf. einen fehlerfreien Code entwickeln können, der keine Bugs verursacht?

  10. Beiträge anzeigen #10 Zitieren
    Ritter Avatar von Kirides
    Registriert seit
    Jul 2009
    Ort
    Norddeutschland
    Beiträge
    1.780
     
    Kirides ist offline
    Hier ist der Code welchen ich in meiner G2 Mod verwende.

    Das benötigt etwas Handarbeit beim Ausrüsten/Ablegen von Bögen/Armbrüsten funktioniert bisher aber ziemlich gut.

    Setzt LeGo ( LeGo_Init(flags | LeGo_HookEngine) ) & Ikarus vorraus


    Damit wird im Inventar immer die Ausgerüstete Pfeilsorte angezeigt (Rotes Kästchen, wie bei Waffen)
    Es wird im Spielstand gespeichert, welcher Pfeil/Bolzen ausgerüstet ist.

    Ausgerüstet wird über das "anlegen" des Pfeils/Bolzens. Kann aber nach belieben gemacht werden.
    Wichtig ist nur, das "X_UpdateMunition_Bow" oder respektive "X_UpdateMunition_Crossbow" korrekt aufgerufen wird.


    UpdateMunition.d (Irgendwo vor den Items parsen, nach LeGo & Ikarus)
    Spoiler:(zum lesen bitte Text markieren)
    Code:
    /*
        -- Story_Globals.d
        var int SC_Equipped_Arrow;
        var int SC_Equipped_Bolt;
    */
    
    const int X_AMMO_RESET = -1;
    
    func void X_UpdateMunition_SetInactiveAll(var C_NPC slf) {
        var int i; i = 0;
        while(TRUE);
            if (NPC_GetInvItemBySlot(slf, ITEM_KAT_MUN, i) == 0) { return; };
            if (!Hlp_IsValidItem(item)) { return; };
            if ((item.mainflag & ITEM_KAT_MUN) == 0) { i+=1; continue; };
    
            if (item.flags & ITEM_MULTI) {
                if (item.flags & (ITEM_CROSSBOW | ITEM_BOW)) {
                    item.flags = item.flags & ~(ITEM_ACTIVE_LEGO);
                };
            };
            i+=1;
        end;
    };
    
    func void X_UpdateMunition_Bow(var C_NPC slf, var int instAmmoParam) {
        var C_ITEM bow;
        var int instAmmo; instAmmo = instAmmoParam;
    
        if (Npc_IsPlayer(slf)) {
            if (SC_Equipped_Arrow != ItRw_Arrow)
            && (SC_Equipped_Arrow != ItRw_Addon_FireArrow)    
            && (SC_Equipped_Arrow != ItRw_Addon_MagicArrow)    
            {
                SC_Equipped_Arrow = ItRw_Arrow;
            };
    
            if (instAmmoParam == X_AMMO_RESET) {
                instAmmo = SC_Equipped_Arrow;
            };
            X_UpdateMunition_SetInactiveAll(slf);
            SC_Equipped_Arrow = instAmmo;
        };
    
        if      (Npc_IsInfightMode(slf, FMODE_FAR)) { bow = Npc_GetReadiedWeapon(slf); }
        else if (Npc_HasEquippedRangedWeapon(slf))  { bow = Npc_GetEquippedRangedWeapon(slf); }
        else                                        { return; };
    
        if (Hlp_IsValidItem(bow)) {
            if (bow.flags & ITEM_BOW) {
                bow.munition = instAmmo;
                if (Npc_IsPlayer(slf)) {
                    if (Npc_GetInvItem(slf, instAmmo)) {
                        if (instAmmoParam != X_AMMO_RESET) {
                            X_Print(TextSpaceText(item.description, TEXT_CONCAT_EQUIPPED));
                        };
                        item.flags = item.flags | ITEM_ACTIVE_LEGO;
                    };
                };
            };
        };
    };
    
    func void X_UpdateMunition_Crossbow(var C_NPC slf, var int instAmmoParam) {
        var C_ITEM cbow;
        var int instAmmo; instAmmo = instAmmoParam;
    
        if (Npc_IsPlayer(slf)) {
            if (SC_Equipped_Bolt != ItRw_Bolt)
            && (SC_Equipped_Bolt != ItRw_Addon_MagicBolt)    
            {
                SC_Equipped_Bolt = ItRw_Bolt;
            };
    
            if (instAmmoParam == X_AMMO_RESET) {
                instAmmo = SC_Equipped_Bolt;
            };
            X_UpdateMunition_SetInactiveAll(slf);
            SC_Equipped_Bolt = instAmmo;
        };
    
        if      (Npc_IsInfightMode(slf, FMODE_FAR)) { cbow = Npc_GetReadiedWeapon(slf); }
        else if (Npc_HasEquippedRangedWeapon(slf))  { cbow = Npc_GetEquippedRangedWeapon(slf); }
        else                                        { return; };
    
        if (Hlp_IsValidItem(cbow)) {
            if (cbow.flags & ITEM_CROSSBOW) {
                cbow.munition = instAmmo;
                if (Npc_IsPlayer(slf)) {
                    if (Npc_GetInvItem(slf, instAmmo)) {
                        if (instAmmoParam != X_AMMO_RESET) {
                            X_Print(TextSpaceText(item.description, TEXT_CONCAT_EQUIPPED));
                        };
                        
                        item.flags = item.flags | ITEM_ACTIVE_LEGO;
                    };
                };
            };
        };
    };
    
    
    /// Gehandled über `_X_UpdateMunition_InitUpdate`
    func void _X_UpdateMunition_FF() {
        if (!MEM_Game.timeStep) { return; };
        if (!Hlp_IsValidNpc(hero)) { return; };
    
        if (SC_Equipped_Bolt != 0) {
            X_UpdateMunition_Crossbow(hero, X_AMMO_RESET);
        } else {
            X_UpdateMunition_Bow(hero, X_AMMO_RESET);
        };
        RemoveHookF(oCGame__Render, 0, _X_UpdateMunition_FF);
    };
    func void _X_UpdateMunition_InitUpdate() {
        HookEngineF(oCGame__Render, 7, _X_UpdateMunition_FF);
    };
    
    func void X_UpdateMunition_EquipBow() {
        if (!Npc_IsPlayer(self)) { return; };
    
        SC_Equipped_Bolt = 0;
        _X_UpdateMunition_InitUpdate();
    };
    func void X_UpdateMunition_UnEquipBow() {
        if (!Npc_IsPlayer(self)) { return; };
        X_UpdateMunition_SetInactiveAll(self);
    };
    
    func void X_UpdateMunition_EquipCrossbow() {
        if (!Npc_IsPlayer(self)) { return; };
    
        SC_Equipped_Arrow = 0;
        _X_UpdateMunition_InitUpdate();
    };
    func void X_UpdateMunition_UnEquipCrossbow() {
        if (!Npc_IsPlayer(self)) { return; };
        X_UpdateMunition_SetInactiveAll(self);
    };


    Anpassungen bei den Waffen:

    Spoiler:(zum lesen bitte Text markieren)
    Code:
    INSTANCE ItRw_Sld_Bow(C_Item)
    {
        // ...
    
        on_equip			=	X_UpdateMunition_EquipBow;
        on_unequip			=	X_UpdateMunition_UnEquipBow;
    
        // ....
    };
    
    INSTANCE ItRw_Mil_Crossbow(C_Item)
    {
        // ...
    
        on_equip			=	X_UpdateMunition_EquipCrossbow;
        on_unequip			=	X_UpdateMunition_UnEquipCrossbow;
    
        // ...
    };
    
    // Andere Bögen / Armbrüste


    Anpassungen um einen Pfeil / Bolzen "ausrüsten" zu können

    Spoiler:(zum lesen bitte Text markieren)
    Code:
    INSTANCE ItRw_Arrow(C_Item)
    {
        // ...
    
        // Damit man den Pfeil "ausrüsten" kann
        scemename			= SCHEME_EQUIPITEM;
        on_state[0]			= Equip_ItRw_Arrow;
    };
    
    func void Equip_ItRw_Arrow() {
        X_UpdateMunition_Bow(self, ItRw_Arrow);
    };
    
    
    
    INSTANCE ItRw_Bolt(C_Item)
    {
        // ...
    
        // Damit man den Bolzen "ausrüsten" kann
        scemename			= SCHEME_EQUIPITEM;
        on_state[0]			= Equip_ItRw_Bolt;
    };
    
    func void Equip_ItRw_Bolt() {
        X_UpdateMunition_Crossbow(self, ItRw_Bolt);
    };


    Hook, damit immer der richtige Zustand im Inventar angezeigt wird. (irgendwo am Ende der Gothic.src parsen lassen aufrufen in/durch Init_Global())

    Spoiler:(zum lesen bitte Text markieren)
    Code:
    func void _Hook_oCNpc__OpenInventory_UpdateItems() {
        if (!Hlp_IsValidNpc(hero)) { return; };
    
        _X_UpdateMunition_InitUpdate();
    };
    
    func void X_UpdateMunition_Init() {
        HookEngineF(oCNpc__OpenInventory , 6, _Hook_oCNpc__OpenInventory_UpdateItems);
    };
    Geändert von Kirides (23.03.2021 um 11:18 Uhr) Grund: Code portabel gestaltet

  11. Beiträge anzeigen #11 Zitieren
    now also in your universe  Avatar von Milky-Way
    Registriert seit
    Jun 2007
    Beiträge
    15.205
     
    Milky-Way ist offline
    Was ist der Sinn hinter der Variable slf in _Hook_oCNpc__OpenInventory_UpdateItems -- die wird gar nicht benutzt?

    Vermutlich wird es hier auch passieren, dass man nach (größeren) Änderungen an den Skripten die Pfeile wieder neu auswählen muss, weil sich die Pfeilinstanz verschoben hat und so die Variable nicht mehr auf die richtige Instanz zeigt? Ist hier nur als Hinweis gedacht, damit sich der Modder beim Testen alter Spielstände nicht wundert.

  12. Beiträge anzeigen #12 Zitieren
    Ritter Avatar von Kirides
    Registriert seit
    Jul 2009
    Ort
    Norddeutschland
    Beiträge
    1.780
     
    Kirides ist offline
    Zitat Zitat von Milky-Way Beitrag anzeigen
    Was ist der Sinn hinter der Variable slf in _Hook_oCNpc__OpenInventory_UpdateItems -- die wird gar nicht benutzt?

    Vermutlich wird es hier auch passieren, dass man nach (größeren) Änderungen an den Skripten die Pfeile wieder neu auswählen muss, weil sich die Pfeilinstanz verschoben hat und so die Variable nicht mehr auf die richtige Instanz zeigt? Ist hier nur als Hinweis gedacht, damit sich der Modder beim Testen alter Spielstände nicht wundert.
    Jop. Probleme beim Verschieben von Instanzen kann es geben, bei tests mit älteren Spielständen.
    Könnte man entsprechend anpassen und gucken ob der aktuelle "ausgerüstete" Instanz-Index überhaupt noch den ItRw... entspricht und ansonsten direkt reset auf standard.
    Man könnte zwar versuchen zu schummeln, indem man den Instanz-namen verwendet (und mit den Ikarus Parser funktionen arbeitet), aber auch der kann verändert werden. Unwahrscheinlich, aber kann passieren.


    Danke für den Hinweis mit slf, war ein überbleibsel.

  13. Beiträge anzeigen #13 Zitieren
    Abenteurer Avatar von Maximus93
    Registriert seit
    Feb 2016
    Ort
    Braunschweig
    Beiträge
    68
     
    Maximus93 ist offline
    Vielen Dank! Klasse Arbeit mal wieder

    Paar Sachen noch:
    1: Kann es sein, dass die X_Print Funktion von dir definiert ist? Ich bekomme diesbezüglich nämlich einen Fehler beim Parsen.
    2: SCHEME_EQUIPITEM wird mir ebenfalls als unbekannt angezeigt.
    3: Muss die Adresse oCNpc__OpenInventory nicht irgendwo definiert sein?
    Geändert von Maximus93 (22.03.2021 um 23:12 Uhr)

  14. Beiträge anzeigen #14 Zitieren
    Ritter Avatar von Kirides
    Registriert seit
    Jul 2009
    Ort
    Norddeutschland
    Beiträge
    1.780
     
    Kirides ist offline
    Zitat Zitat von Maximus93 Beitrag anzeigen
    Vielen Dank! Klasse Arbeit mal wieder

    Paar Sachen noch:
    1: Kann es sein, dass die X_Print Funktion von dir definiert ist? Ich bekomme diesbezüglich nämlich einen Fehler beim Parsen.
    2: SCHEME_EQUIPITEM wird mir ebenfalls als unbekannt angezeigt.
    3: Muss die Adresse oCNpc__OpenInventory nicht irgendwo definiert sein?
    Natürlich... Da habe ich mal wieder nicht ganz aufgepasst

    1. Jop, kann durch beliebige text-darstellung ausgetauscht werden (z.B. "Print" )
    2. SCHEME_EQUIPITEM ist eine "const string SCHEME_EQUIPITEM = "MAP"; "
    3. Ist definiert in der "LeGo\EngineAdr_G2.d"

    Ich bessere den Beitrag oben heute abend aus.

  15. Beiträge anzeigen #15 Zitieren
    Abenteurer Avatar von Maximus93
    Registriert seit
    Feb 2016
    Ort
    Braunschweig
    Beiträge
    68
     
    Maximus93 ist offline
    Zitat Zitat von Kirides Beitrag anzeigen
    Natürlich... Da habe ich mal wieder nicht ganz aufgepasst

    1. Jop, kann durch beliebige text-darstellung ausgetauscht werden (z.B. "Print" )
    2. SCHEME_EQUIPITEM ist eine "const string SCHEME_EQUIPITEM = "MAP"; "
    3. Ist definiert in der "LeGo\EngineAdr_G2.d"

    Ich bessere den Beitrag oben heute abend aus.

    Alles klar. Und die Funktion TextSpaceText verkettet wahrscheinlich nur zwei Strings mit einem Leerzeichen dazwischen oder?
    TEXT_CONCAT_EQUIPPED wäre dann nur noch undefiniert.

  16. Beiträge anzeigen #16 Zitieren
    Ritter Avatar von Kirides
    Registriert seit
    Jul 2009
    Ort
    Norddeutschland
    Beiträge
    1.780
     
    Kirides ist offline
    Zitat Zitat von Maximus93 Beitrag anzeigen
    Alles klar. Und die Funktion TextSpaceText verkettet wahrscheinlich nur zwei Strings mit einem Leerzeichen dazwischen oder?
    TEXT_CONCAT_EQUIPPED wäre dann nur noch undefiniert.
    Jop. Genau das macht sie

    und TEXT_CONCAT_EQUIPPED ist "ausgerüstet"


    Ich habe das Skript oben entsprechend angepasst. Sollte nun hoffentlich Portabel sein. Kann es leider erst gegen heute abend testen.
    Geändert von Kirides (23.03.2021 um 11:19 Uhr)

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