This is a read only copy without any forum functionality of the old Modcraft forum.
If there is anything that you would like to have removed, message me on Discord via Kaev#5208.
Big thanks to Alastor for making this copy!

Menu

Author Topic: [SOLVED] [C++] Set PvP FFA when player enter map  (Read 11314 times)

bizzlesnaff

  • Registred Member
  • Wiki Incarnate
  • *****
  • Posts: 124
    • View Profile
[SOLVED] [C++] Set PvP FFA when player enter map
« on: July 04, 2015, 03:15:45 am »
Hey guys,

I try today to set the pvp stat of every player to ffa, when they entered a specific map (9999)
So...I searched some time and, yeah, thats what i tried out..

Code: [Select]
#include "ScriptPCH.h"

class OnMapEnter : public PlayerScript
{
public:
OnMapEnter() : PlayerScript("OnMapEnter") {}

void OnPlayerEnterMap(Map* map, Player* player)
{

if (player->GetMapId() == 9999)
player->SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
}

};

void AddSC_OnMapEnter()
{
new OnMapEnter();
}

I can compile it, but ingame it didn't work...
Someone an idea ;)?
« Last Edit: July 09, 2015, 03:31:33 pm by Admin »

Kaev

  • Contributors
  • Creator of Worlds
  • *****
  • Posts: 308
    • View Profile
Re: [C++] Set PvP FFA when player enter map
« Reply #1 on: July 04, 2015, 09:27:31 am »
Did you add it to the ScriptLoader? Don't just say yes, look in the file.  I thought i already addes scripts there, but never did.. :P
If yes: Does the Script trigger at all? Print out a message before changing the flag for testing.
« Last Edit: January 01, 1970, 01:00:00 am by Admin »

bizzlesnaff

  • Registred Member
  • Wiki Incarnate
  • *****
  • Posts: 124
    • View Profile
Re: [C++] Set PvP FFA when player enter map
« Reply #2 on: July 04, 2015, 02:48:04 pm »
void AddSC_OnMapEnter(); and AddSC_OnMapEnter();, yes it's in the scriptloader ;)

I'm not quit sure, if I understand the second part. Do you mean I should print out some text, if someone enter the map?

Edit:
tried also to write something like :
Code: [Select]
if (player->GetMapId() == 9999)
player->SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
return (true);
but it's always an error, when i write "return true", and just "return" doesn't change anything..
« Last Edit: January 01, 1970, 01:00:00 am by Admin »

Rochet2

  • Contributors
  • Polygonshifter
  • *****
  • Posts: 59
    • View Profile
    • http://rochet2.github.io/
Re: [C++] Set PvP FFA when player enter map
« Reply #3 on: July 04, 2015, 04:27:26 pm »
OnPlayerEnterMap is not a hook.

If you look in ScriptMgr.cpp you see that OnPlayerEnterMap triggers the hook OnMapChanged, which is what you should be using as well.
C++ has this great new keyword "override" and I recommend using it.
It makes sure the function actually overrides a virtual function like it is supposed to.


Code: [Select]
#include "ScriptPCH.h"

class OnMapEnter : public PlayerScript
{
public:
    OnMapEnter() : PlayerScript("OnMapEnter") { }

    void OnMapChanged(Player* player) override
    {
        if (player->GetMapId() == 9999)
            player->SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
    }

};

void AddSC_OnMapEnter()
{
    new OnMapEnter();
}

By adding prints Kaev meant that you should add code that outputs something to the worldserver console or elsewhere so you can see that the code actually runs.
For example
Code: [Select]
printf("Does this appear in console?n");

If the code above still does not work, it might be that the flags are reverted back after the hook runs.
Many hooks actually execute BEFORE the event actually happens.
You can make a function trigger after the event by using a timed event with 0 as the delay so it will execute "as soon as possible".
« Last Edit: January 01, 1970, 01:00:00 am by Admin »

bizzlesnaff

  • Registred Member
  • Wiki Incarnate
  • *****
  • Posts: 124
    • View Profile
Re: [C++] Set PvP FFA when player enter map
« Reply #4 on: July 04, 2015, 07:13:52 pm »
I used the code now, and added just this:
Code: [Select]
printf("FFA worked?n");
In the console it appears (sadly everytime any player change the map) not only if a player join my map.
But as you said it doesn't work.
I really don't like to leach code, but can u explain me how this should work?
« Last Edit: January 01, 1970, 01:00:00 am by Admin »

Rochet2

  • Contributors
  • Polygonshifter
  • *****
  • Posts: 59
    • View Profile
    • http://rochet2.github.io/
Re: [C++] Set PvP FFA when player enter map
« Reply #5 on: July 04, 2015, 09:02:32 pm »
Most likely (did not check) the player enter map hook runs before updatezone function is called for the player.
In that function call the pvp flags are set again.

