Beispiel #1
0
void EffectBlazeWalk::affect(Creature* pCreature)
	throw(Error)
{
	__BEGIN_TRY

	Assert(pCreature != NULL);

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

	Creature* pAttacker = pZone->getCreature(m_UserObjectID);
	if (pAttacker == NULL )
	{
		setDeadline(0);
		return;
	}

	if (!(pZone->getZoneLevel() & COMPLETE_SAFE_ZONE)
		&& !pCreature->isDead()
		&& !pCreature->isFlag(Effect::EFFECT_CLASS_COMA )
		// 무적상태 체크. by sigi. 2002.9.5
		&& canAttack(pAttacker, pCreature )
	   )
	{
		GCModifyInformation gcMI, gcAttackerMI;
		setDamage(pCreature, m_Point, pAttacker, m_SkillType, &gcMI, &gcAttackerMI);

		if (pAttacker->isPC() ) computeAlignmentChange(pCreature, m_Point, pAttacker, &gcMI, &gcAttackerMI);
		if (pCreature->isPC() ) pCreature->getPlayer()->sendPacket(&gcMI);

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

			if (pSlayer != NULL )
			{
				GCModifyInformation gcMI;
				shareAttrExp(pSlayer, m_Point, 8, 1, 1, gcAttackerMI);
			}
		}

		if (pAttacker->isPC() ) pAttacker->getPlayer()->sendPacket(&gcAttackerMI);

		if (pCreature->isDead() ) setDeadline(0);
	}

	m_AttackNum--;

	if (m_AttackNum > 0 )
	{
		setNextTime(5);
	}
	else setDeadline(0);

