Jump to content

GossipSelect triggered twice

By Roarl
in Serverside

Recommended Posts

Hello,

I am currently working on a small housing system and am almost done with the bare bones but something is still refusing to work properly.

I want to add a very small description of how the housing system works in a gossip menu, but as soon as SendGossipMenuFor it triggers the OnGossipHello instantly. I compared this part to the Transmogrifier script of Rochet2, which works fine, and it really looks the same so I do not get what I am doing wrong.

More concretly, when I click "Why acquire a property ?" in the first menu, the relevant action (case 1 in OnGossipSelect in the code below) is executed (as expected) but then instantly the action made available in the next menu is also executed instantly (default case, with action = 3)  : in the end the second menu never appears, instead OnGossipHello is executed again.

Does anyone have any idea how to avoid this ?

Thanks in advance for your time !

class npc_house_seller : public CreatureScript
{
public:
    npc_house_seller() : CreatureScript("npc_house_seller") { }

    class npc_house_sellerAI : public ScriptedAI
    {
    public:
        npc_house_sellerAI(Creature* creature) : ScriptedAI(creature)   {}

        bool GossipHello(Player* player) override
        {
            return OnGossipHello(player, me);
        }

        static bool OnGossipHello(Player* player, Creature* creature)
        {
            WorldSession* session = player->GetSession();
            AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/ICONS/INV_Misc_Book_11:30:30:-18:0|tWhy acquire a property ?", 1, 0);
            std::stringstream warningMessage;
            warningMessage.str(std::string());
            warningMessage << "Are you sure you want to proceed ? It will cost you " << HousingSystem::instance()->HouseFromSeller(creature->GetSpawnId())->_price / 10000 << " gold and strip you of any previous estate property.";
            AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/ICONS/INV_Enchant_Disenchant:30:30:-18:0|tPurchase this estate", 2, 0, warningMessage.str().c_str(), 0, false);
            SendGossipMenuFor(player, 800001, creature->GetGUID());
            return true;
        }

        bool GossipSelect(Player* player, uint32 /*menu_id*/, uint32 gossipListId) override
        {
            uint32 sender = player->PlayerTalkClass->GetGossipOptionSender(gossipListId);
            uint32 action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId);
            return OnGossipSelect(player, me, sender, action);
        }

        static bool OnGossipSelect(Player* player, Creature* creature, uint32 sender, uint32 action)
        {
            ClearGossipMenuFor(player);
            WorldSession* session = player->GetSession();
            switch (sender)
            {
                case 1:
                {
                    AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/ICONS/Ability_Spy:30:30:-18:0|tBack..", 3, 0);
                    SendGossipMenuFor(player, 800002, creature->GetGUID());
                }   break;
                case 2:
                   if (player->HasEnoughMoney(HousingSystem::instance()->HouseFromSeller(creature->GetSpawnId())->_price))
                   {
                        House* house = HousingSystem::instance()->HouseFromPlayer(player->GetGUID().GetCounter());
                        if (house != nullptr)
                        {
                            house->_owner = 0;
                            // Respawn NPC
                            Map* map = sMapMgr->FindBaseNonInstanceMap(house->_map_id);
                            Position pos(house->_coord_x, house->_coord_y, house->_coord_z, house->_orientation);

                            Creature* cbuffer = new Creature();
                            if (!cbuffer->Create(map->GenerateLowGuid<HighGuid::Unit>(), map, PHASEMASK_ANYWHERE, 50006, pos))
                                delete cbuffer;

                            cbuffer->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), PHASEMASK_ANYWHERE);

                            ObjectGuid::LowType db_guid = cbuffer->GetSpawnId();

                            // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells()
                            // current "creature" variable is deleted and created fresh new, otherwise old values might trigger asserts or cause undefined behavior
                            cbuffer->CleanupsBeforeDelete();
                            delete cbuffer;
                            cbuffer = new Creature();
                            if (!cbuffer->LoadFromDB(db_guid, map, true, true))
                                delete cbuffer;

                            sObjectMgr->AddCreatureToGrid(db_guid, sObjectMgr->GetCreatureData(db_guid));
                            house->_seller = db_guid;
                            HousingSystem::instance()->AdaptSellerMapOnHouseChange(db_guid, house);
                            house->SaveToDB();
                        }
                        house = HousingSystem::instance()->HouseFromSeller(creature->GetSpawnId());
                        house->_owner = player->GetGUID().GetCounter();
                        house->_seller = 0;
                        house->SaveToDB();
                        HousingSystem::instance()->AdaptPlayerMapOnHouseChange(house->_owner, house);
                        // Remove Creature
                        ObjectGuid::LowType guid = creature->GetGUID().GetCounter();
                        creature->CombatStop();
                        creature->DeleteFromDB();
                        creature->AddObjectToRemoveList();
                        player->ModifyMoney(0-HousingSystem::instance()->HouseFromSeller(creature->GetSpawnId())->_price, false);
                        std::stringstream yay;
                        yay.str(std::string());
                        yay << "Congratulations ! You are now the proud owner of this estate ! ";
                        WorldPacket data(SMSG_MOTD);
                        Tokenizer motdTokens(yay.str(), '@');
                        data << uint32(motdTokens.size());
                        for (Tokenizer::const_reference token : motdTokens)
                            data << token;
                        player->GetSession()->SendPacket(&data);
                        player->AddItem(60073,1);
                        player->PlayerTalkClass->SendCloseGossip();
                   }
                   else
                   {
                        std::stringstream nope;
                        nope.str(std::string());
                        nope << "You cannot afford that property ! You need at least " << HousingSystem::instance()->HouseFromSeller(creature->GetSpawnId())->_price/10000 << " gold.";
                        session->SendNotification(nope.str().c_str());
                        player->PlayerTalkClass->SendCloseGossip();
                   }
                   break;

