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

    Bug beim Verkauf geschmiedeter Schwerter an Harad

    Hallo zusammen, ich mal wieder

    Ich bin gerade dabei, ein paar Bugs auszumerzen und da ist einer dabei, bei dem ich nicht weiter weiß:
    Verkauft man Harad Schwerter, von denen man selbst eins equipped hat, so wird dieses Schwert unequipped und man bekommt ein zweites Schwert dieser Sorte ins Inventar.

    Der Einfachheit halber ein Beispiel:
    Der Held hat 5 edle Schwerter im Inventar, eines ist ausgerüstet, der restliche 4er Stapel liegt im Inventar daneben. Verkauft er nun seine selbstgeschmiedeten Schwerter, so werden 4 Stück erkannt (wie es sein soll, denn das angelegte soll dem Helden erhalten bleiben) und verkauft. Das zuvor angelegte Schwert allerdings wird bei diesem Vorgang abgelegt und im Inventar befindet sich zusätzlich noch ein weiteres edles Schwert, sodass es zwei sind. Legt der Held eines davon wieder an und verkauft wieder seine Waffen, wird das zusätzliche Schwert erkannt, verkauft, das angelegte abgelegt und wieder ein zusätzliches Schwert ins Inventar gelegt. Das könnte man ewig so weitermachen.

    Nun weiß ich nicht, wo der Fehler im Code liegt... Ich würde ihn mal hier reinkopieren:

    Code:
    func void DIA_Harad_SellBlades_Info()
    {
        var C_Item EquipWeap;
        var int anzahl_common;
        var int anzahl_groberzweihaender;
        var int anzahl_schwert1;
        var int anzahl_schwert4;
        var int anzahl_rubinklinge;
        var int anzahl_elbastardo;
        var int anzahl_zweihaender1;
        var int anzahl_zweihaender2;
        var int anzahl_zweihaender3;
        var int anzahl_zweihaender4;
        var int anzahl_sturmbringer;
        var int gesamt;
        var string concatText;
        var int lohn;
        AI_Output(other,self,"DIA_Harad_SellBlades_15_00");    //Ich will meine geschmiedeten Waffen verkaufen.
        EquipWeap = Npc_GetEquippedMeleeWeapon(other);
        anzahl_common = Npc_HasItems(other,ItMw_1H_Common_01);
        if(Hlp_IsItem(EquipWeap,ItMw_1H_Common_01) == TRUE)
        {
            anzahl_common = anzahl_common - 1;
        };
        anzahl_groberzweihaender = Npc_HasItems(other,itmw_2h_common_01);
        if(Hlp_IsItem(EquipWeap,itmw_2h_common_01) == TRUE)
        {
            anzahl_groberzweihaender = anzahl_groberzweihaender - 1;
        };
        anzahl_schwert1 = Npc_HasItems(other,ItMw_Schwert1);
        if(Hlp_IsItem(EquipWeap,ItMw_Schwert1) == TRUE)
        {
            anzahl_schwert1 = anzahl_schwert1 - 1;
        };
        anzahl_schwert4 = Npc_HasItems(other,ItMw_Schwert4);
        if(Hlp_IsItem(EquipWeap,ItMw_Schwert4) == TRUE)
        {
            anzahl_schwert4 = anzahl_schwert4 - 1;
        };
        anzahl_rubinklinge = Npc_HasItems(other,ItMw_Rubinklinge);
        if(Hlp_IsItem(EquipWeap,ItMw_Rubinklinge) == TRUE)
        {
            anzahl_rubinklinge = anzahl_rubinklinge - 1;
        };
        anzahl_elbastardo = Npc_HasItems(other,ItMw_ElBastardo);
        if(Hlp_IsItem(EquipWeap,ItMw_ElBastardo) == TRUE)
        {
            anzahl_elbastardo = anzahl_elbastardo - 1;
        };
        anzahl_zweihaender1 = Npc_HasItems(other,itmw_zweihaender1smith);
        if(Hlp_IsItem(EquipWeap,itmw_zweihaender1smith) == TRUE)
        {
            anzahl_zweihaender1 = anzahl_zweihaender1 - 1;
        };
        anzahl_zweihaender2 = Npc_HasItems(other,itmw_zweihaender2smith);
        if(Hlp_IsItem(EquipWeap,itmw_zweihaender2smith) == TRUE)
        {
            anzahl_zweihaender2 = anzahl_zweihaender2 - 1;
        };
        anzahl_zweihaender3 = Npc_HasItems(other,itmw_zweihaender3smith);
        if(Hlp_IsItem(EquipWeap,itmw_zweihaender3smith) == TRUE)
        {
            anzahl_zweihaender3 = anzahl_zweihaender3 - 1;
        };
        anzahl_zweihaender4 = Npc_HasItems(other,itmw_zweihaender4smith);
        if(Hlp_IsItem(EquipWeap,itmw_zweihaender4smith) == TRUE)
        {
            anzahl_zweihaender4 = anzahl_zweihaender4 - 1;
        };
        anzahl_sturmbringer = Npc_HasItems(other,itmw_sturmbringersmith);
        if(Hlp_IsItem(EquipWeap,itmw_sturmbringersmith) == TRUE)
        {
            anzahl_sturmbringer = anzahl_sturmbringer - 1;
        };
        gesamt = anzahl_common + anzahl_schwert1 + anzahl_schwert4 + anzahl_rubinklinge + anzahl_elbastardo + anzahl_groberzweihaender + anzahl_zweihaender1 + anzahl_zweihaender2 + anzahl_zweihaender3 + anzahl_zweihaender4 + anzahl_sturmbringer;
        if(gesamt == 0)
        {
            if((Hlp_IsItem(EquipWeap,ItMw_1H_Common_01) == TRUE) || (Hlp_IsItem(EquipWeap,ItMw_Schwert1) == TRUE) || (Hlp_IsItem(EquipWeap,ItMw_Schwert4) == TRUE) || (Hlp_IsItem(EquipWeap,ItMw_Rubinklinge) == TRUE) || (Hlp_IsItem(EquipWeap,ItMw_ElBastardo) == TRUE) || (Hlp_IsItem(EquipWeap,itmw_2h_common_01) == TRUE) || (Hlp_IsItem(EquipWeap,itmw_zweihaender1smith) == TRUE) || (Hlp_IsItem(EquipWeap,itmw_zweihaender2smith) == TRUE) || (Hlp_IsItem(EquipWeap,itmw_zweihaender3smith) == TRUE) || (Hlp_IsItem(EquipWeap,itmw_zweihaender4smith) == TRUE) || (Hlp_IsItem(EquipWeap,itmw_sturmbringersmith) == TRUE))
            {
                AI_Output(self,other,"DIA_Harad_SellBlades_12_01");    //Du hast nur die, die du am Gürtel trägst. Du solltest sie besser behalten.
            }
            else
            {
                AI_Output(self,other,"DIA_Harad_SellBlades_12_04");    //Dann stell welche her! Ich nehme nur einfache Schwerter an.
            };
        }
        else
        {
            AI_Output(self,other,"DIA_Harad_SellBlades_12_02");    //Hervorragend!
            Npc_RemoveInvItems(other,ItMw_1H_Common_01,anzahl_common);
            Npc_RemoveInvItems(other,itmw_2h_common_01,anzahl_groberzweihaender);
            Npc_RemoveInvItems(other,ItMw_Schwert1,anzahl_schwert1);
            Npc_RemoveInvItems(other,ItMw_Schwert4,anzahl_schwert4);
            Npc_RemoveInvItems(other,ItMw_Rubinklinge,anzahl_rubinklinge);
            Npc_RemoveInvItems(other,ItMw_ElBastardo,anzahl_elbastardo);
            Npc_RemoveInvItems(other,itmw_zweihaender1smith,anzahl_zweihaender1);
            Npc_RemoveInvItems(other,itmw_zweihaender2smith,anzahl_zweihaender2);
            Npc_RemoveInvItems(other,itmw_zweihaender3smith,anzahl_zweihaender3);
            Npc_RemoveInvItems(other,itmw_zweihaender4smith,anzahl_zweihaender4);
            Npc_RemoveInvItems(other,itmw_sturmbringersmith,anzahl_sturmbringer);
            concatText = ConcatStrings(IntToString(gesamt),PRINT_ItemsGegeben);
            AI_PrintScreen(concatText,-1,YPOS_ItemGiven,FONT_ScreenSmall,2);
            AI_Output(self,other,"DIA_Harad_SellBlades_12_03");    //So, und hier hast du deinen Lohn.
            lohn = (anzahl_common * Value_Common1) + (anzahl_schwert1 * Value_Schwert1) + (anzahl_schwert4 * Value_Schwert4) + (anzahl_rubinklinge * Value_Rubinklinge) + (anzahl_elbastardo * Value_ElBastardo) + (anzahl_groberzweihaender * Value_Sld2hSchwert) + (anzahl_zweihaender1 * Value_Zweihaender1) + (anzahl_zweihaender2 * Value_Zweihaender2) + (anzahl_zweihaender3 * Value_Zweihaender3) + (anzahl_zweihaender4 * Value_Zweihaender4) + (anzahl_sturmbringer * Value_Sturmbringer);
            lohn = lohn / 3;
            B_GiveInvItems(self,other,ItMi_Gold,lohn);
        };
    };
    Nach meiner Logik ist der Code richtig so. Gibt es möglicherweise Probleme mit der Funktion "Npc_RemoveInvItems" in diesem Zusammenhang?

    Vielen Dank schon mal für eure Ideen!

    Beste Grüße,
    Gladi

  2. #2
    Falugify
    Gast
     
    Ich habe das einfach so gelöst:
    Wichtig ist wahrscheinlich auch genau die Reihenfolge und der direkte Befehl dafür.

    Code:
    	AI_Output (other, self, "DIA_Harad_SellBlades_15_00"); //Ich will meine geschmiedeten Waffen verkaufen.
    	
    	var C_ITEM equipWeap; equipWeap = Npc_GetEquippedMeleeWeapon(other);
    
    	var int anzahl_common; anzahl_common = Npc_HasItems (other, ItMw_1H_Common_01);
    	if (Hlp_IsItem(equipWeap, ItMw_1H_Common_01) == TRUE) { anzahl_common = anzahl_common - 1; };
    
            var int gesamt; gesamt = (...)
    
    	if (Hlp_IsItem(equipWeap, ItMw_1H_Common_01) == TRUE) 
    	&& (Npc_HasItems(other, ItMw_1H_Common_01) > 1)
    	{ 
    		Npc_RemoveInvItems (other, ItMw_1H_Common_01, 1); 
    	};

  3. Beiträge anzeigen #3
    Kämpfer
    Registriert seit
    Feb 2016
    Ort
    Dresden
    Beiträge
    349
     
    gladi1994 ist offline
    Vielen Dank für die schnelle Antwort!

    Das funktioniert! So in etwa hab ich das auch probiert, allerdings mit EquipItem(other,"hier die jeweilige Item Instanz") darunter.
    Das scheint so beim Helden allerdings nicht so richtig zu funktionieren... Finde es etwas doof, dass der Held das Schwert ablegt, aber immerhin gibt es jetzt schon mal keine gratis Schwerter mehr.

    Besten Dank!

  4. #4
    Falugify
    Gast
     
    Zitat Zitat von gladi1994 Beitrag anzeigen
    Vielen Dank für die schnelle Antwort!

    Das funktioniert! So in etwa hab ich das auch probiert, allerdings mit EquipItem(other,"hier die jeweilige Item Instanz") darunter.
    Das scheint so beim Helden allerdings nicht so richtig zu funktionieren... Finde es etwas doof, dass der Held das Schwert ablegt, aber immerhin gibt es jetzt schon mal keine gratis Schwerter mehr.

    Besten Dank!
    "EquipItem" von der Engine funktioniert fehlerhaft z.B. in Dialogen (siehe Elvrich). Nutze stattdessen das hier:

    Code:
    func void AI_EquipWeapon (var C_NPC slf, var int ItemInst) 
    {
    	const int EquipWeapon_TogglesEquip = 1;
    	const int oCNpc__EquipWeapon_ptr = 7577648;
      
    	if (!Npc_HasItems (slf, ItemInst)) 
    	{
    		CreateInvItems (slf, ItemInst, 1);
    	};
    
    	if (!Npc_GetInvItem(slf, ItemInst)) 
    	{
    		MEM_AssertFail("Unexpected behaviour in EquipWeapon.");
    		return;
    	};
        
    	if ((item.mainflag == ITEM_KAT_NF) && (Npc_HasReadiedMeleeWeapon(slf)))
    	|| ((item.mainflag == ITEM_KAT_FF) && (Npc_HasReadiedRangedWeapon(slf))) {
    		MEM_Warn ("EquipWeapon: Caller wants to equip a weapon while weapon of the same type is readied. Ignoring request.");
    		return;
    	};
        
    	if (item.flags & ITEM_ACTIVE)
    	&& (!EquipWeapon_TogglesEquip) 
    	{
    		MEM_Info ("EquipWeapon: This weapon is already equipped. Ignoring request.");
    		return;
    	};
        
    	CALL_PtrParam(MEM_InstToPtr(item));
    	CALL__thiscall(MEM_InstToPtr(slf), oCNpc__EquipWeapon_ptr);
    };

  5. Beiträge anzeigen #5
    Kämpfer
    Registriert seit
    Feb 2016
    Ort
    Dresden
    Beiträge
    349
     
    gladi1994 ist offline
    Wow, du bist echt schnell!

    Eine solche Funktion hab ich gesucht, analog zu AI_EquipArmor quasi. Die ist so aber nicht in den Standardskripten, oder? Hab sie jedenfalls nicht gefunden.

    Dann probier ich das mal aus, vielen Dank für den Code!


    Edit: Sehe gerade ein paar Ikarus-Anteile in der Funktion, also definitiv nicht in den Rohskripten dabei. Vielen Dank dafür!
    Edit 2: Klappt perfekt, nochmals vielen Dank!
    Geändert von gladi1994 (30.07.2020 um 00:03 Uhr)

  6. Beiträge anzeigen #6
    Ritter Avatar von Kirides
    Registriert seit
    Jul 2009
    Ort
    Norddeutschland
    Beiträge
    1.780
     
    Kirides ist offline
    Zitat Zitat von Falugify Beitrag anzeigen
    "EquipItem" von der Engine funktioniert fehlerhaft z.B. in Dialogen (siehe Elvrich). Nutze stattdessen das hier:

    ...
    Sieht bei mir recht ähnlich aus

    Ich lege die merke mir die Waffen Instanz die ich trage, lege sie ab, bekomme den Sold und lege sie wieder an, damit ist das Problem geschichte und man hat die Waffe am Ende wieder an.

    Code:
    var C_ITEM equipWeap; equipWeap = Npc_GetEquippedMeleeWeapon(oth);
    var int waffenInst; waffenInst = 0;
    if (Hlp_IsValidItem(equipWeap)) {
    	waffenInst = Hlp_GetInstanceId(equipWeap);
    };
    
    // ...
    
    var int anzahl_elbastardo; anzahl_elbastardo = Npc_HasItems (oth, ItMw_ElBastardo);
    if (Hlp_IsItem(equipWeap, ItMw_ElBastardo) == TRUE) { anzahl_elbastardo = anzahl_elbastardo - 1; };
    
    var int gesamt; gesamt = (anzahl_common + anzahl_schwert1 + anzahl_schwert4 + anzahl_rubinklinge + anzahl_elbastardo);
    
    if (waffenInst != 0) { X_ToggleWeapon(oth, waffenInst, FALSE); };
    
    // ...
    
    	B_GiveInvItems (slf, oth, itmi_gold, lohn);
    	};
    
    	if (waffenInst != 0) { X_ToggleWeapon(oth, waffenInst, TRUE); };
    };
    Mein X_ToggleWeapon sieht dabei so aus: (Der Name ist etwas irreführend, da er die waffe nicht wirklich "toggle'd" ... vielleicht bastel ich das noch irgendwann um )

    Spoiler:(zum lesen bitte Text markieren)
    Code:
    /// Legt die angegebene Waffe an, falls sie noch nicht getragen wird und im Inventar vorhanden ist.
    func void X_ToggleWeapon (var C_NPC slf, var int ItemInst, var int on) {
    
        if (!Npc_HasItems (slf, ItemInst)) {
            MEM_Info ("X_EquipWeaponIfExists: Player has no weapon. Ignoring request.");
            return;
        };
    
        if (!Npc_GetInvItem(slf, ItemInst)) {
            MEM_AssertFail("Unexpected behaviour in X_EquipWeaponIfExists.");
            return;
        };
    
        if ((item.flags & ITEM_ACTIVE_LEGO) && on) {
            /* calling EquipWeapon would unequip the weapon. */
            MEM_Info ("X_EquipWeaponIfExists: This weapon is already equipped. Ignoring request.");
            return;
        };
    
        CALL_PtrParam(MEM_InstToPtr(item));
        CALL__thiscall(MEM_InstToPtr(slf), oCNpc__EquipWeapon);
    };
    Geändert von Kirides (30.07.2020 um 16:40 Uhr)

  7. #7
    Falugify
    Gast
     
    Zitat Zitat von Kirides Beitrag anzeigen
    Sieht bei mir recht ähnlich aus

    Ich lege die merke mir die Waffen Instanz die ich trage, lege sie ab, bekomme den Sold und lege sie wieder an, damit ist das Problem geschichte und man hat die Waffe am Ende wieder an.

    Code:
    var C_ITEM equipWeap; equipWeap = Npc_GetEquippedMeleeWeapon(oth);
    var int waffenInst; waffenInst = 0;
    if (Hlp_IsValidItem(equipWeap)) {
    	waffenInst = Hlp_GetInstanceId(equipWeap);
    };
    
    // ...
    
    var int anzahl_elbastardo; anzahl_elbastardo = Npc_HasItems (oth, ItMw_ElBastardo);
    if (Hlp_IsItem(equipWeap, ItMw_ElBastardo) == TRUE) { anzahl_elbastardo = anzahl_elbastardo - 1; };
    
    var int gesamt; gesamt = (anzahl_common + anzahl_schwert1 + anzahl_schwert4 + anzahl_rubinklinge + anzahl_elbastardo);
    
    if (waffenInst != 0) { X_ToggleWeapon(oth, waffenInst, FALSE); };
    
    // ...
    
    	B_GiveInvItems (slf, oth, itmi_gold, lohn);
    	};
    
    	if (waffenInst != 0) { X_ToggleWeapon(oth, waffenInst, TRUE); };
    };
    Mein X_ToggleWeapon sieht dabei so aus: (Der Name ist etwas irreführend, da er die waffe nicht wirklich "toggle'd" ... vielleicht bastel ich das noch irgendwann um )

    Spoiler:(zum lesen bitte Text markieren)
    Code:
    /// Legt die angegebene Waffe an, falls sie noch nicht getragen wird und im Inventar vorhanden ist.
    func void X_ToggleWeapon (var C_NPC slf, var int ItemInst, var int on) {
    
        if (!Npc_HasItems (slf, ItemInst)) {
            MEM_Info ("X_EquipWeaponIfExists: Player has no weapon. Ignoring request.");
            return;
        };
    
        if (!Npc_GetInvItem(slf, ItemInst)) {
            MEM_AssertFail("Unexpected behaviour in X_EquipWeaponIfExists.");
            return;
        };
    
        if ((item.flags & ITEM_ACTIVE_LEGO) && on) {
            /* calling EquipWeapon would unequip the weapon. */
            MEM_Info ("X_EquipWeaponIfExists: This weapon is already equipped. Ignoring request.");
            return;
        };
    
        CALL_PtrParam(MEM_InstToPtr(item));
        CALL__thiscall(MEM_InstToPtr(slf), oCNpc__EquipWeapon);
    };
    Berücksichtigt deine Methode auch den möglichen Dialog, dass die einzige Waffe nur die ist, die man am Gürtel trägt, sprich, wenn man nur 1 verkaufbare Waffe trägt? Oder tritt dadurch der Dialog nicht mehr auf? Das wäre schade.

  8. Beiträge anzeigen #8
    Ritter Avatar von Kirides
    Registriert seit
    Jul 2009
    Ort
    Norddeutschland
    Beiträge
    1.780
     
    Kirides ist offline
    Zitat Zitat von Falugify Beitrag anzeigen
    Berücksichtigt deine Methode auch den möglichen Dialog, dass die einzige Waffe nur die ist, die man am Gürtel trägt, sprich, wenn man nur 1 verkaufbare Waffe trägt? Oder tritt dadurch der Dialog nicht mehr auf? Das wäre schade.
    Da die Zuweisung "var C_ITEM equipWeap; equipWeap = Npc_GetEquippedMeleeWeapon(oth);" vor dem ausziehen passiert, bleibt die reaktion vorhanden, da unten ja die ganzen abfragen auf "Hlp_IsItem(equipWeap, ItMw_1H_Common_01) .... " sind und nicht jedes mal das die aktuelle Waffeninstanz abgefragt wird.

  9. Beiträge anzeigen #9
    Kämpfer
    Registriert seit
    Feb 2016
    Ort
    Dresden
    Beiträge
    349
     
    gladi1994 ist offline
    Zitat Zitat von Kirides Beitrag anzeigen
    Sieht bei mir recht ähnlich aus

    Ich lege die merke mir die Waffen Instanz die ich trage, lege sie ab, bekomme den Sold und lege sie wieder an, damit ist das Problem geschichte und man hat die Waffe am Ende wieder an.

    Code:
    var C_ITEM equipWeap; equipWeap = Npc_GetEquippedMeleeWeapon(oth);
    var int waffenInst; waffenInst = 0;
    if (Hlp_IsValidItem(equipWeap)) {
        waffenInst = Hlp_GetInstanceId(equipWeap);
    };
    
    // ...
    
    var int anzahl_elbastardo; anzahl_elbastardo = Npc_HasItems (oth, ItMw_ElBastardo);
    if (Hlp_IsItem(equipWeap, ItMw_ElBastardo) == TRUE) { anzahl_elbastardo = anzahl_elbastardo - 1; };
    
    var int gesamt; gesamt = (anzahl_common + anzahl_schwert1 + anzahl_schwert4 + anzahl_rubinklinge + anzahl_elbastardo);
    
    if (waffenInst != 0) { X_ToggleWeapon(oth, waffenInst, FALSE); };
    
    // ...
    
        B_GiveInvItems (slf, oth, itmi_gold, lohn);
        };
    
        if (waffenInst != 0) { X_ToggleWeapon(oth, waffenInst, TRUE); };
    };
    Mein X_ToggleWeapon sieht dabei so aus: (Der Name ist etwas irreführend, da er die waffe nicht wirklich "toggle'd" ... vielleicht bastel ich das noch irgendwann um )

    Spoiler:(zum lesen bitte Text markieren)
    Code:
    /// Legt die angegebene Waffe an, falls sie noch nicht getragen wird und im Inventar vorhanden ist.
    func void X_ToggleWeapon (var C_NPC slf, var int ItemInst, var int on) {
    
        if (!Npc_HasItems (slf, ItemInst)) {
            MEM_Info ("X_EquipWeaponIfExists: Player has no weapon. Ignoring request.");
            return;
        };
    
        if (!Npc_GetInvItem(slf, ItemInst)) {
            MEM_AssertFail("Unexpected behaviour in X_EquipWeaponIfExists.");
            return;
        };
    
        if ((item.flags & ITEM_ACTIVE_LEGO) && on) {
            /* calling EquipWeapon would unequip the weapon. */
            MEM_Info ("X_EquipWeaponIfExists: This weapon is already equipped. Ignoring request.");
            return;
        };
    
        CALL_PtrParam(MEM_InstToPtr(item));
        CALL__thiscall(MEM_InstToPtr(slf), oCNpc__EquipWeapon);
    };
    So ähnlich hatte ich das auch erst versucht, aber irgendwo hatte ich wohl einen Fehler.

    Aber passt ja jetzt super!

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