Jump to content

[Fix] Don't allow enter an instance while raid is in combat


Auntie Mangos

Recommended Posts

What bug does the patch fix? What features does the patch add?

Instances like TOC has a counter of how many times the raid has wiped, so it's important tha testers cannot enter the instance until the raid is not in combat (all of them have wiped or have defeated the boss). In any other case, testers will always have the best mark, and then, the best loot, that's unfair.

For which repository revision was the patch created?

All revisions

Is there a thread in the bug report section or at lighthouse?

http://getmangos.eu/community/showthread.php?13298-Don-t-allow-enter-an-instance-while-raid-is-in-combat

Who has been writing thisfix? Please include either forum user names or email addresses.

Me

This is the fix, I recommend to apply it manually :)

diff --git a/src/game/Map.cpp b/src/game/Map.cpp
index d260ee8..a2695d1 100644
--- a/src/game/Map.cpp
+++ b/src/game/Map.cpp
@@ -2379,6 +2379,9 @@ bool InstanceMap::CanEnter(Player *player)
   // cannot enter while players in the instance are in combat
   Group *pGroup = player->GetGroup();
-    if(pGroup && pGroup->InCombatToInstance(GetInstanceId()) && player->isAlive() && player->GetMapId() != GetId())
+    if( pGroup && pGroup->InCombatToInstance(GetInstanceId()) )
   {
       player->SendTransferAborted(GetId(), TRANSFER_ABORT_ZONE_IN_COMBAT);
       return false;
   }

Link to comment
Share on other sites

  • 40 years later...
the "player->isAlive()" seems to be the problem here, maybe you can keep the "player->GetMapId() != GetId()" check.

I think that "player->isAlive()" is to still allows entering players in ghost mode after they release from corpse in instance while "player->GetMapId() != GetId()" should allow players to be summoned while they are already inside the instance (eg. by Warlock summons) but I don't know if those are really "offy" behaviour

Link to comment
Share on other sites

compile error on core 9582 with your patch

MT Map.o -MD -MP -MF .deps/Map.Tpo -c -o Map.o ../../../src/game/Map.cpp

In file included from ../../../src/game/Player.h:30,

from ../../../src/game/Map.cpp:20:

../../../src/game/Group.h:416:7: warning: no newline at end of file

../../../src/game/Map.cpp: In member function âvirtual bool InstanceMap::Add(Player*)â:

../../../src/game/Map.cpp:2453: error: no matching function for call to âGroup::GetBoundInstance(InstanceMap* const)â

../../../src/game/Group.h:330: note: candidates are: InstanceGroupBind* Group::GetBoundInstance(Player*)

../../../src/game/Group.h:331: note: InstanceGroupBind* Group::GetBoundInstance(Map*, Difficulty)

make[3]: *** [Map.o] Error 1

Link to comment
Share on other sites

If you entry in the instance while raid is in combat, it take you to Dalaran :S

I think this is because a custom patch, I had the same problem and I fixed it adding some modifications in MovementHandler.cpp

diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp
index 5e42bab..f7f1a39 100644
--- a/src/game/MovementHandler.cpp
+++ b/src/game/MovementHandler.cpp
@@ -43,8 +43,5 @@ void WorldSession::HandleMoveWorldportAckOpcode()
   // ignore unexpected far teleports
   if(!GetPlayer()->IsBeingTeleportedFar())
       return;

   // get the teleport destination
+    float PlayerX = GetPlayer()->GetPositionX();
+    float PlayerY = GetPlayer()->GetPositionY();
+    float PlayerZ = GetPlayer()->GetPositionZ();
   uint32 PlayerMap = GetPlayer()->GetMapId();
   WorldLocation &loc = GetPlayer()->GetTeleportDest();

@@ -50,8 +50,5 @@ void WorldSession::HandleMoveWorldportAckOpcode()

// possible errors in the coordinate validity check
   if(!MapManager::IsValidMapCoord(loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z, loc.orientation))
   {
       sLog.outError("WorldSession::HandleMoveWorldportAckOpcode: player %s (%d) was teleported far to a not valid location. (map:%u, x:%f, y:%f, "
           "z:%f) We port him to his homebind instead..", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow(), loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z);
       // stop teleportation else we would try this again and again in LogoutPlayer...
       GetPlayer()->SetSemaphoreTeleportFar(false);
       // and teleport the player to a valid place
-        GetPlayer()->TeleportToHomebind();
+    GetPlayer()->TeleportTo(PlayerMap, PlayerX, PlayerY, PlayerZ, 0, 0);
       return;
   }

@@ -77,8 +77,5 @@ void WorldSession::HandleMoveWorldportAckOpcode()

   // the CanEnter checks are done in TeleporTo but conditions may change
   // while the player is in transit, for example the map may get full
   if(!GetPlayer()->GetMap()->Add(GetPlayer()))
   {
       //if player wasn't added to map, reset his map pointer!
       GetPlayer()->ResetMap();

       sLog.outError("WorldSession::HandleMoveWorldportAckOpcode: player %s (%d) was teleported far but couldn't be added to map. (map:%u, x:%f, y:%f, "
           "z:%f) We port him to his homebind instead..", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow(), loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z);
       // teleport the player home
-        GetPlayer()->TeleportToHomebind();
+    GetPlayer()->TeleportTo(PlayerMap, PlayerX, PlayerY, PlayerZ, 0,  0);
       return;
   }

With this, player is teleported where he was before trying to enter

Link to comment
Share on other sites

i try add

 
if (player->GetGroup())
{  
    if (Map *BindMap = sMapMgr.FindMap(player->GetCorpse()->GetMapId(), player->GetCorpse()->GetInstanceId()))
  {
   if (((InstanceMap*)BindMap)->GetInstanceData() && ((InstanceMap*)BindMap)->GetInstanceData()->IsEncounterInProgress())
   {
    if (!player->isAlive())
     player->ResurrectPlayer(0.5f);
    player->SendTransferAborted(mapid, TRANSFER_ABORT_ZONE_IN_COMBAT);    
    return (false);
   }
  }
 }  

in bool MapManager::CanPlayerEnter(uint32 mapid, Player* player)

its work for send message for player and just revive him but i have one problem. if player enter map and no other raid member in map == crash :x

im not sur but its better not teleport player just lock entry of raid and send message, no?

edit : for your patch add

 
// cannot enter while players in the instance are in combat
   Group *pGroup = player->GetGroup();
-    if(pGroup && pGroup->InCombatToInstance(GetInstanceId()) && player->isAlive() && player->GetMapId() != GetId())
+    if( pGroup && pGroup->InCombatToInstance(GetInstanceId()) )
   {
       player->SendTransferAborted(GetId(), TRANSFER_ABORT_ZONE_IN_COMBAT);
+      if (!player->isAlive())
+            player->ResurrectPlayer(0.5f);
     return false;
   }

Link to comment
Share on other sites

Yes, that's right that it would be better don't teleport player and send a message like when you try to enter without raid ("You must be in a raid group to enter X instance"), but I didn't find out how implement that

about

+      if (!player->isAlive())
+            player->ResurrectPlayer(0.5f);

I think that isn't necessary, player will revive when enter at instance

Link to comment
Share on other sites

new branch, again no patches nothing only your change, i get compile error

: ..\\..\\src\\game\\Map.cpp(3487) : error C2065: 'SCRIPT_COMMAND_CREATE_ITEM'

4>..\\..\\src\\game\\Map.cpp(3487) : error C2051

4>..\\..\\src\\game\\Map.cpp(3509) : error C2065: 'SCRIPT_COMMAND_DESPAWN_SELF'

4>..\\..\\src\\game\\Map.cpp(3509) : error C2051

4>..\\..\\src\\game\\Map.cpp(3543) : error C2065

4>..\\..\\src\\game\\Map.cpp(3543) : error C2146

4>..\\..\\src\\game\\Map.cpp(3543) : error C2761: 'Creature *Map::GetCreature(uint64)

4>..\\..\\src\\game\\Map.cpp(3543) : fatal error C1903

same branch without your change, 100 % compiled and no errors
Link to comment
Share on other sites

new branch, again no patches nothing only your change, i get compile error

same branch without your change, 100 % compiled and no errors

Just now I have downloaded lastest revision, with no patches, I have applied the fix, and compiles fine, no errors. So definitely you are doing something wrong.

========== Build: 13 correct, 0 wrong, 0 upgraded, 0 skipped ==========

and that error you say Map.cpp(3487) : error C2065: 'SCRIPT_COMMAND_CREATE_ITEM' has nothing to do with InstanceMap::CanEnter

Sorry, I cannot help you anymore

Link to comment
Share on other sites

  • 4 weeks later...

diff --git a/src/game/Map.cpp b/src/game/Map.cpp
index d260ee8..a2695d1 100644
--- a/src/game/Map.cpp
+++ b/src/game/Map.cpp
@@ -2379,6 +2379,9 @@ bool InstanceMap::CanEnter(Player *player)
   // cannot enter while players in the instance are in combat
   Group *pGroup = player->GetGroup();
-    if(pGroup && pGroup->InCombatToInstance(GetInstanceId()) && player->isAlive() && player->GetMapId() != GetId())
+    if( pGroup && pGroup->InCombatToInstance(GetInstanceId()) )
   {
       player->SendTransferAborted(GetId(), TRANSFER_ABORT_ZONE_IN_COMBAT);
       return false;
   }

Working but the player is teleport to this homebind.

We have to send the message and don't teleport him (lock the portal ?) like other message

i try add

 
if (player->GetGroup())
{  
    if (Map *BindMap = sMapMgr.FindMap(player->GetCorpse()->GetMapId(), player->GetCorpse()->GetInstanceId()))
  {
   if (((InstanceMap*)BindMap)->GetInstanceData() && ((InstanceMap*)BindMap)->GetInstanceData()->IsEncounterInProgress())
   {
    if (!player->isAlive())
     player->ResurrectPlayer(0.5f);
    player->SendTransferAborted(mapid, TRANSFER_ABORT_ZONE_IN_COMBAT);    
    return (false);
   }
  }
 }  

in bool MapManager::CanPlayerEnter(uint32 mapid, Player* player)

its work for send message for player and just revive him but i have one problem. if player enter map and no other raid member in map == crash :x

It's crash because if you are alive your player->GetCorpse()->GetInstanceId() doesn't work (we have no corpse)

I think it's better to check in this fonction because she is before the TP, we just have to find the better way =)

Link to comment
Share on other sites

I wrote something similar for the 0.12-Branch some time ago:

diff --git a/src/game/MapManager.cpp b/src/game/MapManager.cpp
index 5a5e9c7..05a57ce 100644 (file)
--- a/src/game/MapManager.cpp
+++ b/src/game/MapManager.cpp
@@ -18,6 +18,7 @@

#include "MapManager.h"
#include "InstanceSaveMgr.h"
+#include "InstanceData.h"
#include "Policies/SingletonImp.h"
#include "Database/DatabaseEnv.h"
#include "Log.h"
@@ -179,6 +180,16 @@ bool MapManager::CanPlayerEnter(uint32 mapid, Player* player)
                }
            }
        }
+        //The player tries to enter a Instance where a Boss Encouter is in Progress
+        InstanceData* i_data = ((InstanceMap*)GetMap(mapid, player))->GetInstanceData();
+        if (i_data && i_data->IsEncounterInProgress() && !player->isGameMaster())
+        {
+            if (!player->isAlive())
+                player->ResurrectPlayer(30,false);
+            player->GetSession()->SendAreaTriggerMessage("You can not enter Instance %s while Boss Encounter is in Progress", mapName);
+            sLog.outDebug("MAP: Player '%s' can not enter instance of '%s' while boss encounter is in progress",player->GetName(), mapName);
+            return false;
+        }

        //The player has a heroic mode and tries to enter into instance which has no a heroic mode
        if (!entry->SupportsHeroicMode() && player->GetDifficulty() == DUNGEON_DIFFICULTY_HEROIC)

Guess it won't be able to apply on actual master but this way it works correct.

Just note that you may have to update some Instance-Scripts cause either the IsEncounterInProgress Function isn't declared (correctly) or some Bosses doesn't set their status correctly (gets nasty if they set it to in combat but don't set it to finished, as then nobody will be able to enter the instance)

Link to comment
Share on other sites

  • 3 weeks later...
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