• 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] enabling duel/pvp in a patched zone

Status
Not open for further replies.

Black Ace

Insane Member
Hey everyone

Um We are having abit issue with our recently patched zone.

me and my friend turned alterac valley into a normal zone via map.dbc and a patch but we couldn't duel each other and pvp wasn't enable between horde & alliance.
so we edited Areatable.dbc using this tutorial ( http://emudevs.com/showthread.php/1460-Trinity-DBC-Edit-How-to-allow-dueling-in-major-cities )
but it didn't work out and it was same as before .
so we also patched the new edited areatable.dbc along with the edited map.dbc and it still doesn't work.
( keep in mind that we also replaced the edited ones with old ones in server folder. )

I wanted to attach the edited areatable.dbc here but can't since it's considered invalid file. but I can email it if anyone wants to look at it.

I would appreciate any kind of help .
 

Tommy

Founder
Do you still want people to automatically flag when entering the zone? And I'm not quite sure about the dueling.
 

Black Ace

Insane Member
I've set spawn points for ally and horde and I want them to be flagged when they log in till they go off.

ofc I rather give them an option to turn their pvp off when they are in malls
 

Tommy

Founder
I've set spawn points for ally and horde and I want them to be flagged when they log in till they go off.

ofc I rather give them an option to turn their pvp off when they are in malls

About the PvP, only thing I can think of is editing it via Player source file & MiscHandler source file.

In Player.cpp find "Player::UpdatePvPState" (https://github.com/TrinityCore/Trin...server/game/Entities/Player/Player.cpp#L21670)

Once you have that found, on the very bottom of the function, add:

Code:
    if (GetMapId() == 30 && GetAreaId() != 3000 || GetAreaId() != 3000) // 30 = Alterac Valley, 3000 = Horde / Alliance malls AreaIds
        UpdatePvP(true, true);

It will look at this in the function:

Code:
void Player::UpdatePvPState(bool onlyFFA)
{
    /// @todo should we always synchronize UNIT_FIELD_BYTES_2, 1 of controller and controlled?
    // no, we shouldn't, those are checked for affecting player by client
    if (!pvpInfo.IsInNoPvPArea && !IsGameMaster()
        && (pvpInfo.IsInFFAPvPArea || sWorld->IsFFAPvPRealm()))
    {
        if (!HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP))
        {
            SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
            for (ControlList::iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr)
                (*itr)->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
        }
    }
    else if (HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP))
    {
        RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
        for (ControlList::iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr)
            (*itr)->RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
    }

    if (onlyFFA)
        return;

    if (pvpInfo.IsHostile) // in hostile area
    {
        if (!IsPvP() || pvpInfo.EndTimer)
            UpdatePvP(true, true);
    }
    else // in friendly area
    {
        if (IsPvP() && !HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP) && !pvpInfo.EndTimer)
            pvpInfo.EndTimer = time(NULL); // start toggle-off
    }

[COLOR="#00FF00"]    if (GetMapId() == 30 && GetAreaId() != 3000 || GetAreaId() != 3000) // 30 = Alterac Valley, 3000 = Horde / Alliance malls AreaIds
        UpdatePvP(true, true);[/COLOR]
}

Under the function above, you should see "Player::SetPvP": (https://github.com/TrinityCore/Trin...server/game/Entities/Player/Player.cpp#L21706)

In this function, you would want to add the same:

Code:
    if (GetMapId() == 30 && GetAreaId() != 3000 || GetAreaId() != 3000)
        return;

It will look like this in the function:

Code:
void Player::SetPvP(bool state)
{
[COLOR="#00FF00"]    if (GetMapId() == 30 && GetAreaId() != 3000 || GetAreaId() != 3000) // Don't allow them to toggle their PvP
        return;[/COLOR]

    Unit::SetPvP(state);
    for (ControlList::iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr)
        (*itr)->SetPvP(state);
}

To further stop them, you can go to MiscHandler.cpp and find "MiscHandler::HandleTogglePvP", since it is the Opcode being handled and that will be called first before 'SetPvP':

On the top of the function, add the same as above:

Code:
    if (GetMapId() == 30 && GetAreaId() != 3000 || GetAreaId() != 3000) // Don't allow them to toggle their PvP
        return;

It will look like this in the function:

Code:
void WorldSession::HandleTogglePvP(WorldPacket& recvData)
{
[COLOR="#00FF00"]    if (GetMapId() == 30 && GetAreaId() != 3000 || GetAreaId() != 3000) // Don't allow them to toggle their PvP
        return;[/COLOR]

    // this opcode can be used in two ways: Either set explicit new status or toggle old status
    if (recvData.size() == 1)
    {
        bool newPvPStatus;
        recvData >> newPvPStatus;
        GetPlayer()->ApplyModFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP, newPvPStatus);
        GetPlayer()->ApplyModFlag(PLAYER_FLAGS, PLAYER_FLAGS_PVP_TIMER, !newPvPStatus);
    }
    else
    {
        GetPlayer()->ToggleFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP);
        GetPlayer()->ToggleFlag(PLAYER_FLAGS, PLAYER_FLAGS_PVP_TIMER);
    }

    if (GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP))
    {
        if (!GetPlayer()->IsPvP() || GetPlayer()->pvpInfo.EndTimer)
            GetPlayer()->UpdatePvP(true, true);
    }
    else
    {
        if (!GetPlayer()->pvpInfo.IsHostile && GetPlayer()->IsPvP())
            GetPlayer()->pvpInfo.EndTimer = time(NULL); // start toggle-off
    }

    //if (OutdoorPvP* pvp = _player->GetOutdoorPvP())
    // pvp->HandlePlayerActivityChanged(_player);
}

