예제 #1
0
// Check For Debuffs
void CCharacter::RefreshBuff( )
{
    bool bflag = false;
    for( UINT i=0; i<30; i++)
    {
        if(MagicStatus[i].Buff==0) continue;
        clock_t etime = clock() - MagicStatus[i].BuffTime;
        if( etime >= MagicStatus[i].Duration * CLOCKS_PER_SEC )
        {
            switch(MagicStatus[i].Buff)
            {
            case A_ATTACK:
                if(i<15)
                    Status->Attack_up = 0xff;
                else
                    Status->Attack_down = 0xff;
                Stats->Attack_Power = GetAttackPower( );
                break;
            case A_DEFENSE:
                if(i<15)
                    Status->Defense_up= 0xff;
                else
                    Status->Defense_down = 0xff;
                Stats->Defense = GetDefense( );
                break;
            case A_ACCUR:
                if(i<15)
                    Status->Accury_up= 0xff;
                else
                    Status->Accury_down = 0xff;
                Stats->Accury = GetAccury( );
                break;
            case A_MRESIST:
                if(i<15)
                    Status->Magic_Defense_up = 0xff;
                else
                    Status->Magic_Defense_down = 0xff;
                Stats->Magic_Defense = GetMagicDefense( );
                break;
            case A_DODGE:
                if(i<15)
                    Status->Dodge_up = 0xff;
                else
                    Status->Dodge_down = 0xff;
                Stats->Dodge = GetDodge( );
                break;
            case A_DASH:
                if(i<15)
                    Status->Dash_up = 0xff;
                else
                    Status->Dash_down = 0xff;
                Stats->Move_Speed = GetMoveSpeed( );
                break;
            case A_HASTE:
                if(i < 15)
                {
                    Status->Haste_up = 0xff;
                }
                else
                {
                    Status->Haste_down = 0xff;
                }
                Stats->Attack_Speed = GetAttackSpeed();
                break;
            case A_CRITICAL:
                if(i<15)
                    Status->Critical_up = 0xff;
                else
                    Status->Critical_down = 0xff;
                Stats->Critical = GetCritical( );
                break;
            case A_MAX_HP:
                if(i<15)
                    Status->HP_up = 0xff;
                else
                    Status->HP_down = 0xff;
                Stats->MaxHP = GetMaxHP( );
                break;
            case A_MAX_MP:
                if(i<15)
                    Status->MP_up = 0xff;
                else
                    Status->MP_down = 0xff;
                Stats->MaxMP = GetMaxMP( );
                break;
            case A_STUN:
                Status->Stuned = 0xff;
                printf("removing stun\n");
                //StartAction2(NULL, 0, 0, true);
                break;
            case A_POISON:
                Status->Poisoned = 0xff;
                printf("removing poison\n");
                break;
            case A_MUTE:
                Status->Muted = 0xff;
                break;
            case A_GMExtra_Damage:
            case A_Extra_Damage:
                if(i<15)
                {
                    Status->ExtraDamage_up = 0xff;
                    Stats->ExtraDamage = 0;
                }

                else
                    Status->ExtraDamage_down = 0xff;

                break;
            }
            MagicStatus[i].Buff = 0;
            MagicStatus[i].BuffTime = 0;
            MagicStatus[i].Duration = 0;
            MagicStatus[i].Value = 0;
            bflag = true;
        }
        else if (MagicStatus[i].Buff == A_POISON && etime > 1*CLOCKS_PER_SEC) //Do poison dmg every 1.5 seconds
        {
            Stats->HP -= MagicStatus[i].Value;
            MagicStatus[i].BuffTime+= 1*CLOCKS_PER_SEC;
            MagicStatus[i].Duration-=1;
            printf("did %i poison dmg to the player, still %i seconds and %i HP remain \n", MagicStatus[i].Value, MagicStatus[i].Duration, Stats->HP);

            //A bunch of messy code to send dmg packet
            BEGINPACKET( pak, 0x7b6 );
            ADDWORD    ( pak, clientid );
            ADDWORD    ( pak, 0 );
            ADDDWORD   ( pak, 0x000007f8 );
            ADDBYTE    ( pak, 0x00 );
            ADDDWORD   ( pak, MagicStatus[i].Value );

            //If Enemy is killed
            if( IsDead())
            {
                printf("char died\n");
                CDrop* thisdrop = NULL;
                //ADDDWORD   ( pak, 16 );//i don't think this one belongs in irose
                if( !IsSummon( ) && !IsPlayer( ))
                {
                    thisdrop = GetDrop( );
                    if( thisdrop!=NULL)
                    {
                        ADDFLOAT   ( pak, thisdrop->pos.x*100 );
                        ADDFLOAT   ( pak, thisdrop->pos.y*100 );
                        if( thisdrop->type==1)
                        {
                            ADDDWORD( pak, 0xccdf );//0xccccccdf );
                            ADDDWORD( pak, thisdrop->amount );
                        }
                        else
                        {
                            ADDDWORD   ( pak, GServer->BuildItemHead( thisdrop->item ) );
                            ADDDWORD   ( pak, GServer->BuildItemData( thisdrop->item ) );
                        }
                        ADDWORD    ( pak, thisdrop->clientid );
                        ADDWORD    ( pak, thisdrop->owner );
                        CMap* map = GServer->MapList.Index[thisdrop->posMap];
                        map->AddDrop( thisdrop );
                    }
                }
                GServer->SendToVisible( &pak, this, thisdrop );
            }

            //If enemy is still alive
            else
            {
                ADDDWORD   ( pak, 4 );
                GServer->SendToVisible( &pak, this );
            }
        }
    }
    if(bflag)
    {
        BEGINPACKET( pak,0x7b7 );
        ADDWORD    ( pak, clientid );
        ADDDWORD   ( pak, GServer->BuildBuffs( this ) );
        GServer->SendToVisible( &pak, this );
    }
}
예제 #2
0
void CCharacter::RefreshBuff( )
{
    bool bflag = false;
    for( UINT i=0;i<32;i++)
    {
        if(MagicStatus[i].Buff == 0) continue;
        clock_t etime = clock() - MagicStatus[i].BuffTime;
        if( etime >= MagicStatus[i].Duration * CLOCKS_PER_SEC )
        {

            Log(MSG_INFO,"Magic Status %i, vanish after: %i", MagicStatus[i].Status, MagicStatus[i].Duration);

            switch(MagicStatus[i].Status)
            {
                case STATUS_HP_8: case STATUS_HP_18: case STATUS_HP_30: case STATUS_HP_43: case STATUS_HP_58: case STATUS_HP_75: case STATUS_SUMMON_HP:
                case STATUS_HP_92: case STATUS_HP_111: case STATUS_HP_131: case STATUS_HP_152: case STATUS_HP_174: case STATUS_HP_197: case STATUS_HP_221:
                case STATUS_HP_246: case STATUS_HP_272: case STATUS_HP_299: case STATUS_HP_326: case STATUS_HP_354: case STATUS_HP_383: case STATUS_HP_413:
                case STATUS_HP_443: case STATUS_HP_475: case STATUS_HP_539: case STATUS_HP_572: case STATUS_HP_5_PC: case 115:
                {
                    Status->HPHeal = 0xff;
                }
                break;

                case STATUS_MP_6: case STATUS_MP_10: case STATUS_MP_14: case STATUS_MP_18: case STATUS_MP_21: case STATUS_MP_25: case STATUS_MP_29:
                case STATUS_MP_33: case STATUS_MP_36: case STATUS_MP_40: case STATUS_MP_44: case STATUS_MP_48: case STATUS_MP_51: case STATUS_MP_55:
                case STATUS_MP_59: case STATUS_MP_63: case STATUS_MP_66: case STATUS_MP_70: case STATUS_MP_74: case STATUS_MP_78: case STATUS_MP_81:
                case STATUS_MP_85: case STATUS_MP_89: case STATUS_MP_93: case STATUS_MP_96: case 116:
                {
                    Status->MPHeal = 0xff;
                }
                break;

                case 18: // attack power up
                case 19: // attack power down
                case 48: // attack power up
                {
                    if(i == BUFF_ATTACK_UP_POS)
                    {
                        Status->Attack_up = 0xff;
                    }
                    else
                    {
                        Status->Attack_down = 0xff;
                    }
                    Stats->Attack_Power = GetAttackPower( );
                }
                break;
                case 20: // def up
                case 21: // def down
                case 49: // def up
                {
                    if(i==BUFF_DEFENSE_UP_POS)
                    {
                        Status->Defense_up= 0xff;
                    }
                    else
                    {
                        Status->Defense_down = 0xff;
                    }
                    Stats->Defense = GetDefense( );
                }
                break;
                case 24: //Accuracy up
                case 25: //Accuracy down
                case 51: //attack Accuracy up.
                {
                    if(i==BUFF_HITRATE_UP_POS)
                    {
                        Status->Accuracy_up= 0xff;
                    }
                    else
                    {
                        Status->Accuracy_down = 0xff;
                    }
                    Stats->Accuracy = GetAccuracy( );
                }
                break;
                case 22: // macic resistance up
                case 23: // magic resistance down
                case 50: // magic resistance up
                {
                    if(i==BUFF_MDEFENSE_UP_POS)
                    {
                        Status->Magic_Defense_up = 0xff;
                    }
                    else
                    {
                        Status->Magic_Defense_down = 0xff;
                    }
                    Stats->Magic_Defense = GetMagicDefense( );
                }
                break;
                case 28: //dodge up
                case 29: //dodge down
                case 53: //dodge rate up
                {
                    if(i==BUFF_DODGE_UP_POS)
                    {
                        Status->Dodge_up = 0xff;
                    }
                    else
                    {
                        Status->Dodge_down = 0xff;
                    }
                    Stats->Dodge = GetDodge( );
                }
                break;
                case 14: //dash
                case 15: //slow
                case 46: //movement speed increased
                {
                    if(i==BUFF_DASH_UP_POS)
                    {
                        Status->Dash_up = 0xff;
                    }
                    else
                    {
                        Status->Dash_down = 0xff;
                    }
                    Stats->Move_Speed = GetMoveSpeed( );
                }
                break;
                case 16: // haste attack
                case 17: // slow attack
                case 47: // attack speed up
                {
                    if(i==BUFF_HASTE_UP_POS)
                    {
                        Status->Haste_up = 0xff;
                    }
                    else
                    {
                        Status->Haste_down = 0xff;
                    }
                    //Stats->Attack_Speed_Percent = GetAttackSpeedPercent( );
                }
                break;
                case 26: // crit up
                case 27: // crit down
                case 52: // crit up
                {
                    if(i==BUFF_CRITICAL_UP_POS)
                    {
                        Status->Critical_up = 0xff;
                    }
                    else
                    {
                        Status->Critical_down = 0xff;
                    }
                    Stats->Critical = GetCritical( );
                }
                break;
                case 12: // max HP up
                case 44: // max HP up
                {
                    if(i==BUFF_MAX_HP_POS)
                    {
                        Status->HP_up = 0xff;
                    }
                    else
                    {
                        Status->HP_down = 0xff;
                    }
                    Stats->MaxHP = GetMaxHP( );

                    if(Stats->HP > Stats->MaxHP)
                    {
                        Stats->HP = Stats->MaxHP;
                    }
                }
                break;
                case 13: // max MP up
                case 45: // max MP up
                {
                    if(i==BUFF_MAX_MP_POS)
                    {
                        Status->MP_up = 0xff;
                    }
                    else
                    {
                        Status->MP_down = 0xff;
                    }
                    Stats->MaxMP = GetMaxMP( );

                    if(Stats->MP > Stats->MaxMP)
                    {
                        Stats->MP = Stats->MaxMP;
                    }
                }
                break;
                case 32: // faint
                {
                    Status->Faint = 0xff;
                    Status->CanMove = true;
                    Status->CanCastSkill = true;
                    Status->CanAttack = true;
                    //printf("removing stun\n");
                }
                break;
                case 7: case 8: case 9: case 10: case 11: case 89: //poisoned
                {
                    Status->Poisoned = 0xff;
                    //printf("removing poison\n");
                }
                break;
                case 30: // muted
                {
                    Status->Muted = 0xff;
                    Status->CanCastSkill = true;
                }
                break;
                case 31: // sleep May need to be fixed later to accomodate multiple status effects.
                {
                    Status->Sleep = 0xff;
                    Status->CanMove = true;
                    Status->CanCastSkill = true;
                    Status->CanAttack = true;
                }
                break;
                case 36: //A_Extra_Damage:
                case 54: //A_GMExtra_Damage:
                case 83: //Valkyrie Charm:
                {
                    if(i==BUFF_DUMMY_DAMAGE_POS)
                    {
                        Status->ExtraDamage_up = 0xff;
                        Stats->ExtraDamage_add = 0;//We put extardamage add value to 0 if we lost the adddmg buff
                    }
                    else
                    {
                        Status->ExtraDamage_down = 0xff;
                        Stats->ExtraDamage_add = 0;//We put extardamage add value to 0 if we lost the adddmg buff
                    }
                }
                break;
                case 56: //Taunt
                {
                    Status->Taunt = 0xff;
                    //printf("removing Taunt\n");
                }
                break;
                case 58: case 61: case 74: case 77:  case 78: case 79: case 80: //flame
                {
                    Status->Flamed = 0xff;
                }
                break;
                case 33://Stealth,Camoflauge
                {
                    if(IsAttacking( ))
                    {
                        MagicStatus[i].Duration = 0;
                    }
                    Status->Stealth = 0xff;
                    //printf("removing Stealth\n");
                }
                break;
                case 86://Stealth,Weary
                {
                    Status->Weary = 0xff;
                    Status->CanCastSkill = true;
                    //printf("removing Weary\n");
                }
                break;
                case 34://Cloaking
                {
                    Status->Cloaking = 0xff;
                    //printf("removing Cloaking\n");
                }
                break;
                case 35: //ShieldDamage:
                {
                    if(i==BUFF_SHIELD_DAMAGE_POS)
                    {
                        Status->ShieldDamage_up = 0xff;
                        //Stats->ShieldDamage = 0xff;
                    }
                    else
                    {
                        Status->ShieldDamage_down = 0xff;
                        //Stats->ShieldDamage = 0xff;
                    }
                }
                break;
                case 55://Detect
                {
                    Status->Detect = 0xff;
                    Status->Cloaking = 0xff;
                    Status->Stealth = 0xff;
                    //printf("Detect Done\n");
                }
                break;
                case 38://Purify
                {
                    //Buff_Down
                    Status->Attack_down = 0xff;
                    Status->Defense_down = 0xff;
                    Status->Accuracy_down = 0xff;
                    Status->Magic_Defense_down = 0xff;
                    Status->Dodge_down = 0xff;
                    Status->Dash_down = 0xff;
                    Status->Haste_down = 0xff;
                    Status->Critical_down = 0xff;
                    Status->HP_down = 0xff;
                    Status->MP_down = 0xff;
                    Status->ExtraDamage_down = 0xff;
                    Status->ShieldDamage_down = 0xff;
                    Status->ALL_down = 0xff;

                    //Bad Status
                    //Status->Stun = 0xff;
                    Status->Poisoned = 0xff;
                    Status->Muted = 0xff;
                    Status->Sleep = 0xff;
                    Status->Flamed = 0xff;
                    Status->Faint = 0xff;

                    //Stats
                    Stats->Attack_Power = GetAttackPower( );
                    Stats->Defense = GetDefense( );
                    Stats->Accuracy = GetAccuracy( );
                    Stats->Magic_Defense = GetMagicDefense( );
                    Stats->Dodge = GetDodge( );
                    Stats->Move_Speed = GetMoveSpeed( );
                    Stats->Attack_Speed = GetAttackSpeed( );
                    //Stats->Attack_Speed_Percent = GetAttackSpeedPercent();
                    Stats->Critical = GetCritical( );
                    Stats->MaxHP = GetMaxHP( );
                    Stats->MaxMP = GetMaxMP( );
                    //printf("Purify Done\n");
                }
                break;
				case 39:// Dispell
                {
                    //Buff_Down
                    Status->Attack_down = 0xff;
                    Status->Defense_down = 0xff;
                    Status->Accuracy_down = 0xff;
                    Status->Magic_Defense_down = 0xff;
                    Status->Dodge_down = 0xff;
                    Status->Dash_down = 0xff;
                    Status->Haste_down = 0xff;
                    Status->Critical_down = 0xff;
                    Status->HP_down = 0xff;
                    Status->MP_down = 0xff;
                    Status->ExtraDamage_down = 0xff;
                    Status->ShieldDamage_down = 0xff;
                    Status->ALL_down = 0xff;

                    //Buff_Up
                    Status->Attack_up = 0xff;
                    Status->Defense_up = 0xff;
                    Status->Accuracy_up = 0xff;
                    Status->Magic_Defense_up = 0xff;
                    Status->Dodge_up = 0xff;
                    Status->Dash_up = 0xff;
                    Status->Haste_up = 0xff;
                    Status->Critical_up = 0xff;
                    Status->HP_up = 0xff;
                    Status->MP_up = 0xff;
                    Status->ExtraDamage_up = 0xff;
                    Status->ShieldDamage_up = 0xff;
                    Status->ALL_up = 0xff;

                    //Bad Status
                    //Status->Stun = 0xff;
                    Status->Poisoned = 0xff;
                    Status->Muted = 0xff;
                    Status->Sleep = 0xff;
                    Status->Flamed = 0xff;
                    Status->Faint = 0xff;

                    //Stats
                    Stats->Attack_Power = GetAttackPower( );
                    Stats->Defense = GetDefense( );
                    Stats->Accuracy = GetAccuracy( );
                    Stats->Magic_Defense = GetMagicDefense( );
                    Stats->Dodge = GetDodge( );
                    Stats->Move_Speed = GetMoveSpeed( );
                    Stats->Attack_Speed = GetAttackSpeed( );
                    Stats->Critical = GetCritical( );
                    Stats->MaxHP = GetMaxHP( );
                    Stats->MaxMP = GetMaxMP( );
                    //printf("Dispell Done\n");
                }
                break;
                default:
                {
                    Log(MSG_WARNING,"Unknow skill status in charfunctions %u.",MagicStatus[i].Status);
                }
            }
            BEGINPACKET( pak,0x7b7 );
            ADDWORD    ( pak, clientid );
            ADDDWORD   ( pak, GServer->BuildBuffs( this ) );
            GServer->SendToVisible( &pak, this );
            MagicStatus[i].Status = 0;
            MagicStatus[i].Buff = 0;
            MagicStatus[i].BuffTime = 0;
            MagicStatus[i].Duration = 0;
            MagicStatus[i].Value = 0;
            bflag = true;
        }
        else if ( ((MagicStatus[i].Status >= 7 && MagicStatus[i].Status <= 11) || MagicStatus[i].Status == 89) && etime > 1*CLOCKS_PER_SEC) //Do poison dmg every 1.5 seconds
        {
             Stats->HP -= MagicStatus[i].Status; //Actually take 7, 8, 9, 10 or 11 from the health. Based on the Status itself, LMA: can be 89 noc too.
             MagicStatus[i].BuffTime += 1*CLOCKS_PER_SEC;
             MagicStatus[i].Duration -= 1;
             //printf("did %i poison dmg to the player, still %i seconds and %i HP remain \n", MagicStatus[i].Status, MagicStatus[i].Duration, Stats->HP);
             //Log(MSG_WARNING,"did %i poison dmg to the player / monster, still %i seconds and %I64i HP remain", MagicStatus[i].Status, MagicStatus[i].Duration, Stats->HP);

            //LMA: If dead, let's the client resynch
            if(IsDead())
            {
                BEGINPACKET( pak, 0x79f );
                ADDWORD    ( pak, clientid );
                ADDDWORD   ( pak, 1);
                GServer->SendToVisible( &pak, this );
                Log(MSG_INFO,"death poison for %i, amount: %i",clientid,MagicStatus[i].Status);
            }

             //A bunch of messy code to send dmg packet
             BEGINPACKET( pak, 0x7b6 );
             ADDWORD    ( pak, clientid );
             ADDWORD    ( pak, 0 );
             ADDDWORD   ( pak, 0x000007f8 );
             ADDBYTE    ( pak, 0x00 );
             ADDDWORD   ( pak, MagicStatus[i].Status );

             //If Enemy is killed
             if( IsDead())
             {
                 //printf("char died\n");
                 CDrop* thisdrop = NULL;
                 ADDDWORD   ( pak, 16 );
                 if( !IsSummon( ) && !IsPlayer( ))
                 {
                    //LMA: No drop if already dead and drop done.
                    if(drop_dead)
                    {
                        Log(MSG_WARNING,"Trying to make a monster (CID %u, type %u) drop again but already did.",clientid,char_montype);
                    }
                    else
                    {
                         thisdrop = GetDrop( );
                         if( thisdrop!=NULL)
                         {
                             CMap* map = GServer->MapList.Index[thisdrop->posMap];
                             map->AddDrop( thisdrop );
                         }

                    }

                 }

                 //GServer->SendToVisible( &pak, this, thisdrop );
                 GServer->SendToVisible( &pak, this);
             }
             else
             {
                 //If enemy is still alive
                 ADDDWORD   ( pak, 4 );
                 GServer->SendToVisible( &pak, this );
             }
         }
        else if ( MagicStatus[i].Status == 58 || MagicStatus[i].Status == 61 || MagicStatus[i].Status == 71 || MagicStatus[i].Status >= 77 && MagicStatus[i].Status <= 80 || MagicStatus[i].Status == 88 && etime > 1*CLOCKS_PER_SEC) //Do flame dmg every 1.5 seconds
        {
             Stats->HP -= MagicStatus[i].Status;
             MagicStatus[i].BuffTime += 1*CLOCKS_PER_SEC;
             MagicStatus[i].Duration -= 1;
             printf("did %i flame dmg to the player, still %i seconds and %i HP remain \n", MagicStatus[i].Status, MagicStatus[i].Duration, Stats->HP);

            //LMA: If dead, let's the client resynch
            if(IsDead())
            {
                BEGINPACKET( pak, 0x79f );
                ADDWORD    ( pak, clientid );
                ADDDWORD   ( pak, 1);
                GServer->SendToVisible( &pak, this );
                Log(MSG_INFO,"death flame for %i, amount: %i",clientid,MagicStatus[i].Status);
            }

             //A bunch of messy code to send dmg packet
             BEGINPACKET( pak, 0x7b6 );
             ADDWORD    ( pak, clientid );
             ADDWORD    ( pak, 0 );
             ADDDWORD   ( pak, 0x000007f8 );
             ADDBYTE    ( pak, 0x00 );
             ADDDWORD   ( pak, MagicStatus[i].Status );

             //If Enemy is killed
             if( IsDead())
             {
                 //printf("char died\n");
                 CDrop* thisdrop = NULL;
                 ADDDWORD   ( pak, 16 );
                 if( !IsSummon( ) && !IsPlayer( ))
                 {
                    //LMA: No drop if already dead and drop done.
                    if(drop_dead)
                    {
                        Log(MSG_WARNING,"Trying to make a monster (CID %u, type %u) drop again but already did.",clientid,char_montype);
                    }
                    else
                    {
                         thisdrop = GetDrop( );
                         if( thisdrop!=NULL)
                         {
                             CMap* map = GServer->MapList.Index[thisdrop->posMap];
                             map->AddDrop( thisdrop );
                         }

                    }

                 }
                 //GServer->SendToVisible( &pak, this, thisdrop );
                 GServer->SendToVisible( &pak, this);
             }
             else
             {
                 //If enemy is still alive
                 ADDDWORD   ( pak, 4 );
                 GServer->SendToVisible( &pak, this );
             }
         }

    }
    for( UINT i=0;i<32;i++)
    {
        if(MagicStatus2[i].Buff == 0) continue;
        clock_t etime = clock() - MagicStatus2[i].BuffTime;
        if( etime >= MagicStatus2[i].Duration * CLOCKS_PER_SEC )
        {
        CPlayer* thisplayer = GServer->GetClientByID(clientid);
            Log(MSG_INFO,"Magic Status %i, vanish after: %i", MagicStatus2[i].Status, MagicStatus2[i].Duration);

            switch(MagicStatus2[i].Status)
            {
                case 126: // ALLbuff up
                {
                    if(i == BUFF_ATTACK_UP_POS)
                    {
                        Status->Attack_up = 0xff;
                        thisplayer->Attr->ALLbuff = 0;
                    }
                    else
                    {
                        Status->Attack_down = 0xff;
                        thisplayer->Attr->ALLbuff = 0;
                    }
                }
                default:
                {
                    Log(MSG_WARNING,"Unknow skill status in charfunctions %u.",MagicStatus[i].Status);
                }
            }
            BEGINPACKET( pak,0x7b7 );
            ADDWORD    ( pak, clientid );
            ADDDWORD   ( pak, GServer->BuildBuffs( this ) );
            GServer->SendToVisible( &pak, this );
            MagicStatus2[i].Status = 0;
            MagicStatus2[i].Buff = 0;
            MagicStatus2[i].BuffTime = 0;
            MagicStatus2[i].Duration = 0;
            MagicStatus2[i].Value = 0;
        }
    }
//    if(bflag)
//    {
//        BEGINPACKET( pak,0x7b7 );
//        ADDWORD    ( pak, clientid );
//        ADDDWORD   ( pak, GServer->BuildBuffs( this ) );
//        GServer->SendToVisible( &pak, this );
//    }
}
예제 #3
0
파일: battle.cpp 프로젝트: osROSE/osprose
// use skill attack
void CCharacter::UseAtkSkill( CCharacter* Enemy, CSkills* skill, bool deBuff)
{
    // new formula
    long int skillpower = skill->atkpower + Stats->Attack_Power;
    Log( MSG_INFO, "Skillpower = %i (%i + %i)",skillpower,skill->atkpower,Stats->Attack_Power);
    float levelmult = (float) Stats->Level / Enemy->Stats->Level;
    
    if(levelmult > 2)levelmult = 2; //cap level multiplier at 2
    Log( MSG_INFO, "Level Multiplier = %f",levelmult );
    float atkdefmult = 0; 
    float attack = 0;
    float constant = 2.5;
    if(skill->skilltype == 6 || skill->skilltype == 7) //magical damage
    {
        atkdefmult = (float) Stats->Attack_Power / Enemy->Stats->Magic_Defense;
    }
    else
    {
        atkdefmult = (float) Stats->Attack_Power / Enemy->Stats->Defense;
    }
    Log( MSG_INFO, "Attack / Def multiplier = %f",atkdefmult );
    attack = (skillpower * levelmult * atkdefmult) / constant;
    Log( MSG_INFO, "Attack before random mod = %f",attack );
    if(attack < 5) attack = 5;
    float d_attack = attack / 100;
    float mod = GServer->RandNumber( 0, 10 ) * d_attack;
    attack += mod;
    Log( MSG_INFO, "Attack after random mod = %f",attack );
    long int hitpower = (long int)floor(attack);

    skillpower = (int)attack;
    Log( MSG_INFO, "skillpower = %i",skillpower );
    bool bflag = false;
    Enemy->OnBeAttacked( this );
    if(skillpower <= 0) skillpower = 0;
    if(IsPlayer())
    {
        skillpower += (int)(skillpower * (Stats->ExtraDamage))/100;
    }
    if (skill->atkpower == 0)
    {
        skillpower = 0; // If the skill has a 0 atk power, it isn't meant to damage
        Log( MSG_INFO, "This skill does no damage" );
        //ClearBattle( Battle );
        return; // probably need to add some alternative code here for legitimate skills that have no attack power.
    }
    if(skillpower > 2046)skillpower = 2046;
    //Log(MSG_DEBUG,"Cast a skill. damage is %i",skillpower);
    if(!Enemy->IsSummon( ) && Enemy->IsMonster( ))
    {
        Enemy->AddDamage( this, skillpower );
        Enemy->damagecounter += skillpower;// is for AI
    }
    Log( MSG_INFO, "modified skillpower = %i",skillpower );
    Enemy->Stats->HP -= skillpower;
    //if(IsPlayer())
    //    Log(MSG_DEBUG,"Player Spell did damage %i",skillpower);
    //if(IsMonster())
    //    Log(MSG_DEBUG,"Monster spell did damage %i",skillpower);
    BEGINPACKET( pak, 0x7b6 );
    ADDWORD    ( pak, Enemy->clientid );
    ADDWORD    ( pak, clientid );
    ADDDWORD   ( pak, 0x000007f8 );
    ADDBYTE    ( pak, 0x00 );
    if (Enemy->Stats->HP < 1)
    {
        ADDWORD   ( pak, skillpower + 0x8000 );
    }
    else
    {
        ADDWORD   ( pak, skillpower + 0x2000 );
    }
    if(Enemy->IsDead())
    {
        //Log(MSG_DEBUG,"Enemy died");
        CDrop* thisdrop = NULL;
        ADDDWORD   ( pak, 16 );
        if(!Enemy->IsSummon( ) && !Enemy->IsPlayer( ))
        {
            thisdrop = Enemy->GetDrop( );
            if(thisdrop != NULL)
            { 
                CMap* map = GServer->MapList.Index[thisdrop->posMap];
                map->AddDrop( thisdrop );
            }
        }
        //GServer->SendToVisible( &pak, Enemy, thisdrop );
        GServer->SendToVisible( &pak, Enemy );  //Suppressing drop for now. trying a different trick
        OnEnemyDie( Enemy );
    }
    else
    {
        ADDDWORD   ( pak, 4 );
        GServer->SendToVisible( &pak, Enemy );
        bflag = GServer->AddBuffs( skill, Enemy, GetInt( ) );

        //Send (de)buff information to the whole world
        if(skill->nbuffs > 0 && bflag)
        {
            BEGINPACKET( pak, 0x7b5 );
            ADDWORD    ( pak, Battle->skilltarget );
            ADDWORD    ( pak, clientid );
			ADDWORD    ( pak, Battle->skillid );
            ADDWORD    ( pak, GetInt( ) );
            ADDBYTE    ( pak, skill->nbuffs );
            GServer->SendToVisible( &pak, Enemy );
        }
    }
    if (deBuff) return;
    //Send skill animation to the world
    RESETPACKET( pak, 0x7b9);
    ADDWORD    ( pak, clientid);
    ADDWORD    ( pak, Battle->skillid);
    ADDWORD    ( pak, 1);
    GServer->SendToVisible( &pak, this );
    Battle->bufftarget = 0;
    Battle->skilltarget = 0;
    Battle->skillid = 0;
    //Battle->atktype = NORMAL_ATTACK;
}
예제 #4
0
// Check For Debuffs
void CCharacter::RefreshBuff( )
{
    bool bflag = false;
    for( UINT i=0; i<30; i++)
    {
        if(MagicStatus[i].Buff == 0) continue;
        clock_t etime = clock() - MagicStatus[i].BuffTime;
        if( etime >= MagicStatus[i].Duration * CLOCKS_PER_SEC )
        {
            switch(MagicStatus[i].Status)
            {
            case 18: // attack power up
            case 19: // attack power down
            case 48: // attack power up
                if(i<15)
                    Status->Attack_up = 0xff;
                else
                    Status->Attack_down = 0xff;
                Stats->Attack_Power = GetAttackPower( );
                break;
            case 20: // def up
            case 21: // def down
            case 49: // def up
                if(i<15)
                    Status->Defense_up= 0xff;
                else
                    Status->Defense_down = 0xff;
                Stats->Defense = GetDefense( );
                break;
            case 24: //accuracy up
            case 25: //accuracy down
            case 51: //attack accuracy up.
                if(i<15)
                    Status->Accury_up= 0xff;
                else
                    Status->Accury_down = 0xff;
                Stats->Accury = GetAccury( );
                break;
            case 22: // macic resistance up
            case 23: // magic resistance down
            case 50: // magic resistance up
                if(i<15)
                    Status->Magic_Defense_up = 0xff;
                else
                    Status->Magic_Defense_down = 0xff;
                Stats->Magic_Defense = GetMagicDefense( );
                break;
            case 28: //dodge up
            case 29: //dodge down
            case 53: //dodge rate up
                if(i<15)
                    Status->Dodge_up = 0xff;
                else
                    Status->Dodge_down = 0xff;
                Stats->Dodge = GetDodge( );
                break;
            case 14: //dash
            case 15: //slow
            case 46: //movement speed increased
                if(i<15)
                    Status->Dash_up = 0xff;
                else
                    Status->Dash_down = 0xff;
                Stats->Move_Speed = GetMoveSpeed( );
                break;
            case 16: // haste attack
            case 17: // slow attack
            case 47: // attack speed up
                if(i<15)
                    Status->Haste_up = 0xff;
                else
                    Status->Haste_down = 0xff;
                Stats->Attack_Speed = GetAttackSpeed( );
                break;
            case 26: // crit up
            case 27: // crit down
            case 52: // crit up
                if(i<15)
                    Status->Critical_up = 0xff;
                else
                    Status->Critical_down = 0xff;
                Stats->Critical = GetCritical( );
                break;
            case 12: // max HP up
            case 44: // max HP up
                if(i<15)
                    Status->HP_up = 0xff;
                else
                    Status->HP_down = 0xff;
                Stats->MaxHP = GetMaxHP( );
                break;
            case 13: // max MP up
            case 45: // max MP up
                if(i<15)
                    Status->MP_up = 0xff;
                else
                    Status->MP_down = 0xff;
                Stats->MaxMP = GetMaxMP( );
                break;
            case 32: // faint
                Status->Stuned = 0xff;
                Status->CanAttack = true;
                //printf("removing stun\n");
                break;
            case 7:
            case 8:
            case 9:
            case 10:
            case 11: //poisoned
                Status->Poisoned = 0xff;
                //printf("removing poison\n");
                break;
            case 30: // muted
                Status->Muted = 0xff;
                Status->CanCastSkill = true;
                break;
            case 31: // sleep May need to be fixed later to accomodate multiple status effects.
                Status->Sleep = 0xff;
                Status->CanMove = true;
                Status->CanCastSkill = true;
                Status->CanAttack = true;
                break;
            case 54: //A_GMExtra_Damage:
            case 36: //A_Extra_Damage:
                if(i<15)
                {
                    Status->ExtraDamage_up = 0xff;
                    Stats->ExtraDamage = 0xff;
                }
                else
                {
                    Status->ExtraDamage_down = 0xff;
                    Stats->ExtraDamage = 0xff;
                }

                break;
            case 56: // Taunt
                Status->Taunt = 0xff;
                break;
            }

            MagicStatus[i].Status = 0;
            MagicStatus[i].Buff = 0;
            MagicStatus[i].BuffTime = 0;
            MagicStatus[i].Duration = 0;
            MagicStatus[i].Value = 0;
            bflag = true;
        }
        else if (MagicStatus[i].Status >= 7 && MagicStatus[i].Status <= 11 && etime > 1*CLOCKS_PER_SEC) //Do poison dmg every 1.5 seconds
        {
            Stats->HP -= MagicStatus[i].Status; //Actually take 7, 8, 9, 10 or 11 from the health. Based on the Status itself
            MagicStatus[i].BuffTime += 1*CLOCKS_PER_SEC;
            MagicStatus[i].Duration -= 1;
            //printf("did %i poison dmg to the player, still %i seconds and %i HP remain \n", MagicStatus[i].Status, MagicStatus[i].Duration, Stats->HP);

            //A bunch of messy code to send dmg packet
            BEGINPACKET( pak, 0x7b6 );
            ADDWORD    ( pak, clientid );              // client taking damage
            ADDWORD    ( pak, 0 );                     // client doing damage
            ADDDWORD   ( pak, 0x000007f8 );
            ADDBYTE    ( pak, 0x00 );
            if (Stats->HP < 1)
            {
                ADDWORD   ( pak, MagicStatus[i].Status + 0x8000 );
            }
            else
            {
                ADDWORD   ( pak, MagicStatus[i].Status + 0x2000 );
            }
            //ADDDWORD   ( pak, MagicStatus[i].Status ); //damage amount

            //If poisoned entity (player or monster) is killed
            if( IsDead())
            {
                //printf("char died\n");
                CDrop* thisdrop = NULL;
                ADDDWORD   ( pak, 16 );
                if( !IsSummon( ) && !IsPlayer( ))
                {
                    thisdrop = GetDrop( );
                    if( thisdrop != NULL)
                    {
                        CMap* map = GServer->MapList.Index[thisdrop->posMap];
                        map->AddDrop( thisdrop );
                    }
                }
                GServer->SendToVisible( &pak, this ); // removed thisdrop from the packet
            }

            //If enemy is still alive
            else
            {
                ADDDWORD   ( pak, 4 );
                GServer->SendToVisible( &pak, this );
            }
        }
    }
    if(bflag)
    {
        BEGINPACKET( pak,0x7b7 );
        ADDWORD    ( pak, clientid );
        ADDDWORD   ( pak, GServer->BuildBuffs( this ) );
        GServer->SendToVisible( &pak, this );
    }
}
예제 #5
0
파일: battle.cpp 프로젝트: osROSE/osprose
// do normal attack
void CCharacter::NormalAttack( CCharacter* Enemy )
{
    Enemy->OnBeAttacked( this );
    Position->destiny  = Position->current;
    
    // new formula
    float levelmult = (float) Stats->Level / Enemy->Stats->Level;
    if(levelmult > 2)levelmult = 2;
    float atkdefmult = 0; 
    float attack = 0;
    float constant = 4;
    if(Stats->magicattack == 1)
    {
        atkdefmult = (float) Stats->Attack_Power / Enemy->Stats->Magic_Defense;
    }
    else
    {
        atkdefmult = (float) Stats->Attack_Power / Enemy->Stats->Defense;
    }
    attack = Stats->Attack_Power * levelmult * atkdefmult / constant;
    
    if(attack < 5) attack = 5;
    float d_attack = attack / 100;
    float mod = GServer->RandNumber( 0, 10 ) * d_attack;
    attack += mod;
    long int hitpower = (long int)floor(attack);
    if(IsPlayer( )) //temp fix to find balance btw monster and player
    {
        hitpower = (long int)floor(attack * (GServer->Config.PlayerDmg/100.00));
        hitpower+=((hitpower*(Stats->ExtraDamage))/100);
    }
    if(IsSummon( )) //temp fix to find balance btw monster and player
    {
        hitpower = (long int)floor(attack * (GServer->Config.PlayerDmg/100.00));
        Log(MSG_DEBUG,"Summon hitpower = %i",hitpower);
    }
    if(IsMonster( )) //temp fix to find balance btw monster and player
        hitpower = (long int)floor(attack * (GServer->Config.MonsterDmg/100.00));
    bool critical = false;
    if(hitpower <= 5)
    {
        hitpower = 5;
    }
    else
    {
        if(GServer->RandNumber(0,300)<Stats->Critical)
        {
            hitpower = (long int)floor(hitpower * 1.5);
            critical = true;
        }
    }
    // dodge
    unsigned int hitvalue = (unsigned int)floor((double)(Stats->Accury * 40 / Enemy->Stats->Dodge));
    if(hitvalue > 100) hitvalue = 100;
    if(GServer->RandNumber( 0, 100 ) > hitvalue)
        hitpower = 0; // dodged
    if (hitpower > 0x7ff)//2047 packet size limit.
    {
       hitpower = 0x7ff;
    }
    Battle->atktarget = Battle->target;

    if(IsMonster())
    {
        //Log(MSG_INFO,"Monster hits player for %i damage. Attack target = %i",hitpower,Battle->atktarget);
    }
    //Log( MSG_INFO, "hitpower %i. Attack %f ", hitpower,attack );
    if(!Enemy->IsSummon( ) && Enemy->IsMonster( ))
    {
        Enemy->AddDamage( this, hitpower );
        Enemy->damagecounter += hitpower;// is for AI
    }
    Enemy->Stats->HP -= hitpower;



    BEGINPACKET( pak, 0x799 );
    ADDWORD    ( pak, clientid );
    ADDWORD    ( pak, Battle->atktarget );

    if(Enemy->IsDead())
    {
        CDrop* thisdrop = NULL;
        ADDWORD ( pak, (hitpower |   (    critical?0xb000:0x8000   )    ));
        if(!Enemy->IsSummon( ) && !Enemy->IsPlayer( ))
        {
            thisdrop = Enemy->GetDrop( );
            if(thisdrop != NULL)
            {
                //ADDFLOAT   ( pak, thisdrop->pos.x*100 );
                //ADDFLOAT   ( pak, thisdrop->pos.y*100 );
                //if(thisdrop->type == 1)
                //{
                //    ADDWORD( pak, 0xccdf );
                //    ADDDWORD( pak, thisdrop->amount );
                //}
                //else
                //{
                //    ADDWORD   ( pak, GServer->BuildItemHead( thisdrop->item ) );
                //    ADDDWORD   ( pak, GServer->BuildItemData( thisdrop->item ) );
                //}
                //ADDWORD    ( pak, thisdrop->clientid );
                //ADDWORD    ( pak, thisdrop->owner );
                CMap* map = GServer->MapList.Index[thisdrop->posMap];
                map->AddDrop( thisdrop );
            }
        }
        GServer->SendToVisible( &pak, Enemy ); //, thisdrop );
        OnEnemyDie( Enemy );
    }
    else
    {
        ADDWORD   ( pak, (hitpower|(hitpower>0?(critical?0x4000:0):0)));
        GServer->SendToVisible( &pak, Enemy );
    }
    ReduceABC( );
    Battle->lastAtkTime = clock( );
}