GQuestElement::ResultType GQuestGiveQuestItemElement::checkCondition(PlayerCreature* pPC ) const
{
	GQuestInventory& inventory = pPC->getGQuestManager()->getGQuestInventory();
	inventory.getItems().push_back(m_ItemType);
	pPC->getPlayer()->sendPacket(inventory.getInventoryPacket());

	GCSystemMessage gcSM;
	gcSM.setMessage("퀘스트 아이템을 획득했습니다.");
	pPC->getPlayer()->sendPacket(&gcSM);

	if (m_bSave )
	{
		Statement* pStmt = NULL;
		BEGIN_DB
		{
			pStmt = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement();
			pStmt->executeQuery("INSERT INTO GQuestItemObject(ItemType, OwnerID) VALUES (%u, '%s')",
					m_ItemType, pPC->getName().c_str());
			SAFE_DELETE(pStmt);
		}
		END_DB(pStmt)
	}

	return OK;
}
Exemple #2
0
//----------------------------------------------------------------------
// affect
//----------------------------------------------------------------------
void EventKick::sendMessage()
	throw(Error)
{
	__BEGIN_TRY

	Assert(m_pGamePlayer != NULL);
	Creature * pCreature = m_pGamePlayer->getCreature();

	Timeval currentTime;
	getCurrentTime(currentTime);

	Turn_t       RemainTime = max(0, (int)(m_Deadline.tv_sec-currentTime.tv_sec));

    char msg[50];
    sprintf(msg, g_pStringPool->c_str(STRID_DISCONNECT_COUNT_DOWN ),
                    (int)RemainTime);

    string sMsg(msg);

	GCSystemMessage gcSystemMessage;
	gcSystemMessage.setMessage(sMsg);
	pCreature->getPlayer()->sendPacket(&gcSystemMessage);

	__END_CATCH
}
//----------------------------------------------------------------------
// affect
//----------------------------------------------------------------------
void EffectTransportCreature::affect(Creature* pCreature)
	throw(Error)
{
	__BEGIN_TRY

	Timeval      nextTime   = getNextTime();
	Timeval      deadLine   = getDeadline();
	Turn_t       RemainTime = deadLine.tv_sec - nextTime.tv_sec;

//	StringStream msg;
//	msg << (int)RemainTime << "초 후에 " << m_ZoneName << "로 이동됩니다.";

    char msg[50];
    sprintf(msg, g_pStringPool->c_str(STRID_TRANSPORT_CREATURE ),
                    (int)RemainTime,
                    m_ZoneName.c_str());

	string sMsg(msg);

	GCSystemMessage gcSystemMessage;
	gcSystemMessage.setMessage(sMsg);
	pCreature->getPlayer()->sendPacket(&gcSystemMessage);

	setNextTime(m_MessageTick);

	__END_CATCH
}
void EffectVampireRelic::affect(Creature* pCreature)
	throw(Error)
{
	__BEGIN_TRY
																															    	
	//Timeval      nextTime   = getNextTime();
	//Timeval      deadLine   = getDeadline();
	//Turn_t       RemainTime = deadLine.tv_sec - nextTime.tv_sec;

/*
	StringStream msg;

	if (pCreature->isSlayer())
	{
		Slayer* pSlayer = dynamic_cast<Slayer*>(pCreature);

		msg << pSlayer->getName();
	}
	else
	{
		Vampire* pVampire = dynamic_cast<Vampire*>(pCreature);

		msg << pVampire->getName();
	}

	msg << " 님이 뱀파이어 성물을 가졌습니다.";
*/

    char msg[50];
    sprintf(msg, g_pStringPool->c_str(STRID_TAKE_VAMPIRE_RELIC ),
                    pCreature->getName().c_str());

    string sMsg(msg);

	GCSystemMessage gcSystemMessage;

	gcSystemMessage.setType(SYSTEM_MESSAGE_COMBAT);
	gcSystemMessage.setMessage(sMsg);

	g_pZoneGroupManager->broadcast(&gcSystemMessage);


	// Effect붙인다.
	GCAddEffect gcAddEffect;
	gcAddEffect.setObjectID(pCreature->getObjectID());
	gcAddEffect.setEffectID(getSendEffectClass());
	gcAddEffect.setDuration(65000);
	pCreature->getZone()->broadcastPacket(pCreature->getX(), pCreature->getY(), &gcAddEffect);

	setNextTime(m_Tick);

	__END_CATCH
}
void CGRangerSayHandler::execute (CGRangerSay* pPacket , Player* pPlayer)
	 throw(ProtocolException , Error)
{
	__BEGIN_TRY

#ifdef __GAME_SERVER__

	Assert(pPacket != NULL);
	Assert(pPlayer != NULL);

	GamePlayer* pGamePlayer = dynamic_cast<GamePlayer*>(pPlayer);
	Assert(pGamePlayer != NULL);

	Creature* pCreature = pGamePlayer->getCreature();
	Assert(pCreature != NULL);

	// 크리쳐 이름과 메시지를 패킷에 넣는다.
	StringStream msg;
	msg << pCreature->getName() << " " << pPacket->getMessage();

	Race_t race = pCreature->getRace();

	// 패킷 생성
	GCSystemMessage gcSystemMessage;
	gcSystemMessage.setMessage(msg.toString());
	gcSystemMessage.setType(SYSTEM_MESSAGE_RANGER_SAY);

	// 필터 생성
	BroadcastFilterRace filter(race);

	// 모든 사용자에게 뿌리기
	g_pZoneGroupManager->pushBroadcastPacket(&gcSystemMessage, &filter);

/*	map<ZoneGroupID_t, ZoneGroup*>::const_iterator itr = g_pZoneGroupManager->getZoneGroups().begin();
	map<ZoneGroupID_t, ZoneGroup*>::const_iterator endItr = g_pZoneGroupManager->getZoneGroups().end();

	for (; itr != endItr; ++itr )
	{
		GCSystemMessage* pSystemMessage = new GCSystemMessage();
		pSystemMessage->setMessage(msg.toString());
		pSystemMessage->setType(SYSTEM_MESSAGE_RANGER_SAY);
		pSystemMessage->setRace(race);

		itr->second->getZonePlayerManager()->pushBroadcastPacket(pSystemMessage);
	}
*/
#endif

	__END_CATCH
}
GQuestElement::ResultType GQuestGiveVampireExpElement::checkCondition(PlayerCreature* pPC ) const
{
    if (!pPC->isVampire() ) return FAIL;

    GCModifyInformation gcMI;
    Vampire* pVampire = dynamic_cast<Vampire*>(pPC);
    increaseVampExp(pVampire, m_Amount, gcMI);
    pVampire->getPlayer()->sendPacket(&gcMI);

    GCSystemMessage gcSM;
    gcSM.setMessage("경험치를 획득했습니다.");
    pPC->getPlayer()->sendPacket(&gcSM);

    return OK;
}
GQuestElement::ResultType GQuestGiveDomainExpElement::checkCondition(PlayerCreature* pPC ) const
{
	if (!pPC->isSlayer() ) return FAIL;

	GCModifyInformation gcMI;
	Slayer* pSlayer = dynamic_cast<Slayer*>(pPC);
	increaseDomainExp(pSlayer, pSlayer->getHighestSkillDomain(), m_Amount, gcMI);
	pSlayer->getPlayer()->sendPacket(&gcMI);

	GCSystemMessage gcSM;
	gcSM.setMessage("도메인 경험치를 획득했습니다.");
	pSlayer->getPlayer()->sendPacket(&gcSM);

	return OK;
}
////////////////////////////////////////////////////////////////////////////////
// 액션을 실행한다.
////////////////////////////////////////////////////////////////////////////////
void ActionSetResurrectZone::execute (Creature * pCreature1 , Creature * pCreature2) 
	throw(Error)
{
	__BEGIN_TRY

	Assert(pCreature1 != NULL);
	Assert(pCreature2 != NULL);
	Assert(pCreature1->isNPC());
	Assert(pCreature2->isPC());

	// 일단 클라이언트를 위해서 OK 패킷을 함 날린다.
	GCNPCResponse okpkt;
	Player* pPlayer = pCreature2->getPlayer();
	Assert(pPlayer != NULL);
	pPlayer->sendPacket(&okpkt);

	if (pCreature2->isSlayer())
	{
		Slayer* pSlayer = dynamic_cast<Slayer*>(pCreature2);
		pSlayer->setResurrectZoneIDEx(m_ZoneID);
	}
	else if (pCreature2->isVampire())
	{
		Vampire* pVampire = dynamic_cast<Vampire*>(pCreature2);
		pVampire->setResurrectZoneIDEx(m_ZoneID);
	}
	else if (pCreature2->isOusters())
	{
		Ousters* pOusters = dynamic_cast<Ousters*>(pCreature2);
		pOusters->setResurrectZoneIDEx(m_ZoneID);
	}

	GCSystemMessage msg;
	msg.setMessage(g_pStringPool->getString(STRID_SET_RESURRECTION_POSITION ));
	pPlayer->sendPacket(&msg);

	__END_CATCH
}
void CGSelectWayPointHandler::execute(CGSelectWayPoint* pPacket , Player* pPlayer) throw(Error) {
	__BEGIN_TRY __BEGIN_DEBUG_EX

#ifdef __GAME_SERVER__
	Assert(pPacket != NULL);
	Assert(pPlayer != NULL);

	static map<Level_t,Price_t> sPriceMap;

	try {
		int targetDynamicZoneType = g_pDynamicZoneInfoManager->getDynamicZoneTypeByZoneID(pPacket->getZoneID());
		if (targetDynamicZoneType != DYNAMIC_ZONE_MAX) {
			executeEnterQuestZone(pPacket, pPlayer, targetDynamicZoneType);
		}

		// 게임 플레이어의 상태가 정상이 아니라면 걍 리턴한다.
		GamePlayer* pGamePlayer = dynamic_cast<GamePlayer*>(pPlayer);
		Assert(pGamePlayer != NULL);
		if (pGamePlayer->getPlayerStatus() != GPS_NORMAL) return;

		// 크리쳐가 슬레이어가 아니라면 리턴한다.
		Creature* pCreature = pGamePlayer->getCreature();
		Assert(pCreature != NULL);

		PlayerCreature* pPC = dynamic_cast<PlayerCreature*>(pCreature);
		Assert(pPC != NULL);

		if (pPC->getStore()->isOpen()) return;
		if (pCreature->hasRelicItem()) return;

		// 크리쳐가 죽었으면 리턴
		if (pCreature->isDead()) return;

		// 초보존으로 들어가는 경우엔 종족 상관없이 보내준다.
		if (pPacket->getZoneID() == 1122) {
			ZONE_COORD pos(1122);

			if (pCreature->isSlayer()) {
				pos.x = 107;
				pos.y = 27;
			} else if (pCreature->isVampire()) {
				pos.x = 18;
				pos.y = 27;
			} else if (pCreature->isOusters()) {
				pos.x = 12;
				pos.y = 103;
			} else return;

			if (!canEnterBeginnerZone(pCreature)) return;

			// 초보존이 유료존일수도 있을라나...?
#if defined(__PAY_SYSTEM_ZONE__) || defined(__PAY_SYSTEM_FREE_LIMIT__)
			ZoneInfo* pZoneInfo = g_pZoneInfoManager->getZoneInfo(pos.id);
			
			// 유료존인데 유료사용자가 아니면...
      if (pZoneInfo == NULL ||
          ((pZoneInfo->isPayPlay() || pZoneInfo->isPremiumZone())
           && (!pGamePlayer->isPayPlaying() && !pGamePlayer->isFamilyFreePass()))) {
        //Statement* pStmt = NULL;
				string connectIP = pGamePlayer->getSocket()->getHost();

				// 유료 서비스 사용이 가능한가?
				if (pGamePlayer->loginPayPlay(connectIP, pGamePlayer->getID())) {
					sendPayInfo(pGamePlayer);
				} else if (pZoneInfo->isPayPlay()) {
					// 유료 서비스 사용 불가인 경우
					GCSystemMessage gcSystemMessage;

					if (g_pConfig->getPropertyInt("IsNetMarble") == 0) {
						gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CANNOT_ENTER));
					} else {
						gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CANNOT_ENTER));
					}

					pGamePlayer->sendPacket(&gcSystemMessage);

					return;
				}
			}
