Jump to content

[PATCH] Horde & Alliance grouping/trade


Recommended Posts

Hi,

just as far as I understood the whole issue:

The patches presented by Thorazi and now Shin Darth are:

up to revision 8845,

working mechanism: modify the whole groups faction to the one of the leader

-> definitively not blizzlike, as of very unwelcome side effects.

The patches presented by False.Genesis, patro, and visually(?) modified by LouisePalmer are:

up to revision 8076

working mechanism: modify the faction of the other group members to one's own faction

-> still hacky because of the forcing of the "data" updates on leaving/ entering groups

Well, can someone please tell me, why the idea and work of patro & LouisePalmer is not continued any further, as it seems to me the more logical approach!

(this is why I dig out this old thread)

Edit: Inserted FalseGenesis to authors, no offence ;)

Link to comment
Share on other sites

  • Replies 115
  • Created
  • Last Reply

Top Posters In This Topic

i prefer(and currently use) this alliance & horde grouping/trade method too...thx False.Genesis & patro

diff --git a/src/game/Group.cpp b/src/game/Group.cpp
index 18e77bf..2a36307 100644
--- a/src/game/Group.cpp
+++ b/src/game/Group.cpp
@@ -339,6 +339,8 @@ bool Group::AddMember(const uint64 &guid, const char* name)

uint32 Group::RemoveMember(const uint64 &guid, const uint8 &method)
{
+    BroadcastGroupUpdate();
+
    // remove member and change leader (if need) only if strong more 2 members _before_ member remove
    if(GetMembersCount() > (isBGGroup() ? 1 : 2))           // in BG group case allow 1 members group
    {
@@ -1687,3 +1689,18 @@ void Group::_homebindIfInstance(Player *player)
            player->m_InstanceValid = false;
    }
}
+void Group::BroadcastGroupUpdate(void)
+{
+    // Group Hack: force flags update on group leave - for values update hack
+    for(member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
+    {
+        Player *pp = sObjectMgr.GetPlayer(citr->guid);
+        if(pp && pp->IsInWorld())
+        {
+            pp->ForceValuesUpdateAtIndex(UNIT_FIELD_BYTES_2);
+            pp->ForceValuesUpdateAtIndex(UNIT_FIELD_FACTIONTEMPLATE);
+            DEBUG_LOG("-- Forced group value update for '%s'", pp->GetName());
+        }
+    }
+}
+
diff --git a/src/game/Group.h b/src/game/Group.h
index 0411036..2e8ac12 100644
--- a/src/game/Group.h
+++ b/src/game/Group.h
@@ -337,6 +337,9 @@ class MANGOS_DLL_SPEC Group
        InstanceGroupBind* GetBoundInstance(Map* aMap);
        BoundInstancesMap& GetBoundInstances(Difficulty difficulty) { return m_boundInstances[difficulty]; }

+        //Group hack.
+        void BroadcastGroupUpdate(void);
+
    protected:
        bool _addMember(const uint64 &guid, const char* name, bool isAssistant=false);
        bool _addMember(const uint64 &guid, const char* name, bool isAssistant, uint8 group);
diff --git a/src/game/GroupHandler.cpp b/src/game/GroupHandler.cpp
index 0c54d41..ce959de 100644
--- a/src/game/GroupHandler.cpp
+++ b/src/game/GroupHandler.cpp
@@ -196,6 +196,7 @@ void WorldSession::HandleGroupAcceptOpcode( WorldPacket & /*recv_data*/ )
    if(!group->AddMember(GetPlayer()->GetGUID(), GetPlayer()->GetName()))
        return;

+    group->BroadcastGroupUpdate();
}

void WorldSession::HandleGroupDeclineOpcode( WorldPacket & /*recv_data*/ )
diff --git a/src/game/Object.cpp b/src/game/Object.cpp
index e2853d4..ba6800d 100644
--- a/src/game/Object.cpp
+++ b/src/game/Object.cpp
@@ -691,6 +691,38 @@ void Object::BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask *
                    else
                        *data << (m_uint32Values[ index ] & ~UNIT_DYNFLAG_OTHER_TAGGER);
                }
