[Archive] GossipSelect triggered twice
[Archive] GossipSelect triggered twice
tringstream warningMessage;
tring());
tringstream yay;
tring());
tringstream nope;
tring());
tringstream nope;
tring());Archived author: Roarl • Posted: 2018-09-27T09:19:59+00:00
Original source
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:
tringstream warningMessage;
warningMessage.str(std:
tring());
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:
tringstream yay;
yay.str(std:
tring());
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:
tringstream nope;
nope.str(std:
tring());
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:
tringstream nope;
nope.str(std:
tring());
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);
}
};
Archived author: GuildSage • Posted: 2018-09-28T08:47:07+00:00
Original source
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
Archived author: Roarl • Posted: 2018-09-28T09:50:37+00:00
Original source
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;
}
Archived author: GuildSage • Posted: 2018-09-28T10:19:46+00:00
Original source
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