Esempio n. 1
0
void WorldSession::_HandleAreaTriggerOpcode(uint32 id)
{
	LOG_DEBUG("AreaTrigger: %u", id);

	// Are we REALLY here?
	if(!_player->IsInWorld())
		return;

	// Search quest log, find any exploration quests
	sQuestMgr.OnPlayerExploreArea(GetPlayer(), id);

	AreaTriggerEntry* entry = dbcAreaTrigger.LookupEntryForced(id);
	AreaTrigger* pAreaTrigger = AreaTriggerStorage.LookupEntry(id);

	if(entry == NULL)
	{
		LOG_DEBUG("Missing AreaTrigger: %u", id);
		return;
	}

	Player* pPlayer = GetPlayer();
	sHookInterface.OnAreaTrigger(pPlayer, id);
	CALL_INSTANCE_SCRIPT_EVENT(pPlayer->GetMapMgr(), OnAreaTrigger)(GetPlayer(), id);

#ifdef GM_Z_DEBUG_DIRECTLY
	if(_player->GetSession() && _player->GetSession()->CanUseCommand('z'))
		sChatHandler.BlueSystemMessage(this, "[%sSystem%s] |rEntered areatrigger: %s%u. (%s)", MSG_COLOR_WHITE, MSG_COLOR_LIGHTBLUE, MSG_COLOR_SUBWHITE, id, pAreaTrigger ? pAreaTrigger->Name : "Unknown name");
#endif

	// if in BG handle is triggers
	if(_player->m_bg)
	{
		_player->m_bg->HookOnAreaTrigger(_player, id);
		return;
	}

	if(pAreaTrigger == NULL) return;

	switch(pAreaTrigger->Type)
	{
		case ATTYPE_INSTANCE:
			{
				//only ports if player is out of pendings
				if(GetPlayer()->GetPlayerStatus() == TRANSFER_PENDING)
					break;
				if(sWorld.instance_CheckTriggerPrerequisites)
				{
					uint32 reason = CheckTriggerPrerequisites(pAreaTrigger, this, _player, WorldMapInfoStorage.LookupEntry(pAreaTrigger->Mapid));
					if(reason != AREA_TRIGGER_FAILURE_OK)
					{
						const char* pReason = GetPlayer()->GetSession()->LocalizedWorldSrv(AreaTriggerFailureMessages[reason]);
						char msg[200];
						WorldPacket data(SMSG_AREA_TRIGGER_MESSAGE, 50);
						data << uint32(0);

						switch(reason)
						{
							case AREA_TRIGGER_FAILURE_LEVEL:
								snprintf(msg, 200, pReason, pAreaTrigger->required_level);
								data << msg;
								break;
							case AREA_TRIGGER_FAILURE_NO_ATTUNE_I:
								{
									MapInfo* pMi = WorldMapInfoStorage.LookupEntry(pAreaTrigger->Mapid);
									ItemPrototype* pItem = ItemPrototypeStorage.LookupEntry(pMi->required_item);
									if(pItem)
										snprintf(msg, 200, GetPlayer()->GetSession()->LocalizedWorldSrv(35), pItem->Name1);
									else
										snprintf(msg, 200, "%s", GetPlayer()->GetSession()->LocalizedWorldSrv(36));

									data << msg;
								}
								break;
							case AREA_TRIGGER_FAILURE_NO_ATTUNE_Q:
								{
									MapInfo* pMi = WorldMapInfoStorage.LookupEntry(pAreaTrigger->Mapid);
									Quest* pQuest = NULL;

									if( pPlayer->GetTeam() == TEAM_ALLIANCE )
										pQuest = QuestStorage.LookupEntry(pMi->required_quest_1 );
									else
										pQuest = QuestStorage.LookupEntry(pMi->required_quest_2 );

									if(pQuest)
										snprintf(msg, 200, "You must have finished the quest '%s' to pass through here.", pQuest->title);
									else
										snprintf(msg, 200, "You must have finished the quest '%s' to pass through here.", "UNKNOWN" );

									data << msg;
								}
								break;
							case AREA_TRIGGER_FAILURE_NO_KEY:
								{
									MapInfo* pMi = WorldMapInfoStorage.LookupEntry(pAreaTrigger->Mapid);
									ItemPrototype* pItem = ItemPrototypeStorage.LookupEntry(pMi->heroic_key_1);
									if(pItem)
										snprintf(msg, 200, "You must have the item, `%s` to pass through here.", pItem->Name1);
									else
										snprintf(msg, 200, "You must have the item, UNKNOWN to pass through here.");

									data << msg;
								}
								break;
							case AREA_TRIGGER_FAILURE_LEVEL_HEROIC:
								{
									MapInfo* pMi = WorldMapInfoStorage.LookupEntry(pAreaTrigger->Mapid);
									snprintf(msg, 200, pReason, pMi->minlevel_heroic);
									data << msg;
								}
								break;
							default:
								data << pReason;
								break;
						}

						data << uint8(0);
						SendPacket(&data);
						return;
					}
				}
				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;
		default:
			break;
	}
}
Esempio n. 2
0
void WorldSession::_HandleAreaTriggerOpcode(uint32 id)
{		
	DEBUG_LOG( "WorldSession","HandleAreaTriggerOpcode: %u", id);

	// Are we REALLY here?
	CHECK_INWORLD_RETURN;

	// Search quest log, find any exploration quests
	sQuestMgr.OnPlayerExploreArea(GetPlayer(),id);

	AreaTrigger* pAreaTrigger = AreaTriggerStorage.LookupEntry( id );

	sHookInterface.OnAreaTrigger(_player, id);
	CALL_INSTANCE_SCRIPT_EVENT( _player->GetMapMgr(), OnAreaTrigger )( _player, id );

	// if in BG handle is triggers
	if( _player->m_bg )
	{
		_player->m_bg->HookOnAreaTrigger(_player, id);
		return;
	}

	// Hook for Scripted Areatriggers
	_player->GetMapMgr()->HookOnAreaTrigger(_player, id);

	if( _player->GetSession()->CanUseCommand('z') )
	{
		if( pAreaTrigger != NULL )
			sChatHandler.BlueSystemMessage( this, "[%sSystem%s] |rEntered areatrigger: %s%u (%s).", MSG_COLOR_WHITE, MSG_COLOR_LIGHTBLUE, MSG_COLOR_SUBWHITE, id, pAreaTrigger->Name );
		else
			sChatHandler.BlueSystemMessage( this, "[%sSystem%s] |rEntered areatrigger: %s%u", MSG_COLOR_WHITE, MSG_COLOR_LIGHTBLUE, MSG_COLOR_SUBWHITE, id);
	}

	if( pAreaTrigger == NULL )
	{
		OUT_DEBUG("Missing AreaTrigger: %u", id);
		return;
	}

	switch(pAreaTrigger->Type)
	{
	case ATTYPE_INSTANCE:
		{
			if(_player->GetPlayerStatus() != TRANSFER_PENDING) //only ports if player is out of pendings
			{
				MapInfo * pMi = WorldMapInfoStorage.LookupEntry(pAreaTrigger->Mapid);
				MapEntry* map = dbcMap.LookupEntry(pAreaTrigger->Mapid);
				if(!pMi)
					return;

				//do we meet the map requirements?
				uint8 reason = CheckTeleportPrerequsites(pAreaTrigger, this, _player, pAreaTrigger->Mapid);
				if(reason != AREA_TRIGGER_FAILURE_OK)
				{
					const char * pReason = AreaTriggerFailureMessages[reason];
					char msg[200];
					WorldPacket data(SMSG_AREA_TRIGGER_MESSAGE, 50);
					data << uint32(0);

					switch (reason)
					{
					case AREA_TRIGGER_FAILURE_LEVEL:
						{
							snprintf(msg,200,pReason,pAreaTrigger->required_level);
							data << msg;
						}break;
					case AREA_TRIGGER_FAILURE_NO_ATTUNE_I:
						{
							ItemPrototype * pItem = ItemPrototypeStorage.LookupEntry(pMi->required_item);
							snprintf(msg, 200, pReason, pItem ? pItem->Name1 : "UNKNOWN");
							data << msg;
						}break;
					case AREA_TRIGGER_FAILURE_NO_ATTUNE_Q:
						{
							Quest * pQuest = QuestStorage.LookupEntry(pMi->required_quest);
							snprintf(msg, 200, pReason, pQuest ? pQuest->title : "UNKNOWN");

							data << msg;
						}break;
					case AREA_TRIGGER_FAILURE_NO_KEY:
						{
							string temp_msg[2];
							string tmp_msg;
							for(uint32 i = 0; i < 2; ++i) 
							{
								if (pMi->heroic_key[i] && _player->GetItemInterface()->GetItemCount(pMi->heroic_key[i], false)==0)
								{
									ItemPrototype * pKey = ItemPrototypeStorage.LookupEntry(pMi->heroic_key[i]);
									if(pKey)
										temp_msg[i] += pKey->Name1;
									else
										temp_msg[i] += "UNKNOWN";
								}
							}
							tmp_msg += temp_msg[0];
							if(temp_msg[0].size() && temp_msg[1].size())
								tmp_msg += "\" and \"";
							tmp_msg += temp_msg[1];

							snprintf(msg, 200, pReason, tmp_msg.c_str());
							data << msg;
						}break;
					case AREA_TRIGGER_FAILURE_LEVEL_HEROIC:
						{
							snprintf(msg, 200, pReason, pMi->HasFlag(WMI_INSTANCE_XPACK_02) ? 80 : 70);
							data << msg;
						}break;
					default:
						{
							data << pReason;
						}break;
					}

					data << uint8(0);
					SendPacket(&data);
					return;
				}

				if( _player->IsMounted())
					TO_UNIT(_player)->Dismount();

				uint32 InstanceID = 0;
				// Try to find a saved instance and
				// do not handle Hyjal Inn (trigger 4319), since we need a unique mapid when generating our instance_id.

				if( id != 4319 && pMi && ( map->israid() || _player->iRaidType >= MODE_NORMAL_25MEN && pMi->type == INSTANCE_MULTIMODE ) )
				{
					//Do we have a saved instance we should use?
					Instance * in = NULL;
					in = sInstanceMgr.GetSavedInstance( pMi->mapid,_player->GetLowGUID(), _player->iRaidType );
					if( in != NULL  && in->m_instanceId )
					{
						//If we are the first to enter this instance, also set our current group id.
						if( in->m_mapMgr == NULL || (!in->m_mapMgr->HasPlayers() && _player->GetGroupID() != in->m_creatorGroup))
							in->m_creatorGroup =_player->GetGroupID();
						InstanceID = in->m_instanceId;
					}
				}

				//Save our entry point and try to teleport to our instance
				_player->SaveEntryPoint(pAreaTrigger->Mapid);
				_player->SafeTeleport(pAreaTrigger->Mapid, InstanceID, LocationVector(pAreaTrigger->x, pAreaTrigger->y, pAreaTrigger->z, pAreaTrigger->o));
			}
		}break;
	case ATTYPE_QUESTTRIGGER:
		{

		}break;
	case ATTYPE_INN:
		{
			if( _player->IsMounted())
				TO_UNIT(_player)->Dismount();

			// Inn
			if (!_player->m_isResting) 
				_player->ApplyPlayerRestState(true);
		}break;
	case ATTYPE_TELEPORT:
		{
			if( _player->GetPlayerStatus() != TRANSFER_PENDING) //only ports if player is out of pendings
			{
				if( _player->IsMounted() )
					TO_UNIT(_player)->Dismount();

				_player->SaveEntryPoint(pAreaTrigger->Mapid);
				_player->SafeTeleport(pAreaTrigger->Mapid, 0, LocationVector(pAreaTrigger->x, pAreaTrigger->y, pAreaTrigger->z, pAreaTrigger->o));
			}
		}break;
	default:break;
	}
}
Esempio n. 3
0
void WorldSession::_HandleAreaTriggerOpcode(uint32 id)
{
    LOG_DEBUG("AreaTrigger: %u", id);

    if (!_player->IsInWorld())
        return;

    // Search quest log, find any exploration quests
    sQuestMgr.OnPlayerExploreArea(GetPlayer(), id);

    auto area_trigger_entry = sAreaTriggerStore.LookupEntry(id);
    if (area_trigger_entry == nullptr)
    {
        LOG_DEBUG("Missing AreaTrigger: %u", id);
        return;
    }

    Player* pPlayer = GetPlayer();
    sHookInterface.OnAreaTrigger(pPlayer, id);
    CALL_INSTANCE_SCRIPT_EVENT(pPlayer->GetMapMgr(), OnAreaTrigger)(GetPlayer(), id);

#ifdef GM_Z_DEBUG_DIRECTLY
    if (_player->GetSession() && _player->GetSession()->CanUseCommand('z'))
        sChatHandler.BlueSystemMessage(this, "[%sSystem%s] |rEntered areatrigger: %s%u. (%s)", MSG_COLOR_WHITE, MSG_COLOR_LIGHTBLUE, MSG_COLOR_SUBWHITE, id, pAreaTrigger ? pAreaTrigger->Name : "Unknown name");
#endif

    // if in BG handle is triggers
    if (_player->m_bg)
    {
        _player->m_bg->HookOnAreaTrigger(_player, id);
        return;
    }

    MySQLStructure::AreaTrigger const* pAreaTrigger = sMySQLStore.getAreaTrigger(id);
    if (pAreaTrigger == nullptr)
        return;

    switch (pAreaTrigger->type)
    {
        case ATTYPE_INSTANCE:
        {
            //only ports if player is out of pendings
            if (GetPlayer()->GetPlayerStatus() == TRANSFER_PENDING)
                break;
            if (worldConfig.instance.checkTriggerPrerequisitesOnEnter)
            {
                uint32 reason = CheckTriggerPrerequisites(pAreaTrigger, this, _player, sMySQLStore.getWorldMapInfo(pAreaTrigger->mapId));
                if (reason != AREA_TRIGGER_FAILURE_OK)
                {
                    const char* pReason = GetPlayer()->GetSession()->LocalizedWorldSrv(AreaTriggerFailureMessages[reason]);
                    char msg[200];
                    WorldPacket data(SMSG_AREA_TRIGGER_MESSAGE, 50);
                    data << uint32(0);

                    switch (reason)
                    {
                        case AREA_TRIGGER_FAILURE_LEVEL:
                            snprintf(msg, 200, pReason, pAreaTrigger->requiredLevel);
                            data << msg;
                            break;
                        case AREA_TRIGGER_FAILURE_NO_ATTUNE_I:
                        {
                            MySQLStructure::MapInfo const* pMi = sMySQLStore.getWorldMapInfo(pAreaTrigger->mapId);
                            ItemProperties const* pItem = sMySQLStore.getItemProperties(pMi->required_item);
                            if (pItem)
                                snprintf(msg, 200, GetPlayer()->GetSession()->LocalizedWorldSrv(ServerString::SS_MUST_HAVE_ITEM), pItem->Name.c_str());
                            else
                                snprintf(msg, 200, "%s", GetPlayer()->GetSession()->LocalizedWorldSrv(36));

                            data << msg;
                        }
                        break;
                        case AREA_TRIGGER_FAILURE_NO_ATTUNE_QA:
                        {
                            MySQLStructure::MapInfo const* pMi = sMySQLStore.getWorldMapInfo(pAreaTrigger->mapId);
                            QuestProperties const* pQuest = sMySQLStore.getQuestProperties(pMi->required_quest_A);
                            if (pQuest)
                                snprintf(msg, 200, GetPlayer()->GetSession()->LocalizedWorldSrv(ServerString::SS_MUST_HAVE_QUEST), pQuest->title.c_str());
                            else
                                snprintf(msg, 200, "%s", GetPlayer()->GetSession()->LocalizedWorldSrv(36));

                            data << msg;
                        }
                        break;
                        case AREA_TRIGGER_FAILURE_NO_ATTUNE_QH:
                        {
                            MySQLStructure::MapInfo const* pMi = sMySQLStore.getWorldMapInfo(pAreaTrigger->mapId);
                            QuestProperties const* pQuest = sMySQLStore.getQuestProperties(pMi->required_quest_H);
                            if (pQuest)
                                snprintf(msg, 200, GetPlayer()->GetSession()->LocalizedWorldSrv(ServerString::SS_MUST_HAVE_QUEST), pQuest->title.c_str());
                            else
                                snprintf(msg, 200, "%s", GetPlayer()->GetSession()->LocalizedWorldSrv(36));

                            data << msg;
                        }
                        break;
                        case AREA_TRIGGER_FAILURE_NO_KEY:
                        {
                            MySQLStructure::MapInfo const* pMi = sMySQLStore.getWorldMapInfo(pAreaTrigger->mapId);
                            ItemProperties const* pItem = sMySQLStore.getItemProperties(pMi->heroic_key_1);
                            if (pItem)
                                snprintf(msg, 200, GetPlayer()->GetSession()->LocalizedWorldSrv(ServerString::SS_MUST_HAVE_ITEM), pItem->Name.c_str());
                            else
                                snprintf(msg, 200, "%s", GetPlayer()->GetSession()->LocalizedWorldSrv(36));

                            data << msg;
                        }
                        break;
                        case AREA_TRIGGER_FAILURE_LEVEL_HEROIC:
                        {
                            MySQLStructure::MapInfo const* pMi = sMySQLStore.getWorldMapInfo(pAreaTrigger->mapId);
                            snprintf(msg, 200, pReason, pMi->minlevel_heroic);
                            data << msg;
                        }
                        break;
                        default:
                            data << pReason;
                            break;
                    }

                    data << uint8(0);
                    SendPacket(&data);
                    return;
                }
            }
            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;
        default:
            break;
    }
}
Esempio n. 4
0
void GameObject::OnPushToWorld()
{
	Object::OnPushToWorld();
	CALL_INSTANCE_SCRIPT_EVENT( m_mapMgr, OnGameObjectPushToWorld )( TO_GAMEOBJECT(this) );
}
Esempio n. 5
0
bool MapMgr::Do()
{
#ifdef WIN32
	threadid = GetCurrentThreadId();
#endif

	t_currentMapContext.set(this);

	thread_running = true;
	ThreadState.SetVal(THREADSTATE_BUSY);
	SetThreadName("Map mgr - M%u|I%u", this->_mapId , this->m_instanceID);
	ObjectSet::iterator i;
	uint32 last_exec = getMSTime();

	// Create Instance script
	LoadInstanceScript();

	/* create static objects */
	for(GOSpawnList::iterator itr = _map->staticSpawns.GOSpawns.begin(); itr != _map->staticSpawns.GOSpawns.end(); ++itr)
	{
		GameObject* obj = CreateGameObject((*itr)->entry);
		obj->Load((*itr));
		PushStaticObject(obj);
	}

	// Call script OnLoad virtual procedure
	CALL_INSTANCE_SCRIPT_EVENT(this, OnLoad)();

	for(CreatureSpawnList::iterator itr = _map->staticSpawns.CreatureSpawns.begin(); itr != _map->staticSpawns.CreatureSpawns.end(); ++itr)
	{
		Creature* obj = CreateCreature((*itr)->entry);
		obj->Load(*itr, 0, pMapInfo);
		PushStaticObject(obj);
	}

	/* load corpses */
	objmgr.LoadCorpses(this);
	worldstateshandler.InitWorldStates( objmgr.GetWorldStatesForMap( _mapId ) );
	worldstateshandler.setObserver( this );

	// always declare local variables outside of the loop!
	// otherwise there's a lot of sub esp; going on.

	uint32 exec_time, exec_start;

	while((GetThreadState() != THREADSTATE_TERMINATE) && !_shutdown)
	{
		exec_start = getMSTime();

///////////////////////////////////////////// first push to world new objects ////////////////////////////////////////////

		m_objectinsertlock.Acquire();

		if(m_objectinsertpool.size())
		{
			for(i = m_objectinsertpool.begin(); i != m_objectinsertpool.end(); ++i)
			{
				Object* o = *i;

				o->PushToWorld(this);
			}

			m_objectinsertpool.clear();
		}

		m_objectinsertlock.Release();

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		//Now update sessions of this map + objects
		_PerformObjectDuties();

		last_exec = getMSTime();
		exec_time = last_exec - exec_start;
		if(exec_time < MAP_MGR_UPDATE_PERIOD)
		{

			Arcemu::Sleep(MAP_MGR_UPDATE_PERIOD - exec_time);

		}

		//////////////////////////////////////////////////////////////////////////
		// Check if we have to die :P
		//////////////////////////////////////////////////////////////////////////
		if(InactiveMoveTime && UNIXTIME >= InactiveMoveTime)
			break;
	}

	// Teleport any left-over players out.
	TeleportPlayers();

	// Clear the instance's reference to us.
	if(m_battleground)
	{
		BattlegroundManager.DeleteBattleground(m_battleground);
		sInstanceMgr.DeleteBattlegroundInstance(GetMapId(), GetInstanceID());
	}

	if(pInstance)
	{
		// check for a non-raid instance, these expire after 10 minutes.
		if(GetMapInfo()->type == INSTANCE_NONRAID || pInstance->m_isBattleground)
		{
			pInstance->m_mapMgr = NULL;
			sInstanceMgr._DeleteInstance(pInstance, true);
			pInstance = NULL;
		}
		else
		{
			// just null out the pointer
			pInstance->m_mapMgr = NULL;
		}
	}
	else if(GetMapInfo()->type == INSTANCE_NULL)
		sInstanceMgr.m_singleMaps[GetMapId()] = NULL;

	thread_running = false;
	if(thread_kill_only)
		return false;

	// delete ourselves
	delete this;

	// already deleted, so the threadpool doesn't have to.
	return false;
}