+                // FG: pretend that OTHER players in own group are friendly ("blue")
+                else if(index == UNIT_FIELD_BYTES_2 || index == UNIT_FIELD_FACTIONTEMPLATE)
+                {
+                bool ch = false;
+                if(target->GetTypeId() == TYPEID_PLAYER && GetTypeId() == TYPEID_PLAYER && target != this)
+                {
+                    if(target->IsInSameGroupWith((Player*)this) || target->IsInSameRaidWith((Player*)this))
+                    {
+                        if(index == UNIT_FIELD_BYTES_2)
+                        {
+                            DEBUG_LOG("-- VALUES_UPDATE: Sending '%s' the blue-group-fix from '%s' (flag)", target->GetName(), ((Player*)this)->GetName());
+                            *data << ( m_uint32Values[ index ] & (UNIT_BYTE2_FLAG_SANCTUARY << 8) ); // this flag is at uint8 offset 1 !!
+                            ch = true;
+                        }
+                        else if(index == UNIT_FIELD_FACTIONTEMPLATE)
+                        {
+                            FactionTemplateEntry const *ft1, *ft2;
+                            ft1 = ((Player*)this)->getFactionTemplateEntry();
+                            ft2 = ((Player*)target)->getFactionTemplateEntry();
+                            if(ft1 && ft2 && !ft1->IsFriendlyTo(*ft2))
+                                {
+                                uint32 faction = ((Player*)target)->getFaction(); // pretend that all other HOSTILE players have own faction, to allow follow, heal, rezz (trade wont work)
+                                DEBUG_LOG("-- VALUES_UPDATE: Sending '%s' the blue-group-fix from '%s' (faction %u)", target->GetName(), ((Player*)this)->GetName(), faction);
+                                *data << uint32(faction);
+                                ch = true;
+                            }
+                        }
+                    }
+                }
+                if(!ch)
+                *data << m_uint32Values[ index ];
+                }
                else
                {
                    // send in current format (float as float, uint32 as uint32)
@@ -1668,6 +1700,19 @@ Creature* WorldObject::SummonCreature(uint32 id, float x, float y, float z, floa
    return pCreature;
}

+void Object::ForceValuesUpdateAtIndex(uint32 i)
+{
+    m_uint32Values_mirror[i] = GetUInt32Value(i) + 1; // makes server think the field changed
+    if(m_inWorld)
+    {
+        if(!m_objectUpdated)
+        {
+            AddToClientUpdateList();
+            m_objectUpdated = true;
+        }
+    }
+}
+
namespace MaNGOS
{
    class NearUsedPosDo
diff --git a/src/game/Object.h b/src/game/Object.h
index 4707f47..b26d7fe 100644
--- a/src/game/Object.h
+++ b/src/game/Object.h
@@ -301,6 +301,8 @@ class MANGOS_DLL_SPEC Object

        virtual bool hasQuest(uint32 /* quest_id */) const { return false; }
        virtual bool hasInvolvedQuest(uint32 /* quest_id */) const { return false; }
+
+        void ForceValuesUpdateAtIndex(uint32);
    protected:

        Object ( );
diff --git a/src/game/TradeHandler.cpp b/src/game/TradeHandler.cpp
index 6662545..d64062c 100644
--- a/src/game/TradeHandler.cpp
+++ b/src/game/TradeHandler.cpp
@@ -532,11 +532,11 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket)
        return;
    }

-    if (pOther->GetTeam() !=_player->GetTeam() )
+    /*if (pOther->GetTeam() !=_player->GetTeam() )
    {
        SendTradeStatus(TRADE_STATUS_WRONG_FACTION);
        return;
-    }
+    }*/

    if (!pOther->IsWithinDistInMap(_player,10.0f,false))
    {

updated for 8873

Link to comment
Share on other sites

@ Schmoozerd

Yep, I think the False.Genesis's starting idea is better, I continue to use and update it.

There are still some small issues that need to be improved (such as JCJ activation cuz of interfaction healing and other) but overall it's very interesting direction.

rrtn, thanks for posting your update for all.

Test and use it ! :) it works great.

Link to comment
Share on other sites

Many patch was derived from False.Genesis original idéa.

False.Genesis Git here: http://github.com/fgenesis/mangos/commits/master

This is an extract of the last commit about the original False.Genesis's Group patch:

diff -r -u mangosorig//src/game/Group.cpp mangos/src/game/Group.cpp
--- mangosorig//src/game/Group.cpp    2009-11-26 21:23:20.000000000 +0100
+++ mangos/src/game/Group.cpp    2009-11-26 21:25:20.000000000 +0100
@@ -339,6 +339,8 @@