Incase you want to have the pvp flag on even though the player changes zones, you might want to use the update zone hook.

For the timed event, See how BasicEvent is used.

It goes about like this:

Code: [Select]
class MyEvent : public BasicEvent
{
MyEvent(Player* player) : player {}
    bool Execute(uint32, uin64)
{
// my code to do on timed event
return true;
}
Player* player;
};

player->m_events->ScheduleEvent(new MyEvent(player), player->m_events->CalculateTime(0));

Wrote that from memory so dont expect it to work without edits.
« Last Edit: January 01, 1970, 01:00:00 am by Admin »

bizzlesnaff

  • Registred Member
  • Wiki Incarnate
  • *****
  • Posts: 124
    • View Profile
Re: [C++] Set PvP FFA when player enter map
« Reply #6 on: July 05, 2015, 02:05:02 am »
Okay, I searched some time arround copied many things and worked...something...out :D

Code: [Select]
#include "ScriptPCH.h"


#include "ScriptPCH.h"

enum Enums
{
FIRST_TELEDELAY = 1000,

};

struct Event
{
uint8 Events;
};
static std::map<uint32, Event> _events;

class Teleport : public BasicEvent
{
public:
Teleport(Player* player) : _Plr(player) {}

bool Execute(uint64 /*time*/, uint32 /*diff*/)
{
uint32 pEvent;
pEvent = _Plr->GetGUID();

switch (_events[pEvent].Events)
{
case 0: // First Teleport
if (_Plr->GetMapId() == 9999)
_Plr->SetPvP(true);
_Plr->SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
_events[pEvent].Events = 1;
break;

}
return true;
}
Player* _Plr;
};

class OnMapEnter : public PlayerScript
{
public:
OnMapEnter() : PlayerScript("OnMapEnter") {}

void OnChangeMap(Player* player)
{
if (player->GetMapId() == 9999)
player->SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
printf("FFA worked?n");
player->m_Events.AddEvent(new Teleport(player), player->m_Events.CalculateTime(FIRST_TELEDELAY));
}
};

void AddSC_OnMapEnter()
{
new OnMapEnter();
}



Take most of the code from a teleport script or something..
But...I've made any mistake...the server crashs, when I entered the area with an playerchar. The "FFA worked?" is still printed in the console..
« Last Edit: January 01, 1970, 01:00:00 am by Admin »

Rochet2

  • Contributors
  • Polygonshifter
  • *****
  • Posts: 59
    • View Profile
    • http://rochet2.github.io/
Re: [C++] Set PvP FFA when player enter map
« Reply #7 on: July 05, 2015, 08:23:06 am »
Hmm, dont see a reason for it to crash.
Only that it has a thread safety issue.

Removed some of the useless code:
Code: [Select]
#include "ScriptPCH.h"

enum Enums
{
    FIRST_TELEDELAY = 1000,
};

class Teleport : public BasicEvent
{
public:
    Teleport(Player* player) : _Plr(player) { }

    bool Execute(uint64 /*time*/, uint32 /*diff*/)
    {
        if (_Plr->GetMapId() == 9999)
        {
            printf("Executing timed eventn");
            _Plr->SetPvP(true);
            _Plr->SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
        }

        return true;
    }
    Player* _Plr;
};

class OnMapEnter : public PlayerScript
{
public:
    OnMapEnter() : PlayerScript("OnMapEnter") { }

    void OnChangeMap(Player* player)
    {
        if (player->GetMapId() == 9999)
        {
            printf("Adding timed eventn");
            player->m_Events.AddEvent(new Teleport(player), player->m_Events.CalculateTime(FIRST_TELEDELAY));
        }
    }
};

void AddSC_OnMapEnter()
{
    new OnMapEnter();
}



Maybe you should try build in debug mode and or run it under a debugger?
« Last Edit: January 01, 1970, 01:00:00 am by Admin »

bizzlesnaff

  • Registred Member
  • Wiki Incarnate
  • *****
  • Posts: 124
    • View Profile