//cout << "EffectBlazeWalk " << "begin" << endl;
	//cout << "EffectBlazeWalk " << "end" << endl;

	__END_CATCH
}
void EffectDivineGuidance::affect(Creature* pCreature)
	throw(Error)
{
	__BEGIN_TRY

	//cout << "EffectDivineGuidance " << "begin" << endl;
	//cout << "EffectDivineGuidance " << "end" << endl;
	Assert(pCreature != NULL);

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

	Creature* pAttacker = pZone->getCreature(m_UserObjectID);

	if (!(pZone->getZoneLevel() & COMPLETE_SAFE_ZONE)
		&& !pCreature->isDead()
		&& !pCreature->isFlag(Effect::EFFECT_CLASS_COMA)
		// 무적상태 체크. by sigi. 2002.9.5
		&& canAttack(pAttacker, pCreature )
	   )
	{
		GCModifyInformation gcMI, gcAttackerMI;
		setDamage(pCreature, m_Point, pAttacker, SKILL_DIVINE_GUIDANCE, &gcMI, &gcAttackerMI);
		if (pCreature->isPC() ) pCreature->getPlayer()->sendPacket(&gcMI);

		if (pAttacker!=NULL) 
		{
			computeAlignmentChange(pCreature, m_Point, pAttacker, &gcMI, &gcAttackerMI);
			if (pAttacker->isPC() )
			{ 
				if (pAttacker->isSlayer() && !pCreature->isSlayer() )
				{
					Slayer* pSlayer = dynamic_cast<Slayer*>(pAttacker);

					if (pSlayer != NULL )
					{
						GCModifyInformation gcMI;
						shareAttrExp(pSlayer, m_Point, 1, 1, 8, gcAttackerMI);
					}
				}

				if (pAttacker->isPC() ) pAttacker->getPlayer()->sendPacket(&gcAttackerMI);
			}
		}

	}

	setNextTime(m_Tick);

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

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

	try 
	{
		GamePlayer* pGamePlayer = dynamic_cast<GamePlayer*>(pPlayer);
		Assert(pGamePlayer != NULL);	// by sigi

		if (pGamePlayer->getPlayerStatus() != GPS_NORMAL) return;

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

		Zone* pZone = pCreature->getZone();
		Assert(pZone != NULL);
	
		SkillType_t SkillType = pPacket->getSkillType();

		// 완전 안전지대라면 기술 사용 불가. by sigi. 2002.11.14
		ZoneLevel_t ZoneLevel = pZone->getZoneLevel(pCreature->getX(), pCreature->getY());
		if ((ZoneLevel & COMPLETE_SAFE_ZONE) ||
            (pCreature->isFlag(Effect::EFFECT_CLASS_PARALYZE)) ||
            (pCreature->isFlag(Effect::EFFECT_CLASS_CAUSE_CRITICAL_WOUNDS)) ||
            (pCreature->isFlag(Effect::EFFECT_CLASS_EXPLOSION_WATER)) ||
            (pCreature->isFlag(Effect::EFFECT_CLASS_COMA)))
		{
			GCSkillFailed1 _GCSkillFailed1;
			_GCSkillFailed1.setSkillType(SkillType);
			pPlayer->sendPacket(&_GCSkillFailed1);

			return;
		}

        if (pCreature->isFlag(Effect::EFFECT_CLASS_TRANSFORM_TO_WERWOLF)) {
            switch(SkillType) {
                case SKILL_ATTACK_MELEE:
                case SKILL_BITE_OF_DEATH:
                case SKILL_UN_TRANSFORM:
                case SKILL_RAPID_GLIDING:
                    break;
                default:
                    GCSkillFailed1 _GCSkillFailed1;
                    _GCSkillFailed1.setSkillType(SkillType);
                    pPlayer->sendPacket(&_GCSkillFailed1);
                    dynamic_cast<Vampire*>(pCreature)->sendVampireSkillInfo();
                    return;
            }
        }

		disableFlags(pCreature, pZone, SkillType);

		if (pCreature->isSlayer()) 
		{
			Slayer*    pSlayer    = dynamic_cast<Slayer*>(pCreature);
			SkillSlot* pSkillSlot = ((Slayer *)pCreature)->hasSkill(SkillType);
			bool       bSuccess   = true;

			if (pSkillSlot == NULL) bSuccess = false;
			if (!isAbleToUseSelfSkill(pSlayer, SkillType)) bSuccess = false;

/*			if (pSlayer->isFlag(Effect::EFFECT_CLASS_SNIPING_MODE))
			{
				g_Sniping.checkRevealRatio(pSlayer, 20, 10);
			} */

			if (bSuccess) 
			{
				SkillHandler* pSkillHandler = g_pSkillHandlerManager->getSkillHandler(SkillType);
				Assert(pSkillHandler != NULL);
				pSkillHandler->execute(pSlayer, pPacket->getTargetName(), pSkillSlot, pPacket->getCEffectID());
			 }
			 else
			 {
				 GCSkillFailed1 _GCSkillFailed1;
				_GCSkillFailed1.setSkillType(SkillType);
				 pPlayer->sendPacket(&_GCSkillFailed1);
			 }
		} 
		else if (pCreature->isVampire()) 
		{
			Vampire*          pVampire          = dynamic_cast<Vampire*>(pCreature);
			VampireSkillSlot* pVampireSkillSlot = ((Vampire *)pCreature)->hasSkill(SkillType);
			bool              bSuccess          = true;

			//cout << "SkillType:" << (int)SkillType << endl;

/*			if (pVampire->isFlag(Effect::EFFECT_CLASS_EXTREME))
		    {
		   		EffectManager * pEffectManager = pVampire->getEffectManager();
		    	Assert(pEffectManager != NULL);
		    	Effect * pEffect = pEffectManager->findEffect(Effect::EFFECT_CLASS_EXTREME);
		    	if (pEffect != NULL ) {
		    		pEffect->setDeadline(0);
		   	 	}
            } */
			if (pVampireSkillSlot == NULL) bSuccess = false;
			if (!isAbleToUseSelfSkill(pVampire, SkillType)) bSuccess = false;

/*			if (pVampire->isFlag(Effect::EFFECT_CLASS_INVISIBILITY))
			{
				addVisibleCreature(pZone, pVampire, true);
			} */

			if (bSuccess) 
			{
				SkillHandler* pSkillHandler = g_pSkillHandlerManager->getSkillHandler(SkillType);
				Assert(pSkillHandler != NULL);
				pSkillHandler->execute(pVampire, pPacket->getTargetName(), pVampireSkillSlot, pPacket->getCEffectID());
			}
			else
			{
				GCSkillFailed1 _GCSkillFailed1;
				_GCSkillFailed1.setSkillType(SkillType);
				pPlayer->sendPacket(&_GCSkillFailed1);
			}
		} 
		else if (pCreature->isOusters()) 
		{
			Ousters*          pOusters          = dynamic_cast<Ousters*>(pCreature);
			OustersSkillSlot* pOustersSkillSlot = ((Ousters *)pCreature)->hasSkill(SkillType);
			bool              bSuccess          = true;

			if (pOustersSkillSlot == NULL) bSuccess = false;
			if (!isAbleToUseSelfSkill(pOusters, SkillType)) bSuccess = false;

			if (bSuccess) 
			{
				SkillHandler* pSkillHandler = g_pSkillHandlerManager->getSkillHandler(SkillType);
				Assert(pSkillHandler != NULL);
				pSkillHandler->execute(pOusters, pPacket->getTargetName(), pOustersSkillSlot, pPacket->getCEffectID());
			}
			else
			{
				GCSkillFailed1 _GCSkillFailed1;
				_GCSkillFailed1.setSkillType(SkillType);
				pPlayer->sendPacket(&_GCSkillFailed1);
			}
		} 
	} 
	catch (Throwable & t) 
	{
		//cout << t.toString() << endl;
	}

#endif	// __GAME_SERVER__
		
	__END_DEBUG_EX __END_CATCH
}
void EffectPlasmaRocketLauncher::affect(Creature* pCreature)
	throw(Error)
{
	__BEGIN_TRY
	__BEGIN_DEBUG

	Assert(pCreature != NULL);

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

	Creature* pAttacker = pZone->getCreature(m_UserObjectID);

	VSRect rect(0, 0, pZone->getWidth()-1, pZone->getHeight()-1);

	int cX = pCreature->getX();
	int cY = pCreature->getY();
	
	for(int x = -1; x <= 1; x++)
	{
		for(int y= -1; y <= 1; y++)
		{
			int X = cX + x;
			int Y = cY + y;

			if(!rect.ptInRect(X, Y)) continue;
			Tile& tile = pZone->getTile(X, Y);
			
			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* pCreature2 = dynamic_cast<Creature*>(pObject);
					Assert(pCreature2 != NULL);

					if (pCreature2 != pCreature && pCreature2->isSlayer() ) continue;
	
					if (!(pZone->getZoneLevel() & COMPLETE_SAFE_ZONE)
						&& !pCreature2->isDead()
						&& !pCreature2->isFlag(Effect::EFFECT_CLASS_COMA)
						// 무적상태 체크. by sigi. 2002.9.5
						&& canAttack(pAttacker, pCreature2 )
					   )
					{
						GCModifyInformation gcMI, gcAttackerMI;
						setDamage(pCreature2, m_Point, pAttacker, SKILL_PLASMA_ROCKET_LAUNCHER, &gcMI, &gcAttackerMI);
						if (pCreature2->isPC() ) pCreature2->getPlayer()->sendPacket(&gcMI);

						if (pAttacker!=NULL) 
						{
							computeAlignmentChange(pCreature2, m_Point, pAttacker, &gcMI, &gcAttackerMI);
							if (pAttacker->isPC() )
							{ 
								if (pAttacker->isSlayer() && !pCreature2->isSlayer() )
								{
									Slayer* pSlayer = dynamic_cast<Slayer*>(pAttacker);

									if (pSlayer != NULL )
									{
										GCModifyInformation gcMI;
										shareAttrExp(pSlayer, m_Point, 1, 8, 1, gcAttackerMI);
									}
								}

								if (pAttacker->isPC() ) pAttacker->getPlayer()->sendPacket(&gcAttackerMI);
							}
						}
					}

				}
				
			}
		}
	}

	setDeadline(0);

	__END_DEBUG
	__END_CATCH
}
Beispiel #5
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
}
Beispiel #6
0
void EffectPoison::affect(Creature* pCreature)
	throw(Error)
{
	__BEGIN_TRY

	//cout << "EffectPoison " << "begin" << endl;

	Assert(pCreature != NULL);

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

	// 스킬 사용자를 가져온다.
	// !! 이미 존을 나갔을 수 있으므로 NULL이 될 수 있다.
	// by bezz. 2003.1.4
	Creature* pCastCreature = pZone->getCreature(m_UserObjectID);

	// EffectPoison이 크리쳐에게 걸리게 되는 경우에는 현재로서는 
	// GreenPoison에 의해 타일 위에 생긴 
	// EffectGreenPoison 위를 플레이어가 지나갈 때 뿐이다.
	// EffectGreenPoison 내부에서 저항을 고려해서 데미지를 세팅한 다음
	// EffectPoison을 붙이므로, 내부에서 한번 더 계산하면 안된다.
	//Damage_t PoisonDamage = computeMagicDamage(pCreature, m_Point, MAGIC_DOMAIN_POISON, m_Level);
	Damage_t PoisonDamage = m_Point;

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

			GCModifyInformation gcMI;
			::setDamage(pSlayer, PoisonDamage, pCastCreature, SKILL_GREEN_POISON, &gcMI);
			pSlayer->getPlayer()->sendPacket(&gcMI);
		}
		else if (pCreature->isVampire())
		{
			Vampire* pVampire = dynamic_cast<Vampire*>(pCreature);

			GCModifyInformation gcMI;
			::setDamage(pVampire, PoisonDamage, pCastCreature, SKILL_GREEN_POISON, &gcMI);
			pVampire->getPlayer()->sendPacket(&gcMI);
		}
		else if (pCreature->isOusters())
		{
			Ousters* pOusters = dynamic_cast<Ousters*>(pCreature);

			GCModifyInformation gcMI;
			::setDamage(pOusters, PoisonDamage, pCastCreature, SKILL_GREEN_POISON, &gcMI);
			pOusters->getPlayer()->sendPacket(&gcMI);
		}
		else if (pCreature->isMonster())
		{
			Monster* pMonster = dynamic_cast<Monster*>(pCreature);

			::setDamage(pMonster, PoisonDamage, pCastCreature, SKILL_GREEN_POISON);
		}

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

			if (pAttacker!=NULL)
			{ 
				affectKillCount(pAttacker, pCreature);
			}
		}*/
	}
	
	setNextTime(m_Tick);

	//cout << "EffectPoison " << "end" << endl;

	__END_CATCH
}
Beispiel #7
0
void EffectStormPoison::affect(Creature* pCreature)
	throw(Error)
{
	__BEGIN_TRY

	//cout << "EffectStormPoison " << "begin" << endl;

	Assert(pCreature != NULL);

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

	// 사용자를 가져온다.
	// !! 이미 존을 나갔을 수 있으므로 NULL이 될 수 있다.
	// by bezz. 2003.3.13
	Creature* pCastCreature = pZone->getCreature(m_UserObjectID);
	// 캐스터가 없으면 무시한다.
	if (pCastCreature == NULL )
		return;

	// EffectStormPoison은 AcidStorm, PoisonStorm, BloodyStorm위를 지나갈때 붙는다.
	// 이는 3번의 연속 데미지를 주고 사라진다.

	Damage_t StormDamage = m_Point;
	GCModifyInformation GCAttackerMI;

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

			GCModifyInformation gcMI;
			setDamage(pSlayer, StormDamage, pCastCreature, SKILL_POISON_STORM, &gcMI, &GCAttackerMI);

			pSlayer->getPlayer()->sendPacket(&gcMI);
		}
		else if (pCreature->isVampire())
		{
			Vampire* pVampire = dynamic_cast<Vampire*>(pCreature);

			GCModifyInformation gcMI;
			setDamage(pVampire, StormDamage, pCastCreature, SKILL_POISON_STORM, &gcMI, &GCAttackerMI);

			pVampire->getPlayer()->sendPacket(&gcMI);
		}
		else if (pCreature->isOusters())
		{
			Ousters* pOusters = dynamic_cast<Ousters*>(pCreature);

			GCModifyInformation gcMI;
			setDamage(pOusters, StormDamage, pCastCreature, SKILL_POISON_STORM, &gcMI, &GCAttackerMI);

			pOusters->getPlayer()->sendPacket(&gcMI);
		}
		else if (pCreature->isMonster())
		{
			Monster* pMonster = dynamic_cast<Monster*>(pCreature);

			setDamage(pMonster, StormDamage, pCastCreature, SKILL_POISON_STORM, NULL, &GCAttackerMI);
		}

		if (pCastCreature->isVampire() && pCreature->isDead() )
		{
			Vampire* pVampire = dynamic_cast<Vampire*>(pCastCreature);
			int exp = computeCreatureExp(pCreature, KILL_EXP);
			shareVampExp(pVampire, exp, GCAttackerMI);
			pVampire->getPlayer()->sendPacket(&GCAttackerMI);
		}

		// m_CasterName이 pCreature를 죽인 경우의 KillCount 처리
		// by sigi. 2002.9.9
		// set damage 를 불러서 처리한다. 주석 처리
		// by bezz. 2002.12.31
