Example #1
0
void Extreme::execute(Vampire* pVampire)
throw(Error)
{
    __BEGIN_TRY

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

    Assert(pVampire != NULL);

    if(!pVampire->hasSkill(SKILL_EXTREME) ) return;

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


        GCSkillToObjectOK1 _GCSkillToObjectOK1;
        //GCSkillToObjectOK2 _GCSkillToObjectOK2;
        GCSkillToObjectOK3 _GCSkillToObjectOK3;

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

        int oX, oY;

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

        for(oX = -4; oX <= 4; oX++)
            for(oY = -4; oY <= 4; oY++)
            {
                int tileX = myX+oX;
                int tileY = myY+oY;
                if (!rect.ptInRect(tileX, tileY)) continue;

                // 타일 위에! 뱀파이어가 있는지 본다!
                Tile& tile = pZone->getTile(tileX, tileY);
                Creature * pTargetCreature = NULL;
                if(tile.hasCreature(Creature::MOVE_MODE_WALKING)) pTargetCreature = tile.getCreature(Creature::MOVE_MODE_WALKING);

                if(pTargetCreature != NULL && pTargetCreature != pVampire && pTargetCreature->isVampire() ) {

                    bool bEffected   = pTargetCreature->isFlag(Effect::EFFECT_CLASS_EXTREME);

                    if(bEffected ) continue;

                    Vampire* pTargetVampire= dynamic_cast<Vampire*>(pTargetCreature);

                    // 스킬 레벨에 따라 데미지 보너스가 달라진다.
                    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);

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

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

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

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

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

    __END_CATCH
}
Example #2
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 #3
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
}