#endif

			pPC->getGQuestManager()->illegalWarp();
			transportCreature(pCreature, pos.id, pos.x, pos.y, false);
			return;
		}

		if (pPacket->getZoneID() == 1131) {

			if (g_pVariableManager->getVariable(ACTIVE_LEVEL_WAR) == 0) {
				GCSystemMessage gcSystemMessage;
				gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CANNOT_ENTER));
				pGamePlayer->sendPacket(&gcSystemMessage);
				return;
			}
/*
			if (g_pConfig->getPropertyInt("ServerID" ) != 0 )
			{
				GCNoticeEvent gcNoticeEvent;

				gcNoticeEvent.setCode(NOTICE_EVENT_NOT_FIRST_SERVER);
				pGamePlayer->sendPacket(&gcNoticeEvent);
//				GCSystemMessage gcSystemMessage;
//				gcSystemMessage.setMessage(g_pStringPool->getString(STRID_LEVEL_WAR_ONLY_FIRST_SERVER ));
//				pGamePlayer->sendPacket (&gcSystemMessage);
				return;
			}
*/

			// 크리쳐 정보 보고 알아서 튕겨주자 =_=;;
			ZONE_COORD pos(g_pLevelWarZoneInfoManager->getCreatureZoneID(pCreature ));

			if (g_pSweeperBonusManager->isAble(g_pLevelWarZoneInfoManager->getCreatureZoneID(pCreature))) {
				GCSystemMessage gcSystemMessage;
				gcSystemMessage.setMessage(g_pStringPool->getString(STRID_NO_WAR_IN_ACTIVE ));
				pGamePlayer->sendPacket (&gcSystemMessage);
				return;
			}

			if (pCreature->isSlayer()) {
				pos.x = 12;
				pos.y =  9;
			} else if (pCreature->isVampire()) {
				pos.x = 117;
				pos.y =   8;
			} else if (pCreature->isOusters()) {
				pos.x =   9;
				pos.y = 111;
			}
			
#if defined(__PAY_SYSTEM_ZONE__) || defined(__PAY_SYSTEM_FREE_LIMIT__)
			Zone* pZone = getZoneByZoneID(pos.id);
			Assert(pZone != NULL);
			
			LevelWarManager* pLevelWarManager = pZone->getLevelWarManager();
			Assert(pLevelWarManager != NULL);

			if (!pLevelWarManager->hasWar() && !g_pVariableManager->canEnterLevelWarZoneFree() && !pGamePlayer->isPayPlaying() && pGamePlayer->isFamilyFreePass() && !pLevelWarManager->canEnterFreeUser()) {
				GCSystemMessage gcSystemMessage;
				gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CANNOT_ENTER_LEVEL_WAR_ZONE));
				pGamePlayer->sendPacket(&gcSystemMessage);
				return;
			}
#endif
			
			pPC->getGQuestManager()->illegalWarp();
			transportCreature(pCreature, pos.id, pos.x, pos.y, false);
			return;
		}

		if (pPacket->getZoneID() == 72) {
			if (!g_pWarSystem->hasActiveRaceWar()) {
				GCSystemMessage gcSystemMessage;
				gcSystemMessage.setMessage(g_pStringPool->getString(STRID_NO_WAR_IN_ACTIVE));
				pGamePlayer->sendPacket (&gcSystemMessage);

				return;
			}
/*
			if (g_pConfig->getPropertyInt("ServerID" ) != 0 )
			{
				GCNoticeEvent gcNoticeEvent;

				gcNoticeEvent.setCode(NOTICE_EVENT_NOT_FIRST_SERVER);
				pGamePlayer->sendPacket(&gcNoticeEvent);
//				GCSystemMessage gcSystemMessage;
//				gcSystemMessage.setMessage(g_pStringPool->getString(STRID_LEVEL_WAR_ONLY_FIRST_SERVER ));
//				pGamePlayer->sendPacket (&gcSystemMessage);
				return;
			}
*/

			// 크리쳐 정보 보고 알아서 튕겨주자 =_=;;
			ZONE_COORD pos;

			if (pCreature->isSlayer()) {
				pos.id = 73;
				pos.x = 30;
				pos.y = 124;
			} else if (pCreature->isVampire()) {
				pos.id = 71;
				pos.x = 104;
				pos.y = 128; 
			} else if (pCreature->isOusters()) {
				pos.id = 72;
				pos.x = 67;
				pos.y = 165;
			}
/*#if defined(__PAY_SYSTEM_ZONE__) || defined(__PAY_SYSTEM_FREE_LIMIT__)
			ZoneInfo* pZoneInfo = g_pZoneInfoManager->getZoneInfo(pos.id);
			
			// 유료존인데 유료사용자가 아니면...
			if (pZoneInfo==NULL
				|| (pZoneInfo->isPayPlay() || pZoneInfo->isPremiumZone())
					&& (!pGamePlayer->isPayPlaying() && !pGamePlayer->isFamilyFreePass() ))
			{
				//Statement* pStmt = NULL;
				string connectIP = pGamePlayer->getSocket()->getHost();

				// 유료 서비스 사용이 가능한가?
				if (pGamePlayer->loginPayPlay(connectIP, pGamePlayer->getID()))
				{
					sendPayInfo(pGamePlayer);
				}
				else if (pZoneInfo->isPayPlay())
				{
					// 유료 서비스 사용 불가인 경우
					GCSystemMessage gcSystemMessage;

					if (g_pConfig->getPropertyInt("IsNetMarble")==0)
					{
						gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CANNOT_ENTER ));
					}
					else
					{
						gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CANNOT_ENTER ));
					}

					pGamePlayer->sendPacket (&gcSystemMessage);

					return;
				}
			}
#endif*/
			if (!g_pVariableManager->isActiveRaceWarLimiter() || pCreature->isFlag(Effect::EFFECT_CLASS_RACE_WAR_JOIN_TICKET)) {
				pPC->getGQuestManager()->illegalWarp();
				transportCreature(pCreature, pos.id, pos.x, pos.y, false);
				return;
			} else {
				GCSystemMessage gcSystemMessage;
				gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CANNOT_ENTER_DURING_RACE_WAR));
				pGamePlayer->sendPacket(&gcSystemMessage);
				return;
			}
		}

		if (!pCreature->isSlayer() && !pCreature->isOusters()) {
			// 뭔가를 해야하지 않을까?
			return;
		}
		
		if (pCreature->isFlag(Effect::EFFECT_CLASS_HAS_FLAG)) {
			// 뭔가를 해야하지 않을까?
			return;
		}

		if (pCreature->isFlag(Effect::EFFECT_CLASS_HAS_SWEEPER)) {
			// 뭔가를 해야하지 않을까?
			return;
		}

		//Slayer* pSlayer = dynamic_cast<Slayer*>(pCreature);
		//Assert(pSlayer != NULL);

		bool bCancel = false;

		// 이펙트가 걸려있어야 정상적인 이동이다.
		if (pCreature->isOusters() || (pCreature->isSlayer() && pCreature->isFlag(Effect::EFFECT_CLASS_SLAYER_PORTAL))) {
			ZoneID_t    id = pPacket->getZoneID();
			ZoneCoord_t x  = pPacket->getX();
			ZoneCoord_t y  = pPacket->getY();

			if (id == 0 && x == 0 && y == 0) {
				bCancel = true;
			} else {
				// 석화 상태일 경우 생깐다.
				if (pCreature->isFlag(Effect::EFFECT_CLASS_PARALYZE)) {
					bCancel = true;
				}

				// 웨이포인트 매니저를 통해서 클라이언트가 보내온
				// 웨이포인트가 정상적인 웨이포인트인지를 검증한다.
				if (!g_pWayPointManager->isValidWayPoint(id, x, y, pCreature->getRace())) {
					// 뭔가를 해야하지 않을까?
					bCancel = true;

					//return;
				}

				try {

					if (!bCancel) {

#if defined(__PAY_SYSTEM_ZONE__) || defined(__PAY_SYSTEM_FREE_LIMIT__)
						ZoneInfo* pZoneInfo = g_pZoneInfoManager->getZoneInfo(id);
						
						// 유료존인데 유료사용자가 아니면...
            if (pZoneInfo==NULL ||
                ((pZoneInfo->isPayPlay() || pZoneInfo->isPremiumZone()) && (!pGamePlayer->isPayPlaying() && !pGamePlayer->isFamilyFreePass()))) {
              //Statement* pStmt = NULL;
							string connectIP = pGamePlayer->getSocket()->getHost();

							// 유료 서비스 사용이 가능한가?
							if (pGamePlayer->loginPayPlay(connectIP, pGamePlayer->getID())) {
								sendPayInfo(pGamePlayer);
							} else if (pZoneInfo->isPayPlay()) {
								// 유료 서비스 사용 불가인 경우
								GCSystemMessage gcSystemMessage;

								if (g_pConfig->getPropertyInt("IsNetMarble") == 0) {
									gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CANNOT_ENTER));
								} else {
									gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CANNOT_ENTER));
								}

								pGamePlayer->sendPacket (&gcSystemMessage);

								bCancel = true;
							}
						}
#endif

						if (!bCancel) {
							// 이동시키기 전에 이펙트를 삭제한다.
							if (pCreature->isSlayer())
								pCreature->removeFlag(Effect::EFFECT_CLASS_SLAYER_PORTAL);

							if (pCreature->isOusters()) {
								Ousters* pOusters = dynamic_cast<Ousters*>(pCreature);
								Assert(pOusters != NULL);

								GCNoticeEvent gcNoticeEvent;

								// 대지정령의 뿔을 사용할라면 시오람과 계약을 맺었어야 한다.
								if (!pOusters->getFlagSet()->isOn(FLAGSET_GNOMES_HORN)) {
									gcNoticeEvent.setCode(NOTICE_EVENT_CONTRACT_GNOMES_HORN);
									pPlayer->sendPacket(&gcNoticeEvent);
									return;
								}

								Level_t level = pOusters->getLevel();
								Price_t price = sPriceMap[level];

								if (price == 0) {
									price = (Price_t)(pow((double)level, 1.3) * 100) / 2;
									sPriceMap[level] = price;
								}

								/*if (g_pFlagManager->hasFlagWar() && 
										pPacket->getZoneID() == 32 &&
										pPacket->getX() == 124 &&
										pPacket->getY() == 144 ) price = 0;*/

								if (pOusters->getGold() < price) {
									gcNoticeEvent.setCode(NOTICE_EVENT_NOT_ENOUGH_MONEY);
									pPlayer->sendPacket(&gcNoticeEvent);
									return;
								} else {
									pOusters->decreaseGoldEx(price);
									GCModifyInformation gcMI;
									gcMI.addLongData(MODIFY_GOLD, pOusters->getGold());
									pPlayer->sendPacket(&gcMI);
								}
							}

							// 올바른 웨이포인트라면 슬레이어를 이동시켜준다.
							pPC->getGQuestManager()->illegalWarp();
							transportCreature(pCreature, id, x, y, false);
						}
					}
				} catch (NoSuchElementException&) {
					bCancel = true;
				}
			}
		}

		if (bCancel && pCreature->isSlayer()) {
			Zone* pZone = pCreature->getZone();
			Assert(pZone != NULL);

			// id, x, y가 모두 0일 경우 이동을 취소한다는 뜻이다.
			pCreature->removeFlag(Effect::EFFECT_CLASS_SLAYER_PORTAL);

			// 헬기를 제거하라고 뿌려준다.
			GCAddHelicopter gcAddHelicopter;
			gcAddHelicopter.setObjectID(pCreature->getObjectID());
			gcAddHelicopter.setCode(1);
			pZone->broadcastPacket(pCreature->getX(), pCreature->getY(), &gcAddHelicopter);
		}
	} 
	catch (Throwable & t) { 
		cerr << t.toString() << endl; 
	}

