Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added cfpve.cpp #143

Open
wants to merge 6 commits into
base: 3.3.5-cfpve
Choose a base branch
from
Open

Conversation

urwifemykids
Copy link

Target Branch(es):
335

Issues Addressed:
This update addresses issues related to PVE content when cross-faction configurations are enabled. Specifically, it resolves problems encountered when cross-faction groups participate in dungeons or raids with faction-specific mechanics or creature flags.

Example: In the Icecrown Citadel (ICC) raid, the first player to enter the raid determines the faction alignment for the raid. This can lead to complications such as:

The Gunship Battle becoming problematic, as the enemy faction won't be able to use the cannons.
Mobs that should be friendly becoming enemies and vice versa.
This script ensures that all players have a hidden faction mask that matches the raid leader’s faction. This change prevents faction-related issues during PVE encounters. The script can be extended to handle additional PVE encounters or battlegrounds, which is useful if using NPC bots.

Tests Performed:
The script has been tested and functions as intended.

@jackpoz
Copy link
Contributor

jackpoz commented Sep 14, 2024

Note to self: create a branch and change target branch

@urwifemykids
Copy link
Author

urwifemykids commented Sep 14, 2024

Sorry for my ignorance but im not sure what your saying hahaah

@jackpoz
Copy link
Contributor

jackpoz commented Sep 14, 2024

Is the original faction ever restored ?

@jackpoz jackpoz changed the base branch from 3.3.5 to 3.3.5-cfpve September 14, 2024 20:36
@urwifemykids
Copy link
Author

It doesnt... I forgot about that meh

@Aokromes
Copy link
Member

imho this must be merged into main project.

@urwifemykids
Copy link
Author

#include "ScriptMgr.h"
#include "Player.h"
#include "Group.h"
#include "ObjectAccessor.h"

enum MiscCrossFactionPVE
{
ZONE_ICECROWN_CITADEL = 4812,
ICC_MAP_ID = 631,
ZONE_TRIAL_OF_THE_CHAMPION = 4723,
TOCHAMPION_MAP_ID = 650,
ZONE_TRIAL_OF_THE_CRUSADER = 4722,
TOCRUSADER_MAP_ID = 649,
ZONE_PIT_OF_SARON = 4813,
POS_MAP_ID = 658,
ZONE_HALLS_OF_REFLECTION = 4820,
HOR_MAP_ID = 668,
ZONE_FORGE_OF_SOULS = 4809,
FOS_MAP_ID = 632,
ZONE_HALLS_OF_STONE = 4264,
HOS_MAP_ID = 599,
ZONE_THE_NEXUS = 4265,
TN_MAP_ID = 576,
ZONE_WARSONG_GULCH = 3277,
WSG_MAP_ID = 489,
ZONE_ARATHI_BASIN = 3358,
AB_MAP_ID = 529
};

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

// Called when a player enters the world (logs in or teleports)
void OnLogin(Player* player, bool firstLogin) override
{
    HandleFactionChange(player, player->GetMapId());
}

// Called when a player changes zones
void OnUpdateZone(Player* player, uint32 newZone, uint32 /*newArea*/) override
{
    HandleFactionChange(player, newZone);
}

private:
// Store the original faction in a map
std::unordered_map<uint64, uint32> originalFactionMap;

void HandleFactionChange(Player* player, uint32 zoneOrMapId)
{
    static const std::set<uint32> zoneSet = {
        ICC_MAP_ID, TOCHAMPION_MAP_ID, TOCRUSADER_MAP_ID, POS_MAP_ID,
        HOR_MAP_ID, FOS_MAP_ID, HOS_MAP_ID, TN_MAP_ID, WSG_MAP_ID, AB_MAP_ID
    };

    if (zoneSet.count(zoneOrMapId))
    {
        // Change faction to match the group leader
        if (Group* group = player->GetGroup())
        {
            if (Player* leader = ObjectAccessor::FindPlayer(group->GetLeaderGUID()))
            {
                if (originalFactionMap.find(player->GetGUID()) == originalFactionMap.end())
                {
                    // Store the original faction
                    originalFactionMap[player->GetGUID()] = player->GetFaction();
                }
                player->SetFaction(leader->GetFaction());
            }
        }
    }
    else
    {
        // Restore player's original faction
        auto it = originalFactionMap.find(player->GetGUID());
        if (it != originalFactionMap.end())
        {
            player->SetFaction(it->second);
            originalFactionMap.erase(it); // Clean up the map after restoring
        }
    }
}

};

void AddSC_cfpve()
{
new CfPlayerScript();
}

added faction reset
@urwifemykids
Copy link
Author

This is the best I can do for now, if someone wants to help i will accept it, just trying to contribute the best I can, I have added the function to reset faction

CfPlayerScript() : PlayerScript("CfPlayerScript") {}

// Called when a player enters the world (logs in or teleports)
void OnLogin(Player* player, bool firstLogin) override
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change bool firstlogin to bool /* firstlogin */

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

@jackpoz
Copy link
Contributor

jackpoz commented Sep 16, 2024

You added the same file twice.


private:
// Store the original faction in a map
std::unordered_map<uint64, uint32> originalFactionMap;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This container is not thread-safe and I'm pretty sure OnUpdateZone() can be called by multiple maps at the same time, meaning it will cause race conditions.

@d3athbl0w
Copy link

Guys, seeing that it has BG areas such as Warsong Gulch and Arathi Basin, would this be suitable for a Crossfaction Battlegrounds?

@ckegg
Copy link

ckegg commented Oct 21, 2024

You can simply just do this to restore to player's original faction without storing it
player->RestoreFaction();

You also need to consider pet's faction

// set
if (Pet* pet = player->GetPet())
    pet->SetFaction(leader->GetFaction());
// restore
if (Pet* pet = player->GetPet())
    pet->SetFaction(player->GetFaction());

If I were you, I will use GetTeamIdInInstance() to play with faction setup instead

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants