void WorldSession::_HandleAreaTriggerOpcode(uint32 id) { sLog.outDebug("AreaTrigger: %u", id); WorldPacket data(80); AreaTrigger * pAreaTrigger = AreaTriggerStorage.LookupEntry(id); // Search quest log, find any exploration quests sQuestMgr.OnPlayerExploreArea(GetPlayer(),id); // if in BG handle is triggers if(GetPlayer()->m_bgInBattleground && GetPlayer()->GetCurrentBattleground() != NULL) { GetPlayer()->GetCurrentBattleground()->HandleBattlegroundAreaTrigger(GetPlayer(), id); return; } if(GetPermissionCount()) { sChatHandler.BlueSystemMessage(this, "[%sSystem%s] |rEntered areatrigger: %s%u.", MSG_COLOR_WHITE, MSG_COLOR_LIGHTBLUE, MSG_COLOR_SUBWHITE, id); } /* if we don't have an areatrigger, create one on the stack to use for gm scripts :p */ if(!pAreaTrigger) { AreaTrigger tmpTrigger; tmpTrigger.AreaTriggerID = id; ScriptSystem->OnActivateAreaTrigger(&tmpTrigger, _player); return; } /* script prerequsites */ if(ScriptSystem->OnActivateAreaTrigger(pAreaTrigger, _player) == false) return; if(pAreaTrigger->Type == ATTYPE_BATTLEGROUND) { if(pAreaTrigger->Mapid == 489) // hack fix pAreaTrigger->Mapid = 2; else if(pAreaTrigger->Mapid == 529) pAreaTrigger->Mapid = 3; else if(pAreaTrigger->Mapid == 30) pAreaTrigger->Mapid = 1; WorldPacket *pkt = sBattlegroundMgr.BuildBattlegroundListPacket(GetPlayer()->GetGUID(), _player, pAreaTrigger->Mapid); SendPacket(pkt); delete pkt; return; } bool bFailedPre = false; std::string failed_reason; if(pAreaTrigger->required_level) { if(GetPlayer()->getLevel() < pAreaTrigger->required_level) { bFailedPre = true; if(failed_reason.size() > 0) failed_reason += ", and "; else failed_reason = "You must be "; // mm hacky char lvltext[30]; snprintf(lvltext, 30, "at least level %d", (int)pAreaTrigger->required_level); failed_reason += lvltext; } } if(bFailedPre) { failed_reason += " before you're allowed through here."; WorldPacket msg; msg.Initialize(SMSG_AREA_TRIGGER_MESSAGE); msg << uint32(0) << failed_reason << uint8(0); SendPacket(&msg); sLog.outDebug("Player %s failed areatrigger prereq - %s", GetPlayer()->GetName(), failed_reason.c_str()); return; } switch(pAreaTrigger->Type) { case ATTYPE_INSTANCE: { if(GetPlayer()->GetPlayerStatus() != TRANSFER_PENDING) //only ports if player is out of pendings { GetPlayer()->SaveEntryPoint(pAreaTrigger->Mapid); //death system check. Corpse *pCorpse = NULL; // CorpseData *pCorpseData = NULL; MapInfo *pMapinfo = NULL; pMapinfo = WorldMapInfoStorage.LookupEntry(pAreaTrigger->Mapid); if(pMapinfo && !pMapinfo->HasFlag(WMI_INSTANCE_ENABLED)) { WorldPacket msg; msg.Initialize(SMSG_AREA_TRIGGER_MESSAGE); msg << uint32(0) << "This instance is currently unavailable." << uint8(0) << uint8(0); SendPacket(&msg); return; } if(pMapinfo && pMapinfo->HasFlag(WMI_INSTANCE_XPACK_01) && !HasFlag(ACCOUNT_FLAG_XPACK_01)) { WorldPacket msg; msg.Initialize(SMSG_BROADCAST_MSG); msg << uint32(3) << "You must have The Burning Crusade Expansion to access this content." << uint8(0); SendPacket(&msg); return; } if(pMapinfo && pMapinfo->type != INSTANCE_MULTIMODE && GetPlayer()->iInstanceType == MODE_HEROIC && pMapinfo->type != INSTANCE_NULL) { WorldPacket msg; msg.Initialize(SMSG_AREA_TRIGGER_MESSAGE); msg << uint32(0) << "Heroic mode is not available for this instance." << uint8(0) << uint8(0); SendPacket(&msg); return; } if(pMapinfo && pMapinfo->type == INSTANCE_RAID && GetPlayer()->InGroup() && GetPlayer()->GetGroup()->GetGroupType() != GROUP_TYPE_RAID) { WorldPacket msg; msg.Initialize(SMSG_AREA_TRIGGER_MESSAGE); msg << uint32(0) << "You need to be in a raid group to be able to enter this instance." << uint8(0) << uint8(0); SendPacket(&msg); return; } if(pMapinfo && pMapinfo->type == INSTANCE_RAID && !GetPlayer()->InGroup()) { WorldPacket msg; msg.Initialize(SMSG_AREA_TRIGGER_MESSAGE); msg << uint32(0) << "You need to be in a raid group to be able to enter this instance." << uint8(0) << uint8(0); SendPacket(&msg); return; } if(pMapinfo && pMapinfo->required_quest && !_player->HasFinishedQuest(pMapinfo->required_quest)) { WorldPacket msg; msg.Initialize(SMSG_AREA_TRIGGER_MESSAGE); msg << uint32(0) << "You do not have the required attunement to enter this instance."; SendPacket(&msg); return; } if(pMapinfo && pMapinfo->required_item && !_player->GetItemInterface()->GetItemCount(pMapinfo->required_item, true)) { WorldPacket msg; msg.Initialize(SMSG_AREA_TRIGGER_MESSAGE); msg << uint32(0) << "You do not have the required attunement to enter this instance."; SendPacket(&msg); return; } if(!GetPlayer()->isAlive()) { pCorpse = objmgr.GetCorpseByOwner(GetPlayer()->GetGUIDLow()); if(pCorpse) { pMapinfo = WorldMapInfoStorage.LookupEntry(pCorpse->GetMapId()); if(pMapinfo) { if(GetPlayer()->InGroup()) { MapMgr * groupinstance = sWorldCreator.GetInstanceByGroup(GetPlayer()->GetGroup(), GetPlayer(), pMapinfo); if (groupinstance) { if(groupinstance->GetPlayerCount() >= pMapinfo->playerlimit) { data.Initialize(SMSG_TRANSFER_ABORTED); data << uint32(INSTANCE_ABORT_FULL); _player->GetSession()->SendPacket(&data); GetPlayer()->RepopAtGraveyard(GetPlayer()->GetPositionX(),GetPlayer()->GetPositionY(),GetPlayer()->GetPositionZ(), GetPlayer()->GetMapId()); GetPlayer()->ResurrectPlayer(); return; } } } //if its a raid instance and corpse is inside and player is not in a group, ressurect if(pMapinfo->type != INSTANCE_NULL && pMapinfo->type != INSTANCE_PVP && pMapinfo->type != INSTANCE_NONRAID && pMapinfo->type != INSTANCE_MULTIMODE && GetPlayer()->GetMapId() != pCorpse->GetMapId() && pCorpse->GetMapId() == pAreaTrigger->Mapid && !GetPlayer()->InGroup()) { GetPlayer()->ResurrectPlayer(); return; } //if its a instance and player is trying to enter when corpse is on a diferent instance, repop back else if(pMapinfo->type != INSTANCE_NULL && pMapinfo->type != INSTANCE_PVP && pCorpse->GetMapId() != pAreaTrigger->Mapid) { GetPlayer()->RepopAtGraveyard(GetPlayer()->GetPositionX(),GetPlayer()->GetPositionY(),GetPlayer()->GetPositionZ(), GetPlayer()->GetMapId()); return; } } } else { GetPlayer()->RepopAtGraveyard(GetPlayer()->GetPositionX(),GetPlayer()->GetPositionY(),GetPlayer()->GetPositionZ(),GetPlayer()->GetMapId()); return; } } bool result = sWorldCreator.CheckInstanceForObject(static_cast<Object*>(GetPlayer()), pMapinfo); if(result) { GetPlayer()->SaveEntryPoint(pAreaTrigger->Mapid); GetPlayer()->SafeTeleport(pAreaTrigger->Mapid, 0, LocationVector(pAreaTrigger->x, pAreaTrigger->y, pAreaTrigger->z, pAreaTrigger->o)); } } }break; case ATTYPE_QUESTTRIGGER: { }break; case ATTYPE_INN: { // Inn if (!GetPlayer()->m_isResting) GetPlayer()->ApplyPlayerRestState(true); }break; case ATTYPE_TELEPORT: { if(GetPlayer()->GetPlayerStatus() != TRANSFER_PENDING) //only ports if player is out of pendings { GetPlayer()->SaveEntryPoint(pAreaTrigger->Mapid); GetPlayer()->SafeTeleport(pAreaTrigger->Mapid, 0, LocationVector(pAreaTrigger->x, pAreaTrigger->y, pAreaTrigger->z, pAreaTrigger->o)); } }break; case ATTYPE_NULL: { MapInfo *pMapinfo = NULL; pMapinfo = WorldMapInfoStorage.LookupEntry(pAreaTrigger->Mapid); if(pMapinfo && pMapinfo->HasFlag(WMI_INSTANCE_XPACK_01) && !HasFlag(ACCOUNT_FLAG_XPACK_01)) { WorldPacket msg; msg.Initialize(SMSG_BROADCAST_MSG); msg << uint32(3) << "You must have The Burning Crusade Expansion to access this content." << uint8(0); SendPacket(&msg); return; } } default:break; } }
bool WorldCreator::CheckInstanceForObject(Object *obj, MapInfo *pMapinfo) { WorldPacket data(4); Player *_player = NULL; if(obj->GetTypeId() == TYPEID_PLAYER) { _player = static_cast<Player*>(obj); } if(pMapinfo && _player) { switch(pMapinfo->type) { case INSTANCE_NONRAID: case INSTANCE_RAID: case INSTANCE_MULTIMODE: { //instance creation detection types //case 1, player is inside a group aka not soloing //onoes: leader can be inside a instance already and make a group or its a fresh group, noone inside if(_player->InGroup()) //group created, join leader instance. { Group *pGroup = _player->GetGroup(); if(pGroup) { //check if instance already exists(player solo created instance and made group after) MapMgr *pInstance = sWorldCreator.GetInstanceByGroup(pGroup, _player, pMapinfo); if(pInstance) { //INSTANCE_OK if(pInstance->IsCombatInProgress()) { WorldPacket msg; msg.Initialize(SMSG_AREA_TRIGGER_MESSAGE); msg << uint32(0) << "Encounter in progress." << uint8(0) << uint8(0); _player->GetSession()->SendPacket(&msg); return false; } if(pInstance->GetPlayerCount() >= pMapinfo->playerlimit) { data.Initialize(SMSG_TRANSFER_ABORTED); data << uint32(INSTANCE_ABORT_FULL); _player->GetSession()->SendPacket(&data); return false; } _player->SetInstanceID(pInstance->GetInstanceID()); } else { //group leader didnt made any instance yet, create instance for this group. uint32 id = sWorldCreator.CreateInstance(pGroup, pGroup->GetLeader(), pMapinfo->mapid); // again, NULL might not be 0 //if(id != NULL) if(id != 0) { //INSTANCE CREATED _player->SetInstanceID(id); } else { data.Initialize(SMSG_TRANSFER_ABORTED); data << uint32(INSTANCE_ABORT_ERROR); _player->GetSession()->SendPacket(&data); return false; } } } else { data.Initialize(SMSG_TRANSFER_ABORTED); data << uint32(INSTANCE_ABORT_ERROR); _player->GetSession()->SendPacket(&data); return false; } } else { MapMgr *pInstance = sWorldCreator.GetInstanceByCreator(_player, pMapinfo); if(pInstance) { //INSTANCE_OK if(pInstance->IsCombatInProgress()) { WorldPacket msg; msg.Initialize(SMSG_AREA_TRIGGER_MESSAGE); msg << uint32(0) << "Encounter in progress." << uint8(0) << uint8(0); _player->GetSession()->SendPacket(&msg); return false; } if(pInstance->GetPlayerCount() >= pMapinfo->playerlimit) { data.Initialize(SMSG_TRANSFER_ABORTED); data << uint32(INSTANCE_ABORT_FULL); _player->GetSession()->SendPacket(&data); return false; } _player->SetInstanceID(pInstance->GetInstanceID()); } else { uint32 id2 = sWorldCreator.CreateInstance(NULL, _player, pMapinfo->mapid); //if(id2 != NULL) if(id2 != 0) { _player->SetInstanceID(id2); } else { data.Initialize(SMSG_TRANSFER_ABORTED); data << uint32(INSTANCE_ABORT_ERROR); _player->GetSession()->SendPacket(&data); return false; } } } }break; } } return true; }