• This is a read only backup of the old Emudevs forum. If you want to have anything removed, please message me on Discord: KittyKaev

[SOLVED] TrinityCore Gossip Variable Args

Status
Not open for further replies.

Visa

Sexy Member
Is it possible to include Variable Args in a ADD_GOSSIP_ITEM ?

Example :
Code:
 player->ADD_GOSSIP_ITEM(4, "Current VP:%u", GOSSIP_SENDER_MAIN, 0);


Into something relevant to:
Code:
 WorldDatabase.PQuery("SELECT `name` FROM `item_template` where `entry`=[COLOR="#00FF00"]%u[/COLOR]", [COLOR="#FF0000"]itementry[/COLOR]);

^ "itementry" being the variable to '%u'

I was curious if I could do the same with the first one '%u' being the variable to maybe:

Code:
 player->ADD_GOSSIP_ITEM(4, "Current VP:[COLOR="#00FF00"]%u[/COLOR]", GOSSIP_SENDER_MAIN, 0, [COLOR="#FF0000"]currentvp.c_str()[/COLOR]);

I know it doesn't work but something like that, i basically want a "variable" (number from the database) in this case vote points to display on the OnGossipHello initially so you can simply view how many vp you got.

Any help is appreciated
 

Tommy

Founder
Is it possible to include Variable Args in a ADD_GOSSIP_ITEM ?

Example :
Code:
 player->ADD_GOSSIP_ITEM(4, "Current VP:%u", GOSSIP_SENDER_MAIN, 0);


Into something relevant to:
Code:
 WorldDatabase.PQuery("SELECT `name` FROM `item_template` where `entry`=[COLOR="#00FF00"]%u[/COLOR]", [COLOR="#FF0000"]itementry[/COLOR]);

^ "itementry" being the variable to '%u'

I was curious if I could do the same with the first one '%u' being the variable to maybe:

Code:
 player->ADD_GOSSIP_ITEM(4, "Current VP:[COLOR="#00FF00"]%u[/COLOR]", GOSSIP_SENDER_MAIN, 0, [COLOR="#FF0000"]currentvp.c_str()[/COLOR]);

I know it doesn't work but something like that, i basically want a "variable" (number from the database) in this case vote points to display on the OnGossipHello initially so you can simply view how many vp you got.

Any help is appreciated

ADD_GOSSIP_ITEM define directive calls a function that doesn't have a param, array or any parameter of that type to support multiple arguments. ADD_GOSSIP_ITEM parameters are as followed:

Code:
uint8 icon, std::string const& message, uint32 sender, uint32 action

However, to accomplish what you're trying to do, you can use std::eek:stringstream. Like so:

Code:
std::ostringstream ss;
ss << "Current VP: " << currentvp;
player->ADD_GOSSIP_ITEM(4, ss.str().c_str(), GOSSIP_SENDER_MAIN, 0);
 

Tommy

Founder
Makes perfect sense however is there any other way to do this or maybe I'm doing something wrong with my identifiers?

I think i'm approaching this with the wrong code :/

http://paste.emudevs.com/?paste=228

Your QueryResult is the issue.

Code:
        QueryResult select = LoginDatabase.PQuery("SELECT `vp` FROM `cms`.`account_data` where `id`=%u", currentvp);
        Field * fields1 = select->Fetch();
        uint32 currentvp = fields1[0].GetUInt32();
 
        QueryResult status = LoginDatabase.PQuery("SELECT `dp` FROM `cms`.`account_data` where `id`=%u", currentdp);
        Field * fields2 = status->Fetch();
        uint32 currentdp = fields2[1].GetUInt32();

"currentvp" and "currentdp" are declared after you run the select code. Also, it is completely wrong anyway since 'id' should be the accountId. You can also handle this in one QueryResult instead of two. I'm not using Visual Studio so bare with me. IN LIME are the changes that are correct:

Code:
        QueryResult select = LoginDatabase.PQuery("SELECT `vp`, [COLOR="#00FF00"]`dp[/COLOR]` FROM `cms`.`account_data` where `id`=%u", [COLOR="#00FF00"]player->GetSession()->GetAccountId()[/COLOR]);
        Field * fields = select->Fetch();
        uint32 currentvp = fields[0].GetUInt32();
        [COLOR="#00FF00"]uint32 currentdp = fields[1].GetUInt32();[/COLOR]

And it is much more clean if you put that on just one gossip menu item instead of two. Overall:

Code:
bool OnGossipHello(Player* player, Creature* creature)
{
        QueryResult select = LoginDatabase.PQuery("SELECT `vp`, [COLOR="#00FF00"]`dp[/COLOR]` FROM `cms`.`account_data` where `id`=%u", [COLOR="#00FF00"]player->GetSession()->GetAccountId()[/COLOR]);
        Field * fields = select->Fetch();
        uint32 currentvp = fields[0].GetUInt32();
        [COLOR="#00FF00"]uint32 currentdp = fields[1].GetUInt32();[/COLOR]

        std::ostringstream ss;
        [COLOR="#00FF00"]ss << "Current VP: " << currentvp << ", Current DP: " << currentdp;[/COLOR]
        player->ADD_GOSSIP_ITEM(4, ss.str().c_str(), GOSSIP_SENDER_MAIN, 0);

        player->ADD_GOSSIP_ITEM(4, "Spend Vote Points ->", GOSSIP_SENDER_MAIN, 2);
        player->ADD_GOSSIP_ITEM(4, "Spend Donor Points ->", GOSSIP_SENDER_MAIN, 3);
        player->ADD_GOSSIP_ITEM(4, "Nevermind", GOSSIP_SENDER_MAIN, 4);
        player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, creature->GetGUID());

        return true;
}

I don't really recommend doing the QueryResult this way since it is not very clean and optimized performance wise. Should query vote and donation points data when the server starts, put it into a map and re-load the data every X minutes.
 

Rochet2

Moderator / Eluna Dev
For handling player specific data I recommend loading it on login, saving on player save, unloading on player logout.
This way you will have the data in memory for each player when needed, not have it when its not needed and the updates to it get saved when the other player data is saved.

However, since this is vote points and donation points, I believe they can change at any given time in the database due to action in web.
That would either require you to make a system to refresh the core data when a change is made in DB, use the current system you have or you could make things loaded less frequently by setting a timer for example one minute for next reload from DB.

If performance is an issue or is wanted, using database queries is bad, since they are slow and the code runs in a single thread meaning that everything else will be slowed down exactly by the same time amount you execute your code.
Using sleep with 1 second would freeze the whole server for one second.
 
Last edited:

Visa

Sexy Member
Works like a charm, once again thank you Tommy. And yes as of right now I suppose I'll just use DB queries for a more frequent updated check of players VP/DP.
But if it gets to be a load and higher amount of players significantly then yeah I suppose making a timer for refresh would be a better way to do so.

My sincerest thanks to both of you, much appreciated.
 
Last edited:
Status
Not open for further replies.
Top