#endif	// __GAME_SERVER__
		
	__END_DEBUG_EX __END_CATCH
}
void CGModifyGuildMemberHandler::execute (CGModifyGuildMember* pPacket , Player* pPlayer)
	 throw(Error)
{
	__BEGIN_TRY __BEGIN_DEBUG_EX
		
#ifdef __GAME_SERVER__

	//cout << "CGModifyGuildMember received." << endl;

	Assert(pPacket != NULL);
	Assert(pPlayer != NULL);

	SYSTEM_ASSERT(SYSTEM_GUILD);

	GamePlayer* pGamePlayer = dynamic_cast<GamePlayer*>(pPlayer);
	Assert(pGamePlayer != NULL);

	Creature* pCreature = pGamePlayer->getCreature();
	Assert(pCreature != NULL);

	PlayerCreature* pPlayerCreature = dynamic_cast<PlayerCreature*>(pCreature);
	Assert(pPlayerCreature != NULL);

	// 길드를 가져온다.
	Guild* pGuild = g_pGuildManager->getGuild(pPlayerCreature->getGuildID());
	//try { Assert(pGuild != NULL); } catch (Throwable& t ) { return; }
	if (pGuild==NULL) return;

	// 길드 멤버 정보를 가져온다.
	GuildMember* pGuildMember  = pGuild->getMember(pPlayerCreature->getName());
	//try { Assert(pGuild != NULL); } catch (Throwable& t ) { return; }
	if (pGuildMember==NULL) return;

	//cout << "get guild" << endl;

	if (pPacket->getGuildMemberRank() == GuildMember::GUILDMEMBER_RANK_DENY )
	{
		////////////////////////////////////////////////////////
		// 길드 멤버를 추방한다.
		////////////////////////////////////////////////////////

		// 마스터가 아니면 추방할 수 없다.
		if (pGuildMember->getRank() != GuildMember::GUILDMEMBER_RANK_MASTER )
			return;

		if (g_pGuildManager->hasActiveWar(pGuild->getID() ) )
		{
			GCSystemMessage msg;
			msg.setMessage(g_pStringPool->getString(STRID_CANNOT_KICK_DURING_WAR ));
			pPlayer->sendPacket(&msg);

			return;
		}

		GSExpelGuildMember gsExpelGuildMember;
		gsExpelGuildMember.setGuildID(pGuild->getID());
		gsExpelGuildMember.setName(pPacket->getName());
		gsExpelGuildMember.setSender(pPlayerCreature->getName());

		//cout << "send GSExpelGuildMember" << endl;
		g_pSharedServerManager->sendPacket(&gsExpelGuildMember);
	}
	else
	{
		if (pGuild->getActiveMemberCount() >= MAX_GUILDMEMBER_ACTIVE_COUNT )
		{
			GCSystemMessage msg;
			msg.setMessage(g_pStringPool->getString(STRID_CANNOT_ACCEPT_MORE_JOIN ));
			pPlayer->sendPacket(&msg);

			return;
		}
		///////////////////////////////////////////////////////
		// 길드 가입을 승인한다.
		///////////////////////////////////////////////////////

		// 마스터나 서브마스터 이어야 한다.
		if (pGuildMember->getRank() != GuildMember::GUILDMEMBER_RANK_MASTER
		  && pGuildMember->getRank() != GuildMember::GUILDMEMBER_RANK_SUBMASTER )
			return;

		if (g_pGuildManager->hasActiveWar(pGuild->getID() ) )
		{
			GCSystemMessage msg;
			msg.setMessage(g_pStringPool->getString(STRID_CANNOT_ACCEPT_DURING_WAR ));
			pPlayer->sendPacket(&msg);

			return;
		}

		GSModifyGuildMember gsModifyGuildMember;
		gsModifyGuildMember.setGuildID(pGuild->getID());
		gsModifyGuildMember.setName(pPacket->getName());
		gsModifyGuildMember.setGuildMemberRank(pPacket->getGuildMemberRank());
		gsModifyGuildMember.setSender(pPlayerCreature->getName());

		//cout << "send GSModifyGuildMember" << endl;
		g_pSharedServerManager->sendPacket(&gsModifyGuildMember);
	}

#endif	// __GAME_SERVER__
		
	__END_DEBUG_EX __END_CATCH
}
void CGQuitUnionAcceptHandler::execute (CGQuitUnionAccept* pPacket , Player* pPlayer)
	 throw(Error)
{
	__BEGIN_TRY __BEGIN_DEBUG_EX
		
#ifdef __GAME_SERVER__

	Assert(pPacket != NULL);
	Assert(pPlayer != NULL);

    GamePlayer* pGamePlayer = dynamic_cast<GamePlayer*>(pPlayer);
    Assert(pGamePlayer != NULL);

    PlayerCreature* pPlayerCreature = dynamic_cast<PlayerCreature*>(pGamePlayer->getCreature());
    Assert(pPlayerCreature != NULL);

#ifdef __OLD_GUILD_WAR__
	GCSystemMessage gcSM;
	gcSM.setMessage("아직 지원되지 않는 기능입니다.");
	pGamePlayer->sendPacket(&gcSM);
	return;
#endif

	SYSTEM_ASSERT(SYSTEM_GUILD);

	GCGuildResponse gcGuildResponse;

	GuildUnion *pUnion = GuildUnionManager::Instance().getGuildUnion(pPlayerCreature->getGuildID());
	if(pUnion == NULL)
	{
		gcGuildResponse.setCode(GuildUnionOfferManager::NOT_IN_UNION);
		pPlayer->sendPacket(&gcGuildResponse);

		return;
	}
	
	// 요청한놈이 지가 속한 길드의 마스터인가? || 연합의 마스터길드가 내 길드가 맞나?
	if(!g_pGuildManager->isGuildMaster (pPlayerCreature->getGuildID(), pPlayerCreature )
		|| pUnion->getMasterGuildID() != pPlayerCreature->getGuildID() 		
		)
	{
		// GC_GUILD_RESPONSE 날려준다.
		// 내용 : 길드 마스터가 아니자녀 -.-+

		gcGuildResponse.setCode(GuildUnionOfferManager::SOURCE_IS_NOT_MASTER);
		pPlayer->sendPacket(&gcGuildResponse);

		return;
	}

	uint result = GuildUnionOfferManager::Instance().acceptQuit(pPacket->getGuildID());

	gcGuildResponse.setCode(result);
	pPlayer->sendPacket(&gcGuildResponse);
////////////////////

	if(result == GuildUnionOfferManager::OK)
	{
	
		Guild*  pGuild  = g_pGuildManager->getGuild(pPacket->getGuildID());

		if(pGuild == NULL)
		{
			return;
		}
		string  TargetGuildMaster = pGuild->getMaster();

		//cout << "연합탈퇴가 수락되었다. 통보받을 유저는 : " << TargetGuildMaster.c_str() << endl;


		Statement* pStmt = NULL;

		BEGIN_DB
		{
			pStmt = g_pDatabaseManager->getConnection("DARKEDEN" )->createStatement();
			pStmt->executeQuery("INSERT INTO Messages (Receiver, Message) values('%s','%s')", TargetGuildMaster.c_str(),  g_pStringPool->c_str(375 ));

			// 탈퇴수락한뒤에 나 혼자 남아있다면?
			Result *pResult = pStmt->executeQuery("SELECT count(*) FROM GuildUnionMember WHERE UnionID='%u'", pUnion->getUnionID());
			pResult->next();

			if(pResult->getInt(1) == 0)
			{
				//cout << "연합탈퇴가 수락된후..남아있는 멤버가 없으면..연합장이면 안되니까..지워버린다" << endl;
				pStmt->executeQuery("DELETE FROM GuildUnionInfo WHERE UnionID='%u'", pUnion->getUnionID());
				GuildUnionManager::Instance().reload();

			}
		
			
			SAFE_DELETE(pStmt);
		}
		END_DB(pStmt)
		
		// 연합탈퇴하면 연합정보가 바뀌었을 수도 있다. 갱신된 정보를 다시 보내준다.
		Creature *pCreature = NULL;
		pCreature = pGamePlayer->getCreature();

		if(pCreature == NULL)   return;

		GCModifyInformation gcModifyInformation;
		makeGCModifyInfoGuildUnion(&gcModifyInformation, pCreature);

		pPlayer->sendPacket(&gcModifyInformation);

		// 통보받을 유저에게 길드Union정보를 다시 보낸다
		Creature *pTargetCreature = NULL;
		__ENTER_CRITICAL_SECTION((*g_pPCFinder))

	    pTargetCreature = g_pPCFinder->getCreature_LOCKED(TargetGuildMaster);
    	if (pTargetCreature==NULL)
	    {
    	    g_pPCFinder->unlock();
        	return;
	    }
		GCModifyInformation gcModifyInformation;
        makeGCModifyInfoGuildUnion(&gcModifyInformation, pTargetCreature);
        pTargetCreature->getPlayer()->sendPacket(&gcModifyInformation);

		__LEAVE_CRITICAL_SECTION((*g_pPCFinder))
	
		sendGCOtherModifyInfoGuildUnion(pTargetCreature);
		sendGCOtherModifyInfoGuildUnion(pCreature);

		// 다른 서버에 있는 놈들에게 변경사항을 알린다.
        GuildUnionManager::Instance().sendModifyUnionInfo(dynamic_cast<PlayerCreature*>(pTargetCreature)->getGuildID());
        GuildUnionManager::Instance().sendModifyUnionInfo(dynamic_cast<PlayerCreature*>(pCreature)->getGuildID());
				
			
	}
////////////////////////////////////////////////////////////////////////////////
// 액션을 실행한다.
////////////////////////////////////////////////////////////////////////////////
void ActionEnterQuestZone::execute (Creature * pNPC , Creature * pCreature) 
	throw(Error)
{
	__BEGIN_TRY
	__BEGIN_DEBUG

	Assert(pCreature != NULL);
	Assert(pCreature->isPC());

	GamePlayer* pGamePlayer = dynamic_cast<GamePlayer*>(pCreature->getPlayer());
	PlayerCreature* pPC = dynamic_cast<PlayerCreature*>(pCreature);

	Assert(pPC != NULL);

	bool bTransport = true;
#if defined(__PAY_SYSTEM_ZONE__) || defined(__PAY_SYSTEM_FREE_LIMIT__)
	try {

		ZoneInfo* pZoneInfo = g_pZoneInfoManager->getZoneInfo(m_ZoneID);

		// 유료존인데 유료사용자가 아니면...
		if (pZoneInfo==NULL
			|| pZoneInfo->isPayPlay() && !(pGamePlayer->isPayPlaying() || pGamePlayer->isFamilyFreePass()))
		{
			string connectIP = pGamePlayer->getSocket()->getHost();

			// 유료 서비스 사용이 가능한가?
			if (pGamePlayer->loginPayPlay(connectIP, pGamePlayer->getID()))
			{
				sendPayInfo(pGamePlayer);
			}
			else
			{
				// 유료 서비스 사용 불가인 경우
				GCSystemMessage gcSystemMessage;

				if (g_pConfig->getPropertyInt("IsNetMarble")==0)
				{
					gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CANNOT_ENTER_PAY_ZONE ));
				}
				else
				{
					gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CANNOT_ENTER ));
				}

				pGamePlayer->sendPacket (&gcSystemMessage);

				bTransport = false;
			}
		}
	} catch (NoSuchElementException&) {
	}
