• 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] Help with two of Tommy's scripts

Status
Not open for further replies.

teroare

Enthusiast
Hi guys and thanks in advance for looking into this!

I was browsing through Support section and I have found two interesting scripts posted by Tommy for someone inside this section.

First script, and the one I want to get some help in editing is the playtime reward script.
What I want it to do is add some values inside a column in auth database, account table ( vote point section called VP ) instead of awarding an item.

script looks like this :

Code:
class most_played : public PlayerScript
{
public:
    most_played() : PlayerScript("most_played") { }

    void OnLogin(Player* player)
    {
        time_t now = time(0);
        tm* localDateTime = localtime(&now);

        if (localDateTime->tm_wday == 5)
        {
            QueryResult result = CharacterDatabase.Query("SELECT guid, MAX(totaltime) FROM characters");
            if (result)
            {
                Field* fields = result->Fetch();
                uint64 guid = fields[0].GetUInt64();

                if (player->GetGUID() == guid)
                    player->AddItem(3000, 1); // CHANGE 3000 (ITEMID) and 1 (ITEMCOUNT) to what you want!
            }while(result->NextRow());
        }
    }
};

void AddSC_reward_most_played()
{
    new most_played;
}


The second one is a boss kill announcer, which announces the killer's name on chat when the certain creature is killed.
What I want to know is...where do I change the ID of the creature for which, if someone kills it, it will do the announcement ( also, can it disply the whole party mermber's name if boss is killed by a whole party ? ) ?
Also, can the killer or party receive an exp boost for , lets say, 1 hour after killing that boss ? ( this one is rather not important tho, the line above is :) )

Code looks like :

Code:
class npc_boss_died : public CreatureScript
{
public:
    npc_boss_died() : CreatureScript("npc_boss_died") { }
	
    struct npc_boss_diedAI : public ScriptedAI
    {
        npc_boss_diedAI(Creature* creature) : ScriptedAI(creature) { }
		
        void JustDied(Unit* killer)
        {
            std::ostringstream ss;
            if (killer->GetTypeId() == TYPEID_PLAYER)
            {
                ss << killer->ToPlayer()->GetName()
                   << " has killed "
                   << me->GetName()
                   << " a Rare Boss!";
                sWorld->SendGlobalText(ss.str().c_str(), NULL);
            }
        }
   };
	
    CreatureAI* GetAI(Creature* creature) const
    {
        return new npc_boss_diedAI(creature);
    }
};

void AddSC_rare_boss()
{
    new npc_boss_died;
}


Best regards,
Cristi
 

Jameyboor

Retired Staff
For the first one, instead of :
Code:
player->AddItem(3000, 1);
Use something like this :
Code:
uint32 vote_points = 20;
LoginDatabase.PExecute("UPDATE account SET vp = vp + %u WHERE id = %u", vote_points, player->GetSession()->GetAccountId());
I'm not on my pc so there might be some typos.

For the second one you should just execute this SQL query with your desired entry id to make it work:
Code:
UPDATE creature_template SET ScriptName = "npc_boss_died" WHERE entry = yourentry
 

teroare

Enthusiast
Thank you Jamey.

Related to
uint32 vote_points = 20;
LoginDatabase.PExecute("UPDATE account SET vp = vp + %u WHERE id = %u", vote_points, player->GetSession()->GetAccountId());

Won't this try to update "account" in characters database, since characters is the database declared a few lines above?

The script should add the reward in another database than the one it makes the search in.
 

Tommy

Founder
Thank you Jamey.

Related to

Won't this try to update "account" in characters database, since characters is the database declared a few lines above?

The script should add the reward in another database than the one it makes the search in.

No. If it executed into the character database, it would be CharacterDatabase.PExecute, not LoginDatabase.PExecute. It is only selecting the total played time from the character database. The only problem with Jamey's example is that he isn't querying the player's existing vote points, so it won't increment the existing points at all, it will just overwrite them.

It should look like:

Code:
class most_played : public PlayerScript
{
public:
    most_played() : PlayerScript("most_played") { }

    void OnLogin(Player* player)
    {
        time_t now = time(0);
        tm* localDateTime = localtime(&now);

        if (localDateTime->tm_wday == 5)
        {
            QueryResult result = CharacterDatabase.Query("SELECT guid, MAX(totaltime) FROM characters");
            QueryResult result2 = LoginDatabase.PQuery("SELECT vote_points FROM account WHERE id='%u'", player->GetSession()->GetAccountId());
            if (!result2)
                return;

            uint32 votePoints = result2->Fetch()[0].GetUInt32();
            if (result)
            {
                Field* fields = result->Fetch();
                uint64 guid = fields[0].GetUInt64();

                if (player->GetGUID() == guid)
                {
                    votePoints = votePoints + 20; // Change 20 to whatever
                    LoginDatabase.PExecute("UPDATE account SET vote_points='%u' WHERE id='%u', votePoints, player->GetSession()->GetAccountId());
                }
            }while(result->NextRow());
        }
    }
};

void AddSC_reward_most_played()
{
    new most_played;
}


I don't really get what you mean on the second part here:

What I want to know is...where do I change the ID of the creature for which, if someone kills it, it will do the announcement

What do you mean 'change the ID of the creature'? Only thing I know is that you can set the script name to multiple creature's if you want it for more than just one creature.

Anyway, giving XP boost to a player with / without a group goes like this:

Code:
#include "Group.h"

class npc_boss_died : public CreatureScript
{
public:
    npc_boss_died() : CreatureScript("npc_boss_died") { }
	
