Exemple #1
0
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;
	}
}
Exemple #2
0
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;
}