Re: [C++] Set PvP FFA when player enter map
« Reply #8 on: July 05, 2015, 04:03:21 pm »
I'll try that. But for now I take the code you write, and the good thing is...the server don't crash any longer, when I join my map..:D Bad thing is, that there is nothing more in the console...:(
« Last Edit: January 01, 1970, 01:00:00 am by Admin »

Ascathos

  • Moderators
  • Creator of Worlds
  • *****
  • Posts: 1129
    • View Profile
Re: [C++] Set PvP FFA when player enter map
« Reply #9 on: July 05, 2015, 05:42:43 pm »
I haven't used TimedEvents.
I assume you have to effectively call Execute()

Code: [Select]
enum Enums
{
    FIRST_TELEDELAY = 1 * IN_MILLISECONDS
};

class Teleport : public BasicEvent
{
public:
    Teleport(Player* player) : _Plr(player) { }

    bool Teleport::Execute(uint64 /*time*/, uint32 /*diff*/)
    {
        if (_Plr->GetMapId() == 9999)
        {
            printf("Executing timed eventn");
            _Plr->SetPvP(true);
            _Plr->SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
        }

        return true;
    }

private:
    Player* _Plr;
};

class OnMapEnter : public PlayerScript
{
public:
    OnMapEnter() : PlayerScript("OnMapEnter") { }

    void OnChangeMap(Player* player)
    {
        if (player->GetMapId() == 9999)
        {
            printf("Adding timed eventn");
            Teleport* tele = new Teleport(player);
            player->m_Events.AddEvent(tele, player->m_Events.CalculateTime(FIRST_TELEDELAY));
        }
    }
};

Does this work ?
I based it off BattlegroundQueue
« Last Edit: January 01, 1970, 01:00:00 am by Admin »

bizzlesnaff

  • Registred Member
  • Wiki Incarnate
  • *****
  • Posts: 124
    • View Profile
Re: [C++] Set PvP FFA when player enter map
« Reply #10 on: July 05, 2015, 06:13:24 pm »
No, nothing happened. And also nothing print out in the console..
« Last Edit: January 01, 1970, 01:00:00 am by Admin »

Rochet2

  • Contributors
  • Polygonshifter
  • *****
  • Posts: 59
    • View Profile
    • http://rochet2.github.io/
Re: [C++] Set PvP FFA when player enter map
« Reply #11 on: July 06, 2015, 12:42:26 pm »
Try use the override keyword.
In this case you happened to write the OnMapChanged hook wrong in the new script of yours as well.
Correct the hook name to OnMapChanged and it should start triggering again.
« Last Edit: January 01, 1970, 01:00:00 am by Admin »

bizzlesnaff

  • Registred Member
  • Wiki Incarnate
  • *****
  • Posts: 124
    • View Profile
Re: [C++] Set PvP FFA when player enter map
« Reply #12 on: July 06, 2015, 03:32:09 pm »
Okay..I've no Idea whats going on..:D First..it work. The player is ffa flaged, but only if he don't move. If he start walking he lose the ffa flag and get just pvp flaged...that's so weird..:(

edit:
I've tried to disable this part:
Code: [Select]
printf("Executing timed eventn");

// disabled to prevent a new pvp flag
//_Plr->SetPvP(true);  

_Plr->SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);

Yeah...it also not work...the player is now, after he start moving, unflaged..:(
« Last Edit: January 01, 1970, 01:00:00 am by Admin »

Rochet2

  • Contributors
  • Polygonshifter
  • *****
  • Posts: 59
    • View Profile
    • http://rochet2.github.io/
Re: [C++] Set PvP FFA when player enter map
« Reply #13 on: July 06, 2015, 03:47:53 pm »
Try using this hook instead.
https://github.com/TrinityCore/TrinityC ... #L766-L767

The FFA flags are updated on zone update, which might trigger when you start moving (makes you change the zone specific channels and stuff):
You still need the timed event since the hook triggers before the flag setting etc work is done by core normal code.
« Last Edit: January 01, 1970, 01:00:00 am by Admin »

bizzlesnaff

  • Registred Member
  • Wiki Incarnate
  • *****
  • Posts: 124
    • View Profile
Re: [C++] Set PvP FFA when player enter map
« Reply #14 on: July 06, 2015, 04:16:50 pm »
I did anything wrong, I'm sure..

Code: [Select]

class OnMapEnter : public PlayerScript
{
public:
OnMapEnter() : PlayerScript("OnMapEnter") { }

void OnUpdateZone(Player* player, uint32, uint32)
{
if (player->GetMapId() == 9999)
{
printf("UPDATE ZONEn");
Teleport* tele = new Teleport(player);
player->m_Events.AddEvent(tele, player->m_Events.CalculateTime(FIRST_TELEDELAY));
}

}
};

That's not working.:(

edit:

this is working, but only in one zone..if I change the zone, the player is just pvp flaged..

Code: [Select]
class OnMapEnter : public PlayerScript
{
public:
OnMapEnter() : PlayerScript("OnMapEnter") { }

void OnUpdateZone(Player* player, uint32, uint32)
{
if (player->GetMapId() == 9999)
{
printf("UPDATEZONEn");
Teleport* tele = new Teleport(player);
player->m_Events.AddEvent(tele, player->m_Events.CalculateTime(FIRST_TELEDELAY));
}

}
void OnMapChanged(Player* player)
{
if (player->GetMapId() == 9999)
{
printf("ONMAPCHANGEn");
Teleport* tele = new Teleport(player);
player->m_Events.AddEvent(tele, player->m_Events.CalculateTime(FIRST_TELEDELAY));
}
}
};

sec. edit:

The "UPDATE ZONE" print, never appears in the console..:/
« Last Edit: January 01, 1970, 01:00:00 am by Admin »