    struct npc_boss_diedAI : public ScriptedAI
    {
        npc_boss_diedAI(Creature* creature) : ScriptedAI(creature) { }
		
        void JustDied(Unit* killer)
        {
            std::ostringstream ss;
            Group* group = NULL;

            if (killer->GetTypeId() == TYPEID_PLAYER)
            {
                Player* playerKiller = killer->ToPlayer();
                if (!playerKiller)
                    return;

                group = playerKiller->GetGroup();
                if (!group)
                {
                    ss << playerKiller->GetName()
                       << " has killed "
                       << me->GetName()
                       << " a Rare Boss!";
                    //playerKiller->CastSpell(playerKiller, spellId); // Give an xp boost just for one player?
                }
                else
                {
                    for (Group::MemberSlotList::const_iterator itr = group->GetMemberSlots().begin(); itr != group->GetMemberSlots().end(); ++itr)
                    {
                        Group::MemberSlot const& memberSlot = *itr;

                        Player* groupMember = sObjectAccessor->FindPlayer((*itr).guid);
                        if (groupMember && groupMember->IsInWorld())
                        {
                            ss << groupMember->GetName()
                               << " has killed "
                               << me->GetName()
                               << " a Rare Boss!";
                            //groupMember->CastSpell(groupMember, spellId); // XP BUFF
                        }
                    }
                }
                sWorld->SendGlobalText(ss.str().c_str(), NULL);
            }
        }
   };
	
    CreatureAI* GetAI(Creature* creature) const
    {
        return new npc_boss_diedAI(creature);
    }
};
 

Tommy

Founder

Well, there's really no requirement except one. You must have the most played time on the server.

If you wanted to add your own played time amount, I guess you could change the query like this:

Code:
SELECT guid FROM characters WHERE totalTime > 10000;

And that will select the guid of the character if the time is greater than 10000. So, the new script would look like:

Code:
class most_played : public PlayerScript
{
public:
    most_played() : PlayerScript("most_played") { }

    void OnLogin(Player* player)
    {
        time_t now = time(0);
        tm* localDateTime = localtime(&now);

        if (localDateTime->tm_wday == 5)
        {
            QueryResult result = CharacterDatabase.Query("SELECT guid FROM characters WHERE totalTime > 10000");
            QueryResult result2 = LoginDatabase.PQuery("SELECT vote_points FROM account WHERE id='%u'", player->GetSession()->GetAccountId());
            if (!result2)
                return;

            uint32 votePoints = result2->Fetch()[0].GetUInt32();
            if (result)
            {
                Field* fields = result->Fetch();
                uint64 guid = fields[0].GetUInt64();

                if (player->GetGUID() == guid)
                {
                    votePoints = votePoints + 20; // Change 20 to whatever
                    LoginDatabase.PExecute("UPDATE account SET vote_points='%u' WHERE id='%u', votePoints, player->GetSession()->GetAccountId());
                }
            }while(result->NextRow());
        }
    }
};

void AddSC_reward_most_played()
{
    new most_played;
}
 

teroare

Enthusiast
I have checked inside the trinity source, and I see three database declared, login world and characters, what if the database I need isn't declared inside the source files ?

I mean, we have login / character / world and , say , website. How do I declare that, so that the script reward is added inside ( total play time scripot ) ?

Promise this is the last question I have related to this thread.


Regards,
Cristi
 

Tommy

Founder
I have checked inside the trinity source, and I see three database declared, login world and characters, what if the database I need isn't declared inside the source files ?

I mean, we have login / character / world and , say , website. How do I declare that, so that the script reward is added inside ( total play time scripot ) ?

Promise this is the last question I have related to this thread.


Regards,
Cristi

Website queries should be separated from the source. Only thing you should do via website is query the databases through your website instead of doing it through your TrinityCore source, as it isn't safe to do. I mean, the script already queries the Character database and executes through your account database, so I don't see why you need the website -- other than querying the tables from your website.
 

teroare

Enthusiast
What you say basically, is to modify the web to look into a field in account database, instead of the trinitycore look into the website's database, right ?
Sorry if it sounds stupid, trying to get my way around :)
 

Tommy

Founder
What you say basically, is to modify the web to look into a field in account database, instead of the trinitycore look into the website's database, right ?
Sorry if it sounds stupid, trying to get my way around :)

Yes, that's what I'm saying. It isn't safe to access your website through the TC source, and there really isn't a need to do it anyway. Just access the database tables from your website.
 
Status
Not open for further replies.
Top