예제 #1
0
//////////////////////////////////////////////////////////////////////////////
// 뱀파이어 인벤토리 핸들러
//////////////////////////////////////////////////////////////////////////////
void BloodyTunnel::execute(Vampire* pVampire, ObjectID_t InvenObjectID, ObjectID_t InventoryItemObjectID, CoordInven_t X, CoordInven_t Y, CoordInven_t TargetX, CoordInven_t TargetY, VampireSkillSlot* pSkillSlot)
	throw(Error)
{
	__BEGIN_TRY

	//cout << "TID[" << Thread::self() << "]" << getSkillHandlerName() << " Begin" << endl;

	Assert(pVampire != NULL);
	Assert(pSkillSlot != NULL);

	try 
	{
		Player* pPlayer = pVampire->getPlayer();
		Zone* pZone = pVampire->getZone();
		Inventory* pInventory = pVampire->getInventory();

		Assert(pPlayer != NULL);
		Assert(pZone != NULL);
		Assert(pInventory!= NULL);

		// 전쟁 존이라면 BloodyTunnel를 사용할 수 없다.
		// 일단은 ZoneID로 가는데.. ZoneInfo에 넣도록 해야한다.
		///*
		//if (pZone->getZoneID()==1122 || pZone->getZoneID()==1123)
		// 이벤트 경기장/OX 막기. by sigi. 2002.8.31
		//int zoneID = pZone->getZoneID();
		//if (zoneID==1005 || zoneID==1006)
		if (pZone->isNoPortalZone()
			|| pZone->isMasterLair()
			|| pZone->isCastle()
			|| pZone->isHolyLand())
		{
			executeSkillFailException(pVampire, getSkillType());
			//cout << "TID[" << Thread::self() << "]" << getSkillHandlerName() << " End" << endl;
			return;
		}
		//*/

		SubInventory* pInventoryItem = NULL;
		int invenID = 0;

		if (InventoryItemObjectID != 0 )
		{
			//cout << "서브 인벤토리에서 사용 : " << InventoryItemObjectID << endl;
			CoordInven_t X, Y;
			pInventoryItem = dynamic_cast<SubInventory*>(pInventory->findItemOID(InventoryItemObjectID, X, Y ));

			TradeManager* pTradeManager = pZone->getTradeManager();
			Assert(pTradeManager != NULL);

			if (pInventoryItem == NULL || pTradeManager->hasTradeInfo(pVampire->getName()) )
			{
				//cout << "근데 서브 인벤토리가 없다." <<endl;
				executeSkillFailException(pVampire, getSkillType());
				return;
			}

			pInventory = pInventoryItem->getInventory();
			invenID = pInventoryItem->getItemID();
		}

		Item* pItem = pInventory->getItem(X, Y);
		// 아이템이 없거나, 뱀파이어 포탈 아이템이 아니거나, OID가 틀리다면 기술 사용 불가
		if (pItem == NULL || pItem->getItemClass() != Item::ITEM_CLASS_VAMPIRE_PORTAL_ITEM || pItem->getObjectID() != InvenObjectID)
		{
			executeSkillFailException(pVampire, getSkillType());
			//cout << "TID[" << Thread::self() << "]" << getSkillHandlerName() << " End" << endl;
			return;
		}

		VampirePortalItem* pVampirePortalItem = dynamic_cast<VampirePortalItem*>(pItem);
		Assert(pVampirePortalItem != NULL);

		// 뱀파이어 포탈 아이템에 기록된 위치가 없을 경우에는 실패다.
		ZoneID_t    zoneid = pVampirePortalItem->getZoneID();
		ZoneCoord_t tx     = pVampirePortalItem->getX();
		ZoneCoord_t ty     = pVampirePortalItem->getY();
		if (zoneid == 0)
		{
			executeSkillFailException(pVampire, getSkillType());
			//cout << "TID[" << Thread::self() << "]" << getSkillHandlerName() << " End" << endl;
			return;
		}

		// 얻어온 목표 존과 좌표를 검증한다.
		Zone* pTargetZone = getZoneByZoneID(zoneid);

		// 아담의 성지와 다른 존과는 연결되지 않는다.
		if (pZone->isHolyLand() != pTargetZone->isHolyLand())
		{
			executeSkillFailException(pVampire, getSkillType());
			return;
		}

		//cout << "타겟 존 포인터 획득 성공" << endl;

		VSRect* pRect = pTargetZone->getOuterRect();

		if (!pRect->ptInRect(tx, ty))
		{
			executeSkillFailException(pVampire, getSkillType());
			//cout << "TID[" << Thread::self() << "]" << getSkillHandlerName() << " End" << endl;
			return;
		}

		//cout << "좌표 검증 성공" << endl;
		
		GCSkillToInventoryOK1 _GCSkillToInventoryOK1;

		SkillType_t SkillType  = pSkillSlot->getSkillType();
		SkillInfo*  pSkillInfo = g_pSkillInfoManager->getSkillInfo(SkillType);

		int  RequiredMP     = decreaseConsumeMP(pVampire, pSkillInfo);
		bool bManaCheck     = hasEnoughMana(pVampire, RequiredMP);
		bool bTimeCheck     = verifyRunTime(pSkillSlot);
		bool bRangeCheck    = checkZoneLevelToUseSkill(pVampire);
		//bool bHitRoll       = HitRoll::isSuccessMagic(pVampire, pSkillInfo, pSkillSlot);
		bool bHitRoll       = true;

		if (bManaCheck && bTimeCheck && bRangeCheck && bHitRoll)
		{
			decreaseMana(pVampire, RequiredMP, _GCSkillToInventoryOK1);

			SkillInput input(pVampire);
			SkillOutput output;
			computeOutput(input, output);

			// 각각의 존에다가 포탈을 더한다.
			ZONE_COORD s_coord;
			ZONE_COORD t_coord;

			s_coord.id = pZone->getZoneID();
			s_coord.x  = pVampire->getX();
			s_coord.y  = pVampire->getY();

			t_coord.id = pTargetZone->getZoneID();
			t_coord.x  = tx;
			t_coord.y  = ty;

			pZone->addVampirePortal(s_coord.x, s_coord.y, pVampire, t_coord);
			pTargetZone->addVampirePortal(t_coord.x, t_coord.y, pVampire, s_coord);

			_GCSkillToInventoryOK1.setSkillType(SkillType);
			_GCSkillToInventoryOK1.setObjectID(InvenObjectID);
			_GCSkillToInventoryOK1.setCEffectID(0);
			_GCSkillToInventoryOK1.setDuration(0);
		
			pPlayer->sendPacket(&_GCSkillToInventoryOK1);

			// 차지 수를 줄인다.
			pVampirePortalItem->setCharge(pVampirePortalItem->getCharge()-1);

			if (pVampirePortalItem->getCharge() > 0)
			{
				// 아직 차지가 남았다면 살려둔다.
				pVampirePortalItem->save(pVampire->getName(), STORAGE_INVENTORY, invenID, X, Y);
			}
			else
			{
				// 포탈 아이템의 차지가 다 소모되었다면 삭제시킨다.
				pInventory->deleteItem(X, Y);
				pVampirePortalItem->destroy();

				// 아이템 포인터 자체가 지워지고, NULL이 되면,
				// 이펙트 내부에서의 아이템 포인터도 NULL이 되겠지...
				SAFE_DELETE(pVampirePortalItem);
			}

			pSkillSlot->setRunTime(output.Delay);
		} 
		else 
		{
			executeSkillFailNormal(pVampire, getSkillType(), NULL);
		}
	} 
	catch(Throwable & t) 
	{
		executeSkillFailException(pVampire, getSkillType());
	}

	//cout << "TID[" << Thread::self() << "]" << getSkillHandlerName() << " End" << endl;

	__END_CATCH
}
예제 #2
0
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
}
예제 #3
0
////////////////////////////////////////////////////////////////////////////////
// is satisfied?
////////////////////////////////////////////////////////////////////////////////
bool ConditionEnterCastle::isSatisfied (Creature * pCreature1 , Creature * pCreature2, void* pParam) const 
	throw() 
{ 
	/*if (!g_pVariableManager->isActiveCastle())
	{
		return false;
	}*/
	// 나중에 전쟁중인지 체크해야 된다

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

	//cout << "Condition: EnterCastle" << endl;

	bool bPayPlay = false;

	GamePlayer* pGamePlayer = dynamic_cast<GamePlayer*>(pCreature2->getPlayer());
	Assert(pGamePlayer!=NULL);

#if defined(__PAY_SYSTEM_ZONE__) || defined(__PAY_SYSTEM_FREE_LIMIT__)
	// 이미 유료존에 있는 경우라면... 관계없겠지.
	// 패밀리 요금 적용중일 경우
	if (pGamePlayer->isPayPlaying() || pGamePlayer->isFamilyFreePass())
	{
		bPayPlay = true;
	}
	else
	{
		// 일단 zone 요금 체크
		string connectIP = pGamePlayer->getSocket()->getHost();
		
		if (pGamePlayer->loginPayPlay(connectIP, pGamePlayer->getID()))
		{
			sendPayInfo(pGamePlayer);
			bPayPlay = true;
		}
	}
#else
	bPayPlay = true;
#endif

	// 돈 낸 사람만 castle 에 들어갈 수 있다.
	if (bPayPlay)
	{
		// 존을 찾는다.
		Zone* pZone = getZoneByZoneID(m_TargetZoneID);
		Assert(pZone!=NULL);

		// castle 이 아니면 체크할 필요가 없는거다.
		if (!pZone->isCastle())
		{
			return true;
		}

		// 종족간 전쟁중에는 종족에 상관없이 누구나 통과시켜야 한다.
		// 동족간 전쟁중에는 타종족을 통과시켜서는 안 된다.
		// 평시에는 NPC를 통해야 하므로 누구도 통과시킬 수 없다.
		// 전쟁시스템 만들때 이거 다 추가시켜야 된다. 2003. 1.20.
		PlayerCreature* pPC = dynamic_cast<PlayerCreature*>(pCreature2);

		return g_pCastleInfoManager->canPortalActivate(m_TargetZoneID, pPC);
	}

	return false;
}
예제 #4
0
Item* CastleShrineInfoManager::addShrineToZone(ShrineInfo& shrineInfo, ItemType_t itemType )
	throw(Error)
{
	__BEGIN_TRY

	// 성단을 넣을 존을 가져온다.
	Zone* pZone = getZoneByZoneID(shrineInfo.getZoneID());
	Assert(pZone != NULL);

	MonsterCorpse* pShrine = new MonsterCorpse(shrineInfo.getMonsterType(), shrineInfo.getName(), 2);
	Assert(pShrine != NULL);

	pShrine->setShrine(true);
	pShrine->setZone(pZone);

	pZone->getObjectRegistry().registerObject(pShrine);
	shrineInfo.setObjectID(pShrine->getObjectID());

	Item* pItem =  NULL;

/*	if (shrineInfo.getShrineType() == ShrineInfo::SHRINE_GUARD )
	{
		pShrine->setFlag(Effect::EFFECT_CLASS_SHRINE_GUARD);

		EffectShrineGuard* pEffect = new EffectShrineGuard(pShrine);
		pEffect->setShrineID(itemType);
		pEffect->setTick(60 * 10);

		pShrine->getEffectManager().addEffect(pEffect);
	}
	else if (shrineInfo.getShrineType() == ShrineInfo::SHRINE_HOLY )
	{
		pShrine->setFlag(Effect::EFFECT_CLASS_SHRINE_HOLY);

		EffectShrineHoly* pEffect = new EffectShrineHoly(pShrine);
		pEffect->setShrineID(itemType);
		pEffect->setTick(60 * 10);

		pShrine->getEffectManager().addEffect(pEffect);
	}*/

	TPOINT tp = pZone->addItem(pShrine, shrineInfo.getX(), shrineInfo.getY(), true);
	Assert(tp.x != -1);

	// 성의 상징을 추가할 필요가 있다면 추가한다.
	if (shrineInfo.getShrineType() == ShrineInfo::SHRINE_GUARD )
	{
		//if (AddBible[ itemType ] )
		{
			list<OptionType_t> optionNULL;
			pItem = g_pItemFactoryManager->createItem(Item::ITEM_CLASS_CASTLE_SYMBOL, itemType, optionNULL);
			Assert(pItem != NULL);

			char strZoneID[10];
			sprintf(strZoneID, "%d", (int)pZone->getZoneID());

			pZone->registerObject(pItem);
			pItem->create(strZoneID, STORAGE_CORPSE, pShrine->getObjectID(), 0, 0);

			pShrine->addTreasure(pItem);
		}

		// 수호성단이라는걸 표시해둔다.
		pShrine->setFlag(Effect::EFFECT_CLASS_CASTLE_SHRINE_GUARD);

		// 모든 수호성단에 Shield Effect 붙인다
		pShrine->setFlag(Effect::EFFECT_CLASS_SHRINE_SHIELD);

		EffectShrineShield* pEffect = new EffectShrineShield(pShrine);
		pEffect->setShrineID(itemType);
		pEffect->setTick(60 * 10);

		pShrine->getEffectManager().addEffect(pEffect);
	}
	else
	{
		// 성지성단이라는걸 표시해둔다.
		pShrine->setFlag(Effect::EFFECT_CLASS_CASTLE_SHRINE_HOLY);
	}

	// 성단 좌표를 새로 세팅한다.
	shrineInfo.setX(tp.x);
	shrineInfo.setY(tp.y);

	return pItem;

	__END_CATCH
}
예제 #5
0
////////////////////////////////////////////////////////////////////////////////
// 액션을 실행한다.
////////////////////////////////////////////////////////////////////////////////
void ActionRegisterSiege::execute (Creature * pCreature1 , Creature * pCreature2) 
	throw(Error)
{
	__BEGIN_TRY

#ifndef __OLD_GUILD_WAR__

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

	SYSTEM_RETURN_IF_NOT(SYSTEM_GUILD_WAR);

	GCNPCResponse gcNPCResponse;

	PlayerCreature* pPC = dynamic_cast<PlayerCreature*>(pCreature2);
	GuildID_t guildID = pPC->getGuildID();

	if (!g_pVariableManager->isWarActive() || !g_pVariableManager->isActiveGuildWar() )
	{
		gcNPCResponse.setCode(NPC_RESPONSE_WAR_UNAVAILABLE);
		pPC->getPlayer()->sendPacket(&gcNPCResponse);
		return;
	}

	if (!g_pGuildManager->isGuildMaster(guildID, pPC ) )
	{
		gcNPCResponse.setCode(NPC_RESPONSE_NOT_GUILD_MASTER);
		pPC->getPlayer()->sendPacket(&gcNPCResponse);
		return;
	}

	Gold_t warRegistrationFee = g_pVariableManager->getVariable(WAR_REGISTRATION_FEE);
	if (pPC->getGold() < warRegistrationFee )
	{
		gcNPCResponse.setCode(NPC_RESPONSE_NOT_ENOUGH_MONEY);
		pPC->getPlayer()->sendPacket(&gcNPCResponse);
		return;
	}

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

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

	/* 성을 소유했어도 전쟁 신청이 되도록 수정함 (자기 성에는 신청 못하겠지 -_-;;)
	// 이미 성을 소유한 길드인가?
	if (g_pGuildManager->hasCastle(guildID ) )
	{
		gcNPCResponse.setCode(NPC_RESPONSE_ALREADY_HAS_CASTLE);
		pPC->getPlayer()->sendPacket(&gcNPCResponse);
		return;
	}
	*/

//	ServerID_t serverID;
//	ZoneID_t zoneID;
//	bool bHasCastle = g_pGuildManager->hasCastle(guildID , serverID , zoneID);

//	if (bHasCastle && serverID == g_pConfig->getPropertyInt("ServerID" ) && zoneID == m_ZoneID )

	CastleInfo* pCastleInfo = g_pCastleInfoManager->getCastleInfo(m_ZoneID);
	GuildID_t ownerGuildID = pCastleInfo->getGuildID();

	if (guildID == ownerGuildID )
	{
		gcNPCResponse.setCode(NPC_RESPONSE_ALREADY_HAS_CASTLE);
		pPC->getPlayer()->sendPacket(&gcNPCResponse);
		return;
	}

	// 이미 전쟁 신청을 했는가?
	if (g_pGuildManager->hasWarSchedule(guildID ) )
	{
		gcNPCResponse.setCode(NPC_RESPONSE_WAR_ALREADY_REGISTERED);
		pPC->getPlayer()->sendPacket(&gcNPCResponse);
		return;
	}

	// 전쟁 스케쥴이 다 찼는가?
/*	if (!pWarScheduler->canAddWar(WAR_GUILD ) )
	{
		gcNPCResponse.setCode(NPC_RESPONSE_WAR_SCHEDULE_FULL);
		pPC->getPlayer()->sendPacket(&gcNPCResponse);
		return;
	}

	GuildWar* pWar = new GuildWar(m_ZoneID, guildID, War::WAR_STATE_WAIT);

	pWar->setRegistrationFee(warRegistrationFee);

	if (!pWarScheduler->addWar(pWar ) )
	{
		gcNPCResponse.setCode(NPC_RESPONSE_WAR_SCHEDULE_FULL);
		pPC->getPlayer()->sendPacket(&gcNPCResponse);

		SAFE_DELETE(pWar);
		return;
	}*/

	Schedule* pNextSchedule = pWarScheduler->getRecentSchedule();

	Work* pNextWork = NULL;
	if (pNextSchedule != NULL ) pNextWork = pNextSchedule->getWork();

	SiegeWar* pNextWar = dynamic_cast<SiegeWar*>(pNextWork);

	if (pNextWar == NULL )
	{
		pNextWar = new SiegeWar(m_ZoneID, War::WAR_STATE_WAIT);
		pNextWar->addRegistrationFee(warRegistrationFee);
		pNextWar->addChallengerGuild(guildID);

		if (!pWarScheduler->addWar(pNextWar ) )
		{
			gcNPCResponse.setCode(NPC_RESPONSE_WAR_SCHEDULE_FULL);
			pPC->getPlayer()->sendPacket(&gcNPCResponse);

			SAFE_DELETE(pNextWar);
			return;
		}
	}
	else if (pNextWar->getChallengerGuildCount() < 5 )
	{
		WarSchedule* pNextWarSchedule = dynamic_cast<WarSchedule*>(pNextSchedule);
		Assert(pNextWarSchedule != NULL);

		pNextWar->addRegistrationFee(warRegistrationFee);
		pNextWar->addChallengerGuild(guildID);
		pNextWarSchedule->save();
	}
	else
	{
		gcNPCResponse.setCode(NPC_RESPONSE_WAR_SCHEDULE_FULL);
		pPC->getPlayer()->sendPacket(&gcNPCResponse);

//		SAFE_DELETE(pNextWar);
		return;
	}

	pPC->decreaseGoldEx(warRegistrationFee);

	GCModifyInformation gcMI;
	gcMI.addLongData(MODIFY_GOLD, pPC->getGold());
	pPC->getPlayer()->sendPacket(&gcMI);

	gcNPCResponse.setCode(NPC_RESPONSE_WAR_REGISTRATION_OK);
	pPC->getPlayer()->sendPacket(&gcNPCResponse);
	return;

#endif

	__END_CATCH
}
예제 #6
0
////////////////////////////////////////////////////////////////////////////////
// 액션을 실행한다.
////////////////////////////////////////////////////////////////////////////////
void ActionDenyReinforce::execute (Creature * pCreature1 , Creature * pCreature2) 
	throw(Error)
{
	__BEGIN_TRY

#ifndef __OLD_GUILD_WAR__

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

	SYSTEM_RETURN_IF_NOT(SYSTEM_GUILD_WAR);

	GCNPCResponse gcNPCResponse;

	PlayerCreature* pPC = dynamic_cast<PlayerCreature*>(pCreature2);
	GuildID_t guildID = pPC->getGuildID();

	if (!g_pVariableManager->isWarActive() || !g_pVariableManager->isActiveGuildWar() )
	{
		gcNPCResponse.setCode(NPC_RESPONSE_WAR_UNAVAILABLE);
		pPC->getPlayer()->sendPacket(&gcNPCResponse);
		return;
	}

	if (!g_pGuildManager->isGuildMaster(guildID, pPC ) )
	{
		gcNPCResponse.setCode(NPC_RESPONSE_NOT_GUILD_MASTER);
		pPC->getPlayer()->sendPacket(&gcNPCResponse);
		return;
	}

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

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

	CastleInfo* pCastleInfo = g_pCastleInfoManager->getCastleInfo(m_ZoneID);
	GuildID_t ownerGuildID = pCastleInfo->getGuildID();

	if (guildID != ownerGuildID )
	{
		gcNPCResponse.setCode(NPC_RESPONSE_NOT_YOUR_CASTLE);
		pPC->getPlayer()->sendPacket(&gcNPCResponse);
		return;
	}

	Schedule* pNextSchedule = pWarScheduler->getRecentSchedule();

	Work* pNextWork = NULL;
	if (pNextSchedule != NULL ) pNextWork = pNextSchedule->getWork();

	SiegeWar* pNextWar = dynamic_cast<SiegeWar*>(pNextWork);

	if (pNextWar == NULL || pNextWar->recentReinforceCandidate() == 0 )
	{
		gcNPCResponse.setCode(NPC_RESPONSE_NO_WAR_REGISTERED);
		pPC->getPlayer()->sendPacket(&gcNPCResponse);

		//SAFE_DELETE(pNextWar);
		return;
	}
	else if (pNextWar->getReinforceGuildID() == 0 )
	{
		WarSchedule* pNextWarSchedule = dynamic_cast<WarSchedule*>(pNextSchedule);
		Assert(pNextWarSchedule != NULL);

		if (!pNextWar->denyReinforce() )
		{
			gcNPCResponse.setCode(NPC_RESPONSE_CANNOT_ACCEPT);
			pPC->getPlayer()->sendPacket(&gcNPCResponse);

			//SAFE_DELETE(pNextWar);
			return;
		}
	}
	else
	{
		gcNPCResponse.setCode(NPC_RESPONSE_ALREADY_REINFORCE_ACCEPTED);
		pPC->getPlayer()->sendPacket(&gcNPCResponse);

		//SAFE_DELETE(pNextWar);
		return;
	}

	gcNPCResponse.setCode(NPC_RESPONSE_ACCEPT_OK);
	pPC->getPlayer()->sendPacket(&gcNPCResponse);

	gcNPCResponse.setCode(NPC_RESPONSE_QUIT_DIALOGUE);
	pPC->getPlayer()->sendPacket(&gcNPCResponse);

	return;

#endif

	__END_CATCH
}
예제 #7
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
}