#endif

	if (bTransport)
	{
		// Dynamic 존인지 확인.
		int targetDynamicZoneType = g_pDynamicZoneInfoManager->getDynamicZoneTypeByZoneID(m_ZoneID);

		if (targetDynamicZoneType != DYNAMIC_ZONE_MAX )
		{
			// Dynamic 존일 경우
			DynamicZoneGroup* pDynamicZoneGroup = g_pDynamicZoneManager->getDynamicZoneGroup(targetDynamicZoneType);
			Assert(pDynamicZoneGroup != NULL);

			DynamicZone* pDynamicZone = pDynamicZoneGroup->getAvailableDynamicZone();
			Assert(pDynamicZone != NULL);

			transportCreature(pCreature, pDynamicZone->getZoneID(), m_X, m_Y, true);

			if (targetDynamicZoneType == DYNAMIC_ZONE_ALTER_OF_BLOOD )
			{
				DynamicZoneAlterOfBlood* pAlterOfBlood = dynamic_cast<DynamicZoneAlterOfBlood*>(pDynamicZone);
				Assert(pAlterOfBlood != NULL);
				pAlterOfBlood->setRace(pPC->getRace());
			}
		}
		else
		{
			// Dynamic 존이 아닐 경우
			transportCreature(pCreature, m_ZoneID, m_X, m_Y, true);
		}
	}
	else
	{
	    GCNPCResponse response;
	    response.setCode(NPC_RESPONSE_QUIT_DIALOGUE);
	    pGamePlayer->sendPacket(&response);
	}

	__END_DEBUG
	__END_CATCH
}
//----------------------------------------------------------------------
//
// SGAddGuildMemberOKHandler::execute()
//
//----------------------------------------------------------------------
void SGAddGuildMemberOKHandler::execute (SGAddGuildMemberOK* pPacket )
throw(ProtocolException , Error )
{
    __BEGIN_TRY __BEGIN_DEBUG_EX

#ifdef __GAME_SERVER__

    // 길드 멤버 object 를 만든다.
    GuildMember* pGuildMember = new GuildMember();
    pGuildMember->setGuildID(pPacket->getGuildID());
    pGuildMember->setName(pPacket->getName());
    pGuildMember->setRank(pPacket->getGuildMemberRank());

    // 길드에 추가한다.
    Guild* pGuild = g_pGuildManager->getGuild(pGuildMember->getGuildID());
    pGuild->addMember(pGuildMember);

    // 멤버에게 메세지를 보낸다.
    __ENTER_CRITICAL_SECTION((*g_pPCFinder))

    Creature* pCreature = g_pPCFinder->getCreature_LOCKED(pGuildMember->getName());
    if (pCreature != NULL && pCreature->isPC() )
    {
        Player* pPlayer = pCreature->getPlayer();
        Assert(pPlayer != NULL);

        if (pGuildMember->getRank() == GuildMember::GUILDMEMBER_RANK_MASTER ||
                pGuildMember->getRank() == GuildMember::GUILDMEMBER_RANK_SUBMASTER )		// 길드마스터나 서브마스터일 경우
        {
            PlayerCreature* pPlayerCreature = dynamic_cast<PlayerCreature*>(pCreature);
            Assert(pPlayerCreature != NULL);

            Gold_t Fee;
            if (pGuildMember->getRank() == GuildMember::GUILDMEMBER_RANK_MASTER )
                Fee = REQUIRE_SLAYER_MASTER_GOLD;
            else if (pGuildMember->getRank() == GuildMember::GUILDMEMBER_RANK_SUBMASTER )
                Fee = REQUIRE_SLAYER_SUBMASTER_GOLD;
            else
                Fee = 0;

            Gold_t CurMoney = pPlayerCreature->getGold();
            if (CurMoney < Fee )
            {
                // 큰일났군
                CurMoney = 0;
            }
            else
                CurMoney -= Fee;

            pPlayerCreature->setGoldEx(CurMoney);

            if (Fee != 0 )
            {
                GCModifyInformation gcModifyInformation;
                gcModifyInformation.addLongData(MODIFY_GOLD, CurMoney);

                // 바뀐정보를 클라이언트에 보내준다.
                pPlayer->sendPacket(&gcModifyInformation);
            }

            // 길드 가입 메시지를 보여준다.
            GCSystemMessage gcSystemMessage;
            if (pGuild->getRace() == Guild::GUILD_RACE_SLAYER )
                gcSystemMessage.setMessage(g_pStringPool->getString(STRID_TEAM_JOIN_ACCEPTED ));
            else if (pGuild->getRace() == Guild::GUILD_RACE_VAMPIRE )
                gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CLAN_JOIN_ACCEPTED ));
            else if (pGuild->getRace() == Guild::GUILD_RACE_OUSTERS )
                gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CLAN_JOIN_ACCEPTED ));
            pPlayer->sendPacket(&gcSystemMessage);

        }
        else if (pGuildMember->getRank() == GuildMember::GUILDMEMBER_RANK_WAIT )
        {
            // 길드 가입 신청 메시지를 보낸다.
            GCSystemMessage gcSystemMessage;
            if (pGuild->getRace() == Guild::GUILD_RACE_SLAYER )
                gcSystemMessage.setMessage(g_pStringPool->getString(STRID_TEAM_JOIN_TRY ));
            else if (pGuild->getRace() == Guild::GUILD_RACE_VAMPIRE )
                gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CLAN_JOIN_TRY ));
            else if (pGuild->getRace() == Guild::GUILD_RACE_OUSTERS )
                gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CLAN_JOIN_TRY ));

            pPlayer->sendPacket(&gcSystemMessage);
        }
    }
    else
    {
        // 접속이 안되어 있다.

        // 마스터나 서브마스터일 경우
        // DB 에서 돈을 까도록 한다.
        if ((pGuildMember->getRank() == GuildMember::GUILDMEMBER_RANK_MASTER ||
                pGuildMember->getRank() == GuildMember::GUILDMEMBER_RANK_SUBMASTER )		// 길드마스터나 서브마스터일 경우
                && pPacket->getServerGroupID() == g_pConfig->getPropertyInt("ServerID" ) )		// 이 게임 서버에서 추가한 길드원인가?
        {
            Gold_t Fee;
            if (pGuildMember->getRank() == GuildMember::GUILDMEMBER_RANK_MASTER )
                Fee = REQUIRE_SLAYER_MASTER_GOLD;
            else if (pGuildMember->getRank() == GuildMember::GUILDMEMBER_RANK_SUBMASTER )
                Fee = REQUIRE_SLAYER_SUBMASTER_GOLD;
            else
                Fee = 0;

            string table = "";
            if (pGuild->getRace() == Guild::GUILD_RACE_SLAYER )
            {
                table = "Slayer";
            }
            else if (pGuild->getRace() == Guild::GUILD_RACE_VAMPIRE )
            {
                table = "Vampire";
            }
            else if (pGuild->getRace() == Guild::GUILD_RACE_OUSTERS )
            {
                table = "Ousters";
            }

            if (table != "" && Fee != 0 )
            {
                Statement* pStmt = NULL;

                BEGIN_DB
                {
                    pStmt = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement();
                    pStmt->executeQuery("UPDATE %s SET Gold = IF (%u > Gold , 0, Gold - %u ) WHERE Name = '%s'",
                    table.c_str(), Fee, Fee, pGuildMember->getName().c_str());
                }
                END_DB(pStmt)
            }
        }
//----------------------------------------------------------------------
// 
// SGModifyGuildOKHandler::execute()
// 
//----------------------------------------------------------------------
void SGModifyGuildOKHandler::execute (SGModifyGuildOK* pPacket )
	 throw(ProtocolException , Error )
{
	__BEGIN_TRY __BEGIN_DEBUG_EX

#ifdef __GAME_SERVER__

	Guild* pGuild = g_pGuildManager->getGuild(pPacket->getGuildID());
	Assert(pGuild != NULL);

	if (pGuild->getState() == Guild::GUILD_STATE_WAIT && pPacket->getGuildState() == Guild::GUILD_STATE_ACTIVE )
	{
		/////////////////////////////////////////////////////////////
		// 존 추가
		/////////////////////////////////////////////////////////////
/*		if (pGuild->getServerGroupID() == g_pConfig->getPropertyInt("ServerID" ) )
		{
			// 이 게임 서버에 길드 아지트를 만든다.

			//////////////
			// Zone Info
			//////////////
			ZoneInfo* pZoneInfo = new ZoneInfo();
			pZoneInfo->setZoneID(pGuild->getZoneID());
			pZoneInfo->setZoneGroupID(2);
			pZoneInfo->setZoneType("NPC_SHOP");
			pZoneInfo->setZoneLevel(0);
			pZoneInfo->setZoneAccessMode("PUBLIC");
			pZoneInfo->setZoneOwnerID("");
			pZoneInfo->setPayPlay("");
			if (pGuild->getRace() == Guild::GUILD_RACE_SLAYER )
			{
				pZoneInfo->setSMPFilename("team_hdqrs.smp");
				pZoneInfo->setSSIFilename("team_hdqrs.ssi");
				string Name = "team - " + pGuild->getName();
				pZoneInfo->setFullName(Name);
				pZoneInfo->setShortName(Name);
			}
			else if (pGuild->getRace() == Guild::GUILD_RACE_VAMPIRE )
			{
				pZoneInfo->setSMPFilename("clan_hdqrs.smp");
				pZoneInfo->setSSIFilename("clan_hdqrs.ssi");
				string Name = "clan - " + pGuild->getName();
				pZoneInfo->setFullName(Name);
				pZoneInfo->setShortName(Name);
			}

			g_pZoneInfoManager->addZoneInfo(pZoneInfo);
			
			/////////
			// Zone
			/////////
			Zone* pZone = new Zone(pGuild->getZoneID());
			Assert(pZone != NULL);

			ZoneGroup* pZoneGroup = g_pZoneGroupManager->getZoneGroup(2);
			Assert(pZoneGroup != NULL);

			pZone->setZoneGroup(pZoneGroup);
			pZoneGroup->addZone(pZone);
			pZone->init();
		}
*/

		// 정식 길드로 변경
		pGuild->setState(Guild::GUILD_STATE_ACTIVE);

		HashMapGuildMember& Members = pGuild->getMembers();
		HashMapGuildMemberItor itr = Members.begin();
		for (; itr != Members.end(); itr++ )
		{
			GuildMember* pGuildMember = itr->second;

			// 멤버가 접속해 있다면
			__ENTER_CRITICAL_SECTION((*g_pPCFinder))

			Creature* pCreature = g_pPCFinder->getCreature_LOCKED(pGuildMember->getName());
			if (pCreature != NULL && pCreature->isPC() )
			{
				Player* pPlayer = pCreature->getPlayer();
				Assert(pPlayer != NULL);

				PlayerCreature* pPlayerCreature = dynamic_cast<PlayerCreature*>(pCreature);
				Assert(pPlayerCreature != NULL);

				// 길드 아이디를 바꿔준다.
				pPlayerCreature->setGuildID(pGuild->getID());

				// 클라이언트에 길드 아이디가 바꼈음을 알려준다.
				GCModifyGuildMemberInfo gcModifyGuildMemberInfo;
				gcModifyGuildMemberInfo.setGuildID(pGuild->getID());
				gcModifyGuildMemberInfo.setGuildName(pGuild->getName());
				gcModifyGuildMemberInfo.setGuildMemberRank(pGuildMember->getRank());
				pPlayer->sendPacket(&gcModifyGuildMemberInfo);

				// 주위에 알린다.
				Zone* pZone = pCreature->getZone();
				Assert(pZone != NULL);

				GCOtherModifyInfo gcOtherModifyInfo;
				gcOtherModifyInfo.setObjectID(pCreature->getObjectID());
				gcOtherModifyInfo.addShortData(MODIFY_GUILDID, pPlayerCreature->getGuildID());

				pZone->broadcastPacket(pCreature->getX(), pCreature->getY(), &gcOtherModifyInfo, pCreature);

				// 정식 길드가 되었음을 알림
				Statement* pStmt = NULL;
				Result* pResult = NULL;

				BEGIN_DB
				{
					pStmt = g_pDatabaseManager->getConnection("DARKEDEN" )->createStatement();
					pResult = pStmt->executeQuery("SELECT Message FROM Messages WHERE Receiver = '%s'", pGuildMember->getName().c_str());

					while (pResult->next() )
					{
						GCSystemMessage gcSystemMessage;
						gcSystemMessage.setMessage(pResult->getString(1));
						pPlayer->sendPacket(&gcSystemMessage);
					}

					pStmt->executeQuery("DELETE FROM Messages WHERE Receiver = '%s'", pGuildMember->getName().c_str());

					SAFE_DELETE(pStmt);
				}
				END_DB(pStmt)
			}

			__LEAVE_CRITICAL_SECTION((*g_pPCFinder))
		}
//----------------------------------------------------------------------
// 
// SGDeleteGuildOKHandler::execute()
// 
//----------------------------------------------------------------------
void SGDeleteGuildOKHandler::execute (SGDeleteGuildOK* pPacket )
	 throw(ProtocolException , Error )
{
	__BEGIN_TRY

#ifdef __GAME_SERVER__

	// 길드 아지트에 있는 멤버를 warp 시킨다.
	// 길드 아지트를 삭제한다.
	// 멤버 warp와 길드 아지트 삭제 시 다른 쓰레드에서 ZoneGroup Thread 내부에서 일어나게 해야 별탈이 없을 듯 하다.
	// 일단은 걍 둔다. Portal 이 막히므로 다시 들어갈 수 없을 것이다.
	
	Assert(pPacket != NULL);

	// 길드를 가져온다.
	Guild* pGuild = g_pGuildManager->getGuild(pPacket->getGuildID());
	try { Assert(pGuild != NULL); } catch (Throwable& ) { return; }


	// 길드 활동 중인 상태에서의 해체인지 대기 중인 상태에서의 해체인지 구별한다.
	if (pGuild->getState() == Guild::GUILD_STATE_ACTIVE )
	{
		HashMapGuildMember& Members = pGuild->getMembers();
		HashMapGuildMemberItor itr = Members.begin();

		for (; itr != Members.end(); itr++ )
		{
			GuildMember* pGuildMember = itr->second;

			// 접속해 있으면
			__ENTER_CRITICAL_SECTION((*g_pPCFinder))

			Creature* pCreature = g_pPCFinder->getCreature_LOCKED(pGuildMember->getName());
			if (pCreature != NULL && pCreature->isPC() )
			{
				Player* pPlayer = pCreature->getPlayer();
				Assert(pPlayer != NULL);

				PlayerCreature* pPlayerCreature = dynamic_cast<PlayerCreature*>(pCreature);
				Assert(pPlayerCreature != NULL);

				// Slayer, Vampire 의 길드 아이디를 바꾼다.
				if (pPlayerCreature->isSlayer() )
				{
					pPlayerCreature->setGuildID(99);		// 슬레이어 가입안한 상태의 길드 ID

					// 클라이언트에 길드 아이디가 바꼈음을 알린다.
					GCModifyGuildMemberInfo gcModifyGuildMemberInfo;
					gcModifyGuildMemberInfo.setGuildID(pPlayerCreature->getGuildID());
					gcModifyGuildMemberInfo.setGuildName("");
					gcModifyGuildMemberInfo.setGuildMemberRank(GuildMember::GUILDMEMBER_RANK_DENY);
					pPlayer->sendPacket(&gcModifyGuildMemberInfo);
				}
				else if (pPlayerCreature->isVampire() )
				{
					pPlayerCreature->setGuildID(0);		// 뱀파이어 가입안한 상태의 길드 ID

					// 클라이언트에 길드 아이디가 바꼈음을 알린다.
					GCModifyGuildMemberInfo gcModifyGuildMemberInfo;
					gcModifyGuildMemberInfo.setGuildID(pPlayerCreature->getGuildID());
					gcModifyGuildMemberInfo.setGuildName("");
					gcModifyGuildMemberInfo.setGuildMemberRank(GuildMember::GUILDMEMBER_RANK_DENY);
					pPlayer->sendPacket(&gcModifyGuildMemberInfo);
				}
				else if (pPlayerCreature->isOusters() )
				{
					pPlayerCreature->setGuildID(66);		// 아우스터즈 가입안한 상태의 길드 ID

					// 클라이언트에 길드 아이디가 바꼈음을 알린다.
					GCModifyGuildMemberInfo gcModifyGuildMemberInfo;
					gcModifyGuildMemberInfo.setGuildID(pPlayerCreature->getGuildID());
					gcModifyGuildMemberInfo.setGuildName("");
					gcModifyGuildMemberInfo.setGuildMemberRank(GuildMember::GUILDMEMBER_RANK_DENY);
					pPlayer->sendPacket(&gcModifyGuildMemberInfo);
				}

				// 주위에 클라이언트에 길드 아이디가 바꼈음을 알린다.
				GCOtherModifyInfo gcOtherModifyInfo;
				gcOtherModifyInfo.setObjectID(pCreature->getObjectID());
				gcOtherModifyInfo.addShortData(MODIFY_GUILDID, pPlayerCreature->getGuildID());

				Zone* pZone = pCreature->getZone();
				Assert(pZone != NULL);

				pZone->broadcastPacket(pCreature->getX(), pCreature->getY(), &gcOtherModifyInfo, pCreature);
			}

			__LEAVE_CRITICAL_SECTION((*g_pPCFinder))

			// Guild Member 객체를 삭제한다.
			SAFE_DELETE(pGuildMember);
		}

		// 길드 멤버 맵을 삭제한다.
		Members.clear();

		// 길드 매니저에서 길드를 삭제한다.
		g_pGuildManager->deleteGuild(pGuild->getID());

		// 길드 객체를 삭제한다.
		SAFE_DELETE(pGuild);
	}
	else if (pGuild->getState() == Guild::GUILD_STATE_WAIT )
	{
		HashMapGuildMember& Members = pGuild->getMembers();
		HashMapGuildMemberItor itr = Members.begin();

		Statement* pStmt = NULL;
		Result* pResult = NULL;

		BEGIN_DB
		{
			pStmt = g_pDatabaseManager->getConnection("DARKEDEN" )->createStatement();
			
			for (; itr != Members.end(); itr++ )
			{
				GuildMember* pGuildMember = itr->second;

				// 접속해 있으면
				__ENTER_CRITICAL_SECTION((*g_pPCFinder))

				Creature* pCreature = g_pPCFinder->getCreature_LOCKED(pGuildMember->getName());
				if (pCreature != NULL && pCreature->isPC() )
				{
					Player* pPlayer = pCreature->getPlayer();
					Assert(pPlayer != NULL);

					PlayerCreature* pPlayerCreature = dynamic_cast<PlayerCreature*>(pCreature);
					Assert(pPlayerCreature != NULL);

					// 등록비를 환불한다.
					Gold_t Gold = pPlayerCreature->getGold();
					if (pGuildMember->getRank() == GuildMember::GUILDMEMBER_RANK_MASTER )
					{
						Gold = min((uint64_t)(Gold + RETURN_SLAYER_MASTER_GOLD), (uint64_t)2000000000);
					}
					else if (pGuildMember->getRank() == GuildMember::GUILDMEMBER_RANK_SUBMASTER )
					{
						Gold = min((uint64_t)(Gold + RETURN_SLAYER_SUBMASTER_GOLD), (uint64_t)2000000000);
					}

					pPlayerCreature->setGoldEx(Gold);

					GCModifyInformation gcModifyInformation;
					gcModifyInformation.addLongData(MODIFY_GOLD, Gold);
					pPlayer->sendPacket(&gcModifyInformation);

					// 메시지를 보낸다.
					pResult = pStmt->executeQuery("SELECT Message FROM Messages WHERE Receiver = '%s'", pCreature->getName().c_str());

					while (pResult->next() )
					{
						GCSystemMessage message;
						message.setMessage(pResult->getString(1));
						pPlayer->sendPacket(&message);
					}

					pStmt->executeQuery("DELETE FROM Messages WHERE Receiver = '%s'", pCreature->getName().c_str());
				}

				__LEAVE_CRITICAL_SECTION((*g_pPCFinder))

				// 길드 멤버 객체를 삭제한다.
				SAFE_DELETE(pGuildMember);
			}

			// 길드 멤버 해쉬 맵을 지운다.
			Members.clear();

			// 길드 매니저에서 길드를 삭제한다.
			g_pGuildManager->deleteGuild(pGuild->getID());
			GuildUnionManager::Instance().removeMasterGuild(pGuild->getID());

			// 길드 객체를 삭제한다.
			SAFE_DELETE(pGuild);

			SAFE_DELETE(pStmt);
		}
		END_DB(pStmt)
	}
void CGRequestUnionInfoHandler::execute (CGRequestUnionInfo* pPacket , Player* pPlayer)
	 throw(Error)
{
	__BEGIN_TRY __BEGIN_DEBUG_EX
		
#ifdef __GAME_SERVER__

	Assert(pPacket != NULL);
	Assert(pPlayer != NULL);

	SYSTEM_ASSERT(SYSTEM_GUILD);

	GamePlayer* pGamePlayer = dynamic_cast<GamePlayer*>(pPlayer);
	Assert(pGamePlayer != NULL);

	PlayerCreature* pPlayerCreature = dynamic_cast<PlayerCreature*>(pGamePlayer->getCreature());
	Assert(pPlayerCreature != NULL);

#ifdef __OLD_GUILD_WAR__
	GCSystemMessage gcSM;
	gcSM.setMessage("아직 지원되지 않는 기능입니다.");
	pGamePlayer->sendPacket(&gcSM);
	return;
#endif

	GCGuildResponse gcGuildResponse;
	
	GuildUnion	*pGuildUnion	= GuildUnionManager::Instance().getGuildUnion(pPlayerCreature->getGuildID());
	// 자기가 속한 길드가 연합에 가입되어있는지 찾는다
	if (pGuildUnion == NULL)
	{
	
		gcGuildResponse.setCode(GuildUnionOfferManager::NOT_IN_UNION);
		pPlayer->sendPacket(&gcGuildResponse);

		return;
	}

	// Master 길드의 정보를 가져온다.
	Guild* pGuild = g_pGuildManager->getGuild(pGuildUnion->getMasterGuildID());

	if (pGuild == NULL)
	{
		gcGuildResponse.setCode(GuildUnionOfferManager::NO_TARGET_UNION);
		pPlayer->sendPacket(&gcGuildResponse);
	
		return;
	}

	
	GCShowUnionInfo	gcShowUnionInfo;
	
	if (pGuild->getState() == Guild::GUILD_STATE_ACTIVE )
	{
		
		gcShowUnionInfo.getMasterGuildInfo().setGuildID(pGuild->getID());
		gcShowUnionInfo.getMasterGuildInfo().setGuildName(pGuild->getName());
		gcShowUnionInfo.getMasterGuildInfo().setGuildState(pGuild->getState());
		gcShowUnionInfo.getMasterGuildInfo().setGuildMaster(pGuild->getMaster());
		gcShowUnionInfo.getMasterGuildInfo().setGuildMemberCount(pGuild->getActiveMemberCount());
		gcShowUnionInfo.getMasterGuildInfo().setGuildIntro(pGuild->getIntro());
		gcShowUnionInfo.getMasterGuildInfo().setJoinFee(0);
	}

	list<GuildID_t> gList = pGuildUnion->getGuildList();
	list<GuildID_t>::iterator itr = gList.begin();
	for (; itr != gList.end() ; ++itr )
    {

		Guild*	pGuild2	= g_pGuildManager->getGuild(*itr); 
		if(pGuild2 != NULL)
		{
			SingleGuildInfo	*GuildInfo	= new SingleGuildInfo;
			
			GuildInfo->setGuildID(pGuild2->getID());
			GuildInfo->setGuildName(pGuild2->getName());
			GuildInfo->setGuildState(pGuild2->getState());
			GuildInfo->setGuildMaster(pGuild2->getMaster());
			GuildInfo->setGuildMemberCount(pGuild2->getActiveMemberCount());
			GuildInfo->setGuildIntro(pGuild2->getIntro());
			GuildInfo->setJoinFee(0);

			gcShowUnionInfo.addGuildInfoList(GuildInfo);
		}
    }
	
	pPlayer->sendPacket(&gcShowUnionInfo);
	
#endif	// __GAME_SERVER__
		
	__END_DEBUG_EX __END_CATCH
}
void EffectRelicPosition::affect(Item* pItem)
	throw(Error)
{
	__BEGIN_TRY

	// 존 정보를 얻는다.
	ZoneInfo* pZoneInfo = g_pZoneInfoManager->getZoneInfo(m_ZoneID);
	Assert(pZoneInfo != NULL);

	if (pItem->getItemClass() == Item::ITEM_CLASS_RELIC)
	{
		// 성물의 정보를 얻는다.
		ItemType_t relicIndex = pItem->getItemType();
		const RelicInfo* pRelicInfo = dynamic_cast<RelicInfo*>(g_pRelicInfoManager->getItemInfo(relicIndex));
		Assert(pRelicInfo != NULL);

//		StringStream msg;

/*		// 위치를 알린다.
		msg << "성물(" << pRelicInfo->getName() << ")이 "
			<< pZoneInfo->getFullName() << "(" << (int)m_X << ", " << (int)m_Y << ")에 떨어져 있습니다."; */

		char msg[100];

		sprintf(msg, g_pStringPool->c_str(STRID_RELIC_IN_ZONE ),
						pRelicInfo->getName().c_str(),
						pZoneInfo->getFullName().c_str(),
						(int)m_X,
						(int)m_Y
		);

		GCSystemMessage gcSystemMessage;
		gcSystemMessage.setType(SYSTEM_MESSAGE_COMBAT);
		gcSystemMessage.setMessage(msg);

		g_pHolyLandManager->broadcast(&gcSystemMessage);

		setNextTime(m_Tick);
	}
	else if (pItem->getItemClass() == Item::ITEM_CLASS_BLOOD_BIBLE)
	{
		ShrineSet* pShrineSet = g_pShrineInfoManager->getShrineSet(m_Part);
		Assert(pShrineSet!=NULL);

		GCBloodBibleStatus* pGCBBS = new GCBloodBibleStatus;
		pGCBBS->setItemType(m_Part);
		pGCBBS->setZoneID(m_ZoneID);
		pGCBBS->setStorage(STORAGE_ZONE);
		//pGCBBS->setRace(pShrineSet->getOwnerRace());
		pGCBBS->setShrineRace(pShrineSet->getOwnerRace());
		pGCBBS->setX(m_X);
		pGCBBS->setY(m_Y);

//		g_pHolyLandManager->broadcast(pGCBBS);
		g_pZoneGroupManager->broadcast(pGCBBS);
		g_pShrineInfoManager->registerBloodBibleStatus(m_Part, pGCBBS);
		/*
		msg << "피의 성서 조각이 "
			<< pZoneInfo->getFullName() << "(" << (int)m_X << ", " << (int)m_Y << ")에 떨어져 있습니다.";

		g_pZoneGroupManager->broadcast(&gcSystemMessage);
		*/

		setNextTime(999999);
	}
	else if (pItem->getItemClass() == Item::ITEM_CLASS_CASTLE_SYMBOL)
	{
//		StringStream msg;

//		msg << "성의 상징이 "
//			<< pZoneInfo->getFullName() << "(" << (int)m_X << ", " << (int)m_Y << ")에 떨어져 있습니다.";

		char msg[200];
		sprintf(msg, g_pStringPool->c_str(STRID_BROADCAST_CASTLE_SYMBOL_POSITION_3 ),
						pZoneInfo->getFullName().c_str(), (int)m_X, (int)m_Y);

		GCSystemMessage gcSystemMessage;
		gcSystemMessage.setType(SYSTEM_MESSAGE_HOLY_LAND);
		gcSystemMessage.setMessage(msg);

		g_pCastleInfoManager->broadcastShrinePacket(m_Part, &gcSystemMessage);

		setNextTime(m_Tick);
//		g_pZoneGroupManager->broadcast(&gcSystemMessage);
	}
	else
	{
		return;
	}


	__END_CATCH
}
////////////////////////////////////////////////////////////////////////////////
// 액션을 실행한다.
////////////////////////////////////////////////////////////////////////////////
void ActionWarpToNoviceZone::execute (Creature * pNPC , Creature * pCreature) 
	throw(Error)
{
	__BEGIN_TRY
	__BEGIN_DEBUG

	Assert(pCreature != NULL);
	Assert(pCreature->isPC());

	if (!pCreature->isSlayer() ) return;

	Slayer* pSlayer = dynamic_cast<Slayer*>(pCreature);

	ZoneID_t ZoneID = pSlayer->getZoneID();
	ZoneCoord_t	X = pSlayer->getX();
	ZoneCoord_t Y = pSlayer->getY();
	Attr_t totalAttr = pSlayer->getTotalAttr(ATTR_BASIC);

	GamePlayer* pGamePlayer = dynamic_cast<GamePlayer*>(pCreature->getPlayer());

	bool bTransport = true;

	if (totalAttr <= 40 )
	{
		ZoneID = m_NoviceZoneID;
		X = m_NoviceX;
		Y = m_NoviceY;
	}
	else if (totalAttr <= 60 )
	{
		ZoneID = m_BeginnerZoneID;
		X = m_BeginnerX;
		Y = m_BeginnerY;
	}
	else
	{
		GCSystemMessage gcSystemMessage;
		gcSystemMessage.setMessage(g_pStringPool->getString(STRID_NOT_BEGINNER ));
		pGamePlayer->sendPacket (&gcSystemMessage);

		bTransport = false;
	}

	//Zone* pZone = pCreature->getZone();


#if defined(__PAY_SYSTEM_ZONE__) || defined(__PAY_SYSTEM_FREE_LIMIT__)
	try {

		ZoneInfo* pZoneInfo = g_pZoneInfoManager->getZoneInfo(ZoneID);

		// 유료존인데 유료사용자가 아니면...
		if (pZoneInfo==NULL
			|| pZoneInfo->isPayPlay() && !pGamePlayer->isPayPlaying())
		{
			string connectIP = pGamePlayer->getSocket()->getHost();

			// 유료 서비스 사용이 가능한가?
			if (pGamePlayer->loginPayPlay(connectIP, pGamePlayer->getID()))
			{
				sendPayInfo(pGamePlayer);
			}
			else
			{
				// 유료 서비스 사용 불가인 경우
				GCSystemMessage gcSystemMessage;

				if (g_pConfig->getPropertyInt("IsNetMarble")==0)
				{
					gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CANNOT_ENTER_PAY_ZONE));
				}
				else
				{
					gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CANNOT_ENTER));
				}

				pGamePlayer->sendPacket (&gcSystemMessage);

				bTransport = false;
			}
		}
	} catch (NoSuchElementException&) {
	}
#endif

	if (bTransport)
	{
		transportCreature(pCreature, ZoneID, X, Y, true);
	}
	else
	{
		if (pNPC != NULL )
		{
			GCNPCResponse response;
			response.setCode(NPC_RESPONSE_QUIT_DIALOGUE);
			pGamePlayer->sendPacket(&response);
		}
	}

	__END_DEBUG
	__END_CATCH
}
////////////////////////////////////////////////////////////////////////////////
// 액션을 실행한다.
////////////////////////////////////////////////////////////////////////////////
void ActionActivatePortal::execute (Creature * pNPC , Creature * pCreature) 
	throw(Error)
{
	__BEGIN_TRY
	__BEGIN_DEBUG

	Assert(pCreature != NULL);
	Assert(pCreature->isPC());

	GamePlayer* pGamePlayer = dynamic_cast<GamePlayer*>(pCreature->getPlayer());
	PlayerCreature* pPC = dynamic_cast<PlayerCreature*>(pCreature);
	//Zone* pZone = pCreature->getZone();

	bool bTransport = true;

#if defined(__PAY_SYSTEM_ZONE__) || defined(__PAY_SYSTEM_FREE_LIMIT__)
	try {

		ZoneInfo* pZoneInfo = g_pZoneInfoManager->getZoneInfo(m_ZoneID);

		// 유료존인데 유료사용자가 아니면...
		if (pZoneInfo==NULL
			|| pZoneInfo->isPayPlay() && !pGamePlayer->isPayPlaying())
		{
			string connectIP = pGamePlayer->getSocket()->getHost();

			// 유료 서비스 사용이 가능한가?
			if (pGamePlayer->loginPayPlay(connectIP, pGamePlayer->getID()))
			{
				sendPayInfo(pGamePlayer);
			}
			else if (!pGamePlayer->isFamilyFreePass() ) // 패밀리 프리 패스는 유료존으로 갈 수 있다.
			{
				// 유료 서비스 사용 불가인 경우
				GCSystemMessage gcSystemMessage;

				if (g_pConfig->getPropertyInt("IsNetMarble")==0)
				{
					gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CANNOT_ENTER_PAY_ZONE));
				}
				else
				{
					gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CANNOT_ENTER));
				}

				pGamePlayer->sendPacket (&gcSystemMessage);

				bTransport = false;
			}
		}
	} catch (NoSuchElementException&) {
	}