/*		if (pCreature->isDead())
		{
			Creature* pAttacker = pZone->getCreature(m_UserObjectID);

			if (pAttacker!=NULL)
			{ 
				affectKillCount(pAttacker, pCreature);
			}
		}*/
	}
	
	setNextTime(m_Tick);

	//cout << "EffectStormPoison " << "end" << endl;

	__END_CATCH
}
void CGUseMessageItemFromInventoryHandler::executeEventTree(CGUseMessageItemFromInventory* pPacket, Player* pPlayer)
	throw(ProtocolException, Error)
{
	__BEGIN_TRY __BEGIN_DEBUG_EX

#ifdef __GAME_SERVER__

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

	// 상위 함수에서 에러 체크를 많이 했기 때문에,
	// 에러 체크를 대폭 축소한다.
	GamePlayer*     pGamePlayer  = dynamic_cast<GamePlayer*>(pPlayer);
	Creature*       pCreature    = pGamePlayer->getCreature();
	PlayerCreature* pPC          = dynamic_cast<PlayerCreature*>(pCreature);
	Inventory*      pInventory   = pPC->getInventory();
	Zone*           pZone        = pPC->getZone();
	CoordInven_t    InvenX       = pPacket->getX();
	CoordInven_t    InvenY       = pPacket->getY();
	Item*           pItem        = pInventory->getItem(InvenX, InvenY);
	ObjectID_t      ItemObjectID = pItem->getObjectID();
	MonsterType_t	MType		 = 0;

	int				time		 = 0;

	switch (pItem->getItemType() )
	{
		case 12:
			MType = 482;
			time = g_pVariableManager->getVariable(CHRISTMAS_TREE_DECAY_TIME ) / 10;
			break;
		case 26:
			MType = 650;
			time = 21600;
			break;
		case 27:
			MType = 650;
			time = 43200;
			break;
		case 28:
			MType = 650;
			time = 86400;
			break;
		default:
			{
				filelog("EventTree.log", "이상한 아템을 썼다. : %s 가 %d", pPC->getName().c_str(), pItem->getItemType());
				GCCannotUse _GCCannotUse;
				_GCCannotUse.setObjectID(pPacket->getObjectID());
				pGamePlayer->sendPacket(&_GCCannotUse);
			}
			return;
	}

	// 타일에 스킬을 쓰는 것이라고 보고 쓸 수 있는지를 체크한다.
	// 안전지대에서는 사용할 수 없다.
	// 쓸 수 있는 아이템 타입인지 왁인한다. ItemType 이 12인 것만 사용할 수 있다.
	// 근처에(플레이어 주위의 5x5타일 이내) 다른 트리가 있다면 사용할 수 없다.
	if (!isAbleToUseTileSkill(pCreature )
		|| pZone->isMasterLair()
		|| ItemObjectID != pPacket->getObjectID()
		|| checkCorpse(pZone, MType, pPC->getX() - 2, pPC->getY() - 2, pPC->getX() + 2, pPC->getY() + 2 )
		)
	{
		GCCannotUse _GCCannotUse;
		_GCCannotUse.setObjectID(pPacket->getObjectID());
		pGamePlayer->sendPacket(&_GCCannotUse);
		return;
	}

	// 성이면 성주 길드원만 쓸 수 있다.
	if (!pPC->isGOD() )
	{
		if (pZone->isCastle() )
		{
			if (!g_pCastleInfoManager->isCastleMember(pZone->getZoneID(), pPC ) )
			{
				GCCannotUse _GCCannotUse;
				_GCCannotUse.setObjectID(pPacket->getObjectID());
				pGamePlayer->sendPacket(&_GCCannotUse);
				return;
			}
		}
		// 성이 아닌 곳의 안전지대에선 절대 못 쓴다.
		else if (pZone->getZoneLevel(pCreature->getX(), pCreature->getY()) & SAFE_ZONE)
		{
			GCCannotUse _GCCannotUse;
			_GCCannotUse.setObjectID(pPacket->getObjectID());
			pGamePlayer->sendPacket(&_GCCannotUse);
			return;
		}
	}

/*	// 트리를 존에 추가한다. (트리는 몬스터 시체를 이용한다)
    MonsterCorpse* pMonsterCorpse = new MonsterCorpse(482, pPacket->getMessage(), 2); 
    Assert(pMonsterCorpse!=NULL); 
 
    pZone->getObjectRegistry().registerObject(pMonsterCorpse); 
 
    // 생성된 시체를 존에 추가한다. 
	int delayTime = g_pVariableManager->getVariable(CHRISTMAS_TREE_DECAY_TIME); // by sigi. 2002.12.17
	TPOINT pt = pZone->addItem(pMonsterCorpse, pPC->getX(), pPC->getY(), true, delayTime);	// 6시간 뒤에 트리(시체)가 사라진다.
	if (pt.x == -1)*/
	if (!createBulletinBoard(pZone, pPC->getX(), pPC->getY(), MType, pPacket->getMessage(), 
				VSDateTime::currentDateTime().addSecs(time ) ) )
	{
		GCCannotUse _GCCannotUse;
		_GCCannotUse.setObjectID(pPacket->getObjectID());
		pGamePlayer->sendPacket(&_GCCannotUse);

		return;
	}

	// 사용한 아이템이므로 지워준다.
	pInventory->deleteItem(InvenX, InvenY);
	pItem->destroy();
	SAFE_DELETE(pItem);

	// 아이템을 사용했다고 클라이언트에 알린다.
	GCUseOK gcUseOK;
	pGamePlayer->sendPacket(&gcUseOK);

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

#endif
    __END_DEBUG_EX __END_CATCH
}
void EffectVigorDropToCreature::affect(Creature* pCreature)
	throw(Error)
{
	__BEGIN_TRY

	//cout << "EffectVigorDropToCreature " << "begin" << endl;

	Assert(pCreature != NULL);

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

	// 스킬 사용자를 가져온다.
	// !! 이미 존을 나갔을 수 있으므로 NULL이 될 수 있다.
	// by bezz. 2003.1.4
	Creature* pCastCreature = pZone->getCreature(m_UserObjectID);

	// EffectVigorDropToCreature은 AcidStorm, PoisonStorm, BloodyStorm위를 지나갈때 붙는다.
	// 이는 3번의 연속 데미지를 주고 사라진다.

	Damage_t DropDamage = m_Point;

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

			GCModifyInformation gcMI;
			setDamage(pSlayer, DropDamage, pCastCreature, SKILL_VIGOR_DROP, &gcMI);

			pSlayer->getPlayer()->sendPacket(&gcMI);
		}
		else if (pCreature->isVampire())
		{
			Vampire* pVampire = dynamic_cast<Vampire*>(pCreature);

			GCModifyInformation gcMI;
			setDamage(pVampire, DropDamage, pCastCreature, SKILL_VIGOR_DROP, &gcMI);

			pVampire->getPlayer()->sendPacket(&gcMI);
		}
		else if (pCreature->isOusters())
		{
			Ousters* pOusters = dynamic_cast<Ousters*>(pCreature);

			GCModifyInformation gcMI;
			setDamage(pOusters, DropDamage, pCastCreature, SKILL_VIGOR_DROP, &gcMI);

			pOusters->getPlayer()->sendPacket(&gcMI);
		}
		else if (pCreature->isMonster())
		{
			Monster* pMonster = dynamic_cast<Monster*>(pCreature);

			setDamage(pMonster, DropDamage, pCastCreature, SKILL_VIGOR_DROP);
		}

		// m_CasterName이 pCreature를 죽인 경우의 KillCount 처리
		// by sigi. 2002.9.9
		// setDamage 를 불러서 처리한다. 주석처리
		// by bezz. 2002.12.31
