Beispiel #1
0
void EffectComa::unaffect(Creature* pDeadCreature)
	throw(Error)
{
	__BEGIN_TRY

	Assert(pDeadCreature != NULL);
	//Assert(pDeadCreature->isDead());

	// 이펙트 플래그를 삭제해준다.
	pDeadCreature->removeFlag(Effect::EFFECT_CLASS_COMA);
	// 날아오면 강제로 죽이는 코드를 집어넣는다.
	if (pDeadCreature->isSlayer()) {
		Slayer* pSlayer = dynamic_cast<Slayer*>(pDeadCreature);
		pSlayer->setHP(0, ATTR_CURRENT);
	}
	else if (pDeadCreature->isVampire()) {
		Vampire* pVampire = dynamic_cast<Vampire*>(pDeadCreature);
		pVampire->setHP(0, ATTR_CURRENT);
	}
	else if (pDeadCreature->isOusters())
	{
		Ousters* pOusters = dynamic_cast<Ousters*>(pDeadCreature);
		pOusters->setHP(0, ATTR_CURRENT);
	}

	__END_CATCH
}
void DynamicZoneSlayerMirrorOfAbyss::killPC()
{
	Assert(m_pZone != NULL);

    // PC 를 죽인다.
    map<ObjectID_t, Creature*>::const_iterator itr = m_pZone->getPCManager()->getCreatures().begin();
    map<ObjectID_t, Creature*>::const_iterator endItr = m_pZone->getPCManager()->getCreatures().end();

    for (; itr != endItr; ++itr )
    {
        Assert(itr->second != NULL);

        if (itr->second->isPC() )
        {
            PlayerCreature* pPC = dynamic_cast<PlayerCreature*>(itr->second);
            Assert(pPC != NULL);

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

				pSlayer->setHP(0);
			}
			else if (pPC->isVampire() )
			{
				Vampire* pVampire = dynamic_cast<Vampire*>(pPC);
				Assert(pVampire != NULL);

				pVampire->setHP(0);
			}
			else if (pPC->isOusters() )
			{
				Ousters* pOusters = dynamic_cast<Ousters*>(pPC);
				Assert(pOusters != NULL);

				pOusters->setHP(0);
			}
        }
    }
}
Beispiel #3
0
void EffectDecreaseHP::unaffect(Creature* pCreature)
	throw(Error)
{
	__BEGIN_TRY
	__BEGIN_DEBUG

	Assert(pCreature != NULL);

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

	pCreature->removeFlag(Effect::EFFECT_CLASS_DECREASE_HP);

	Damage_t decreaseHP = m_Point;

	if (!(pZone->getZoneLevel() & COMPLETE_SAFE_ZONE)
		&& !pCreature->isDead()
		&& !pCreature->isFlag(Effect::EFFECT_CLASS_COMA)
		// 무적상태 체크. by sigi. 2002.9.5
		&& canAttack(NULL, pCreature )
	   )
	{
		if (pCreature->isSlayer())
		{
			Slayer* pSlayer = dynamic_cast<Slayer*>(pCreature);

			HP_t CurrentHP = pSlayer->getHP(ATTR_CURRENT);

			if (CurrentHP > 0)
			{
				HP_t RemainHP  = max(0, CurrentHP -(int)decreaseHP);

				pSlayer->setHP(RemainHP, ATTR_CURRENT);

				GCModifyInformation gcMI;
				gcMI.addShortData(MODIFY_CURRENT_HP, RemainHP);
				pSlayer->getPlayer()->sendPacket(&gcMI);

				// 변한 HP를 브로드캐스팅해준다.
				GCStatusCurrentHP pkt;
				pkt.setObjectID(pSlayer->getObjectID());
				pkt.setCurrentHP(RemainHP);
				pZone->broadcastPacket(pSlayer->getX(), pSlayer->getY(), &pkt);
			}
		}
		else if (pCreature->isVampire())
		{
			Vampire* pVampire = dynamic_cast<Vampire*>(pCreature);

			HP_t CurrentHP = pVampire->getHP(ATTR_CURRENT);

			if (CurrentHP > 0)
			{
				HP_t RemainHP  = max(0, CurrentHP -(int)decreaseHP);

				pVampire->setHP(RemainHP, ATTR_CURRENT);

				GCModifyInformation gcMI;
				gcMI.addShortData(MODIFY_CURRENT_HP, RemainHP);
				pVampire->getPlayer()->sendPacket(&gcMI);

				// 공격(흡혈) 당하는 경우에는 공격자의 성향이 바뀜 by sigi. 2002.12.27
				Creature* pAttacker = pZone->getCreature(m_UserObjectID);
				if (pAttacker!=NULL && pAttacker->isVampire())
				{
					Vampire* pAttackVampire = dynamic_cast<Vampire*>(pAttacker);

					GCModifyInformation gcAttackerMI;
					computeAlignmentChange(pVampire, decreaseHP, pAttackVampire, NULL, &gcAttackerMI);

					// 뭔가 변한 정보가 있다면 보내준다.
					if (gcAttackerMI.getShortCount()+gcAttackerMI.getLongCount() > 0)
					{
						pAttackVampire->getPlayer()->sendPacket(&gcAttackerMI);
					}
				}

				// 변한 HP를 브로드캐스팅해준다.
				GCStatusCurrentHP pkt;
				pkt.setObjectID(pVampire->getObjectID());
				pkt.setCurrentHP(RemainHP);
				pZone->broadcastPacket(pVampire->getX(), pVampire->getY(), &pkt);
			}
		}
		else if (pCreature->isOusters())
		{
			Ousters* pOusters = dynamic_cast<Ousters*>(pCreature);

			HP_t CurrentHP = pOusters->getHP(ATTR_CURRENT);

			if (CurrentHP > 0)
			{
				HP_t RemainHP  = max(0, CurrentHP -(int)decreaseHP);

				pOusters->setHP(RemainHP, ATTR_CURRENT);

				GCModifyInformation gcMI;
				gcMI.addShortData(MODIFY_CURRENT_HP, RemainHP);
				pOusters->getPlayer()->sendPacket(&gcMI);

				// 공격(흡혈) 당하는 경우에는 공격자의 성향이 바뀜 by sigi. 2002.12.27
				Creature* pAttacker = pZone->getCreature(m_UserObjectID);
				if (pAttacker!=NULL && pAttacker->isOusters())
				{
					Ousters* pAttackOusters = dynamic_cast<Ousters*>(pAttacker);

					GCModifyInformation gcAttackerMI;
					computeAlignmentChange(pOusters, decreaseHP, pAttackOusters, NULL, &gcAttackerMI);

					// 뭔가 변한 정보가 있다면 보내준다.
					if (gcAttackerMI.getShortCount()+gcAttackerMI.getLongCount() > 0)
					{
						pAttackOusters->getPlayer()->sendPacket(&gcAttackerMI);
					}
				}

				// 변한 HP를 브로드캐스팅해준다.
				GCStatusCurrentHP pkt;
				pkt.setObjectID(pOusters->getObjectID());
				pkt.setCurrentHP(RemainHP);
				pZone->broadcastPacket(pOusters->getX(), pOusters->getY(), &pkt);
			}
		}
		else if (pCreature->isMonster())
		{
			Monster* pMonster = dynamic_cast<Monster*>(pCreature);

			HP_t CurrentHP = pMonster->getHP(ATTR_CURRENT);

			if (CurrentHP > 0)
			{
				HP_t RemainHP  = max(0, CurrentHP -(int)decreaseHP);

				pMonster->setHP(RemainHP, ATTR_CURRENT);

				// 변한 HP를 브로드캐스팅해준다.
				GCStatusCurrentHP pkt;
				pkt.setObjectID(pMonster->getObjectID());
				pkt.setCurrentHP(RemainHP);
				pZone->broadcastPacket(pMonster->getX(), pMonster->getY(), &pkt);

				if (RemainHP == 0 )
				{
					Creature* pAttacker = pZone->getCreature(m_UserObjectID);
					if (pAttacker != NULL && pAttacker->isVampire() )
					{
						Vampire* pAttackVampire = dynamic_cast<Vampire*>(pAttacker);

						GCModifyInformation gcMI;
						increaseAlignment(pAttackVampire, pCreature, gcMI);

						if (gcMI.getShortCount() > 0 || gcMI.getLongCount() > 0 )
							pAttackVampire->getPlayer()->sendPacket(&gcMI);
					}
				}
			}
		}


		// m_CasterName이 pCreature를 죽인 경우의 KillCount 처리
		// by sigi. 2002.9.9
		if (pCreature->isDead())
		{
			Creature* pAttacker = pZone->getCreature(m_UserObjectID);

			if (pAttacker!=NULL)
			{ 
				if (pAttacker->isVampire())
				{
					Vampire* pVampire = dynamic_cast<Vampire*>(pAttacker);
					// 죽일때 경험치를 준다.
					GCModifyInformation mi;

					int exp = computeCreatureExp(pCreature, KILL_EXP);
					shareVampExp(pVampire, exp, mi);

					if (pCreature->isMonster() )
					{
						increaseFame(pVampire, decreaseHP);
						mi.addLongData(MODIFY_FAME, pVampire->getFame());
					}

					pAttacker->getPlayer()->sendPacket(&mi);
				}
				else if (pAttacker->isOusters() )
				{
					Ousters* pOusters = dynamic_cast<Ousters*>(pAttacker);
					GCModifyInformation mi;
					int exp = computeCreatureExp(pCreature, 100);
					shareOustersExp(pOusters, exp, mi);

					if (pCreature->isMonster() )
					{
						increaseFame(pOusters, decreaseHP);
						mi.addLongData(MODIFY_FAME, pOusters->getFame());
					}
				}

				affectKillCount(pAttacker, pCreature);
			}
		}
	}

	__END_DEBUG
	__END_CATCH
}
void EffectBloodyWallBlocked::affect()
	throw(Error)
{
	__BEGIN_TRY

	//cout << "EffectBloodyWallBlocked" << "affect BEGIN" << endl;
	
	Assert(m_pZone != NULL);

	// 현재 이펙트가 붙어있는 타일을 받아온다.
    Tile& tile = m_pZone->getTile(m_X, m_Y);

	HP_t CurrentHP = 0;
	HP_t RemainHP  = 0;

	// 타일 안에 존재하는 오브젝트들을 검색한다.
    const list<Object*>& oList = tile.getObjectList();
	list<Object*>::const_iterator itr = oList.begin();
    for (; itr != oList.end(); itr++) 
	{
		Assert(*itr != NULL);

		Object* pObject = *itr;
		Assert(pObject != NULL);

    	if (pObject->getObjectClass() == Object::OBJECT_CLASS_CREATURE)
		{
			Creature* pCreature = dynamic_cast<Creature*>(pObject);
			Assert(pCreature != NULL);

			// 무적상태 체크. by sigi. 2002.9.5
			// 산 면역. by sigi. 2002.9.13
			if (!canAttack(NULL, pCreature )
				|| pCreature->isFlag(Effect::EFFECT_CLASS_IMMUNE_TO_BLOOD_DRAIN)
				|| pCreature->isFlag(Effect::EFFECT_CLASS_COMA)
				|| pCreature->isDead())
			{
				continue;
			}

			int AcidDamage = computeMagicDamage(pCreature, m_Damage, SKILL_BLOODY_WALL);

			if (pCreature->getMoveMode() != Creature::MOVE_MODE_FLYING)
			{
				if (pCreature->isSlayer()) 
				{
					Slayer* pSlayer = dynamic_cast<Slayer*>(pCreature);

					CurrentHP = pSlayer->getHP(ATTR_CURRENT);
					RemainHP  = max(0, CurrentHP -(int)AcidDamage);

					pSlayer->setHP(RemainHP, ATTR_CURRENT);

					GCModifyInformation gcMI;
					gcMI.addShortData(MODIFY_CURRENT_HP, pSlayer->getHP(ATTR_CURRENT));

					Player* pPlayer = pSlayer->getPlayer();
					Assert(pPlayer != NULL);
					pPlayer->sendPacket(&gcMI);

					// 변한 HP를 브로드캐스팅해준다.
					GCStatusCurrentHP pkt;
					pkt.setObjectID(pSlayer->getObjectID());
					pkt.setCurrentHP(RemainHP);
					m_pZone->broadcastPacket(pSlayer->getX(), pSlayer->getY(), &pkt);
				} 
/*				else if (pCreature->isVampire())
				{
					Vampire* pVampire = dynamic_cast<Vampire*>(pCreature);

					CurrentHP = pVampire->getHP(ATTR_CURRENT);
					RemainHP  = max(0, CurrentHP -(int)AcidDamage);

					pVampire->setHP(RemainHP, ATTR_CURRENT);

					GCModifyInformation gcMI;
					gcMI.addShortData(MODIFY_CURRENT_HP, pVampire->getHP(ATTR_CURRENT));

					Player* pPlayer = pVampire->getPlayer();
					Assert(pPlayer != NULL);
					pPlayer->sendPacket(&gcMI);

					// 변한 HP를 브로드캐스팅해준다.
					GCStatusCurrentHP pkt;
					pkt.setObjectID(pVampire->getObjectID());
					pkt.setCurrentHP(RemainHP);
					m_pZone->broadcastPacket(pVampire->getX(), pVampire->getY(), &pkt);
				}
				*/
				else if (pCreature->isOusters())
				{
					Ousters* pOusters = dynamic_cast<Ousters*>(pCreature);

					CurrentHP = pOusters->getHP(ATTR_CURRENT);
					RemainHP  = max(0, CurrentHP -(int)AcidDamage);

					pOusters->setHP(RemainHP, ATTR_CURRENT);

					GCModifyInformation gcMI;
					gcMI.addShortData(MODIFY_CURRENT_HP, pOusters->getHP(ATTR_CURRENT));

					Player* pPlayer = pOusters->getPlayer();
					Assert(pPlayer != NULL);
					pPlayer->sendPacket(&gcMI);

					// 변한 HP를 브로드캐스팅해준다.
					GCStatusCurrentHP pkt;
					pkt.setObjectID(pOusters->getObjectID());
					pkt.setCurrentHP(RemainHP);
					m_pZone->broadcastPacket(pOusters->getX(), pOusters->getY(), &pkt);
				}
				else if (pCreature->isMonster())
				{
					Monster* pMonster = dynamic_cast<Monster*>(pCreature);

					CurrentHP = pMonster->getHP(ATTR_CURRENT);
					RemainHP  = max(0, CurrentHP -(int)AcidDamage);

					pMonster->setHP(RemainHP, ATTR_CURRENT);

					if(m_CasterName != "" ) {
						// 시전자의 데미지를 추가해 준다.
						// 맞는 놈이 몬스터이고, 공격자가 사람이라면,
						// 데미지에 따라서 변하는 우선권 테이블을 갱신해 주어야 한다.
						pMonster->addPrecedence(m_CasterName, m_PartyID, AcidDamage);
						pMonster->setLastHitCreatureClass(Creature::CREATURE_CLASS_VAMPIRE);
					}

					// 변한 HP를 브로드캐스팅해준다.
					GCStatusCurrentHP pkt;
					pkt.setObjectID(pMonster->getObjectID());
					pkt.setCurrentHP(RemainHP);
					m_pZone->broadcastPacket(pMonster->getX(), pMonster->getY(), &pkt);
				}


				// m_CasterName이 pCreature를 죽인 경우의 KillCount 처리
				// by sigi. 2002.8.31
				if (pCreature->isDead())
				{
					Creature* pAttacker = m_pZone->getCreature(m_CasterName);

					if (pAttacker!=NULL)
					{ 
						affectKillCount(pAttacker, pCreature);
					}
				}
			}
		}
	}
	
	// 한번만..
	//setNextTime(m_Tick);

	//cout << "EffectBloodyWallBlocked" << "affect END" << endl;

	__END_CATCH 
}
Beispiel #5
0
void ActionHeal::execute (Creature * pCreature1 , Creature * pCreature2) 
	throw(Error)
{
	__BEGIN_TRY

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

	Player* pPlayer = pCreature2->getPlayer();
	Zone*   pZone   = pCreature2->getZone();
	
	Assert(pPlayer != NULL);

	// 일단 클라이언트를 위해서 OK 패킷을 함 날린다.
	GCNPCResponse okpkt;
	okpkt.setCode(NPC_RESPONSE_HEAL);
	pPlayer->sendPacket(&okpkt);

	// 죽었거나 코마 걸려있으면 안 치료해준다.
	if (pCreature2->isDead() || pCreature2->isFlag(Effect::EFFECT_CLASS_COMA ) )
	{
		return;
	}

	// 슬레이어라면...
	if (pCreature2->isSlayer())
	{
		Slayer*             pSlayer        = dynamic_cast<Slayer*>(pCreature2);
		EffectManager*      pEffectManager = pSlayer->getEffectManager();
		GCModifyInformation modifyPkt;
		GCRemoveEffect      removePkt;
		GCStatusCurrentHP   hpPkt;

		// 먼저 HP랑 MP를 풀로 채워준다.
		if (pSlayer->getHP(ATTR_CURRENT) < pSlayer->getHP(ATTR_MAX))
		{
			pSlayer->setHP(pSlayer->getHP(ATTR_MAX), ATTR_CURRENT);
			modifyPkt.addShortData(MODIFY_CURRENT_HP, pSlayer->getHP(ATTR_CURRENT));

			hpPkt.setObjectID(pSlayer->getObjectID());
			hpPkt.setCurrentHP(pSlayer->getHP(ATTR_CURRENT));
		}
		if (pSlayer->getMP(ATTR_CURRENT) < pSlayer->getMP(ATTR_MAX))
		{
			pSlayer->setMP(pSlayer->getMP(ATTR_MAX), ATTR_CURRENT);
			modifyPkt.addShortData(MODIFY_CURRENT_MP, pSlayer->getMP(ATTR_CURRENT));
		}

		// 흡혈 이펙트를 삭제한다.
		Effect* pBloodDrainEffect = pEffectManager->findEffect(Effect::EFFECT_CLASS_BLOOD_DRAIN);
		if (pBloodDrainEffect != NULL)
		{
			// DB에서 삭제하고, 이펙트 매니저에서 삭제한다.
			pBloodDrainEffect->destroy(pSlayer->getName());
			pEffectManager->deleteEffect(pSlayer, Effect::EFFECT_CLASS_BLOOD_DRAIN);

			// 흡혈 아르바이트를 방지하기 위한 후유증 이펙트를 붙여준다.
			if (pSlayer->isFlag(Effect::EFFECT_CLASS_AFTERMATH))
			{
				Effect* pEffect = pEffectManager->findEffect(Effect::EFFECT_CLASS_AFTERMATH);
				EffectAftermath* pEffectAftermath = dynamic_cast<EffectAftermath*>(pEffect);
				pEffectAftermath->setDeadline(5*600); // 5분 동안 지속된다.
			}
			else
			{
				EffectAftermath* pEffectAftermath = new EffectAftermath(pSlayer);
				pEffectAftermath->setDeadline(5*600); // 5분 동안 지속된다.
				pEffectManager->addEffect(pEffectAftermath);
				pSlayer->setFlag(Effect::EFFECT_CLASS_AFTERMATH);
				pEffectAftermath->create(pSlayer->getName());
			}

			// 패킷에다 정보를 더한다.
			removePkt.addEffectList((EffectID_t)Effect::EFFECT_CLASS_BLOOD_DRAIN);

			// 흡혈을 치료하면 능력치가 변화하게 된다.
			SLAYER_RECORD prev;
			pSlayer->getSlayerRecord(prev);
			pSlayer->initAllStat();
			pSlayer->sendModifyInfo(prev);
			pSlayer->sendRealWearingInfo();
		}

		// 독 이펙트를 삭제한다.
		Effect* pEffectPoison = pEffectManager->findEffect(Effect::EFFECT_CLASS_POISON);
		if (pEffectPoison != NULL)
		{
			// 이펙트 매니저에서 삭제한다.
			pEffectManager->deleteEffect(pSlayer, Effect::EFFECT_CLASS_POISON);

			// 패킷에다 정보를 더한다.
			removePkt.addEffectList((EffectID_t)Effect::EFFECT_CLASS_POISON);
		}

		// 다크블루 포이즌 이펙트를 삭제한다.
		Effect* pEffectDarkBluePoison = pEffectManager->findEffect(Effect::EFFECT_CLASS_DARKBLUE_POISON);
		if (pEffectDarkBluePoison != NULL)
		{
			// 이펙트 매니저에서 삭제한다.
			pEffectManager->deleteEffect(pSlayer, Effect::EFFECT_CLASS_DARKBLUE_POISON);

			// 패킷에다 정보를 더한다.
			removePkt.addEffectList((EffectID_t)Effect::EFFECT_CLASS_DARKBLUE_POISON);
		}

		// 패킷 날려준다.
		removePkt.setObjectID(pSlayer->getObjectID());
		pPlayer->sendPacket(&modifyPkt);
		pZone->broadcastPacket(pSlayer->getX(), pSlayer->getY(), &removePkt);
		pZone->broadcastPacket(pSlayer->getX(), pSlayer->getY(), &hpPkt, pSlayer);

		//log(LOG_HEAL, pSlayer->getName(), "");
	}
	else if (pCreature2->isVampire())
	{
		Vampire*            pVampire = dynamic_cast<Vampire*>(pCreature2);
		//EffectManager*      pEffectManager = pVampire->getEffectManager();
		GCModifyInformation modifyPkt;
		GCRemoveEffect      removePkt;
		GCStatusCurrentHP   hpPkt;

		// HP 채워주고...
		if (pVampire->getHP(ATTR_CURRENT) < pVampire->getHP(ATTR_MAX))
		{
			pVampire->setHP(pVampire->getHP(ATTR_MAX), ATTR_CURRENT);
			modifyPkt.addShortData(MODIFY_CURRENT_HP, pVampire->getHP(ATTR_CURRENT));

			hpPkt.setObjectID(pVampire->getObjectID());
			hpPkt.setCurrentHP(pVampire->getHP(ATTR_CURRENT));
		}

		// 패킷 날려준다.
		removePkt.setObjectID(pVampire->getObjectID());
		pPlayer->sendPacket(&modifyPkt);
		pZone->broadcastPacket(pVampire->getX(), pVampire->getY(), &removePkt);
		pZone->broadcastPacket(pVampire->getX(), pVampire->getY(), &hpPkt, pVampire);

		//log(LOG_HEAL, pVampire->getName(), "");
	}
	else if (pCreature2->isOusters())
	{
		Ousters*             pOusters        = dynamic_cast<Ousters*>(pCreature2);
		EffectManager*      pEffectManager = pOusters->getEffectManager();
		GCModifyInformation modifyPkt;
		GCRemoveEffect      removePkt;
		GCStatusCurrentHP   hpPkt;

		// 먼저 HP랑 MP를 풀로 채워준다.
		if (pOusters->getHP(ATTR_CURRENT) < pOusters->getHP(ATTR_MAX) || pOusters->getSilverDamage() != 0 )
		{
			Silver_t prev = pOusters->getSilverDamage();

			if (prev != 0 )
			{
				pOusters->setSilverDamage(0);
				modifyPkt.addShortData(MODIFY_SILVER_DAMAGE, pOusters->getSilverDamage());
			}

			pOusters->setHP(pOusters->getHP(ATTR_MAX), ATTR_CURRENT);
			modifyPkt.addShortData(MODIFY_CURRENT_HP, pOusters->getHP(ATTR_CURRENT));

			hpPkt.setObjectID(pOusters->getObjectID());
			hpPkt.setCurrentHP(pOusters->getHP(ATTR_CURRENT));
		}
		if (pOusters->getMP(ATTR_CURRENT) < pOusters->getMP(ATTR_MAX))
		{
			pOusters->setMP(pOusters->getMP(ATTR_MAX), ATTR_CURRENT);
			modifyPkt.addShortData(MODIFY_CURRENT_MP, pOusters->getMP(ATTR_CURRENT));
		}

		// 독 이펙트를 삭제한다.
		Effect* pEffectPoison = pEffectManager->findEffect(Effect::EFFECT_CLASS_POISON);
		if (pEffectPoison != NULL)
		{
			// 이펙트 매니저에서 삭제한다.
			pEffectManager->deleteEffect(pOusters, Effect::EFFECT_CLASS_POISON);

			// 패킷에다 정보를 더한다.
			removePkt.addEffectList((EffectID_t)Effect::EFFECT_CLASS_POISON);
		}

		// 다크블루 포이즌 이펙트를 삭제한다.
		Effect* pEffectDarkBluePoison = pEffectManager->findEffect(Effect::EFFECT_CLASS_DARKBLUE_POISON);
		if (pEffectDarkBluePoison != NULL)
		{
			// 이펙트 매니저에서 삭제한다.
			pEffectManager->deleteEffect(pOusters, Effect::EFFECT_CLASS_DARKBLUE_POISON);

			// 패킷에다 정보를 더한다.
			removePkt.addEffectList((EffectID_t)Effect::EFFECT_CLASS_DARKBLUE_POISON);
		}

		// 흡혈 이펙트를 삭제한다.
		Effect* pBloodDrainEffect = pEffectManager->findEffect(Effect::EFFECT_CLASS_BLOOD_DRAIN);
		if (pBloodDrainEffect != NULL)
		{
			pBloodDrainEffect->setDeadline(0);

			// 흡혈 아르바이트를 방지하기 위한 후유증 이펙트를 붙여준다.
			if (pOusters->isFlag(Effect::EFFECT_CLASS_AFTERMATH))
			{
				Effect* pEffect = pEffectManager->findEffect(Effect::EFFECT_CLASS_AFTERMATH);
				EffectAftermath* pEffectAftermath = dynamic_cast<EffectAftermath*>(pEffect);
				pEffectAftermath->setDeadline(5*600); // 5분 동안 지속된다.
			}
			else
			{
				EffectAftermath* pEffectAftermath = new EffectAftermath(pOusters);
				pEffectAftermath->setDeadline(5*600); // 5분 동안 지속된다.
				pEffectManager->addEffect(pEffectAftermath);
				pOusters->setFlag(Effect::EFFECT_CLASS_AFTERMATH);
				pEffectAftermath->create(pOusters->getName());
			}

			// 패킷에다 정보를 더한다.
			removePkt.addEffectList((EffectID_t)Effect::EFFECT_CLASS_BLOOD_DRAIN);
		}


		// 패킷 날려준다.
		removePkt.setObjectID(pOusters->getObjectID());
		pPlayer->sendPacket(&modifyPkt);
		pZone->broadcastPacket(pOusters->getX(), pOusters->getY(), &removePkt);
		pZone->broadcastPacket(pOusters->getX(), pOusters->getY(), &hpPkt, pOusters);

		//log(LOG_HEAL, pOusters->getName(), "");

	}
	__END_CATCH
}
Beispiel #6
0
void EventResurrect::activate () 
	throw(Error)
{
	__BEGIN_TRY
	__BEGIN_DEBUG

	Assert(m_pGamePlayer != NULL);

	Creature * pDeadPC = m_pGamePlayer->getCreature();

	Assert(pDeadPC != NULL);

	// 하이드한 상태에서 죽었다면, 하이드를 풀어준다.
	pDeadPC->removeFlag(Effect::EFFECT_CLASS_HIDE);

	// 무브모드를 바꿔준다.
	if (pDeadPC->isVampire() && pDeadPC->isFlag(Effect::EFFECT_CLASS_TRANSFORM_TO_BAT))
	{
		pDeadPC->setMoveMode(Creature::MOVE_MODE_FLYING);
	}
	else
	{
		pDeadPC->setMoveMode(Creature::MOVE_MODE_WALKING);
	}

	// HP를 채워준다.
	if (pDeadPC->isSlayer())
	{
		Slayer* pSlayer = dynamic_cast<Slayer*>(pDeadPC);
		pSlayer->setHP(pSlayer->getHP(ATTR_MAX), ATTR_CURRENT);
	}
	else if (pDeadPC->isVampire())
	{
		Vampire* pVampire = dynamic_cast<Vampire*>(pDeadPC);
		pVampire->setHP(pVampire->getHP(ATTR_MAX), ATTR_CURRENT);
	}
	else if (pDeadPC->isOusters())
	{
		Ousters* pOusters = dynamic_cast<Ousters*>(pDeadPC);
		pOusters->setHP(pOusters->getHP(ATTR_MAX), ATTR_CURRENT);
	}

	// 새 zone을 설정하지 않는다. by sigi. 2002.5.11
	Zone* pOldZone = pDeadPC->getZone();
	Assert(pOldZone != NULL);

	try 
	{
		// 존그룹의 ZPM에서 플레이어를 삭제한다.
		pOldZone->getZoneGroup()->getZonePlayerManager()->deletePlayer(m_pGamePlayer->getSocket()->getSOCKET());

		// 여기서 설정해줘야지만 Save 이벤트가 IPM에서 동작하지 않는다.
		m_pGamePlayer->setPlayerStatus(GPS_WAITING_FOR_CG_READY);

		// IPM으로 플레이어를 옮긴다.
		//g_pIncomingPlayerManager->pushPlayer(m_pGamePlayer);
		pOldZone->getZoneGroup()->getZonePlayerManager()->pushOutPlayer(m_pGamePlayer);

	} 
	catch (NoSuchElementException& t) 
	{
		filelog("eventRessurect.txt", "%s-%s", t.toString().c_str(), pDeadPC->getName().c_str());
		cerr << "EventResurrect::activate() : NoSuchElementException" << endl;
		//throw Error("존에 플레이어가 존재하지 않습니다.");
		// 어떻게 없어졌겠지.. -_-;
		// 무시하고.. 그냥 진행한다.
		// by sigi. 2002.11.25
	}

	// 죽었을 당시 killCreature에서 존을 셋팅 하기 때문에 그냥 할당 받으면 된다.

	// 이거는 ZonePlayerManager의 heartbeat에서 처리한다.
	// 주석처리 by sigi. 2002.5.14
	//pDeadPC->registerObject();

	/*
	// GCUpdateInfo 패킷을 만들어둔다.
	GCUpdateInfo gcUpdateInfo;

	makeGCUpdateInfo(&gcUpdateInfo, pDeadPC);
	
	m_pGamePlayer->sendPacket(&gcUpdateInfo);
	*/

	__END_DEBUG
	__END_CATCH
}
Beispiel #7
0
//////////////////////////////////////////////////////////////////////////////
// 뱀파이어 오브젝트 핸들러
//////////////////////////////////////////////////////////////////////////////
void BiteOfDeath::execute(Vampire* pVampire, ObjectID_t TargetObjectID, VampireSkillSlot* pSkillSlot, CEffectID_t CEffectID)
	throw(Error)
{
	__BEGIN_TRY
		
	//cout << "TID[" << Thread::self() << "]" << getSkillHandlerName() << "begin " << endl;

	Assert(pVampire != NULL);
	
	try 
	{
		Player* pPlayer = pVampire->getPlayer();
		Zone* pZone = pVampire->getZone();
		Assert(pPlayer != NULL);
		Assert(pZone != NULL);

		Creature* pTargetCreature = pZone->getCreature(TargetObjectID);
		//Assert(pTargetCreature != NULL);

		// NPC는 공격할 수 없다.
		// 저주 면역. by sigi. 2002.9.13
		// NoSuch제거. by sigi. 2002.5.2
		if (pTargetCreature==NULL
			|| !canAttack(pVampire, pTargetCreature )
			|| pTargetCreature->isNPC()
			|| !pVampire->isFlag(Effect::EFFECT_CLASS_TRANSFORM_TO_WERWOLF)
			|| pTargetCreature->isDead()
			|| pTargetCreature->isFlag(Effect::EFFECT_CLASS_COMA))
		{
			executeSkillFailException(pVampire, getSkillType());
			//cout << "TID[" << Thread::self() << "]" << getSkillHandlerName() << " end " << endl;
			return;
		}

		GCSkillToObjectOK1 _GCSkillToObjectOK1;
		GCSkillToObjectOK2 _GCSkillToObjectOK2;
		GCSkillToObjectOK3 _GCSkillToObjectOK3;
		GCSkillToObjectOK4 _GCSkillToObjectOK4;
		GCSkillToObjectOK5 _GCSkillToObjectOK5;
		GCSkillToObjectOK6 _GCSkillToObjectOK6;

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

		int  RequiredMP  = decreaseConsumeMP(pVampire, pSkillInfo);
		bool bManaCheck  = hasEnoughMana(pVampire, RequiredMP);
		bool bRangeCheck = verifyDistance(pVampire, pTargetCreature, pSkillInfo->getRange());
		bool bHitRoll    = HitRoll::isSuccessBloodDrain(pVampire, pTargetCreature);
		bool bCanHit     = canHit(pVampire, pTargetCreature, SkillType);
		bool bPK         = verifyPK(pVampire, pTargetCreature);
		bool bMaster	 = false;

		if (pTargetCreature->isMonster() )
		{
			Monster* pTargetMonster = dynamic_cast<Monster*>(pTargetCreature);
			Assert(pTargetMonster != NULL);

			if (pTargetMonster->isMaster()
#ifdef __UNDERWORLD__
					|| pTargetMonster->isUnderworld() || pTargetMonster->getMonsterType() == 599
#endif
			)
			{
				bMaster = true;
			}
		}

		ZoneCoord_t targetX = pTargetCreature->getX();
		ZoneCoord_t targetY = pTargetCreature->getY();
		ZoneCoord_t myX     = pVampire->getX();
		ZoneCoord_t myY     = pVampire->getY();

		if (bManaCheck && bRangeCheck && bHitRoll && bCanHit && bPK && !bMaster)
		{
			decreaseMana(pVampire, RequiredMP, _GCSkillToObjectOK1);

        	bool bCanSeeCaster = canSee(pTargetCreature, pVampire);

			Exp_t Exp = computeCreatureExp(pTargetCreature, BLOODDRAIN_EXP + KILL_EXP);
			shareVampExp(pVampire, Exp, _GCSkillToObjectOK1);

			if (!pVampire->isFlag(Effect::EFFECT_CLASS_MEPHISTO))
			{
				HP_t HealPoint = (Exp==0? computeBloodDrainHealPoint(pTargetCreature, BLOODDRAIN_EXP) : Exp);
				HP_t CurrentHP = pVampire->getHP();
				HP_t MaxHP	   = pVampire->getHP(ATTR_MAX);
				HP_t NewHP     = min((int)MaxHP , (int)CurrentHP + (int)HealPoint);

				// 은 데미지 관련 처리를 해 준다.
				Silver_t newSilverDamage = max(0, (int)pVampire->getSilverDamage()-(int)HealPoint);
				pVampire->saveSilverDamage(newSilverDamage);
				_GCSkillToObjectOK1.addShortData(MODIFY_SILVER_DAMAGE, newSilverDamage);

				// 뱀파이어의 HP를 세팅한다.
				pVampire->setHP(NewHP);

				GCStatusCurrentHP gcStatusCurrentHP;
				gcStatusCurrentHP.setObjectID(pVampire->getObjectID());
				gcStatusCurrentHP.setCurrentHP(NewHP);
				pZone->broadcastPacket(pVampire->getX(), pVampire->getY(), &gcStatusCurrentHP, pVampire);

				_GCSkillToObjectOK1.addShortData(MODIFY_CURRENT_HP, NewHP);
			}


			// 타겟 쥑여뿐다.
			if (pTargetCreature->isSlayer() )
			{
				Slayer* pSlayer = dynamic_cast<Slayer*>(pTargetCreature);
				pSlayer->setHP(0);
			}
			else if (pTargetCreature->isVampire() )
			{
				Vampire* pTargetVampire = dynamic_cast<Vampire*>(pTargetCreature);
				pTargetVampire->setHP(0);
			}
			else if (pTargetCreature->isOusters() )
			{
				Ousters* pOusters = dynamic_cast<Ousters*>(pTargetCreature);
				pOusters->setHP(0);
			}
			else if (pTargetCreature->isMonster() )
			{
				Monster* pMonster = dynamic_cast<Monster*>(pTargetCreature);
				HP_t decreaseHP = pMonster->getHP();
				pMonster->setHP(0);

				increaseFame(pVampire, decreaseHP);
				_GCSkillToObjectOK1.addLongData(MODIFY_FAME, pVampire->getFame());
			}
			else Assert(false);

			affectKillCount(pVampire, pTargetCreature);

			_GCSkillToObjectOK1.setSkillType(SkillType);
			_GCSkillToObjectOK1.setCEffectID(CEffectID);
			_GCSkillToObjectOK1.setTargetObjectID(TargetObjectID);
		
			_GCSkillToObjectOK2.setObjectID(pVampire->getObjectID());
			_GCSkillToObjectOK2.setSkillType(SkillType);
		
			_GCSkillToObjectOK3.setObjectID(pVampire->getObjectID());
			_GCSkillToObjectOK3.setSkillType(SkillType);
			_GCSkillToObjectOK3.setTargetXY (targetX, targetY);
			
			_GCSkillToObjectOK4.setSkillType(SkillType);
			_GCSkillToObjectOK4.setTargetObjectID(TargetObjectID);
			
			_GCSkillToObjectOK5.setObjectID(pVampire->getObjectID());
			_GCSkillToObjectOK5.setSkillType(SkillType);
			_GCSkillToObjectOK5.setTargetObjectID (TargetObjectID);
			
			_GCSkillToObjectOK6.setXY(myX, myY);
			_GCSkillToObjectOK6.setSkillType(SkillType);

			if (bCanSeeCaster) // 10은 땜빵 수치다.
			{
				computeAlignmentChange(pTargetCreature, 10, pVampire, &_GCSkillToObjectOK2, &_GCSkillToObjectOK1);
			}
			else // 10은 땜빵 수치다.
			{
				computeAlignmentChange(pTargetCreature, 10, pVampire, &_GCSkillToObjectOK6, &_GCSkillToObjectOK1);
			}
								
			list<Creature *> cList;
			cList.push_back(pTargetCreature);
			cList.push_back(pVampire);
			cList = pZone->broadcastSkillPacket(myX, myY, targetX, targetY, &_GCSkillToObjectOK5, cList);

			pZone->broadcastPacket(myX, myY, &_GCSkillToObjectOK3, cList);
			pZone->broadcastPacket(targetX, targetY, &_GCSkillToObjectOK4, cList);

			// Send Packet
			pPlayer->sendPacket(&_GCSkillToObjectOK1);

			if (pTargetCreature->isPC()) 
			{
				Player* pTargetPlayer = pTargetCreature->getPlayer();
				if (pTargetPlayer == NULL)
				{
					//cout << "TID[" << Thread::self() << "]" << getSkillHandlerName() << " end " << endl;
					return;
				}

				if (bCanSeeCaster) pTargetPlayer->sendPacket(&_GCSkillToObjectOK2);
				else pTargetPlayer->sendPacket(&_GCSkillToObjectOK6);
			}
			else if (pTargetCreature->isMonster())
			{
				Monster* pTargetMonster = dynamic_cast<Monster*>(pTargetCreature);
				pTargetMonster->addEnemy(pVampire);
			}
		} 
		else 
		{
			executeSkillFailNormal(pVampire, getSkillType(), pTargetCreature);
		}
	}
	catch (Throwable & t) 
	{
		executeSkillFailException(pVampire, getSkillType());
	}

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

	__END_CATCH
}