#endif

	if (bTransport)
	{
		if (m_ZoneID == 1410 )
		{
			if (pCreature->isFlag(Effect::EFFECT_CLASS_CAN_ENTER_GDR_LAIR ) )
			{
				Effect* pEffect = pCreature->findEffect(Effect::EFFECT_CLASS_CAN_ENTER_GDR_LAIR);
				if (pEffect != NULL ) pEffect->setDeadline(0);
			}

			if (pCreature->isSlayer() )
			{
				Slayer* pSlayer = dynamic_cast<Slayer*>(pCreature);
				Assert(pSlayer != NULL);

				// 오토바이를 타고 있으면 오토바이에서 내린다.
				if (pSlayer->hasRideMotorcycle() )
				{
					pSlayer->getOffMotorcycle();
				}
			}

			if (pCreature->isOusters() )
			{
				Ousters* pOusters = dynamic_cast<Ousters*>(pCreature);
				Assert(pOusters != NULL);

				// 실프 타고 있으면 내려준다
				if (pOusters->isFlag(Effect::EFFECT_CLASS_SUMMON_SYLPH) )
				{
					Effect* pEffect = pOusters->findEffect(Effect::EFFECT_CLASS_SUMMON_SYLPH);
					if (pEffect != NULL ) pEffect->setDeadline(0);
				}
			}

			if (pCreature->isVampire() )
			{
				Vampire* pVampire = dynamic_cast<Vampire*>(pCreature);
				Assert(pVampire != NULL);

				if (pVampire->isFlag(Effect::EFFECT_CLASS_TRANSFORM_TO_BAT) )
				{
					addUntransformCreature(pVampire->getZone(), pVampire, true);
				}
			}
		}

		if (pNPC != NULL )
		{
			pPC->getGQuestManager()->illegalWarp();
		}

		transportCreature(pCreature, m_ZoneID, m_X, m_Y, true);
	}
	else
	{
	    GCNPCResponse response;
	    response.setCode(NPC_RESPONSE_QUIT_DIALOGUE);
	    pGamePlayer->sendPacket(&response);
	}

	__END_DEBUG
	__END_CATCH
}
void CGModifyTaxRatioHandler::execute (CGModifyTaxRatio* pPacket , Player* pPlayer)
	 throw(Error)
{
	__BEGIN_TRY __BEGIN_DEBUG_EX
		
#ifdef __GAME_SERVER__

	Assert(pPacket != NULL);
	Assert(pPlayer != NULL);

	GamePlayer* pGamePlayer = dynamic_cast<GamePlayer*>(pPlayer);
	Assert(pGamePlayer != NULL);

	PlayerCreature* pPC = dynamic_cast<PlayerCreature*>(pGamePlayer->getCreature());
	Assert(pPC != NULL);

#ifdef __OLD_GUILD_WAR__
	GCSystemMessage gcSM;
	gcSM.setMessage("아직 지원되지 않는 기능입니다.");
	pGamePlayer->sendPacket(&gcSM);
	return;
#endif

	GuildID_t guildID = pPC->getGuildID();

	list<CastleInfo*> pCastleInfoList = g_pCastleInfoManager->getGuildCastleInfos(guildID);
	if (pCastleInfoList.empty() )
	{
		GCNPCResponse fail;
		fail.setCode(NPC_RESPONSE_MODIFY_TAX_RATIO_FAIL);

		pGamePlayer->sendPacket(&fail);
		return;
	}

	bool bOwner = false;
	list<CastleInfo*>::iterator itr = pCastleInfoList.begin();
	CastleInfo* pCastleInfo = NULL;
	for (; itr != pCastleInfoList.end() ; itr++ )
	{
		if ((*itr)->getZoneID() == pPC->getZoneID() )
		{
			pCastleInfo = (*itr);
			bOwner = true;
			break;
		}
	}

	if (!g_pGuildManager->isGuildMaster(guildID, pPC )	// 길드 마스터가 아니다.
		|| !bOwner											// 이 플레이어의 길드가 점령한 성이 아니다.
		|| pPacket->getRatio() > 10
	)
	{
		GCNPCResponse fail;
		fail.setCode(NPC_RESPONSE_MODIFY_TAX_RATIO_FAIL);

		pGamePlayer->sendPacket(&fail);
		return;
	}

	g_pCastleInfoManager->setItemTaxRatio(pPC->getZone(), pPacket->getRatio()+100);
	GCNPCResponse ok;
	ok.setCode(NPC_RESPONSE_MODIFY_TAX_RATIO_OK);
	pGamePlayer->sendPacket(&ok);
	
#endif	// __GAME_SERVER__
		
	__END_DEBUG_EX __END_CATCH
}
void EffectHasVampireRelic::affect(Creature* pCreature)
	throw(Error)
{
	__BEGIN_TRY
																															    	
	//Timeval      nextTime   = getNextTime();
	//Timeval      deadLine   = getDeadline();
	//Turn_t       RemainTime = deadLine.tv_sec - nextTime.tv_sec;
	/*
	StringStream msg;

	if (pCreature->isSlayer())
	{
		Slayer* pSlayer = dynamic_cast<Slayer*>(pCreature);

		msg << pSlayer->getName();
	}
	else
	{
		Vampire* pVampire = dynamic_cast<Vampire*>(pCreature);

		msg << pVampire->getName();
	}

	msg << " 님이 뱀파이어 성물을 가졌습니다.";

	GCSystemMessage gcSystemMessage;
	gcSystemMessage.setMessage(msg.toString());

	g_pZoneGroupManager->broadcast(&gcSystemMessage);
	*/
	// 존 정보를 얻는다.
	Zone* pZone = pCreature->getZone();
	Assert(pZone!=NULL);

	ZoneInfo* pZoneInfo = g_pZoneInfoManager->getZoneInfo(pZone->getZoneID());
	Assert(pZoneInfo != NULL);

    // 위치를 알린다.
    char msg[100];

	const char* race;
	if (pCreature->isSlayer() )
	{
		race = g_pStringPool->c_str(STRID_SLAYER);
	}
	else if (pCreature->isVampire() )
	{
		race = g_pStringPool->c_str(STRID_VAMPIRE);
	}
	else if (pCreature->isOusters() )
	{
		race = g_pStringPool->c_str(STRID_OUSTERS);
	}

    sprintf(msg, g_pStringPool->c_str(STRID_HAVING_VAMPIRE_RELIC ),
                pCreature->getName().c_str(),
				race,
//                (pCreature->isSlayer() ? g_pStringPool->c_str(STRID_SLAYER ) : g_pStringPool->c_str(STRID_VAMPIRE ) ),
                (int)pCreature->getX(),
                (int)pCreature->getY()
   );

/*	// 위치를 알린다.
	StringStream msg;
	msg << pCreature->getName() << " 님(" << (pCreature->isSlayer() ? "슬레이어" : "뱀파이어" ) << ")이 " 
		<< pZoneInfo->getFullName() << "(" << (int)pCreature->getX() << ", " << (int)pCreature->getY()
		<< ")에서 뱀파이어 성물을 가지고 있습니다."; */

	GCSystemMessage gcSystemMessage;
	gcSystemMessage.setMessage(msg);

	g_pZoneGroupManager->broadcast(&gcSystemMessage);

	setNextTime(m_Tick);

	__END_CATCH
}
////////////////////////////////////////////////////////////////////////////////
// 액션을 실행한다.
////////////////////////////////////////////////////////////////////////////////
void ActionEnterGDRLair::execute (Creature * pNPC , Creature * pCreature) 
	throw(Error)
{
	__BEGIN_TRY
	__BEGIN_DEBUG

	Assert(pCreature != NULL);
	Assert(pCreature->isPC());

	GamePlayer* pGamePlayer = dynamic_cast<GamePlayer*>(pCreature->getPlayer());
	PlayerCreature* pPC = dynamic_cast<PlayerCreature*>(pCreature);

	Assert(pPC != NULL);

	ZoneID_t zoneID;
	ZoneCoord_t X, Y;

	if (m_PortalID == GDRLairManager::Instance().getCorrectPortal() )
	{
		zoneID = 1412;
		X = 142;
		Y = 169;
	}
	else
	{
		zoneID = 1411;
		X = 125;
		Y = 58;
	}

	bool bTransport = true;
#if defined(__PAY_SYSTEM_ZONE__) || defined(__PAY_SYSTEM_FREE_LIMIT__)
	try {

		ZoneInfo* pZoneInfo = g_pZoneInfoManager->getZoneInfo(zoneID);

		// 유료존인데 유료사용자가 아니면...
		if (pZoneInfo==NULL
			|| pZoneInfo->isPayPlay() && !pGamePlayer->isPayPlaying())
		{
			string connectIP = pGamePlayer->getSocket()->getHost();

			// 유료 서비스 사용이 가능한가?
			if (pGamePlayer->loginPayPlay(connectIP, pGamePlayer->getID()))
			{
				sendPayInfo(pGamePlayer);
			}
			else
			{
				// 유료 서비스 사용 불가인 경우
				GCSystemMessage gcSystemMessage;

				if (g_pConfig->getPropertyInt("IsNetMarble")==0)
				{
					gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CANNOT_ENTER_PAY_ZONE ));
				}
				else
				{
					gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CANNOT_ENTER ));
				}

				pGamePlayer->sendPacket (&gcSystemMessage);

				bTransport = false;

				return;
			}
		}
	} catch (NoSuchElementException&) {
	}