/*		if (pCreature->isDead())
		{
			Creature* pAttacker = pZone->getCreature(m_CasterName);

			if (pAttacker!=NULL)
			{ 
				affectKillCount(pAttacker, pCreature);
			}
		}*/
	}
	
	setNextTime(m_Tick);

	//cout << "EffectVigorDropToCreature " << "end" << endl;

	__END_CATCH
}
Beispiel #10
0
//////////////////////////////////////////////////////////////////////////////
// 뱀파이어 타일 핸들러
//////////////////////////////////////////////////////////////////////////////
void Darkness::execute(Vampire* pVampire, ZoneCoord_t X, ZoneCoord_t Y, VampireSkillSlot* pVampireSkillSlot, CEffectID_t CEffectID)
throw(Error)
{
    __BEGIN_TRY

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

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

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

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

        GCSkillToTileOK1 _GCSkillToTileOK1;
        GCSkillToTileOK2 _GCSkillToTileOK2;
        GCSkillToTileOK3 _GCSkillToTileOK3;
        GCSkillToTileOK4 _GCSkillToTileOK4;
        GCSkillToTileOK5 _GCSkillToTileOK5;
        GCSkillToTileOK6 _GCSkillToTileOK6;

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

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

        // Knowledge of Innate 가 있다면 hit bonus 10
        int HitBonus = 0;
        if (pVampire->hasRankBonus(RankBonus::RANK_BONUS_KNOWLEDGE_OF_INNATE ) )
        {
            RankBonus* pRankBonus = pVampire->getRankBonus(RankBonus::RANK_BONUS_KNOWLEDGE_OF_INNATE);
            Assert(pRankBonus != NULL);

            HitBonus = pRankBonus->getPoint();
        }

        int  RequiredMP  = decreaseConsumeMP(pVampire, pSkillInfo);
        bool bManaCheck  = hasEnoughMana(pVampire, RequiredMP);
        bool bTimeCheck  = verifyRunTime(pVampireSkillSlot);
        bool bRangeCheck = verifyDistance(pVampire, X, Y, pSkillInfo->getRange());
        bool bHitRoll    = HitRoll::isSuccessMagic(pVampire, pSkillInfo, pVampireSkillSlot, HitBonus);
        bool bSlayerSafeZone = pZone->getZoneLevel(X, Y ) & SLAYER_SAFE_ZONE;

        bool bTileCheck = false;
        VSRect rect(0, 0, pZone->getWidth()-1, pZone->getHeight()-1);
        if (rect.ptInRect(X, Y)) bTileCheck = true;

        if (bManaCheck && bTimeCheck && bRangeCheck && bHitRoll && bTileCheck && !bSlayerSafeZone)
        {
            decreaseMana(pVampire, RequiredMP, _GCSkillToTileOK1);

            // 이펙트의 지속시간을 계산한다.
            SkillInput input(pVampire);
            SkillOutput output;
            computeOutput(input, output);

            // Wisdom of Darkness 이 있다면 지속시간 30% 증가
            if (pVampire->hasRankBonus(RankBonus::RANK_BONUS_WISDOM_OF_DARKNESS ) )
            {
                RankBonus* pRankBonus = pVampire->getRankBonus(RankBonus::RANK_BONUS_WISDOM_OF_DARKNESS);
                Assert(pRankBonus != NULL);

                output.Duration += getPercentValue(output.Duration, pRankBonus->getPoint());
            }

            Range_t    Range    = 3;

            int oX, oY;

            list<Creature*> cList;	// denier list

            int edge = 1;

            // Wide Darkness 이 있다면 범위가 5*5 로 수정. skill type 을 수정한다.
            if (pVampire->hasRankBonus(RankBonus::RANK_BONUS_WIDE_DARKNESS ) )
            {
                RankBonus* pRankBonus = pVampire->getRankBonus(RankBonus::RANK_BONUS_WIDE_DARKNESS);
                Assert(pRankBonus != NULL);

                Range = pRankBonus->getPoint();
                edge = (pRankBonus->getPoint() - 1 ) / 2;

                SkillType = SKILL_DARKNESS_WIDE;
            }

//			map<int, uint> canAddMap;

            for(oY = -edge; oY <= edge; oY++)
                for(oX = -edge; oX <= edge; oX++)
                {
                    int tileX = X+oX;
                    int tileY = Y+oY;
                    if (rect.ptInRect(tileX, tileY))
                    {
                        Tile& tile = pZone->getTile(tileX, tileY);

//					if (canAddMap[normalizeCoord_DARKNESS(oX, oY, edge )] == 1 ) continue;

                        if (tile.hasItem() )
                        {
                            Item* pItem = tile.getItem();
                            if (pItem != NULL && pItem->getItemClass() == Item::ITEM_CLASS_CORPSE && pItem->getItemType() == MONSTER_CORPSE )
                            {
                                MonsterCorpse* pMonsterCorpse = dynamic_cast<MonsterCorpse*>(pItem);
                                if (g_pFlagManager->isFlagPole(pMonsterCorpse ) )
                                {
//								canAddMap[normalizeCoord_DARKNESS(oX+1, oY, edge )] = 1;
//								canAddMap[normalizeCoord_DARKNESS(oX+1, oY+1, edge )] = 1;
//								canAddMap[normalizeCoord_DARKNESS(oX, oY+1, edge )] = 1;
                                    continue;
                                }
                            }
                        }

                        if (tile.getEffect(Effect::EFFECT_CLASS_TRYING_POSITION ) != NULL ) continue;

                        // 현재 타일에다 이펙트를 추가할 수 있다면...
                        if (tile.canAddEffect())
                        {
                            // 머시 그라운드 있음 추가 못한당.
                            if (tile.getEffect(Effect::EFFECT_CLASS_MERCY_GROUND) != NULL ) continue;
                            if (tile.getEffect(Effect::EFFECT_CLASS_DARKNESS_FORBIDDEN) != NULL ) continue;

                            // 같은 effect가 있으면 지운다.
                            Effect* pOldEffect = tile.getEffect(Effect::EFFECT_CLASS_DARKNESS);
                            if (pOldEffect != NULL)
                            {
                                ObjectID_t effectID = pOldEffect->getObjectID();
                                pZone->deleteEffect(effectID);// fix me
                            }

                            // 이펙트 클래스를 생성한다.
                            EffectDarkness* pEffect = new EffectDarkness(pZone , tileX, tileY);
                            pEffect->setDeadline(output.Duration);
                            pEffect->setLevel(pVampire->getINT());
                            pEffect->setDuration(output.Duration);
                            pEffect->setStartTime();

                            // Tile에 붙이는 Effect는 ObjectID를 등록받아야 한다.
                            ObjectRegistry & objectregister = pZone->getObjectRegistry();
                            objectregister.registerObject(pEffect);
                            pZone->addEffect(pEffect);
                            tile.addEffect(pEffect);

                            const list<Object*>& oList = tile.getObjectList();
                            for(list<Object*>::const_iterator itr = oList.begin(); itr != oList.end(); itr++)
                            {
                                Object* pTarget = *itr;
                                Creature* pTargetCreature = NULL;
                                if (pTarget->getObjectClass() == Object::OBJECT_CLASS_CREATURE
                                        && ((pTargetCreature = dynamic_cast<Creature*>(pTarget))->isSlayer() || pTargetCreature->isOusters() )
                                   )
                                {
                                    cList.push_back(pTargetCreature);
                                    _GCSkillToTileOK2.addCListElement(pTargetCreature->getObjectID());
                                    _GCSkillToTileOK4.addCListElement(pTargetCreature->getObjectID());
                                    _GCSkillToTileOK5.addCListElement(pTargetCreature->getObjectID());
                                }

                                pEffect->affectObject(pTarget, false);
                            }
                        }
                    }
                }

            _GCSkillToTileOK1.setSkillType(SkillType);
            _GCSkillToTileOK1.setCEffectID(CEffectID);
            _GCSkillToTileOK1.setX(X);
            _GCSkillToTileOK1.setY(Y);
            _GCSkillToTileOK1.setDuration(output.Duration);
            _GCSkillToTileOK1.setRange(Range);

            _GCSkillToTileOK2.setObjectID(pVampire->getObjectID());
            _GCSkillToTileOK2.setSkillType(SkillType);
            _GCSkillToTileOK2.setX(X);
            _GCSkillToTileOK2.setY(Y);
            _GCSkillToTileOK2.setDuration(output.Duration);
            _GCSkillToTileOK2.setRange(Range);
            //_GCSkillToTileOK2.addShortData(MODIFY_VISION, DARKNESS_SIGHT);

            _GCSkillToTileOK3.setObjectID(pVampire->getObjectID());
            _GCSkillToTileOK3.setSkillType(SkillType);
            _GCSkillToTileOK3.setX(X);
            _GCSkillToTileOK3.setY(Y);

            _GCSkillToTileOK4.setSkillType(SkillType);
            _GCSkillToTileOK4.setX(X);
            _GCSkillToTileOK4.setY(Y);
            _GCSkillToTileOK4.setRange(Range);
            _GCSkillToTileOK4.setDuration(output.Duration);

            _GCSkillToTileOK5.setObjectID(pVampire->getObjectID());
            _GCSkillToTileOK5.setSkillType(SkillType);
            _GCSkillToTileOK5.setX(X);
            _GCSkillToTileOK5.setY(Y);
            _GCSkillToTileOK5.setRange(Range);
            _GCSkillToTileOK5.setDuration(output.Duration);

            _GCSkillToTileOK6.setOrgXY(myX, myY);
            _GCSkillToTileOK6.setSkillType(SkillType);
            _GCSkillToTileOK6.setX(X);
            _GCSkillToTileOK6.setY(Y);
            _GCSkillToTileOK6.setDuration(output.Duration);
            _GCSkillToTileOK6.setRange(Range);
            //_GCSkillToTileOK6.addShortData(MODIFY_VISION, DARKNESS_SIGHT);

            for(list<Creature*>::const_iterator itr = cList.begin(); itr != cList.end(); itr++)
            {
                Creature* pTargetCreature = *itr;
                if (canSee(pTargetCreature, pVampire)) pTargetCreature->getPlayer()->sendPacket(&_GCSkillToTileOK2);
                else pTargetCreature->getPlayer()->sendPacket(&_GCSkillToTileOK6);
            }

            pPlayer->sendPacket(&_GCSkillToTileOK1);

            cList.push_back(pVampire);

            list<Creature*> watcherList = pZone->getWatcherList(myX, myY, pVampire);

            // watcherList에서 cList에 속하지 않고, caster(pVampire)를 볼 수 없는 경우는
            // OK4를 보내고.. cList에 추가한다.
            for(list<Creature*>::const_iterator itr = watcherList.begin(); itr != watcherList.end(); itr++)
            {
                bool bBelong = false;
                for(list<Creature*>::const_iterator tItr = cList.begin(); tItr != cList.end(); tItr++)
                    if (*itr == *tItr)
                        bBelong = true;

                Creature* pWatcher = (*itr);
                if (bBelong == false && canSee(pWatcher, pVampire) == false)
                {
                    //Assert(pWatcher->isPC());	// 당연 PC다.. Zone::getWatcherList는 PC만 return한다
                    if (!pWatcher->isPC())
                    {
                        //cout << "Darkness : 왓처 리스트가 PC가 아닙니다." << endl;
                        GCSkillFailed1 _GCSkillFailed1;
                        _GCSkillFailed1.setSkillType(getSkillType());
                        pVampire->getPlayer()->sendPacket(&_GCSkillFailed1);

                        //cout << "TID[" << Thread::self() << "]" << getSkillHandlerName() << " End" << endl;
                        return;
                    }
                    pWatcher->getPlayer()->sendPacket(&_GCSkillToTileOK4);
                    cList.push_back(*itr);
                }
            }

            cList = pZone->broadcastSkillPacket(myX, myY, X, Y, &_GCSkillToTileOK5, cList, false);

            pZone->broadcastPacket(myX, myY,  &_GCSkillToTileOK3 , cList);

            pZone->broadcastPacket(X, Y,  &_GCSkillToTileOK4 , cList);

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

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

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

#ifdef __GAME_SERVER__

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

    try
    {
        // 특수기술 테스트를 위해서 임시로 넣어두는 코드이다.
        GamePlayer* pGamePlayer = dynamic_cast<GamePlayer*>(pPlayer);

        Assert(pGamePlayer != NULL);	// by sigi

        if (pGamePlayer->getPlayerStatus() == GPS_NORMAL)
        {
            Creature* pCreature = pGamePlayer->getCreature();
            Assert(pCreature != NULL);	// by sigi

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

            SkillType_t SkillType = pPacket->getSkillType();

            // 완전 안전지대라면 기술 사용 불가. by sigi. 2002.11.14
            ZoneLevel_t ZoneLevel = pZone->getZoneLevel(pCreature->getX(), pCreature->getY());
            if ((ZoneLevel & COMPLETE_SAFE_ZONE) ||
                    (pCreature->isFlag(Effect::EFFECT_CLASS_PARALYZE)) ||
                    (pCreature->isFlag(Effect::EFFECT_CLASS_CAUSE_CRITICAL_WOUNDS)) ||
                    (pCreature->isFlag(Effect::EFFECT_CLASS_EXPLOSION_WATER)) ||
                    (pCreature->isFlag(Effect::EFFECT_CLASS_COMA)))
            {
                GCSkillFailed1 _GCSkillFailed1;
                _GCSkillFailed1.setSkillType(SkillType);
                pPlayer->sendPacket(&_GCSkillFailed1);

                return;
            }
            if (pCreature->isFlag(Effect::EFFECT_CLASS_TRANSFORM_TO_WERWOLF)) {
                switch(SkillType) {
                case SKILL_ATTACK_MELEE:
                case SKILL_BITE_OF_DEATH:
                case SKILL_UN_TRANSFORM:
                case SKILL_RAPID_GLIDING:
                    break;
                default:
                    GCSkillFailed1 _GCSkillFailed1;
                    _GCSkillFailed1.setSkillType(SkillType);
                    pPlayer->sendPacket(&_GCSkillFailed1);
                    dynamic_cast<Vampire*>(pCreature)->sendVampireSkillInfo();
                    return;
                }
            }
            if (pCreature->isFlag(Effect::EFFECT_CLASS_ABERRATION ) )
            {
                EffectAberration* pEffect = dynamic_cast<EffectAberration*>(pCreature->findEffect(Effect::EFFECT_CLASS_ABERRATION));
                if (pEffect != NULL && (rand()%100) < pEffect->getRatio())
                {
                    //cout << "aberration affected " << endl;
                    Dir_t dir = rand()%8;
                    pPacket->setX(pPacket->getX() + dirMoveMask[dir].x*3);
                    pPacket->setY(pPacket->getY() + dirMoveMask[dir].y*3);
                }
            }

            disableFlags(pCreature, pZone, SkillType);

            if (pCreature->isSlayer())
            {
                Slayer*    pSlayer    = dynamic_cast<Slayer*>(pCreature);
                SkillSlot* pSkillSlot = ((Slayer *)pCreature)->hasSkill(SkillType);
                bool       bSuccess   = true;

                if (SkillType == SKILL_BURNING_SOL_LAUNCH )
                {
                    pSkillSlot = ((Slayer *)pCreature)->hasSkill(SKILL_BURNING_SOL_CHARGING);
                }

                if (SkillType == SKILL_SWEEP_VICE_3 || SkillType == SKILL_SWEEP_VICE_5 )
                {
                    pSkillSlot = ((Slayer *)pCreature)->hasSkill(SKILL_SWEEP_VICE_1);
                }

                if (SkillType == SKILL_TURRET_FIRE ) pSkillSlot = ((Slayer *)pCreature)->hasSkill(SKILL_INSTALL_TURRET);

                if (pSkillSlot == NULL) bSuccess = false;
                if (!isAbleToUseTileSkill(pSlayer)) bSuccess = false;

                /*				if (pCreature->isSlayer() && pCreature->isFlag(Effect::EFFECT_CLASS_SNIPING_MODE))
                				{
                					Slayer* pSlayer = dynamic_cast<Slayer*>(pCreature);
                					Assert(pSlayer != NULL);
                					g_Sniping.checkRevealRatio(pSlayer, 20, 10);
                				} */

                if (bSuccess)
                {
                    SkillHandler* pSkillHandler = g_pSkillHandlerManager->getSkillHandler(SkillType);
                    Assert(pSkillHandler != NULL);

#ifdef __PROFILE_SKILLS__
                    beginProfileEx(SkillTypes2String[SkillType]);
                    pSkillHandler->execute(pSlayer, pPacket->getX(), pPacket->getY(), pSkillSlot, pPacket->getCEffectID());
                    endProfileEx(SkillTypes2String[SkillType]);
#else
                    pSkillHandler->execute(pSlayer, pPacket->getX(), pPacket->getY(), pSkillSlot, pPacket->getCEffectID());
#endif
                }
                else
                {
                    GCSkillFailed1 _GCSkillFailed1;
                    _GCSkillFailed1.setSkillType(SkillType);
                    pPlayer->sendPacket(&_GCSkillFailed1);
                }
            }
            else if (pCreature->isVampire())
            {
                Vampire*          pVampire          = dynamic_cast<Vampire*>(pCreature);
                VampireSkillSlot* pVampireSkillSlot = pVampire->hasSkill(SkillType);
                bool              bSuccess          = true;

                if (SkillType == SKILL_EAT_CORPSE && pVampire->isFlag(Effect::EFFECT_CLASS_TRANSFORM_TO_WOLF))
                {
                    SkillHandler* pSkillHandler = g_pSkillHandlerManager->getSkillHandler(SKILL_EAT_CORPSE);
                    Assert(pSkillHandler != NULL);
                    pSkillHandler->execute(pVampire, pPacket->getX(), pPacket->getY(), pVampireSkillSlot, pPacket->getCEffectID());
                    return;
                }

                if (pVampireSkillSlot == NULL) bSuccess = false;
                if (!isAbleToUseTileSkill(pVampire)) bSuccess = false;

                /*				if (pVampire->isFlag(Effect::EFFECT_CLASS_INVISIBILITY))
                				{
                					addVisibleCreature(pZone, pVampire, true);
                				}

                                if (pVampire->isFlag(Effect::EFFECT_CLASS_EXTREME))
                	            {
                	            	EffectManager * pEffectManager = pVampire->getEffectManager();
                	            	Assert(pEffectManager != NULL);
                	            	Effect * pEffect = pEffectManager->findEffect(Effect::EFFECT_CLASS_EXTREME);
                	            	if (pEffect != NULL ) {
                	            		pEffect->setDeadline(0);
                	            	}
                				} */
                if (bSuccess)
                {
                    SkillHandler* pSkillHandler = g_pSkillHandlerManager->getSkillHandler(SkillType);
                    Assert(pSkillHandler != NULL);

#ifdef __PROFILE_SKILLS__
                    beginProfileEx(SkillTypes2String[SkillType]);
                    pSkillHandler->execute(pVampire, pPacket->getX(), pPacket->getY(), pVampireSkillSlot, pPacket->getCEffectID());
                    endProfileEx(SkillTypes2String[SkillType]);
#else
                    pSkillHandler->execute(pVampire, pPacket->getX(), pPacket->getY(), pVampireSkillSlot, pPacket->getCEffectID());
#endif
                }
                else
                {
                    GCSkillFailed1 _GCSkillFailed1;
                    _GCSkillFailed1.setSkillType(SkillType);
                    pPlayer->sendPacket(&_GCSkillFailed1);
                }
            }
            else if (pCreature->isOusters())
            {
                Ousters*          pOusters          = dynamic_cast<Ousters*>(pCreature);
                OustersSkillSlot* pOustersSkillSlot = pOusters->hasSkill(SkillType);
                bool              bSuccess          = true;

                if (pOustersSkillSlot == NULL) bSuccess = false;
                if (!isAbleToUseTileSkill(pOusters)) bSuccess = false;
                if (SkillType == SKILL_DESTRUCTION_SPEAR && pOusters->hasSkill(SKILL_DESTRUCTION_SPEAR_MASTERY) == NULL )
                {
                    //cout << "has no mastery : destruction spear" << endl;
                    bSuccess = false;
                }
                if (SkillType == SKILL_ICE_LANCE && pOusters->hasSkill(SKILL_ICE_LANCE_MASTERY) == NULL )
                {
                    //cout << "has no mastery : ice lance" << endl;
                    bSuccess = false;
                }

                if (bSuccess)
                {
                    SkillHandler* pSkillHandler = g_pSkillHandlerManager->getSkillHandler(SkillType);
                    Assert(pSkillHandler != NULL);

#ifdef __PROFILE_SKILLS__
                    beginProfileEx(SkillTypes2String[SkillType]);
                    pSkillHandler->execute(pOusters, pPacket->getX(), pPacket->getY(), pOustersSkillSlot, pPacket->getCEffectID());
                    endProfileEx(SkillTypes2String[SkillType]);
#else
                    pSkillHandler->execute(pOusters, pPacket->getX(), pPacket->getY(), pOustersSkillSlot, pPacket->getCEffectID());
#endif
                }
                else
                {
                    GCSkillFailed1 _GCSkillFailed1;
                    _GCSkillFailed1.setSkillType(SkillType);
                    pPlayer->sendPacket(&_GCSkillFailed1);
                }
            }
        }
    }
    catch(Throwable & t)
    {
        //cout << t.toString() << endl;
    }

#endif	// __GAME_SERVER__

    __END_DEBUG_EX __END_CATCH
}