uint32 Group::RemoveMember(const uint64 &guid, const uint8 &method)
{
+    BroadcastGroupUpdate();
+
    // remove member and change leader (if need) only if strong more 2 members _before_ member remove
    if(GetMembersCount() > (isBGGroup() ? 1 : 2))           // in BG group case allow 1 members group
    {
@@ -1687,3 +1689,34 @@
            player->m_InstanceValid = false;
    }
}
+
+void Group::BroadcastGroupUpdate(void)
+{
+    // FG: HACK: force flags update on group leave - for values update hack
+    // -- not very efficient but safe
+    for(member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
+    {
+        Player *pp = sObjectMgr.GetPlayer(citr->guid);
+        if(pp && pp->IsInWorld())
+        {
+            pp->ForceValuesUpdateAtIndex(UNIT_FIELD_BYTES_2);
+            pp->ForceValuesUpdateAtIndex(UNIT_FIELD_FACTIONTEMPLATE);
+            DEBUG_LOG("-- Forced group value update for '%s'", pp->GetName());
+            if(pp->GetPet())
+            {
+                pp->GetPet()->ForceValuesUpdateAtIndex(UNIT_FIELD_BYTES_2);
+                pp->GetPet()->ForceValuesUpdateAtIndex(UNIT_FIELD_FACTIONTEMPLATE);
+                DEBUG_LOG("-- Forced group value update for '%s' pet '%s'", pp->GetName(), pp->GetPet()->GetName());
+            }
+            for(uint32 i = 0; i < MAX_TOTEM; ++i)
+            {
+                if(Unit *totem = Unit::GetUnit(*pp, pp->m_TotemSlot[i]))
+                {
+                    totem->ForceValuesUpdateAtIndex(UNIT_FIELD_BYTES_2);
+                    totem->ForceValuesUpdateAtIndex(UNIT_FIELD_FACTIONTEMPLATE);
+                    DEBUG_LOG("-- Forced group value update for '%s' totem #%u", pp->GetName(), i);
+                }
+            }
+        }
+    }
+}
\\ Pas de fin de ligne à la fin du fichier.
diff -r -u mangosorig//src/game/Group.h mangos/src/game/Group.h
--- mangosorig//src/game/Group.h    2009-11-26 21:23:20.000000000 +0100
+++ mangos/src/game/Group.h    2009-11-26 21:27:57.000000000 +0100
@@ -337,6 +337,9 @@
        InstanceGroupBind* GetBoundInstance(Map* aMap);
        BoundInstancesMap& GetBoundInstances(Difficulty difficulty) { return m_boundInstances[difficulty]; }

+        // FG: evil hacks
+        void BroadcastGroupUpdate(void);
+
    protected:
        bool _addMember(const uint64 &guid, const char* name, bool isAssistant=false);
        bool _addMember(const uint64 &guid, const char* name, bool isAssistant, uint8 group);
diff -r -u mangosorig//src/game/GroupHandler.cpp mangos/src/game/GroupHandler.cpp
--- mangosorig//src/game/GroupHandler.cpp    2009-11-26 21:23:20.000000000 +0100
+++ mangos/src/game/GroupHandler.cpp    2009-11-26 21:28:54.000000000 +0100
@@ -196,6 +196,9 @@
    if(!group->AddMember(GetPlayer()->GetGUID(), GetPlayer()->GetName()))
        return;

+    // FG: part of blue group fix
+    group->BroadcastGroupUpdate();
+
}

void WorldSession::HandleGroupDeclineOpcode( WorldPacket & /*recv_data*/ )
diff -r -u mangosorig//src/game/Object.cpp mangos/src/game/Object.cpp
--- mangosorig//src/game/Object.cpp    2009-11-26 21:23:20.000000000 +0100
+++ mangos/src/game/Object.cpp    2009-11-26 21:36:36.000000000 +0100
@@ -691,6 +691,50 @@
                    else
                        *data << (m_uint32Values[ index ] & ~UNIT_DYNFLAG_OTHER_TAGGER);
                }
