Roarl Posted September 27, 2018 Share Posted September 27, 2018 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 More sharing options...
GuildSage Posted September 28, 2018 Share Posted September 28, 2018 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 More sharing options...
Roarl Posted September 28, 2018 Author Share Posted September 28, 2018 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 More sharing options...
GuildSage Posted September 28, 2018 Share Posted September 28, 2018 I am not entirely certain but I think is because default: // Transmogrify { if (!sender && !action) { OnGossipHello(player, creature); return true; } } break; maybe I m wrong Link to comment Share on other sites More sharing options...
GossipSelect triggered twice
By Roarlin Serverside
Recommended Posts