#endif

	if (bTransport)
	{
		if (pPC->isSlayer() )
		{
			Slayer* pSlayer = dynamic_cast<Slayer*>(pPC);
			Assert(pSlayer != NULL);

			// 오토바이를 타고 있으면 오토바이에서 내린다.
			if (pSlayer->hasRideMotorcycle() )
			{
				pSlayer->getOffMotorcycle();
			}
		}

		if (pPC->isOusters() )
		{
			Ousters* pOusters = dynamic_cast<Ousters*>(pPC);
			Assert(pOusters != NULL);

			// 실프 타고 있으면 내려준다
			if (pOusters->isFlag(Effect::EFFECT_CLASS_SUMMON_SYLPH) )
			{
				Effect* pEffect = pOusters->findEffect(Effect::EFFECT_CLASS_SUMMON_SYLPH);
				if (pEffect != NULL ) pEffect->setDeadline(0);
			}
		}

		if (pPC->isVampire() )
		{
			Vampire* pVampire = dynamic_cast<Vampire*>(pPC);
			Assert(pVampire != NULL);

			if (pVampire->isFlag(Effect::EFFECT_CLASS_TRANSFORM_TO_BAT) )
			{
				addUntransformCreature(pVampire->getZone(), pVampire, true);
			}
		}

		Effect* pEffect = pPC->findEffect(Effect::EFFECT_CLASS_CAN_ENTER_GDR_LAIR);
		if (pEffect != NULL ) pEffect->setDeadline(0);

		transportCreature(pCreature, zoneID, X, Y, true);
	}
	else
	{
		GCSystemMessage gcSystemMessage;
		gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CANNOT_ENTER ));
		pGamePlayer->sendPacket (&gcSystemMessage);
	}

	__END_DEBUG
	__END_CATCH
}
Exemple #23
0
////////////////////////////////////////////////////////////////////////////////
// 액션을 실행한다.
////////////////////////////////////////////////////////////////////////////////
void ActionEnterSiege::execute (Creature * pNPC , Creature * pCreature) 
	throw(Error)
{
	__BEGIN_TRY
	__BEGIN_DEBUG

	Assert(pCreature != NULL);
	Assert(pCreature->isPC());

	GamePlayer* pGamePlayer = dynamic_cast<GamePlayer*>(pCreature->getPlayer());
	if (!g_pWarSystem->hasCastleActiveWar(m_ZoneID ) )
	{
		GCSystemMessage gcSM;
		gcSM.setMessage("공선전 중에만 입장하실 수 있습니다.");
		pGamePlayer->sendPacket(&gcSM);
		return;
	}

	PlayerCreature* pPC = dynamic_cast<PlayerCreature*>(pCreature);

	Assert(pPC != NULL);

	Zone* pZone = getZoneByZoneID(m_ZoneID);
	Assert(pZone != NULL);

	WarScheduler* pWS = pZone->getWarScheduler();
	Assert(pWS != NULL);

	ZoneID_t siegeZoneID = SiegeManager::Instance().getSiegeZoneID(m_ZoneID);
	Assert(siegeZoneID != 0);

/*	WarSchedule* pSchedule = dynamic_cast<WarSchedule*>(pWS->getRecentSchedule());
	if (pSchedule == NULL )
	{
		return;
	}*/

	SiegeWar* pSiegeWar = dynamic_cast<SiegeWar*>(g_pWarSystem->getActiveWar(m_ZoneID ));
	if (pSiegeWar == NULL )
	{
		GCSystemMessage gcSM;
		gcSM.setMessage("타입 1 서버 오류입니다. 운영팀에 문의하세요.");
		pGamePlayer->sendPacket(&gcSM);
		return;
	}

	int side = pSiegeWar->getGuildSide(pPC->getGuildID());
	if (side == 0 )
	{
		GCSystemMessage gcSM;
		gcSM.setMessage("전쟁에 참가한 길드가 아닙니다.");
		pGamePlayer->sendPacket(&gcSM);
		return;
	}
	
	if (!g_pGuildManager->isGuildMaster(pPC->getGuildID(), pPC ) )
	{
		GCSystemMessage gcSM;
		gcSM.setMessage("길드 마스터만 가능합니다.");
		pGamePlayer->sendPacket(&gcSM);
		return;
	}

	static TPOINT targetPos[7] =
	{
		{172, 38},
		{172, 38},
		{20, 232},
		{20, 232},
		{20, 232},
		{20, 232},
		{20, 232}
	};

	// 소환자의 존과 좌표.
	ZoneID_t ZoneNum = siegeZoneID;
	Coord_t ZoneX = targetPos[side-1].x;
	Coord_t ZoneY = targetPos[side-1].y;

	for (int i=0; i<7; ++i )
	{
		deleteCreatureEffect(pPC, (Effect::EffectClass)(Effect::EFFECT_CLASS_SIEGE_DEFENDER + i));
	}

	if (side < 8 && side > 0 )
	{
		//cout << "side : " << side << endl;
		addSimpleCreatureEffect(pPC, (Effect::EffectClass)(Effect::EFFECT_CLASS_SIEGE_DEFENDER + side - 1));
	}

	EventTransport* pEvent = dynamic_cast<EventTransport*>(pGamePlayer->getEvent(Event::EVENT_CLASS_TRANSPORT));
	bool newEvent = false;
	if (pEvent==NULL)
	{
		pEvent = new EventTransport(pGamePlayer);
		newEvent = true;
	}

//		pEvent = new EventTransport(pGamePlayer);
	pEvent->setTargetZone(ZoneNum, ZoneX, ZoneY);
	pEvent->setDeadline(0);

	if (newEvent )
		pGamePlayer->addEvent(pEvent);

	__END_DEBUG
	__END_CATCH
}
////////////////////////////////////////////////////////////////////////////////
// 액션을 실행한다.
////////////////////////////////////////////////////////////////////////////////
void ActionTradeLairItem::execute(Creature * pCreature1 , Creature * pCreature2) 
	throw(Error)
{
	__BEGIN_TRY

	Assert(pCreature1 != NULL);
	Assert(pCreature2 != NULL);
	Assert(pCreature1->isNPC());
	Assert(pCreature2->isPC());

	if (m_Type <= 5 )
	{
		SYSTEM_RETURN_IF_NOT(SYSTEM_MASTER_LAIR);
	}

	PlayerCreature* pPC = dynamic_cast<PlayerCreature*>(pCreature2);
	Assert(pPC != NULL);

	Player* pPlayer = pPC->getPlayer();
	Assert(pPlayer != NULL);

	GCNPCResponse okpkt;
	pPlayer->sendPacket(&okpkt);
	StringStream message;

	/*

	GCSystemMessage gcSystemMessage;
	gcSystemMessage.setMessage("아직 지원되지 않는 기능입니다");
	pPlayer->sendPacket(&gcSystemMessage);
	*/


	//cout << "ActionTradeLairItem" << ":" << m_Type;

	Inventory* pInventory = pPC->getInventory();

	// 먼저 아이템을 가지고 있는가를 체크한다.
	Item* pMasterItem = NULL;
	MonsterType_t MonsterType = 0;

	Item* pItem1 = NULL;
	bool bUpgrade = false;
	
	// 옵션에 따라서 다른 아이템을 검사해야 한다.
	// 코난 : 팬던트/ 비쥬만 체크한다.
	// 브리콜라카스: 테페즈 펜던트/비쥬만 체크해야 한다
	// 카임 : 바토리 팬던트/비쥬만 체크해야 한다.

	if (m_Type == 0) // 코난, 비쥬
	{
		pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 0);
		MonsterType = BATORI_TYPE;

		if (pMasterItem == NULL )
		{
			pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 2);
			MonsterType = TEPEZ_TYPE;
			if (pMasterItem == NULL )
			{
				pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 8); //질드레 비쥬
				MonsterType = GDR_TYPE;
				bUpgrade = true;
			}
		}
	}
	else if (m_Type == 1) // 코난, 팬던트
	{
		pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 1);
		MonsterType = BATORI_TYPE;

		if (pMasterItem == NULL)
		{
			pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 3);
			MonsterType = TEPEZ_TYPE;
			if (pMasterItem == NULL )
			{
				pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 9); //질드레 펜던트
				MonsterType = GDR_TYPE;
				bUpgrade = true;
			}
		}
	}
	else if (m_Type == 2) // 브리콜라카스, 비쥬
	{
		pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 2);