                default:
                {
                    std::stringstream nope;
                    nope.str(std::string());
                    nope << "Triggered " << sender << " !";
                    session->SendNotification(nope.str().c_str());
                }   return OnGossipHello(player, creature);
            }
            return true;
        }
    };

    CreatureAI* GetAI(Creature *creature) const override
    {
        return new npc_house_sellerAI(creature);
    }
};

 

Link to comment
Share on other sites

The problem is that  you send only 1 menu

you need to send 2 like 

AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/ICONS/Ability_Spy:30:30:-18:0|tBack..", 3, 0);

AddGossipItemFor(player,GOSSIP_ICON_MONEY_BAG,"<==Back", 4,0);

SendGossipMenuFor(player, 800002, creature->GetGUID());

I hope you understand what I m saying

Link to comment
Share on other sites

Hi, thanks for your answer.

I get your point and indeed, adding a second GossipItem in the menu before sending it works.

But do you know why it is that way ? And do you have any idea why it works for Rochet2's script and not for mine ?

For instance, in the code below at case

case EQUIPMENT_SLOT_END + 9:

the menu is working as it should.

static bool OnGossipSelect(Player* player, Creature* creature, uint32 sender, uint32 action)
        {
            ClearGossipMenuFor(player);
            WorldSession* session = player->GetSession();
            switch (sender)
            {
                case EQUIPMENT_SLOT_END: // Show items you can use
                    ShowTransmogItems(player, creature, action);
                    break;
                case EQUIPMENT_SLOT_END + 1: // Main menu
                    OnGossipHello(player, creature);
                    break;
                case EQUIPMENT_SLOT_END + 2: // Remove Transmogrifications
                    {
                        bool removed = false;
                        for (uint8 slot = EQUIPMENT_SLOT_START; slot < EQUIPMENT_SLOT_END; ++slot)
                        {
                            if (Item* newItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
                            {
                                if (!newItem->transmog)
                                    continue;
                                newItem->transmog = 0;
                                newItem->SetState(ITEM_CHANGED, player);
                                sTransmogrification->UpdateItem(player, newItem);
                                removed = true;
                            }
                        }
                        if (removed)
                            session->SendAreaTriggerMessage("%s", GTS(LANG_ERR_UNTRANSMOG_OK));
                        else
                            session->SendNotification(LANG_ERR_UNTRANSMOG_NO_TRANSMOGS);
                        OnGossipHello(player, creature);
                    } break;
                case EQUIPMENT_SLOT_END + 3: // Remove Transmogrification from single item
                    {
                        if (Item* newItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, action))
                        {
                            if (newItem->transmog)
                            {
                                newItem->transmog = 0;
                                newItem->SetState(ITEM_CHANGED, player);
                                sTransmogrification->UpdateItem(player, newItem);
                                session->SendAreaTriggerMessage("%s", GTS(LANG_ERR_UNTRANSMOG_OK));
                            }
                            else
                                session->SendNotification(LANG_ERR_UNTRANSMOG_NO_TRANSMOGS);
                        }
                        OnGossipSelect(player, creature, EQUIPMENT_SLOT_END, action);
                    } break;
#ifdef PRESETS
                case EQUIPMENT_SLOT_END + 4: // Presets menu
                    {
                        if (!sTransmogrification->EnableSets)
                        {
                            OnGossipHello(player, creature);
                            return true;
                        }
                        if (sTransmogrification->EnableSetInfo)
                            AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/ICONS/INV_Misc_Book_11:30:30:-18:0|tHow sets work", EQUIPMENT_SLOT_END + 10, 0);

                        if (!player->presetMap.empty())
                        {
                            for (PresetMapType::const_iterator it = player->presetMap.begin(); it != player->presetMap.end(); ++it)
                                AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/ICONS/INV_Misc_Statue_02:30:30:-18:0|t" + it->second.name, EQUIPMENT_SLOT_END + 6, it->first);

                            if (player->presetMap.size() < sTransmogrification->MaxSets)
                                AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/GuildBankFrame/UI-GuildBankFrame-NewTab:30:30:-18:0|tSave set", EQUIPMENT_SLOT_END + 8, 0);
                        }
                        else
                            AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/GuildBankFrame/UI-GuildBankFrame-NewTab:30:30:-18:0|tSave set", EQUIPMENT_SLOT_END + 8, 0);
                        AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/ICONS/Ability_Spy:30:30:-18:0|tBack..", EQUIPMENT_SLOT_END + 1, 0);
                        SendGossipMenuFor(player, DEFAULT_GOSSIP_MESSAGE, creature->GetGUID());
                    } break;
                case EQUIPMENT_SLOT_END + 5: // Use preset
                    {
                        if (!sTransmogrification->EnableSets)
                        {
                            OnGossipHello(player, creature);
                            return true;
                        }
                        // action = presetID

                        PresetMapType::const_iterator it = player->presetMap.find(action);
                        if (it != player->presetMap.end())
                        {
                            for (PresetslotMapType::const_iterator it2 = it->second.slotMap.begin(); it2 != it->second.slotMap.end(); ++it2)
                                if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, it2->first))
                                    sTransmogrification->PresetTransmog(player, item, it2->second, it2->first);
                        }
                        OnGossipSelect(player, creature, EQUIPMENT_SLOT_END + 6, action);
                    } break;
                case EQUIPMENT_SLOT_END + 6: // view preset
                    {
                        if (!sTransmogrification->EnableSets)
                        {
                            OnGossipHello(player, creature);
                            return true;
                        }
                        // action = presetID

                        PresetMapType::const_iterator it = player->presetMap.find(action);
                        if (it == player->presetMap.end())
                        {
                            OnGossipSelect(player, creature, EQUIPMENT_SLOT_END + 4, 0);
                            return true;
                        }

                        for (PresetslotMapType::const_iterator it2 = it->second.slotMap.begin(); it2 != it->second.slotMap.end(); ++it2)
                            AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, sTransmogrification->GetItemIcon(it2->second, 30, 30, -18, 0) + sTransmogrification->GetItemLink(it2->second, session), sender, action);

                        AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/ICONS/INV_Misc_Statue_02:30:30:-18:0|tUse set", EQUIPMENT_SLOT_END + 5, action, "Using this set for transmogrify will bind transmogrified items to you and make them non-refundable and non-tradeable.\nDo you wish to continue?\n\n" + it->second.name, 0, false);
                        AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/PaperDollInfoFrame/UI-GearManager-LeaveItem-Opaque:30:30:-18:0|tDelete set", EQUIPMENT_SLOT_END + 7, action, "Are you sure you want to delete " + it->second.name + "?", 0, false);
                        AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/ICONS/Ability_Spy:30:30:-18:0|tBack..", EQUIPMENT_SLOT_END + 4, 0);
                        SendGossipMenuFor(player, DEFAULT_GOSSIP_MESSAGE, creature->GetGUID());
                    } break;
                case EQUIPMENT_SLOT_END + 7: // Delete preset
                    {
                        if (!sTransmogrification->EnableSets)
                        {
                            OnGossipHello(player, creature);
                            return true;
                        }
                        // action = presetID

                        auto it = player->presetMap.find(action);
                        if (it != player->presetMap.end())
                        {
                            CharacterDatabase.PExecute("DELETE FROM `custom_transmogrification_sets` WHERE `Owner` = %u AND `PresetID` = %u", player->GetGUID().GetCounter(), uint32(action));
                            player->presetMap.erase(it);
                        }

                        OnGossipSelect(player, creature, EQUIPMENT_SLOT_END + 4, 0);
                    } break;
                case EQUIPMENT_SLOT_END + 8: // Save preset
                    {
                        if (!sTransmogrification->EnableSets)
                        {
                            OnGossipHello(player, creature);
                            return true;
                        }

                        if (player->presetMap.size() >= sTransmogrification->MaxSets)
                        {
                            OnGossipHello(player, creature);
                            return true;
                        }

                        uint32 cost = 0;
                        bool canSave = false;
                        for (uint8 slot = EQUIPMENT_SLOT_START; slot < EQUIPMENT_SLOT_END; ++slot)
                        {
                            if (!sTransmogrification->GetSlotName(slot, session))
                                continue;
                            if (Item* newItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
                            {
                                uint32 entry = newItem->transmog;
                                if (!entry)
                                    continue;
                                const ItemTemplate* temp = sObjectMgr->GetItemTemplate(entry);
                                if (!temp)
                                    continue;
                                if (!sTransmogrification->SuitableForTransmogrification(player, temp)) // no need to check?
                                    continue;
                                cost += sTransmogrification->GetSpecialPrice(temp);
                                canSave = true;
                                AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, sTransmogrification->GetItemIcon(entry, 30, 30, -18, 0) + sTransmogrification->GetItemLink(entry, session), EQUIPMENT_SLOT_END + 8, 0);
                            }
                        }
                        if (canSave)
                            AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/GuildBankFrame/UI-GuildBankFrame-NewTab:30:30:-18:0|tSave set", 0, 0, "Insert set name", cost*sTransmogrification->SetCostModifier + sTransmogrification->SetCopperCost, true);
                        AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/PaperDollInfoFrame/UI-GearManager-Undo:30:30:-18:0|tUpdate menu", sender, action);
                        AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/ICONS/Ability_Spy:30:30:-18:0|tBack..", EQUIPMENT_SLOT_END + 4, 0);
                        SendGossipMenuFor(player, DEFAULT_GOSSIP_MESSAGE, creature->GetGUID());
                    } break;
                case EQUIPMENT_SLOT_END + 10: // Set info
                    {
                        AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/ICONS/Ability_Spy:30:30:-18:0|tBack..", EQUIPMENT_SLOT_END + 4, 0);
                        SendGossipMenuFor(player, sTransmogrification->SetNpcText, creature->GetGUID());
                    } break;
#endif
                case EQUIPMENT_SLOT_END + 9: // Transmog info
                    {
                        AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "|TInterface/ICONS/Ability_Spy:30:30:-18:0|tBack..", EQUIPMENT_SLOT_END + 1, 0);
                        SendGossipMenuFor(player, sTransmogrification->TransmogNpcText, creature->GetGUID());
                    } break;
                default: // Transmogrify
                    {
                        if (!sender && !action)
                        {
                            OnGossipHello(player, creature);
                            return true;
                        }
                        // sender = slot, action = display
                        TransmogTrinityStrings res = sTransmogrification->Transmogrify(player, ObjectGuid(HighGuid::Item, 0, action), sender);
                        if (res == LANG_ERR_TRANSMOG_OK)
                            session->SendAreaTriggerMessage("%s", GTS(LANG_ERR_TRANSMOG_OK));
                        else
                            session->SendNotification(res);
                        // OnGossipSelect(player, EQUIPMENT_SLOT_END, sender);
                        new Timed(player, creature, EQUIPMENT_SLOT_END, sender);
                    } break;
            }
            return true;
        }

 

Link to comment
Share on other sites

×
×
  • Create New...