+                                // FG: pretend that OTHER players in own group are friendly ("blue")
+                else if(index == UNIT_FIELD_BYTES_2 || index == UNIT_FIELD_FACTIONTEMPLATE)
+                {
+                    bool ch = false;
+                    if((GetTypeId() == TYPEID_PLAYER || GetTypeId() == TYPEID_UNIT) && target != this)
+                    {
+                        bool forcefriendly = false; // bool for pets/totems to offload more code from the big if below
+                        if(GetTypeId() == TYPEID_UNIT)
+                        {
+                            forcefriendly = (((Creature*)this)->isTotem() || ((Creature*)this)->isPet())
+                                && ((Creature*)this)->GetOwner()->GetTypeId() == TYPEID_PLAYER
+                                && ((Creature*)this)->GetOwner()->IsFriendlyTo(target) // pet owner must be friendly to target
+                                && ((Creature*)this)->GetOwner() != target // no need to send hackfix to pet owner
+                                && (target->IsInSameGroupWith((Player*)((Creature*)this)->GetOwner()) || target->IsInSameRaidWith((Player*)((Creature*)this)->GetOwner()));
+                        }
+
+                        if(((Unit*)this)->IsSpoofSamePlayerFaction() || forcefriendly
+                            || (target->GetTypeId() == TYPEID_PLAYER && GetTypeId() == TYPEID_PLAYER && (target->IsInSameGroupWith((Player*)this) || target->IsInSameRaidWith((Player*)this))))
+                        {
+                            if(index == UNIT_FIELD_BYTES_2)
+                            {
+                                DEBUG_LOG("-- VALUES_UPDATE: Sending '%s' the blue-group-fix from '%s' (flag)", target->GetName(), ((Unit*)this)->GetName());
+                                *data << ( m_uint32Values[ index ] & (UNIT_BYTE2_FLAG_SANCTUARY << 8) ); // this flag is at uint8 offset 1 !!
+                                ch = true;
+                            }
+                            else if(index == UNIT_FIELD_FACTIONTEMPLATE)
+                            {
+                                FactionTemplateEntry const *ft1, *ft2;
+                                ft1 = ((Unit*)this)->getFactionTemplateEntry();
+                                ft2 = ((Unit*)target)->getFactionTemplateEntry();
+                                if(ft1 && ft2 && (!ft1->IsFriendlyTo(*ft2) || ((Unit*)this)->IsSpoofSamePlayerFaction()))
+                                {
+                                    uint32 faction = ((Player*)target)->getFaction(); // pretend that all other HOSTILE players have own faction, to allow follow, heal, rezz (trade wont work)
+                                    DEBUG_LOG("-- VALUES_UPDATE: Sending '%s' the blue-group-fix from '%s' (faction %u)", target->GetName(), ((Unit*)this)->GetName(), faction);
+                                    *data << uint32(faction);
+                                    ch = true;
+                                }
+                            }
+                        }
+                    }
+                    if(!ch)
+                        *data << m_uint32Values[ index ];
+
+                }
                else
                {
                    // send in current format (float as float, uint32 as uint32)
@@ -1668,6 +1712,19 @@
    return pCreature;
}

+void Object::ForceValuesUpdateAtIndex(uint32 i)
+{
+    m_uint32Values_mirror[i] = GetUInt32Value(i) + 1; // makes server think the field changed
+    if(m_inWorld)
+    {
+        if(!m_objectUpdated)
+        {
+            AddToClientUpdateList();
+            m_objectUpdated = true;
+        }
+    }
+}
+
namespace MaNGOS
{
    class NearUsedPosDo
diff -r -u mangosorig//src/game/Object.h mangos/src/game/Object.h
--- mangosorig//src/game/Object.h    2009-11-26 21:23:20.000000000 +0100
+++ mangos/src/game/Object.h    2009-11-26 21:37:35.000000000 +0100
@@ -301,6 +301,9 @@

        virtual bool hasQuest(uint32 /* quest_id */) const { return false; }
        virtual bool hasInvolvedQuest(uint32 /* quest_id */) const { return false; }
+
+     void ForceValuesUpdateAtIndex(uint32);
+
    protected:

        Object ( );
diff -r -u mangosorig//src/game/TradeHandler.cpp mangos/src/game/TradeHandler.cpp
--- mangosorig//src/game/TradeHandler.cpp    2009-11-26 21:23:20.000000000 +0100
+++ mangos/src/game/TradeHandler.cpp    2009-11-26 21:38:21.000000000 +0100
@@ -532,11 +532,11 @@
        return;
    }

-    if (pOther->GetTeam() !=_player->GetTeam() )
+    /*if (pOther->GetTeam() !=_player->GetTeam() )
    {
        SendTradeStatus(TRADE_STATUS_WRONG_FACTION);
        return;
-    }
+    }*/

    if (!pOther->IsWithinDistInMap(_player,10.0f,false))
    {
diff -r -u mangosorig//src/game/Unit.cpp mangos/src/game/Unit.cpp
--- mangosorig//src/game/Unit.cpp    2009-11-26 21:23:20.000000000 +0100
+++ mangos/src/game/Unit.cpp    2009-11-26 21:42:57.000000000 +0100
@@ -156,6 +156,10 @@
    // remove aurastates allowing special moves
    for(int i=0; i < MAX_REACTIVE; ++i)
        m_reactiveTimer[i] = 0;
+
+    // FG
+    m_spoofSamePlayerFaction = false;
+
}