//		if (pMasterItem == NULL ) pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 8); //질드레 비쥬
		MonsterType = TEPEZ_TYPE;
	}
	else if (m_Type == 3) // 브리콜라카스, 팬던트
	{
		pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 3);
//		if (pMasterItem == NULL ) pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 9); //질드레 펜던트
		MonsterType = TEPEZ_TYPE;
	}
	else if (m_Type == 4) // 카임, 비쥬
	{
		pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 0);
//		if (pMasterItem == NULL ) pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 8); //질드레 비쥬
		MonsterType = BATORI_TYPE;
	}
	else if (m_Type == 5) // 카임, 팬던트
	{
		pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 1);
//		if (pMasterItem == NULL ) pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 9); //질드레 펜던트
		MonsterType = BATORI_TYPE;
	}
	else if (m_Type == 10) // 질드레, 비쥬
	{
		pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 8);
		bUpgrade = true;
		MonsterType = GDR_TYPE;
	}
	else if (m_Type == 11) // 질드레, 팬던트
	{
		pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 9);
		bUpgrade = true;
		MonsterType = GDR_TYPE;
	}
	else if (m_Type == 6) // 젬스톤이지롱~
	{
		pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 4);
		MonsterType = BATORI_TYPE;
	}
	else if (m_Type == 7) // 보름달~
	{
		pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 5);
		ItemMineInfo* pItemMineInfo;

		if (pPC->isSlayer() )
		{
			Slayer* pSlayer = dynamic_cast<Slayer*>(pPC);
			Assert(pSlayer != NULL);

			Attr_t totalAttr = pSlayer->getTotalAttr(ATTR_BASIC);

			if (totalAttr <= 130 )	// 하드코딩 ㅜ.ㅠ
				pItemMineInfo = g_pItemMineInfoManager->getItemMineInfo(0);
			else if (totalAttr <= 210 )
				pItemMineInfo = g_pItemMineInfoManager->getItemMineInfo(1);
			else if (totalAttr <= 270 )
				pItemMineInfo = g_pItemMineInfoManager->getItemMineInfo(2);
			else if (totalAttr <= 300 )
				pItemMineInfo = g_pItemMineInfoManager->getItemMineInfo(3);
			else
				pItemMineInfo = g_pItemMineInfoManager->getItemMineInfo(4);
		}
		else if (pPC->isVampire() )
		{
			Vampire* pVampire = dynamic_cast<Vampire*>(pPC);
			Assert(pVampire != NULL);

			Level_t level = pVampire->getLevel();

			if (level <= 20 )
				pItemMineInfo = g_pItemMineInfoManager->getItemMineInfo(5);
			else if (level <= 40 )
				pItemMineInfo = g_pItemMineInfoManager->getItemMineInfo(6);
			else if (level <= 60 )
				pItemMineInfo = g_pItemMineInfoManager->getItemMineInfo(7);
			else if (level <= 90 )
				pItemMineInfo = g_pItemMineInfoManager->getItemMineInfo(8);
			else
				pItemMineInfo = g_pItemMineInfoManager->getItemMineInfo(9);
		}
		else if (pPC->isOusters() )
		{
			Ousters* pOusters = dynamic_cast<Ousters*>(pPC);
			Assert(pOusters != NULL);

			Level_t level = pOusters->getLevel();

			if (level <= 20 )
				pItemMineInfo = g_pItemMineInfoManager->getItemMineInfo(10);
			else if (level <= 40 )
				pItemMineInfo = g_pItemMineInfoManager->getItemMineInfo(11);
			else if (level <= 60 )
				pItemMineInfo = g_pItemMineInfoManager->getItemMineInfo(12);
			else if (level <= 90 )
				pItemMineInfo = g_pItemMineInfoManager->getItemMineInfo(13);
			else
				pItemMineInfo = g_pItemMineInfoManager->getItemMineInfo(14);
		}
		else Assert(false);

		pItem1 = pItemMineInfo->getItem();
		setItemGender(pItem1, (pPC->getSex()==FEMALE)?GENDER_FEMALE:GENDER_MALE);
	}
	else if (m_Type == 8) // 그믐달~
	{
		pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 6);

		if (pPC->isSlayer() )
		{
			pItem1 = g_pItemMineInfoManager->getRandomItem(15, 32);
		}
		else if (pPC->isVampire() )
		{
			pItem1 = g_pItemMineInfoManager->getRandomItem(33, 45);
		}
		else if (pPC->isOusters() )
		{
			pItem1 = g_pItemMineInfoManager->getRandomItem(46, 61);
		}

		setItemGender(pItem1, (pPC->getSex()==FEMALE)?GENDER_FEMALE:GENDER_MALE);
	}
	else if (m_Type == 9) // 빨간색 복주머니
	{
		pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 7);

		if (pPC->isSlayer() )
		{
			pItem1 = g_pItemMineInfoManager->getRandomItem(62, 81);
		}
		else if (pPC->isVampire() )
		{
			pItem1 = g_pItemMineInfoManager->getRandomItem(82, 96);
		}
		else if (pPC->isOusters() )
		{
			pItem1 = g_pItemMineInfoManager->getRandomItem(97, 112);
		}
	}
	else
	{
		// 거래를 위한 NPC의 Property가 잘못되었다. 이런 경우에는
		// 운영팀으로 문의를 하면 바로 처리를 할 수 있다.
		GCSystemMessage gcSystemMessage;
		gcSystemMessage.setMessage(g_pStringPool->getString(STRID_NPC_ERROR ));
		pPlayer->sendPacket(&gcSystemMessage);

		GCNPCResponse response;
		response.setCode(NPC_RESPONSE_QUIT_DIALOGUE);
		pPlayer->sendPacket(&response);
		return;
	}
	
	if (pMasterItem == NULL)
	{
		GCSystemMessage gcSystemMessage;
		gcSystemMessage.setMessage(g_pStringPool->getString(STRID_NO_LAIR_ITEM ));
		pPlayer->sendPacket(&gcSystemMessage);

		GCNPCResponse response;
		response.setCode(NPC_RESPONSE_QUIT_DIALOGUE);
		pPlayer->sendPacket(&response);

		return;
	}

	Zone* pZone = pPC->getZone();

