////////////////////////////////////////////////////////////////////////////////
// 액션을 실행한다.
////////////////////////////////////////////////////////////////////////////////
void ActionGiveNewbieItem::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();
    Assert(pPlayer != NULL);

    // 먼저 클라이언트를 위해 GCNPCResponse를 보내준다.
    GCNPCResponse okpkt;
    pPlayer->sendPacket(&okpkt);

    // 초보자가 슬레이어가 아닌 경우는 없다.
    if (!pCreature2->isSlayer()) return;

    Slayer*    pSlayer    = dynamic_cast<Slayer*>(pCreature2);
    FlagSet*   pFlagSet   = pSlayer->getFlagSet();
    Inventory* pInventory = pSlayer->getInventory();
    Zone*      pZone      = pSlayer->getZone();

    ////////////////////////////////////////////////////////////
    // 진짜 초보인지를 검사한다.
    // 0번을 초보 아이템 받았다 플래그로 정했다.
    // 이것은 어디까지나 땜빵 코드다.
    ////////////////////////////////////////////////////////////

    if (pFlagSet->isOn(0)) return;

    ////////////////////////////////////////////////////////////
    // 각 아이템 클래스에 따라 아이템을 생성한다.
    ////////////////////////////////////////////////////////////
    Item* pItem[10] = { NULL, };
    int   i         = 0;

    for (i=0; i<10; i++) pItem[i] = NULL;

    list<OptionType_t> nullList;

    if (m_ItemClass == Item::ITEM_CLASS_SWORD)
    {
        // 무기
        pItem[0] = CREATE_ITEM(Item::ITEM_CLASS_SWORD, 0, nullList);
        // 포션
        pItem[1] = CREATE_ITEM(Item::ITEM_CLASS_POTION, 0, nullList);
        pItem[2] = CREATE_ITEM(Item::ITEM_CLASS_POTION, 0, nullList);
        pItem[3] = CREATE_ITEM(Item::ITEM_CLASS_POTION, 0, nullList);
        pItem[4] = CREATE_ITEM(Item::ITEM_CLASS_POTION, 5, nullList);
    }
    else if (m_ItemClass == Item::ITEM_CLASS_BLADE)
    {
        // 무기
        pItem[0] = CREATE_ITEM(Item::ITEM_CLASS_BLADE, 0, nullList);
        // 포션
        pItem[1] = CREATE_ITEM(Item::ITEM_CLASS_POTION, 0, nullList);
        pItem[2] = CREATE_ITEM(Item::ITEM_CLASS_POTION, 0, nullList);
        pItem[3] = CREATE_ITEM(Item::ITEM_CLASS_POTION, 0, nullList);
        pItem[4] = CREATE_ITEM(Item::ITEM_CLASS_POTION, 5, nullList);
    }
    else if (m_ItemClass == Item::ITEM_CLASS_CROSS)
    {
        // 무기
        pItem[0] = CREATE_ITEM(Item::ITEM_CLASS_CROSS, 0, nullList);
        // 포션
        pItem[1] = CREATE_ITEM(Item::ITEM_CLASS_POTION, 0, nullList);
        pItem[2] = CREATE_ITEM(Item::ITEM_CLASS_POTION, 5, nullList);
        pItem[3] = CREATE_ITEM(Item::ITEM_CLASS_POTION, 5, nullList);
        pItem[4] = CREATE_ITEM(Item::ITEM_CLASS_POTION, 5, nullList);
    }
    else if (m_ItemClass == Item::ITEM_CLASS_MACE)
    {
        // 무기
        pItem[0] = CREATE_ITEM(Item::ITEM_CLASS_MACE, 0, nullList);
        // 포션
        pItem[1] = CREATE_ITEM(Item::ITEM_CLASS_POTION, 0, nullList);
        pItem[2] = CREATE_ITEM(Item::ITEM_CLASS_POTION, 5, nullList);
        pItem[3] = CREATE_ITEM(Item::ITEM_CLASS_POTION, 5, nullList);
        pItem[4] = CREATE_ITEM(Item::ITEM_CLASS_POTION, 5, nullList);
    }
    else if (m_ItemClass == Item::ITEM_CLASS_AR)
    {
        // 무기
        pItem[0] = CREATE_ITEM(Item::ITEM_CLASS_AR, 0, nullList);
        // 포션
        pItem[1] = CREATE_ITEM(Item::ITEM_CLASS_POTION, 0, nullList);
        pItem[2] = CREATE_ITEM(Item::ITEM_CLASS_POTION, 0, nullList);
        pItem[3] = CREATE_ITEM(Item::ITEM_CLASS_POTION, 5, nullList);
        pItem[4] = CREATE_ITEM(Item::ITEM_CLASS_POTION, 5, nullList);
        // 탄창
        pItem[5] = CREATE_ITEM(Item::ITEM_CLASS_MAGAZINE, 2, nullList);
        Magazine* pMagazine = dynamic_cast<Magazine*>(pItem[5]);
        pMagazine->setNum(9);
    }
    else if (m_ItemClass == Item::ITEM_CLASS_SR)
    {
        // 무기
        pItem[0] = CREATE_ITEM(Item::ITEM_CLASS_SR, 0, nullList);
        // 포션
        pItem[1] = CREATE_ITEM(Item::ITEM_CLASS_POTION, 0, nullList);
        pItem[2] = CREATE_ITEM(Item::ITEM_CLASS_POTION, 0, nullList);
        pItem[3] = CREATE_ITEM(Item::ITEM_CLASS_POTION, 5, nullList);
        pItem[4] = CREATE_ITEM(Item::ITEM_CLASS_POTION, 5, nullList);
        // 탄창
        pItem[5] = CREATE_ITEM(Item::ITEM_CLASS_MAGAZINE, 6, nullList);
        Magazine* pMagazine = dynamic_cast<Magazine*>(pItem[5]);
        pMagazine->setNum(9);
    }
    else if (m_ItemClass == Item::ITEM_CLASS_SG)
    {
        // 무기
        pItem[0] = CREATE_ITEM(Item::ITEM_CLASS_SG, 0, nullList);
        // 포션
        pItem[1] = CREATE_ITEM(Item::ITEM_CLASS_POTION, 0, nullList);
        pItem[2] = CREATE_ITEM(Item::ITEM_CLASS_POTION, 0, nullList);
        pItem[3] = CREATE_ITEM(Item::ITEM_CLASS_POTION, 5, nullList);
        pItem[4] = CREATE_ITEM(Item::ITEM_CLASS_POTION, 5, nullList);
        // 탄창
        pItem[5] = CREATE_ITEM(Item::ITEM_CLASS_MAGAZINE, 0, nullList);
        Magazine* pMagazine = dynamic_cast<Magazine*>(pItem[5]);
        pMagazine->setNum(9);
    }
    else if (m_ItemClass == Item::ITEM_CLASS_SMG)
    {
        // 무기
        pItem[0] = CREATE_ITEM(Item::ITEM_CLASS_SMG, 0, nullList);
        // 포션
        pItem[1] = CREATE_ITEM(Item::ITEM_CLASS_POTION, 0, nullList);
        pItem[2] = CREATE_ITEM(Item::ITEM_CLASS_POTION, 0, nullList);
        pItem[3] = CREATE_ITEM(Item::ITEM_CLASS_POTION, 5, nullList);
        pItem[4] = CREATE_ITEM(Item::ITEM_CLASS_POTION, 5, nullList);
        // 탄창
        pItem[5] = CREATE_ITEM(Item::ITEM_CLASS_MAGAZINE, 4, nullList);
        Magazine* pMagazine = dynamic_cast<Magazine*>(pItem[5]);
        pMagazine->setNum(9);
    }
    else
    {
        return;
    }

    ////////////////////////////////////////////////////////////
    // 생성한 아이템을 등록하고, DB에 저장하고,
    // 클라이언트에게 정보를 날려준다.
    ////////////////////////////////////////////////////////////
    ObjectRegistry& OR = pZone->getObjectRegistry();
    TPOINT           pt;
    GCCreateItem     gcCreateItem;

    for (i=0; i<10; i++)
    {
        if (pItem[i] != NULL)
        {
            OR.registerObject(pItem[i]);

            if (pInventory->addItem(pItem[i], pt))
            {
                pItem[i]->create(pSlayer->getName(), STORAGE_INVENTORY, 0, pt.x, pt.y);

                gcCreateItem.setObjectID(pItem[i]->getObjectID());
                gcCreateItem.setItemClass(pItem[i]->getItemClass());
                gcCreateItem.setItemType(pItem[i]->getItemType());
                gcCreateItem.setOptionType(pItem[i]->getOptionTypeList());
                gcCreateItem.setDurability(pItem[i]->getDurability());
                gcCreateItem.setSilver(pItem[i]->getSilver());

                if (pItem[i]->getItemClass() == Item::ITEM_CLASS_MAGAZINE)
                {
                    Magazine* pMag = dynamic_cast<Magazine*>(pItem[i]);
                    gcCreateItem.setItemNum(pMag->getNum());
                }
                else
                {
                    gcCreateItem.setItemNum(pItem[i]->getNum());
                }

                gcCreateItem.setInvenX(pt.x);
                gcCreateItem.setInvenY(pt.y);

                pPlayer->sendPacket(&gcCreateItem);
            }
            else
            {
                SAFE_DELETE(pItem[i]);
            }
        }
    }

    // 돈도 준다네...
    //pSlayer->setGoldEx(pSlayer->getGold() + 500);
    // by sigi. 2002.9.18
    pSlayer->increaseGoldEx(500);
    GCModifyInformation gcModifyInformation;
    gcModifyInformation.addLongData(MODIFY_GOLD, pSlayer->getGold());
    pPlayer->sendPacket(&gcModifyInformation);

    ////////////////////////////////////////////////////////////
    // 아이템을 받았으니, 현재 FlagSet을 저장한다.
    // 0번을 초보 아이템 받았다 플래그로 정했다.
    // 이것은 어디까지나 땜빵 코드다.
    ////////////////////////////////////////////////////////////
    pFlagSet->turnOn(FLAGSET_RECEIVE_NEWBIE_ITEM);

    if (m_ItemClass == Item::ITEM_CLASS_SWORD || m_ItemClass == Item::ITEM_CLASS_BLADE)
    {
        // 무사일 경우 1
        pFlagSet->turnOn(FLAGSET_RECEIVE_NEWBIE_ITEM_FIGHTER);
    }
    else if (m_ItemClass == Item::ITEM_CLASS_CROSS || m_ItemClass == Item::ITEM_CLASS_MACE)
    {
        // 성직자일 경우 2
        pFlagSet->turnOn(FLAGSET_RECEIVE_NEWBIE_ITEM_CLERIC);
    }
    else
    {
        // 군인일 경우 3
        pFlagSet->turnOn(FLAGSET_RECEIVE_NEWBIE_ITEM_GUNNER);
    }

    pFlagSet->save(pSlayer->getName());

    __END_CATCH
}
Example #2
0
//////////////////////////////////////////////////////////////////////////////
// 슬레이어 셀프 핸들러
//////////////////////////////////////////////////////////////////////////////
void Extreme::execute(Vampire* pVampire, VampireSkillSlot* pVampireSkillSlot, CEffectID_t CEffectID)
throw(Error)
{
    __BEGIN_TRY

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

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

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

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

        GCSkillToSelfOK1 _GCSkillToSelfOK1;
        GCSkillToSelfOK2 _GCSkillToSelfOK2;

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

        // 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  = (int)pSkillInfo->getConsumeMP();
        bool bManaCheck  = hasEnoughMana(pVampire, RequiredMP);
        bool bTimeCheck  = verifyRunTime(pVampireSkillSlot);
        bool bRangeCheck = checkZoneLevelToUseSkill(pVampire);
        bool bHitRoll    = HitRoll::isSuccessMagic(pVampire, pSkillInfo, pVampireSkillSlot, HitBonus);
        bool bEffected   = pVampire->isFlag(Effect::EFFECT_CLASS_EXTREME);

        if (bManaCheck && bTimeCheck && bRangeCheck && bHitRoll && !bEffected)
        {
            decreaseMana(pVampire, RequiredMP, _GCSkillToSelfOK1);

            // 스킬 레벨에 따라 데미지 보너스가 달라진다.
            SkillInput input(pVampire);
            SkillOutput output;
            computeOutput(input, output);

            // 이펙트 클래스를 만들어 붙인다.
            EffectExtreme* pEffect = new EffectExtreme(pVampire);
            pEffect->setDeadline(output.Duration);
            pEffect->setDamageBonus(output.Damage);
            pVampire->addEffect(pEffect);
            pVampire->setFlag(Effect::EFFECT_CLASS_EXTREME);

            // 이로 인하여 바뀌는 능력치를 보낸다.
            VAMPIRE_RECORD prev;
            pVampire->getVampireRecord(prev);
            pVampire->initAllStat();
            pVampire->sendRealWearingInfo();
            pVampire->sendModifyInfo(prev);

            // 패킷을 만들어 보낸다.
            _GCSkillToSelfOK1.setSkillType(SkillType);
            _GCSkillToSelfOK1.setCEffectID(CEffectID);
            _GCSkillToSelfOK1.setDuration(output.Duration);

            _GCSkillToSelfOK2.setObjectID(pVampire->getObjectID());
            _GCSkillToSelfOK2.setSkillType(SkillType);
            _GCSkillToSelfOK2.setDuration(output.Duration);

            pPlayer->sendPacket(&_GCSkillToSelfOK1);

            pZone->broadcastPacket(pVampire->getX(), pVampire->getY(),  &_GCSkillToSelfOK2, pVampire);

            // 이펙트가 붙었다고 알려준다.
            GCAddEffect gcAddEffect;
            gcAddEffect.setObjectID(pVampire->getObjectID());
            gcAddEffect.setEffectID(Effect::EFFECT_CLASS_EXTREME);
            gcAddEffect.setDuration(output.Duration);
            pZone->broadcastPacket(pVampire->getX(), pVampire->getY(), &gcAddEffect);

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

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

    __END_CATCH
}
Example #3
0
//////////////////////////////////////////////////////////////////////////////
// 슬레이어 타일 핸들러
//////////////////////////////////////////////////////////////////////////////
void Purify::execute(Slayer * pSlayer, ZoneCoord_t X, ZoneCoord_t Y, SkillSlot* pSkillSlot, CEffectID_t CEffectID)
throw(Error)
{
    __BEGIN_TRY

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

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

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

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

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

        SkillType_t       SkillType  = pSkillSlot->getSkillType();
        SkillInfo*        pSkillInfo = g_pSkillInfoManager->getSkillInfo(SkillType);
        SkillDomainType_t DomainType = pSkillInfo->getDomainType();
        SkillLevel_t      SkillLevel = pSkillSlot->getExpLevel();

        int  RequiredMP  = (int)pSkillInfo->getConsumeMP();
        bool bManaCheck  = hasEnoughMana(pSlayer, RequiredMP);
        bool bTimeCheck  = verifyRunTime(pSkillSlot);
        bool bRangeCheck = verifyDistance(pSlayer, X, Y, pSkillInfo->getRange());

        bool bTileCheck = false;
        VSRect rect(0, 0, pZone->getWidth()-1, pZone->getHeight()-1);
        if (rect.ptInRect(X, Y))
        {
            Tile& tile = pZone->getTile(X, Y);
            if (tile.hasCreature(Creature::MOVE_MODE_BURROWING)) bTileCheck = true;
        }

        if (bManaCheck && bTimeCheck && bRangeCheck && bTileCheck)
        {
            decreaseMana(pSlayer, RequiredMP, _GCSkillToTileOK1);

            SkillGrade Grade  = g_pSkillInfoManager->getGradeByDomainLevel(pSlayer->getSkillDomainLevel(DomainType));

            SkillInput input(pSlayer, pSkillSlot);
            SkillOutput output;
            computeOutput(input, output);

            Damage_t Damage = output.Damage;
            Range_t  Range  = output.Range;

            int oX = 0, oY = 0;
            list<Creature*> cList;	// 당하는 분들 list
            for(oY = -Range; oY <= Range; oY++)
            {
                for(oX = -Range; oX <= Range; oX++)
                {
                    int tileX = X+oX;
                    int tileY = Y+oY;

                    if (rect.ptInRect(tileX, tileY))
                    {
                        Tile& tile = pZone->getTile(tileX, tileY);

                        // 현재 타일에 땅 속에 있는 크리쳐가 존재한다면...
                        if (tile.hasCreature(Creature::MOVE_MODE_BURROWING))
                        {
                            Creature* pTargetCreature = tile.getCreature(Creature::MOVE_MODE_BURROWING);
                            Assert(pTargetCreature != NULL);

                            int ratio = 0;

                            if (pTargetCreature->isVampire())
                            {
                                Vampire* pVampire = dynamic_cast<Vampire*>(pTargetCreature);
                                ratio = 75 + SkillLevel - pVampire->getLevel();
                            }
                            else if (pTargetCreature->isMonster())
                            {
                                Monster* pMonster = dynamic_cast<Monster*>(pTargetCreature);
                                ratio = 75 + SkillLevel - pMonster->getLevel();
                            }
                            else
                            {
                                Assert(false);
                            }

                            bool UnBurrow = false;
                            if (rand()%100 < ratio) UnBurrow = true;

                            if (UnBurrow)
                            {
                                // 땅속에서 끄집어내진 놈들 리스트에 추가한다.
                                cList.push_back(pTargetCreature);

                                ObjectID_t targetObjectID = pTargetCreature->getObjectID();

                                _GCSkillToTileOK1.addCListElement(targetObjectID);
                                _GCSkillToTileOK2.addCListElement(targetObjectID);
                                _GCSkillToTileOK5.addCListElement(targetObjectID);

                                // 땅 속에 들어있는 놈을 꺼내어, 데미지를 준다.
                                addUnburrowCreature(pZone, pTargetCreature, tileX, tileY, pTargetCreature->getDir());
                                setDamage(pTargetCreature, Damage, pSlayer, SkillType, &_GCSkillToTileOK2, &_GCSkillToTileOK1);
                            }
                        }
                    }
                }
            }

            // 경험치를 올린다.
            Exp_t ExpUp = 10* (Grade + 1);
            shareAttrExp(pSlayer, ExpUp, 1, 1, 8, _GCSkillToTileOK1);
            increaseDomainExp(pSlayer, DomainType, pSkillInfo->getPoint(), _GCSkillToTileOK1);
            increaseSkillExp(pSlayer, DomainType,  pSkillSlot, pSkillInfo, _GCSkillToTileOK1);

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

            _GCSkillToTileOK1.setSkillType(SkillType);
            _GCSkillToTileOK1.setCEffectID(CEffectID);
            _GCSkillToTileOK1.setX(X);
            _GCSkillToTileOK1.setY(Y);
            _GCSkillToTileOK1.setDuration(0);

            _GCSkillToTileOK2.setObjectID(pSlayer->getObjectID());
            _GCSkillToTileOK2.setSkillType(SkillType);
            _GCSkillToTileOK2.setX(X);
            _GCSkillToTileOK2.setY(Y);
            _GCSkillToTileOK2.setDuration(0);
            _GCSkillToTileOK2.setRange(Range);

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

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

            _GCSkillToTileOK5.setObjectID(pSlayer->getObjectID());
            _GCSkillToTileOK5.setSkillType(SkillType);
            _GCSkillToTileOK5.setX(X);
            _GCSkillToTileOK5.setY(Y);
            _GCSkillToTileOK5.setRange(Range);
            _GCSkillToTileOK5.setDuration(0);

            // 땅 속에서 끄집어내진 놈들에게 체력이 닳았다는 것을 알려줘야한다.
            for(list<Creature*>::const_iterator itr = cList.begin(); itr != cList.end(); itr++)
            {
                Creature* pTargetCreature = *itr;

                if (pTargetCreature->isPC())
                {
                    _GCSkillToTileOK2.clearList();
                    HP_t targetHP = 0;
                    if (pTargetCreature->isSlayer())
                    {
                        targetHP = (dynamic_cast<Slayer*>(pTargetCreature))->getHP(ATTR_CURRENT);
                    }
                    else if (pTargetCreature->isVampire())
                    {
                        targetHP = (dynamic_cast<Vampire*>(pTargetCreature))->getHP(ATTR_CURRENT);
                    }
                    else if (pTargetCreature->isOusters())
                    {
                        targetHP = (dynamic_cast<Ousters*>(pTargetCreature))->getHP(ATTR_CURRENT);
                    }

                    _GCSkillToTileOK2.addShortData(MODIFY_CURRENT_HP, targetHP);
                    pTargetCreature->getPlayer()->sendPacket(&_GCSkillToTileOK2);
                }
                else if (pTargetCreature->isMonster())
                {
                    (dynamic_cast<Monster*>(pTargetCreature))->addEnemy(pSlayer);
                }
            }

            pPlayer->sendPacket(&_GCSkillToTileOK1);

            cList.push_back(pSlayer);

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

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

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

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

    __END_CATCH
}
Example #4
0
void Extreme::execute(Vampire* pVampire, ObjectID_t TargetObjectID,  VampireSkillSlot* pVampireSkillSlot, CEffectID_t CEffectID)
throw(Error)
{
    __BEGIN_TRY

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

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


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

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

        // NoSuch제거. by sigi. 2002.5.2
        if (pTargetCreature==NULL)
        {
            executeSkillFailException(pVampire, getSkillType());
            return;
        }

        GCSkillToObjectOK1 _GCSkillToObjectOK1;
        GCSkillToObjectOK2 _GCSkillToObjectOK2;
        GCSkillToObjectOK3 _GCSkillToObjectOK3;

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

        int  RequiredMP  = (int)pSkillInfo->getConsumeMP();
        bool bManaCheck  = hasEnoughMana(pVampire, RequiredMP);
        bool bTimeCheck  = verifyRunTime(pVampireSkillSlot);
        bool bRangeCheck = checkZoneLevelToUseSkill(pVampire);
        bool bHitRoll    = HitRoll::isSuccessMagic(pVampire, pSkillInfo, pVampireSkillSlot);
        bool bEffected   = pTargetCreature->isFlag(Effect::EFFECT_CLASS_EXTREME);

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

        if (bManaCheck && bTimeCheck && bRangeCheck && bHitRoll && !bEffected && pTargetCreature->isVampire() )
        {
            Vampire* pTargetVampire= dynamic_cast<Vampire*>(pTargetCreature);

            ZoneCoord_t X   = pTargetVampire->getX();
            ZoneCoord_t Y   = pTargetVampire->getY();

            decreaseMana(pVampire, RequiredMP, _GCSkillToObjectOK1);

            // 스킬 레벨에 따라 데미지 보너스가 달라진다.
            SkillInput input(pVampire);
            SkillOutput output;
            computeOutput(input, output);

            // 이펙트 클래스를 만들어 붙인다.
            EffectExtreme* pEffect = new EffectExtreme(pTargetVampire);
            pEffect->setDeadline(output.Duration);
            pEffect->setDamageBonus(output.Damage);
            pTargetVampire->addEffect(pEffect);
            pTargetVampire->setFlag(Effect::EFFECT_CLASS_EXTREME);

            // 이로 인하여 바뀌는 능력치를 보낸다.
            VAMPIRE_RECORD prev;
            pTargetVampire->getVampireRecord(prev);
            pTargetVampire->initAllStat();
            pTargetVampire->sendRealWearingInfo();
            pTargetVampire->sendModifyInfo(prev);

            // 패킷을 만들어 보낸다.
            _GCSkillToObjectOK1.setSkillType(SkillType);
            _GCSkillToObjectOK1.setCEffectID(CEffectID);
            _GCSkillToObjectOK1.setDuration(output.Duration);


            _GCSkillToObjectOK3.setObjectID(pVampire->getObjectID());
            _GCSkillToObjectOK3.setSkillType(SkillType);
            _GCSkillToObjectOK3.setTargetXY (X, Y);

            pPlayer->sendPacket(&_GCSkillToObjectOK1);

            if (pTargetCreature->isPC())
            {
                Player* pTargetPlayer = pTargetCreature->getPlayer();
                Assert(pTargetPlayer != NULL);

                _GCSkillToObjectOK2.setObjectID(pVampire->getObjectID());
                _GCSkillToObjectOK2.setSkillType(SkillType);
                _GCSkillToObjectOK2.setDuration(output.Duration);

                pTargetPlayer->sendPacket(&_GCSkillToObjectOK2);
            }
            else
            {
                Assert(false);
            }

            list<Creature *> cList;
            cList.push_back(pTargetCreature);
            cList.push_back(pVampire);
            pZone->broadcastPacket(myX, myY, &_GCSkillToObjectOK3, cList);

            // 이펙트가 붙었다고 알려준다.
            GCAddEffect gcAddEffect;
            gcAddEffect.setObjectID(pTargetVampire->getObjectID());
            gcAddEffect.setEffectID(Effect::EFFECT_CLASS_EXTREME);
            gcAddEffect.setDuration(output.Duration);
            pZone->broadcastPacket(pTargetVampire->getX(), pTargetVampire->getY(), &gcAddEffect);

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

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

    __END_CATCH
}