HOWEVER, logic being, if they are in their mall areas and they unflag, they will stay unflagged until they flag for PvP. You will probably need to make a PlayerScript and call the hook OnUpdateZone. If they aren't in the mall zone/area, flag them for PvP.

This might seem a lot, but it really isn't. I'm not positive if there's an easier solution, there might be by DBC, but that could be a pointless edit in my opinion. Hope this helps and I'm going to bed!
 
Last edited:

Black Ace

Insane Member
hey , so we tried your solution tommy and we had an issue once we started compiling and it identified GetMapId, GetAreaId as wrong functions.
it happened with mischandler.cpp, below you can see your own code.

To further stop them, you can go to MiscHandler.cpp and find "MiscHandler::HandleTogglePvP", since it is the Opcode being handled and that will be called first before 'SetPvP':

On the top of the function, add the same as above:

Code:
    if (GetMapId() == 30 && GetAreaId() != 3000 || GetAreaId() != 3000) // Don't allow them to toggle their PvP
        return;

It will look like this in the function:

Code:
void WorldSession::HandleTogglePvP(WorldPacket& recvData)
{
[COLOR="#00FF00"]    if (GetMapId() == 30 && GetAreaId() != 3000 || GetAreaId() != 3000) // Don't allow them to toggle their PvP
        return;[/COLOR]

    // this opcode can be used in two ways: Either set explicit new status or toggle old status
    if (recvData.size() == 1)
    {
        bool newPvPStatus;
        recvData >> newPvPStatus;
        GetPlayer()->ApplyModFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP, newPvPStatus);
        GetPlayer()->ApplyModFlag(PLAYER_FLAGS, PLAYER_FLAGS_PVP_TIMER, !newPvPStatus);
    }
    else
    {
        GetPlayer()->ToggleFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP);
        GetPlayer()->ToggleFlag(PLAYER_FLAGS, PLAYER_FLAGS_PVP_TIMER);
    }

    if (GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP))
    {
        if (!GetPlayer()->IsPvP() || GetPlayer()->pvpInfo.EndTimer)
            GetPlayer()->UpdatePvP(true, true);
    }
    else
    {
        if (!GetPlayer()->pvpInfo.IsHostile && GetPlayer()->IsPvP())
            GetPlayer()->pvpInfo.EndTimer = time(NULL); // start toggle-off
    }

    //if (OutdoorPvP* pvp = _player->GetOutdoorPvP())
    // pvp->HandlePlayerActivityChanged(_player);
}

so my friend used this code to fix the error and it worked out :

Code:
 if  (GetPlayer()->GetMapId() == 30 && GetPlayer()->GetAreaId() != 3000 || GetPlayer()->GetAreaId() != 3000) // Don't allow them to toggle their PvP
        return;

technically he added getplayer()-> behind some of them and it fixed the error .

then we compiled it and went ingame to see what's going on and it's same as before , we can't duel and zone isn't pvpable.

hm so any idea?
 

Tommy

Founder
Yeah, I wasn't using Visual Studio and I forgot to add GetPlayer()->, my fault. Well as I said before:

HOWEVER, logic being, if they are in their mall areas and they unflag, they will stay unflagged until they flag for PvP. You will probably need to make a PlayerScript and call the hook OnUpdateZone. If they aren't in the mall zone/area, flag them for PvP.

You'll need something like this to flag players when they enter Alterac Valley and leave the mall areas:

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

    void OnUpdateZone(Player* player, uint32 newZone, uint32 newArea)
    {
        if (player->GetMapId() == 30 && newArea != 3000 || newArea != 3000) // 3000 = mall areaId
            player->SetPvP(true);
    }
};

void AddSC_flag()
{
    new pvp_flag;
}
 

Black Ace

Insane Member
hm added this script too but it still has no effect .

This is getting really weird and annoying.
 
Status
Not open for further replies.
Top