//	if (MonsterType != 0 ) // 루팅표를 참조해서 아이템을 만들어오는 경우
	if (pItem1 == NULL )
	{
		QuestItemInfo* pItemInfo = dynamic_cast<QuestItemInfo*>(g_pQuestItemInfoManager->getItemInfo(pMasterItem->getItemType() ));
		Assert(pItemInfo!=NULL);

		///////////////////////////////////////////////////////////////////////////////
		// 가장 난감한 부분
		//   아이템을 랜덤하게 선택해야 한다.
		//   일단은 기본 아이템 하나로 한다.
		//////////////////////////////////////////////////////////////////////////////
		const MonsterInfo* pMonsterInfo = g_pMonsterInfoManager->getMonsterInfo(MonsterType);
		TreasureList *pTreasureList = NULL;

		// 종족에 따라서 주는 아이템도 달라야 한다.
		if (pCreature2->isSlayer())
			pTreasureList = pMonsterInfo->getSlayerTreasureList();
		else if (pCreature2->isVampire())
			pTreasureList = pMonsterInfo->getVampireTreasureList();
		else if (pCreature2->isOusters())
			pTreasureList = pMonsterInfo->getOustersTreasureList();

		const list<Treasure*>& treasures = pTreasureList->getTreasures();

		list<Treasure*>::const_iterator itr = treasures.begin();

		ITEM_TEMPLATE it;

		for(; itr != treasures.end(); itr++)
		{
			Treasure* pTreasure = (*itr);

			it.ItemClass = Item::ITEM_CLASS_MAX;
			it.ItemType = 0;

			// QuestItem 마다 다른.. 옵션이 2개 붙을 확률
			it.NextOptionRatio = pItemInfo->getBonusRatio();

			//cout << "TradeLairItem: BonusRatio = " << it.NextOptionRatio << endl;

			if (pTreasure->getRandomItem(&it) )
			{
/*				if (bUpgrade && isPossibleUpgradeItemType(it.ItemClass ) )
				{
					it.ItemType = getUpgradeItemType(it.ItemClass, it.ItemType, 1);
				}
*/
				pItem1 = g_pItemFactoryManager->createItem(it.ItemClass, it.ItemType, it.OptionType);
				Assert(pItem1 != NULL);
			}
		}

		if (pItem1 == NULL)
		{
			StringStream msg;
			msg << "ActionTradeLairItem: "
				<< (int)it.ItemClass << ", "
				<< (int)it.ItemType << ", "
				<< (int)it.bCreateOption << ", "
				<< getOptionTypeToString(it.OptionType);

			filelog("tradeLairItemBUG.txt", "%s", msg.toString().c_str());

			GCSystemMessage gcSystemMessage;
			gcSystemMessage.setMessage(g_pStringPool->getString(STRID_ITEM_CREATE_ERROR ));
			pPlayer->sendPacket(&gcSystemMessage);

			GCNPCResponse response;
			response.setCode(NPC_RESPONSE_QUIT_DIALOGUE);
			pPlayer->sendPacket(&response);

			return;
		}
	}

	TPOINT pt;

	pItem1->setGrade(min(7,ItemGradeManager::Instance().getRandomBeadGrade()));
	pZone->registerObject(pItem1);

	// 만약 inventory에 공간이 있다면, 넣는다. 
	if(pInventory->addItem(pItem1, pt))
	{
		pItem1->create(pPC->getName(), STORAGE_INVENTORY, 0, pt.x, pt.y);

		GCCreateItem gcCreateItem;
/*		gcCreateItem.setObjectID(pItem1->getObjectID());
		gcCreateItem.setItemClass(pItem1->getItemClass());
		gcCreateItem.setItemType(pItem1->getItemType());
		gcCreateItem.setOptionType(pItem1->getOptionTypeList());
		gcCreateItem.setDurability(pItem1->getDurability());
		gcCreateItem.setItemNum(pItem1->getNum());
		gcCreateItem.setInvenX(pt.x);
		gcCreateItem.setInvenY(pt.y);
		gcCreateItem.setGrade(pItem1->getGrade());*/

		makeGCCreateItem(&gcCreateItem, pItem1, pt.x, pt.y);

		pPlayer->sendPacket(&gcCreateItem);

		// ItemTraceLog 를 남긴다
		if (pItem1 != NULL && pItem1->isTraceItem() )
		{
			remainTraceLog(pItem1, pCreature1->getName(), pCreature2->getName(), ITEM_LOG_CREATE, DETAIL_EVENTNPC);
		}

		// 기존의 아이템을 없앤다
		GCDeleteInventoryItem gcDeleteInventoryItem;
		gcDeleteInventoryItem.setObjectID(pMasterItem->getObjectID());
		pPlayer->sendPacket(&gcDeleteInventoryItem);

		// 서버에서 없애준다.
		pInventory->deleteItem(pMasterItem->getObjectID());	// 좌표로 바꿔주면 좋을건데..
		// ItemTraceLog 를 남긴다
		if (pMasterItem != NULL && pMasterItem->isTraceItem() )
		{
			remainTraceLog(pMasterItem, pCreature2->getName(), pCreature1->getName(), ITEM_LOG_DELETE, DETAIL_EVENTNPC);
		}
		pMasterItem->destroy();
		SAFE_DELETE(pMasterItem);

		// 사용자에게 성공 메시지 출력
//		StringStream message;
//		message << "성공적으로 교환되었습니다";
		GCSystemMessage gcSystemMessage;
		gcSystemMessage.setMessage(g_pStringPool->getString(STRID_TRADE_SUCCESS ));
		pPlayer->sendPacket(&gcSystemMessage);
	}
	else
	{
//		StringStream buf;
//		buf << "인벤토리에 공간이 부족합니다";

		GCSystemMessage gcSystemMessage;
		gcSystemMessage.setMessage(g_pStringPool->getString(STRID_NOT_ENOUGH_INVENTORY_SPACE ));
		pPlayer->sendPacket(&gcSystemMessage);
	}

	GCNPCResponse response;
	response.setCode(NPC_RESPONSE_QUIT_DIALOGUE);
	pPlayer->sendPacket(&response);

	__END_CATCH
}