Unit::~Unit()
diff -r -u mangosorig//src/game/Unit.h mangos/src/game/Unit.h
--- mangosorig//src/game/Unit.h    2009-11-26 21:23:20.000000000 +0100
+++ mangos/src/game/Unit.h    2009-11-26 21:46:17.000000000 +0100
@@ -1553,6 +1553,10 @@
        void AddPetAura(PetAura const* petSpell);
        void RemovePetAura(PetAura const* petSpell);

+        // FG
+        inline void SetSpoofSamePlayerFaction(bool b) { m_spoofSamePlayerFaction = b; }
+        inline bool IsSpoofSamePlayerFaction(void) {return m_spoofSamePlayerFaction; }
+
    protected:
        explicit Unit ();

@@ -1603,6 +1607,9 @@
        uint32 m_regenTimer;
        uint32 m_lastManaUseTimer;

+        // FG:
+        bool m_spoofSamePlayerFaction : 1;
+
    private:
        bool IsTriggeredAtSpellProcEvent(Unit *pVictim, Aura* aura, SpellEntry const* procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const*& spellProcEvent );
        bool HandleDummyAuraProc(   Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);

Or if you prefer ... a patch file ready for 8876 : DOWNLOAD NOW!

As you see this version added possibility to control NPC faction spoofing for each player

independently from scripts and show pets/totems as friendly.

So Thx for all guys working on mangos project ;)

Link to comment
Share on other sites

@Schmoozerd - if you mean to the main mangos branch that will never happen. this is just a very none blizz like option.

@wormyke - that is a patch :blink: copy/paste the code to a text document and rename it to group.patch

Well it could hapend. Since the FullPVP option that I made back in the days are still in Mangos. Even though blizz like you cant pvp HvsH AvsA in world map...

Link to comment
Share on other sites

  • 1 month later...
  • 3 weeks later...
  • 4 months later...
@Schmoozerd - if you mean to the main mangos branch that will never happen. this is just a very none blizz like option.

Wikipedia has a policy that says that if a rule prevents you from improving or maintaining Wikipedia, you should ignore it. I don't see why Mangos should operate in a different manner. It seems like a highly useful feature. If someone doesn't like it, he can always choose not to enable it in mangosd.conf.

Link to comment
Share on other sites

yes - but there are two problems:

1) what will happen if blizz changes the faction-unfriendlyness even more in the client?

2) is this acceptable in terms of hacks or not (the general idea about spoofing the IDs of the other players in a group is I think not to be considered a hack

But I too would love such a feature in the main-branch, but well, that's the devs choice!

Link to comment
Share on other sites

IMO it's far too hacky to be included, but if a proper disclaimer was put in there I don't see why it couldn't be.

The only problem is that if mangos includes something, they have to support it, even if that means complaints and false bug reports because of this hack patch.

Link to comment
Share on other sites

I copied all the updated text from the OP into a file called c:\\mangos\\faction.patch

then i did as you said, opened c:\\mangos in qgit, and went file>apply patch, and selected the patch. It asked me if i wanted to commit or just apply to working dir, which i said working dir.

it said "patch format detection failed"

i've tried renaming it as faction.diff and faction.eml and those don't work either.

Link to comment
Share on other sites

Sorry I don't have a better answer for you but it does work for my server. Your welcome to check it outif you like, enchanted-arts.com. I can't for the life of me figure out why it works for me and your having errors. Are you patching the same version MaNGOS/0.16.0 (* * Revision 10044 - *)? Honestly since I do all of my patches by hand, opening up each and every file and putting in the code I can't say if a patch file works on diff pulls from a repository. If that smartass guy is still around maybe he can tell us. :)

Link to comment
Share on other sites

I also prefer to do my patches by hand, but i havn't had time to learn the format of git code and figure out how yet :)

I don't doubt your code works fine, hopefully i can just get in my server!

I'l update if i figure out .patch file formats enough to make the change.

EDIT: Ahh, i think i get this. Thanks!

EDIT2: One thing i have found that needs fixing. For some reason in the group.cpp code, it's calling "UNIT_FIELD_FACTIONTEMPLA TE" instead of "UNIT_FIELD_FACTIONTEMPLATE" (notice the extra space making template templa te)

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. Privacy Policy Terms of Use