Exemplo n.º 1
0
// return magic defense
unsigned int CMonster::GetMagicDefense()
{
    UINT mdef = 0;
    mdef = thisnpc->magicdefense;

    if(IsSummon())//Tomiz : Check and Add The Owner MDEFF To Base Summon Value(STB)
    {
        CPlayer* ownerclient = GetOwner( );
        if(ownerclient!=NULL)
        {
            UINT lvlp = thisnpc->level;
            mdef += (long int)floor((double)(ownerclient->Stats->Magic_Defense * lvlp) / 100);
            Log(MSG_INFO,"SUMMON %i Got %i Mdeff from is owner, lvlp: %i",thisnpc->id,(mdef - thisnpc->magicdefense),lvlp);
        }
    }

    if(Status->Magic_Defense_up!=0xff)
    {
        mdef += MagicStatus[Status->Magic_Defense_up].Value;
    }
    if(Status->Magic_Defense_down!=0xff)
    {
        mdef -= MagicStatus[Status->Magic_Defense_down].Value;
    }

    if(IsSummon())
    {
        Log(MSG_INFO,"SUMMON: %i Final MDEFF: %i",thisnpc->id,mdef);
    }

    return mdef;
}
Exemplo n.º 2
0
// return accury
unsigned int CMonster::GetAccury()
{
    UINT hitrate = 0;
    hitrate = thisnpc->hitrate;

    if(IsSummon())//Tomiz : Check and Add The Owner ACC To Base Summon Value(STB)
    {
        CPlayer* ownerclient = GetOwner( );
        if(ownerclient!=NULL)
        {
            UINT lvlp = thisnpc->level;
            hitrate += (long int)floor((double)(ownerclient->Stats->Accury * lvlp) / 100);
            Log(MSG_INFO,"SUMMON %i Got %i Acc from is owner, lvlp: %i",thisnpc->id,(hitrate - thisnpc->hitrate),lvlp);
        }
    }

    if(Status->Accury_up!=0xff)
    {
        hitrate += MagicStatus[Status->Accury_up].Value;
    }
    if(Status->Accury_down!=0xff)
    {
        hitrate -= MagicStatus[Status->Accury_down].Value;
    }

    if(IsSummon())
    {
        Log(MSG_INFO,"SUMMON: %i Final ACC: %i",thisnpc->id,hitrate);
    }

    return hitrate;
}
Exemplo n.º 3
0
// called when a monster die [give exp/give extra drop]
bool CMonster::OnDie( )
{
    CMap* map = GServer->MapList.Index[Position->Map];
    if(map->ghost!=0)
    {
     if((map->IsNight( ) || map->ghost==2) && !IsGhost( ) && !IsGhostSeed( ) && !IsSummon( ))
       {
        UINT gs = GServer->RandNumber( 0, 100 );
        if(gs<30) // 30% / 70%
            {   // spawn a ghost seed [for now will be 701 [level 1 ghost seed] ]
                map->AddMonster( 701, Position->current, 0, NULL, NULL, Position->respawn, true );
            }
        }
    }
    
    //LMA begin
    //CF mode 1
    //20070621-211100
    UINT special_exp=0;
    UINT special_lvl=0;
    
    if (map->is_cf==1)
    {
       //what monster is dead?
       if(this->montype==map->id_def_mon)
       {
           //oh my god, they killed a j&b !! (or the monster with exp)
           special_exp=(UINT) map->mon_lvl;
           special_lvl= (UINT) map->mon_exp;
       }
       else
       {
           if (this->montype!=map->id_temp_mon)
           {
                UINT gs = GServer->RandNumber( 0, 100 );
                if(gs<map->percent)
                {
                  //we use the temporary monster as a decoy.
                  fPoint position_cf = GServer->RandInCircle( Position->current, 50 );
                  CMonster* monster2 = map->AddMonster( map->id_temp_mon, position_cf, 0, NULL, NULL, 0, true );           
                }
                
           }

       }
       
    }
    
    GServer->GiveExp( this , special_lvl, special_exp );
    //LMA End
    

    return true; 
}
Exemplo n.º 4
0
// Get Monster Defense
unsigned int CMonster::GetDefense()
{
    unsigned int defense;
    defense =  thisnpc->defense;

    if(IsSummon())//Tomiz : Check and Add The Owner DEFF To Base Summon Value(STB)
    {
        CPlayer* ownerclient = GetOwner( );
        if(ownerclient!=NULL)
        {
            UINT lvlp = thisnpc->level;
            defense += (long int)floor((double)(ownerclient->Stats->Defense * lvlp) / 100);
            Log(MSG_INFO,"SUMMON: %i Got %i Deff from is owner, lvlp: %i",thisnpc->id,(defense - thisnpc->defense),lvlp);
        }
    }

    if(thisnpc->subweapon!=0)
    {
        defense += GServer->EquipList[SUBWEAPON].Index[thisnpc->subweapon]->defense;
    }
    if(Status->Defense_up!=0xff)
    {
        defense += MagicStatus[Status->Defense_up].Value;
    }
    if(Status->Defense_down!=0xff)
    {
        defense -= MagicStatus[Status->Defense_down].Value;
    }

    if(IsSummon())
    {
        Log(MSG_INFO,"SUMMON: %i Final DEFF: %i",thisnpc->id,defense);
    }

    return defense;
}
Exemplo n.º 5
0
// Get Mob Attack Power
unsigned int CMonster::GetAttackPower()
{
	unsigned int attack;
	attack = thisnpc->atkpower;

	if(IsSummon())//Tomiz : Check and Add The Owner AP To Base Summon Value(STB)
    {
        CPlayer* ownerclient = GetOwner( );
        if(ownerclient!=NULL)
        {
            UINT lvlp = thisnpc->level;
            attack += (long int)floor((double)(ownerclient->Stats->Attack_Power * lvlp) / 100);
            Log(MSG_INFO,"SUMMON: %i Got %i AP from is owner, lvlp: %i",thisnpc->id,(attack - thisnpc->atkpower),lvlp);
        }
    }

    if(thisnpc->weapon!=0)
    {
        attack += GServer->EquipList[8].Index[thisnpc->weapon]->attackpower;
    }
    if(Status->Attack_up!=0xff)
    {
        attack += MagicStatus[Status->Attack_up].Value;
    }
    if(Status->Attack_down!=0xff)
    {
        attack -= MagicStatus[Status->Attack_down].Value;
    }

    if(IsSummon())
    {
        Log(MSG_INFO,"SUMMON: %i Final ATK: %i",thisnpc->id,attack);
    }

	return attack;
}
Exemplo n.º 6
0
// return dodge
unsigned int CMonster::GetDodge()
{
    UINT dodge = 0;
    dodge = thisnpc->dodge;

    if(IsSummon())//Tomiz : Check and Add The Owner DODGE To Base Summon Value(STB)
    {
        CPlayer* ownerclient = GetOwner( );
        if(ownerclient!=NULL)
        {
            UINT lvlp = thisnpc->level;
            dodge += (long int)floor((double)(ownerclient->Stats->Dodge * lvlp) / 100);
            Log(MSG_INFO,"SUMMON: %i Got %i Dodge from is owner, lvlp: %i",thisnpc->id,(dodge - thisnpc->dodge),lvlp);
        }
    }

    if(dodge == 0)// prevent a /0 for hawk skill
    {
        dodge = thisnpc->defense;
    }
    if(Status->Dodge_up!=0xff)
    {
        dodge += MagicStatus[Status->Dodge_up].Value;
    }
    if(Status->Dodge_down!=0xff)
    {
        dodge -= MagicStatus[Status->Dodge_down].Value;
    }

    if(IsSummon())
    {
        Log(MSG_INFO,"SUMMON: %i Final DODGE: %i",thisnpc->id,dodge);
    }

    return dodge;
}
Exemplo n.º 7
0
bool CMonster::OnFar( )
{
    //if Owner too far away, we kill the bonfire.
    if(IsBonfire())
    {
       UnspawnMonster( );
       return true;
    }

    //osprose.
    if(!IsSummon())return true;

    Position->destiny = Position->source; //ON TARGET LOST
    ClearBattle( Battle );
    MoveTo( Position->source );
    return true;
}
Exemplo n.º 8
0
// return a player pointers
CPlayer* CMonster::GetOwner( )
{
    if(!IsSummon( )) return NULL;
    CPlayer* ownerclient = GServer->GetClientByID( owner, Position->Map );
    return ownerclient;
}
Exemplo n.º 9
0
// Spawn a monster
//LMA: added handling of skill summons.
void CMonster::SpawnMonster( CPlayer* player, CMonster* thismon )
{
    BEGINPACKET( pak, 0x792 );
	ADDWORD    ( pak, clientid );
	ADDFLOAT   ( pak, Position->current.x*100 );
	ADDFLOAT   ( pak, Position->current.y*100 );
	ADDDWORD   ( pak, 0xcdcdcdcd );
	ADDDWORD   ( pak, 0xcdcdcdcd );

	if(IsDead( ))
	{
	   ADDWORD    ( pak, 0x0003 );
	   ADDWORD    ( pak, 0x0000 );
    }
	else if(IsOnBattle( ))
	{
       //LMA: for supportive summons (lucky ghost...)
       if(Battle->bufftarget==Battle->target)
       {
    	   ADDWORD    ( pak, 0x0002 );
    	   ADDWORD    ( pak, 0x0000 );
       }
       else
       {
    	   ADDWORD    ( pak, 0x0002 );
    	   ADDWORD    ( pak, Battle->target );
       }
    } else if(IsMoving( ))
	{
	   ADDWORD    ( pak, 0x0001 );
	   ADDWORD    ( pak, 0x0000 );
    } else {
    	ADDWORD    ( pak, 0x0000 );
    	ADDWORD    ( pak, 0x0000 );
    }

    if(IsSummon( ) )
    {
        ADDBYTE    ( pak, 0x01 );
    } else {
        ADDBYTE    ( pak, 0x00 );
    }
    ADDWORD(pak, 0x0000);

    if(Stats->HP > MAXHPMOB)
    {
        Stats->HP = (long long) MAXHPMOB;
    }
    ADDDWORD   ( pak, Stats->HP );

	if(thismon->owner != player->clientid)
    {
        CMap* map = GServer->MapList.Index[Position->Map];

        if (thismon->team!=0)
        {
            ADDDWORD( pak,thismon->team);
        }
        else
        {
            if(IsSummon( ) && map->allowpvp!=0)
            {
                //Hostil
                ADDDWORD( pak, 0x00000064 );
            }
            else if (IsSummon( ) && map->allowpvp==0)
            {
                //Friendly
                ADDDWORD ( pak, 2 );
            }
            else
            {
                //Hostil
                ADDDWORD( pak, 0x00000064 );
            }
        }
    } else {
        //Friendly
        ADDDWORD( pak, 2 );
    }

    ADDDWORD( pak, GServer->BuildBuffs( this ) );
	ADDDWORD   ( pak, montype );
	if(IsSummon( ))
    {
        ADDWORD( pak, owner );

        if (thismon->skillid>0)
        {
           ADDWORD( pak, thismon->skillid ); //id del skill (si es summon de skill)
        }
        else
        {
           ADDWORD( pak, 0x0000 ); //id del skill (si es summon de skill)
        }

    }
	player->client->SendPacket( &pak );

    //LMA: supportive summons (lucky ghost)
    if(IsSummon()&&buffid>0&&(player==GetOwner()))
    {
        Log(MSG_INFO,"The summon is spawned");
        StartAction( player,SUMMON_BUFF,buffid);
        Log(MSG_INFO,"completly");
        buffid=0;  //only one buff
    }

}
Exemplo n.º 10
0
// 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( );
}
Exemplo n.º 11
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 );
    }
}
Exemplo n.º 12
0
// update attack values and destiny  position
bool CMonster::UpdateValues( )
{       
    //LMA: Some special case where special monsters stay still (mc, bonfires and so on...)
    if(stay_still&&(!IsBonfire()))
       return true;
        
    if(IsSummon( ) && CanMove( ))
    {
        CPlayer* thisclient = GetOwner( );
        if(thisclient!=NULL)
        {               
            if(!IsBonfire())
            {
                if(!IsOnBattle( ) && thisclient->IsAttacking( ))
                {
                    Battle->target = thisclient->Battle->target;
                    Battle->atktarget = Battle->target;
                    Battle->atktype = NORMAL_ATTACK;
                    Battle->contatk = true;
                    CCharacter* Enemy = GetCharTarget( );
                    if(Enemy!=NULL)
                        StartAction( Enemy, NORMAL_ATTACK );
                }
                else
                if(!IsOnBattle( ))
                {
                    Position->source = thisclient->Position->current;
                    float distance = GServer->distance( Position->destiny , thisclient->Position->current );
                    if((distance>15 && !IsOnBattle()) || distance>50)
                        Move( );                
                }
            
            }
            else
            {
                //LMA: Let's kill bonfires if owner too far away :).
                float distance = GServer->distance( Position->current , thisclient->Position->current );
                if(distance>25)
                {
                   UnspawnMonster( );
                   return false;                
                }
                
                return true;
            }
            
        }
        else
        {
            UnspawnMonster( );
            return false;
        }
    }                           
    if(!IsMoving( ) && !IsOnBattle( ) && CanMove( ))        
    {         
        clock_t etime = clock() - Position->lastMoveTime;  
        if(etime > 20*CLOCKS_PER_SEC) 
            Move( );    
    }
    if(!IsSummon( ))
    {
        CPlayer* player = GetNearPlayer( 10 );
        if(player!=NULL)
            OnEnemyOnSight( player );
    } 
    return true;
}
Exemplo n.º 13
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 );
//    }
}
Exemplo n.º 14
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 );
    }
}
Exemplo n.º 15
0
//arnold
// do AoE skill
bool CCharacter::AoeSkill( CSkills* skill, CCharacter* Enemy )
{
    Position->destiny = Position->current;
    //Log(MSG_INFO,"Doing AOE Skill");
    //if(Battle->castTime == 0)
    //{
        BEGINPACKET( pak, 0x7bb );
        ADDWORD    ( pak, clientid );
        GServer->SendToVisible( &pak, (CCharacter*)this );
    //    Battle->castTime = clock();
    //    return true;
    //}
    //else
    //{
    //    clock_t etime = clock() - Battle->castTime;
    //    if(etime < SKILL_DELAY)
    //       return true;
    //}
    //Battle->castTime = 0;
    CMap* map = GServer->MapList.Index[Position->Map];

    //PY replacement code
    if(IsPlayer() || IsSummon())
    {
        for(UINT i=0;i<map->MonsterList.size();i++)
        {
            CMonster* monster = map->MonsterList.at(i);
            if(monster == NULL) continue;
            if(monster->clientid == clientid) continue;
            if(monster->IsSummon( ) && (map->allowpvp == 0 || monster->owner == clientid)) continue;
            if(GServer->IsMonInCircle( Position->skilltargetpos, monster->Position->current,(float)skill->aoeradius + 1))
                UseAtkSkill( (CCharacter*) monster, skill );
        }
    }
    if(IsMonster() && !IsSummon())
    {
        for(UINT i=0;i<map->PlayerList.size();i++)
        {
            CPlayer* player = map->PlayerList.at(i);
            if(player == NULL)continue;
            if(player->clientid == clientid) continue;
            if(GServer->IsMonInCircle( Position->skilltargetpos,player->Position->current,(float)skill->aoeradius+1))
                UseAtkSkill( (CCharacter*) player, skill );
        }
    }
    //PY end

    // this code appears to me to be completely wrong replaced with code above
    /*
    for(UINT i=0;i<map->MonsterList.size();i++)
    {
        CMonster* monster = map->MonsterList.at(i);
        if(monster->clientid == clientid) continue;
        if(IsSummon( ) || IsPlayer( ))
        {
            if(monster->IsSummon( ) && (map->allowpvp==0 || monster->owner == clientid)) continue;
        }
        else
        {
            if(!monster->IsSummon( )) continue;
        }
        if(GServer->IsMonInCircle( Position->skilltargetpos, monster->Position->current,(float)skill->aoeradius + 1))
            UseAtkSkill( (CCharacter*) monster, skill );
    }
    if(map->allowpvp!=0 || (IsMonster( ) && !IsSummon( )))
    {
        for(UINT i=0;i<map->PlayerList.size();i++)
        {
            CPlayer* player = map->PlayerList.at(i);
            if(player->clientid==clientid) continue;
            if(GServer->IsMonInCircle( Position->skilltargetpos,player->Position->current,(float)skill->aoeradius+1))
                UseAtkSkill( (CCharacter*) player, skill );
        }
    }*/
    Battle->iscasting = 1;
    //Log(MSG_DEBUG,"Cast a skill. Iscasting set to true");
    if(Enemy != NULL)
    {
        if(Enemy->IsDead( ))
            ClearBattle( Battle );
    }
    else
        ClearBattle( Battle );
    Stats->MP -= (skill->mp - (skill->mp * Stats->MPReduction / 100));
    if(Stats->MP < 0) Stats->MP = 0;
    Battle->lastAtkTime = clock( );

    return true;
}
Exemplo n.º 16
0
// Spawn a monster
//LMA: added handling of skill summons.
void CMonster::SpawnMonster( CPlayer* player, CMonster* thismon )
{
    BEGINPACKET( pak, 0x792 );
												
	//struct tag_ADD_CHAR
	ADDWORD    ( pak, clientid );
	ADDFLOAT   ( pak, Position->current.x*100 );
	ADDFLOAT   ( pak, Position->current.y*100 );						//current X and Y position

	if((thismon->bonushp > 0 || thismon->bonusmp > 0) && (thismon->skillid > 0))	//What is this? It seems to be sending this in place of destination if the monster is not able to move. Bonfires and so on
	{
    	ADDFLOAT   ( pak, 0xcdcdcdcd );
    	ADDFLOAT   ( pak, 0xcdcdcdcd );
    }
    else
    {
     	ADDFLOAT   ( pak, Position->destiny.x*100 );					//Destination position. This should always follow current position
    	ADDFLOAT   ( pak, Position->destiny.y*100 );
    }
	// next 2 WORDS are m_wCommand and m_wTargetOBJ
	if(IsDead( ))
	{
	   ADDWORD    ( pak, 0x0003 );
	   ADDWORD    ( pak, 0x0000 );
    }
	else if(IsOnBattle( ))
	{
       //LMA: for supportive summons (lucky ghost...)
       if(Battle->bufftarget == Battle->target)
       {
    	   ADDWORD    ( pak, 0x0002 );
    	   ADDWORD    ( pak, 0x0000 );
       }
       else
       {
    	   ADDWORD    ( pak, 0x0002 );
    	   ADDWORD    ( pak, Battle->target );
       }
    }
	else if(IsMoving( ))
	{
	   ADDWORD    ( pak, 0x0001 );
	   ADDWORD    ( pak, 0x0000 );
    }
    else
    {
    	ADDWORD    ( pak, 0x0000 );
    	ADDWORD    ( pak, 0x0000 );
    }
	ADDBYTE		( pak, thisnpc->stance );
    ADDWORD   ( pak, Stats->HP );
	ADDWORD	  ( pak, 0x0000 );
	// now Team Number
	if(thismon->owner != player->clientid)
    {
        CMap* map = GServer->MapList.Index[Position->Map];

        //LMA: adding team...
        if (thismon->team!=0)
        {
            ADDWORD( pak,thismon->team);
        }
        else
        {
            if(IsSummon( ) && map->allowpvp!=0)
            {
                //Hostil
                ADDWORD( pak, 0x0064 );
            }
            else if (IsSummon( ) && map->allowpvp==0)
            {
                //Friendly
                ADDWORD ( pak, 0x0000 );
            }
            else
            {
                //Hostil
                ADDWORD( pak, 0x0064 );
            }
        }
    }
    else
    {
        //Friendly
        ADDWORD( pak, 0x0000 );
    }
	ADDWORD ( pak, 0x0000 );
	//and finally DWORD StatusFlag
    ADDDWORD( pak, GServer->BuildBuffs( this ) );
		
	//struct gsv_MOB_CHAR
	ADDWORD   ( pak, montype );
	ADDWORD   ( pak, 0x0000 );
	ADDWORD	  ( pak, thismon->Stats->Level );
	ADDWORD   ( pak, thismon->Stats->Size );

	player->client->SendPacket( &pak );

    //LMA: supportive summons (lucky ghost)
	//PY: Another special case. Will probably need to remove this later
    if(IsSummon() && buffid > 0 && (player == GetOwner()))
    {
        Log(MSG_INFO,"The summon is spawned");
        /*CPlayer* player = GetOwner( );
        if (ownplayer==NULL)
           return true;*/
        StartAction( player,SUMMON_BUFF,buffid);
        Log(MSG_INFO,"completly");
        buffid=0;  //only one buff
    }

}
Exemplo n.º 17
0
// Spawn a monster
//LMA: added handling of skill summons.
void CMonster::SpawnMonster( CPlayer* player, CMonster* thismon )
{
    BEGINPACKET( pak, 0x792 );
	ADDWORD    ( pak, clientid );
	ADDFLOAT   ( pak, Position->current.x*100 );
	ADDFLOAT   ( pak, Position->current.y*100 );

	if((thismon->bonushp>0||thismon->bonusmp>0)&&(thismon->skillid>0))
	{
    	ADDFLOAT   ( pak, 0xcdcdcdcd );
    	ADDFLOAT   ( pak, 0xcdcdcdcd );
    }
    else
    {
     	ADDFLOAT   ( pak, Position->destiny.x*100 );
    	ADDFLOAT   ( pak, Position->destiny.y*100 );
    }

	if(IsDead( ))
	{
	   ADDWORD    ( pak, 0x0003 );
	   ADDWORD    ( pak, 0x0000 );
    }
	else if(IsOnBattle( ))
	{
       //LMA: for supportive summons (lucky ghost...)
       if(Battle->bufftarget==Battle->target)
       {
    	   ADDWORD    ( pak, 0x0002 );
    	   ADDWORD    ( pak, 0x0000 );
       }
       else
       {
    	   ADDWORD    ( pak, 0x0002 );
    	   ADDWORD    ( pak, Battle->target );
       }

    }
	else if(IsMoving( ))
	{
	   ADDWORD    ( pak, 0x0001 );
	   ADDWORD    ( pak, 0x0000 );
    }
    else
    {
    	ADDWORD    ( pak, 0x0000 );
    	ADDWORD    ( pak, 0x0000 );
    }

    if(IsSummon( ) )
    {
        ADDBYTE    ( pak, 0x01 );
    }
    else
    {
        ADDBYTE    ( pak, 0x00 );
    }

    //LMA: Little check, for now we "only" have a DWORD for monster's HP so there is a limit
    //broken by some monsters (Turak boss)
    if(Stats->HP>MAXHPMOB)
    {
        LogDebugPriority(3);
        LogDebug("Too much HP for monster %i (%I64i->%I64i)",thismon->montype,Stats->HP,MAXHPMOB);
        LogDebugPriority(4);
        Stats->HP=(long long) MAXHPMOB;
    }

    ADDDWORD   ( pak, Stats->HP );

	if(thismon->owner != player->clientid)
    {
        CMap* map = GServer->MapList.Index[Position->Map];

        //LMA: adding team...
        if (thismon->team!=0)
        {
            ADDDWORD( pak,thismon->team);
        }
        else
        {
            if(IsSummon( ) && map->allowpvp!=0)
            {
                //Hostil
                ADDDWORD( pak, 0x00000064 );
            }
            else if (IsSummon( ) && map->allowpvp==0)
            {
                //Friendly
                ADDDWORD ( pak, 0x00000000 );
            }
            else
            {
                //Hostil
                ADDDWORD( pak, 0x00000064 );
            }

            //TODO: LMA, test if necessary or not anymore...
            /*
            else if(thismon->montype>=1474&&thismon->montype<=1489)
            {
                //LMA: Xmas trees are friendly.
                ADDDWORD ( pak, 0x00000000 );
            }
            */

        }

    }
    else
    {
        //Friendly
        ADDDWORD( pak, 0x00000000 );
    }

    ADDDWORD( pak, GServer->BuildBuffs( this ) );
	ADDWORD   ( pak, montype );
	ADDWORD   ( pak, 0x0000 );
	if(IsSummon( ))
    {
        ADDWORD( pak, owner );

        if (thismon->skillid>0)
        {
           ADDWORD( pak, thismon->skillid ); //id del skill (si es summon de skill)
        }
        else
        {
           ADDWORD( pak, 0x0000 ); //id del skill (si es summon de skill)
        }

    }
	player->client->SendPacket( &pak );

    //LMA: supportive summons (lucky ghost)
    if(IsSummon()&&buffid>0&&(player==GetOwner()))
    {
        Log(MSG_INFO,"The summon is spawned");
        /*CPlayer* player = GetOwner( );
        if (ownplayer==NULL)
           return true;*/
        StartAction( player,SUMMON_BUFF,buffid);
        Log(MSG_INFO,"completly");
        buffid=0;  //only one buff
    }

}
Exemplo n.º 18
0
void CCharacter::DoAttack( )
{
    //if(Status->Sleep <= 0xff)
    //{
    //    ClearBattle( Battle );
    //    return; // can't take any action while we are asleep can we?
    //}
    //Log(MSG_INFO,"skill type %i selected. Chartype = %i",Battle->atktype, CharType);
    if(Battle->iscasting == 1) 
    {
        CCharacter* Enemy = GetCharTarget( );
        if(Enemy == NULL)
        {
            ClearBattle( Battle );
            return;
        }
        //Log(MSG_DEBUG,"Iscasting detected as true. Reset to false.");
        if(CanAttack())
        {
            //if(IsPlayer())
            //{
            //    Log(MSG_DEBUG,"Should reach here once on normal attack. iscasting state = %i",Battle->iscasting);
            //}
            ClearBattle( Battle );
            StartAction(Enemy, NORMAL_ATTACK, 0);
        }
        else
        {
            return;
        }
        return;
    }
    if(!CanAttack())
    {
        return;
    }
    if(IsSummon())
    {
        CCharacter* Enemy = GetCharTarget( );
        if(Enemy == NULL || (Battle->atktype != SKILL_AOE && Battle->atktype != BUFF_AOE))
        {
            //Log(MSG_DEBUG,"No Enemy found");
            ClearBattle( Battle );
            return;
        }
        if(this == Enemy) //summoned monster is attacking itself. It has been observed to happen
        {
            //Log(MSG_INFO,"Clearing Battle for this summon");
            ClearBattle( Battle );
            return;
        }
        if(Enemy->IsSummon())
        {
            CMonster* thisMonster = reinterpret_cast<CMonster*>(this);
            if(thisMonster == NULL)
            {
                ClearBattle( Battle );
                return;           
            }
            CMonster* otherMonster = reinterpret_cast<CMonster*>(Enemy);
            if(otherMonster == NULL)
            {
                ClearBattle( Battle );
                return;           
            }
            if(thisMonster->owner == otherMonster->owner)
            {
                //Log(MSG_INFO,"Clearing Battle for this summon");
                ClearBattle( Battle );
                return;                    
            }                
        }
    }
    CMap* map = GServer->MapList.Index[Position->Map];
    //Log(MSG_INFO,"DoAttack Battle Attack type = %i",Battle->atktype);
    switch(Battle->atktype)
    {
        case NORMAL_ATTACK://normal attack
        {
            //if(!Status->CanAttack)
            //    return; //can't attack right now.
            CCharacter* Enemy = GetCharTarget( );
            if(Enemy == NULL)
            {
                ClearBattle( Battle );
                return;
            }
            if(Enemy == this)
            {
                //Log(MSG_INFO,"WTF?? I AM trying to attack myself");
                ClearBattle( Battle );
            }
            if(IsTargetReached( Enemy ))
            {
                //if(IsMonster())
                //    Log(MSG_INFO,"Monster is trying to hit the player");
                NormalAttack( Enemy );
                if (Enemy->IsMonster()) // do monster AI script when monster is attacked.
                {
                    CMonster* monster = GServer->GetMonsterByID(Enemy->clientid, Enemy->Position->Map);
                    if(monster == NULL)return;
                    //monster->DoAi(monster->thisnpc->AI, 3);
                    monster->DoAi(monster->monAI, 3);
                }
            }
        }
        break;
        case SKILL_ATTACK://skill attack
        {
            CCharacter* Enemy = GetCharTarget( );
            if(Enemy == NULL)
            {
                ClearBattle( Battle );
                return;
            }
            CSkills* skill = GServer->GetSkillByID( Battle->skillid );
            if(skill == NULL)
            {
                //ClearBattle( Battle );
                return;
            }
            if(IsTargetReached( Enemy, skill )) 
            {
                SkillAttack( Enemy, skill );
                if (Enemy->IsMonster())
                {
                    CMonster* monster = GServer->GetMonsterByID(Enemy->clientid, Enemy->Position->Map);
                    if(monster == NULL)return;
                    monster->DoAi(monster->monAI, 3);
                }
            }
        }
        break;
        case SKILL_BUFF://buffs
        {


            CCharacter* Enemy = GetCharTarget( );
            if(Enemy == NULL)
            {
                //Log(MSG_DEBUG,"this target is NULL");
                ClearBattle( Battle );
                return;
            }
            CSkills* skill = GServer->GetSkillByID( Battle->skillid );
            if(skill == NULL)
            {
                //Log(MSG_DEBUG,"this skill is NULL");
                return;
            }

            if(IsTargetReached( Enemy, skill ))
            {
                //Log(MSG_DEBUG,"Skill successfully cast");
                BuffSkill( Enemy, skill );
            }
        }
        break;
        case SKILL_AOE:
        //case SKILL_SELF: //this is impossible. it can never be set
        case AOE_TARGET:
        {


            //Log(MSG_DEBUG,"Called skill type %i",Battle->atktype);
            CCharacter* Enemy = NULL;
            CSkills* skill = GServer->GetSkillByID( Battle->skillid );
            if(skill == NULL)
            {
                ClearBattle( Battle );
                return;
            }
            if(Battle->atktype == AOE_TARGET)
            {
                float distance = GServer->distance( Position->current, Position->destiny );
                if(distance <= skill->range)
                {
                    Position->destiny = Position->current;
                    AoeSkill( skill, Enemy );
                }
            }
            else
            {
                Position->skilltargetpos = Position->current;
                AoeSkill( skill, NULL );
            }
        }
        break;
        case BUFF_SELF:
        {

            //    return; // can't cast skills right now
            CSkills* skill = GServer->GetSkillByID( Battle->skillid );
            if(skill == NULL)
            {
                //ClearBattle( Battle );
                return;
            }
            BuffSkill( this, skill );
        }
        break;
        case BUFF_AOE:
        {
            //Log(MSG_INFO,"BUFF AOE selected");
            CSkills* skill = GServer->GetSkillByID( Battle->skillid );
            if(skill == NULL)
            {
                //ClearBattle( Battle );

                return;
            }
            AoeBuff( skill );
        }
        break;
        default:
            return;
        break;
    }
}