コード例 #1
0
ファイル: MonsterEvents.cpp プロジェクト: karlseven/ROED
// called when a enemy is on sight
bool CMonster::OnEnemyOnSight( CPlayer* Enemy )
{
    clock_t etime = clock() - lastSighCheck;
    if(etime<5000) return true;
    if(!IsOnBattle( ))
    {
        if(thisnpc->aggresive>1)
        {
            UINT aggro = GServer->RandNumber(2,15);
            if(thisnpc->aggresive>=aggro && !IsGhostSeed( ))
            {
                //osprose.
                /*
                Enemy->ClearObject( this->clientid );
				SpawnMonster(Enemy, this );
				*/
                StartAction( (CCharacter*) Enemy, NORMAL_ATTACK, 0 );
            }
            else
            if(IsGhostSeed( ) || thisnpc->aggresive>5)
                MoveTo( Enemy->Position->current, true );
        }
        lastSighCheck = clock();
    }
    return true;
}
コード例 #2
0
ファイル: MonsterEvents.cpp プロジェクト: karlseven/ROED
// called when a monster is attacked  [attack/use atk skill/use buff/run/summon]
bool CMonster::OnBeAttacked( CCharacter* Enemy )
{
    Battle->hitby = Enemy->clientid;

    if(!IsOnBattle( ))
    {

        //LMA: yeah hurt me (used for Santa Rudolph).
        if(thisnpc->helpless==1)
        {
            StartAction( Enemy, STAY_STILL_ATTACK, 0 );
            return true;
        }

        //Some monsters do not attack and stay still (mc)
        if(!stay_still)
        {
            StartAction( Enemy, NORMAL_ATTACK, 0 );
        }
        else
        {
            Log(MSG_INFO,"Stay still attack");
            StartAction( Enemy, STAY_STILL_ATTACK, 0 );
        }

    }

    return true;
}
コード例 #3
0
ファイル: charfunctions.cpp プロジェクト: shiftone242/osirose
bool CCharacter::IsAttacking( )
{
    if(IsOnBattle( ))
    {
        switch(Battle->atktype)
        {
        case SKILL_BUFF:
        case BUFF_SELF:
        case BUFF_AOE:
            return false;
        }
    }
    else return false;
    return true;
}
コード例 #4
0
ファイル: MonsterEvents.cpp プロジェクト: osROSE/osrose
// called when a monster is attacked  [attack/use atk skill/use buff/run/summon]
bool CMonster::OnBeAttacked( CCharacter* Enemy )
{
    if(!IsOnBattle( ))
    {
        //Some monsters do not attack and stay still (mc)
        if(!stay_still)
        {
            StartAction( Enemy, NORMAL_ATTACK, 0 ); 
        }
        else
        {
            StartAction( Enemy, STAY_STILL_ATTACK, 0 ); 
        }
        
    }
    
    return true;        
}
コード例 #5
0
ファイル: character.cpp プロジェクト: RavenX8/osirose
// update position
void CCharacter::UpdatePosition( )
{
    if(IsOnBattle( ) && Battle->target!=0)
    {
        CCharacter* Target = GetCharTarget( );
        if(Target!=NULL)  
        {
            if(IsMonster())
            {
                float distance = GServer->distance( Position->current, Position->source );
                if(distance>50)//AI should take care of this
                {
                    OnFar( );
                }
                //else Position->destiny = Target->Position->current;
            }
            //else Position->destiny = Target->Position->current;
        }
        else ClearBattle( Battle );
    }
    if(!IsMoving()){
      /*  if(IsPlayer()) */ Position->lastMoveTime = clock();
        return;
        }
	float dx = Position->destiny.x - Position->current.x;
	float dy = Position->destiny.y - Position->current.y;
	float distance = sqrt( (dx*dx) + (dy*dy) );
    float ntime = ( distance / (float(Stats->Move_Speed)/100.f)) * CLOCKS_PER_SEC;// * 100000; 
    clock_t etime = clock() - Position->lastMoveTime;       	
	if (ntime<=etime || distance==0) 
    {		
		Position->current.x = Position->destiny.x;
		Position->current.y = Position->destiny.y;		
    }
	else 
    {
		Position->current.x = dx*(etime/ntime) + Position->current.x;
		Position->current.y = dy*(etime/ntime) + Position->current.y;
	}
	Position->lastMoveTime = clock();    
}
コード例 #6
0
ファイル: Monster.cpp プロジェクト: TheDgtl/osrose
// 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
    }

}
コード例 #7
0
ファイル: Monster.cpp プロジェクト: PurpleYouko/KTRose_Server
// 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
    }

}
コード例 #8
0
ファイル: Monster.cpp プロジェクト: karlseven/ROED
// 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
    }

}
コード例 #9
0
ファイル: Monster.cpp プロジェクト: osROSE/osrose
// 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;
}
コード例 #10
0
ファイル: character.cpp プロジェクト: TheDgtl/osrose
// update position
void CCharacter::UpdatePosition( bool monster_stay_still )
{
    /* old version
    if(IsOnBattle( ) && Battle->target!=0)
    {
        CCharacter* Target = GetCharTarget( );
        if(Target!=NULL)
        {
            if(IsMonster())
            {
                float distance = GServer->distance( Position->current, Position->source );
                if(distance>30)
                {
                    if(Position->Map==8)
                        Log(MSG_INFO,"Update Position, OnFar");

                    OnFar( );
                }
                else
                {
                    if (!monster_stay_still)
                       Position->destiny = Target->Position->current; //MOBS ONLY
                    else
                        Log(MSG_INFO,"This one stays still");

                    if(Position->Map==8)
                        Log(MSG_INFO,"Update Position, destiny=Target->Position->current (%2.f:%.2f)",Position->destiny.x,Position->destiny.y);

                }

            }
            else
            {
                if(Position->Map==8)
                    Log(MSG_INFO,"Update Position Player, destiny=Target->Position->current (%2.f:%.2f)",Position->destiny.x,Position->destiny.y);

                Position->destiny = Target->Position->current; //ONLY IF NO TARGET ON BATTLE
            }

        }
        else
        {
            if(Position->Map==8)
                Log(MSG_INFO,"Update Position,no target, clear battle");

            ClearBattle( Battle );
        }

    }
    */

    //LMA: osprose.
    if(IsOnBattle( ) && Battle->target!=0)
    {
        CCharacter* Target = GetCharTarget( );

        if(Target == NULL)
        {
            ClearBattle( Battle );
        }
        else
        {
            Position->destiny=Target->Position->current;
        }

    }
	//osprose end.


    if(Position->Map==8)
    {
        float tempdist = GServer->distance(Position->current,Position->destiny);

        if(IsPlayer())
        {
            Log(MSG_INFO,"Player HP %I64i, (%.2f:%.2f)->(%.2f:%.2f)=%.2f speed %u",Stats->HP,Position->current.x,Position->current.y,Position->destiny.x,Position->destiny.y,tempdist,Stats->Move_Speed);
        }
        else
        {
            //Log(MSG_INFO,"Monster HP %I64i, (%.2f:%.2f)->(%.2f:%.2f)=%.2f speed %u",Stats->HP,Position->current.x,Position->current.y,Position->destiny.x,Position->destiny.y,tempdist,Stats->Move_Speed);
            //Log(MSG_LOAD,"Monster (%.2f:%.2f)->(%.2f:%.2f)",Position->current.x,Position->current.y,Position->destiny.x,Position->destiny.y);
        }

    }


    //LMA maps: special case (arrive in Game)
    //and he changed map (GM or scroll or teleporter or boat?)
    //2do: other cases too, all in fact...
    bool is_done=false;
    if (IsPlayer( )&&((last_map==-1&&last_coords==-1)||(last_map!=Position->Map)))
    {
      	//updating player's grid
    	int new_coords=0;
    	int new_map=0;
    	int grid_id=0;

      	//deleting previous presence...
      	if (last_map!=-1&&last_coords!=-1)
      	{
          	grid_id=GServer->allmaps[last_map].grid_id;
            if (grid_id!=-1&&!GServer->allmaps[last_map].always_on&&GServer->gridmaps[grid_id].coords[last_coords]>0)
               GServer->gridmaps[grid_id].coords[last_coords]--;
        }

        //New coordinates
    	new_map=Position->Map;
    	grid_id=GServer->allmaps[new_map].grid_id;
        new_coords=GServer->GetGridNumber(new_map,(UINT) floor(Position->current.x),(UINT) floor(Position->current.y));
    	last_map=new_map;
    	last_coords=new_coords;

    	if (grid_id!=-1||!GServer->allmaps[new_map].always_on)
           GServer->gridmaps[grid_id].coords[new_coords]++;

   	    is_done=true;
    }

    if(!IsMoving())
    {
        //osprose
        if(IsPlayer())Position->lastMoveTime = clock();
        //osprose end
        return;
    }

	float dx = Position->destiny.x - Position->current.x;
	float dy = Position->destiny.y - Position->current.y;
	float distance = sqrt( (dx*dx) + (dy*dy) );
    float ntime = ( distance / Stats->Move_Speed * GServer->MOVE_SPEED_MODIF );
    clock_t etime = clock() - Position->lastMoveTime;

    //LMA: bad, that's bad...
	//if (ntime<=etime || distance<1.0 )
	if (ntime<=etime || distance<0.01 )
    {
        // if (IsPlayer()) printf("Arrived! X: %i, Y: %i\n", (int)Position->current.x, (int)Position->current.y);
        if(Position->Map==8&&IsMonster())
            Log(MSG_INFO," Monster Arrived, J (%.2f:%.2f)->(%.2f:%.2f)",Position->current.x,Position->current.y,Position->destiny.x,Position->destiny.y);

		Position->current.x = Position->destiny.x;
		Position->current.y = Position->destiny.y;
    }
	else
    {
		Position->current.x += dx*(etime/ntime);
		Position->current.y += dy*(etime/ntime);
	}

	Position->lastMoveTime = clock( );

	//LMA: maps (for player)
	if(!IsPlayer()||is_done)
	   return;

	//updating player's grid
	int new_coords=0;
	int new_map=0;
	int grid_id=0;

	new_map=Position->Map;
	grid_id=GServer->allmaps[new_map].grid_id;
	new_coords=GServer->GetGridNumber(new_map,(UINT) floor(Position->current.x),(UINT) floor(Position->current.y));
	//changed?
    if (last_map==new_map&&new_coords==last_coords)
         return;

     //Let's update.
	if (grid_id!=-1||!GServer->allmaps[new_map].always_on)
	   GServer->gridmaps[grid_id].coords[new_coords]++;

   //deleting player from his previous map
   grid_id=GServer->allmaps[last_map].grid_id;
   if (grid_id!=-1&&!GServer->allmaps[last_map].always_on&&GServer->gridmaps[grid_id].coords[last_coords]>0)
      GServer->gridmaps[grid_id].coords[last_coords]--;

    //Log(MSG_INFO,"Now[%i,%i],Was[%i,%i]",new_map,new_coords,last_map,last_coords);
	last_map=new_map;
	last_coords=new_coords;
}
コード例 #11
0
ファイル: character.cpp プロジェクト: karlseven/ROED
void CCharacter::UpdatePosition( bool monster_stay_still )
{
    //LMA: osprose.
    if(IsOnBattle( ) && Battle->target!=0)
    {
        CCharacter* Target = GetCharTarget( );

        if(Target == NULL)
        {
            ClearBattle( Battle );
        }
        else
        {
            //LMA: Don't need to move if the target is reached.
            //Bad idea since the monster can go away and it seems
            //player goes automatically after him client side...
            /*
            if (Battle->atktype==NORMAL_ATTACK)
            {
                if(!IsTargetReached( Target ))
                {
                    Position->destiny=Target->Position->current;
                }

            }
            else
            {
                Position->destiny=Target->Position->current;
            }
            */
            //So let's go back to the old way.
             //LMA: done in DoAttack...
            //Can be "dangerous" since it checks range for normal attack
            //and if we're with skills the range isn't the same so player changes
            //its destiny all the time from skill range to weapon range.
            /*if(!IsTargetReached( Target ))
            {
                Position->destiny=Target->Position->current;
            }*/

        }

    }
	//osprose end.

    //LMA: position in map 8
    /*if(Position->Map==8)
    {
        float tempdist = GServer->distance(Position->current,Position->destiny);

        if(IsPlayer())
        {
            Log(MSG_INFO,"Player HP %I64i, (%.2f:%.2f)->(%.2f:%.2f)=%.2f speed %u",Stats->HP,Position->current.x,Position->current.y,Position->destiny.x,Position->destiny.y,tempdist,Stats->Move_Speed);
        }
        else
        {
            Log(MSG_INFO,"Monster HP %I64i, (%.2f:%.2f)->(%.2f:%.2f)=%.2f speed %u",Stats->HP,Position->current.x,Position->current.y,Position->destiny.x,Position->destiny.y,tempdist,Stats->Move_Speed);
            //Log(MSG_LOAD,"Monster (%.2f:%.2f)->(%.2f:%.2f)",Position->current.x,Position->current.y,Position->destiny.x,Position->destiny.y);
        }

    }*/

    //LMA maps: special case (arrive in Game)
    //and he changed map (GM or scroll or teleporter or boat?)
    //2do: other cases too, all in fact...
    bool is_done=false;
    if (IsPlayer( )&&((last_map==-1&&last_coords==-1)||(last_map!=Position->Map)))
    {
      	//updating player's grid
    	int new_coords=0;
    	int new_map=0;
    	int grid_id=0;

      	//deleting previous presence...
      	if (last_map!=-1&&last_coords!=-1)
      	{
          	grid_id=GServer->allmaps[last_map].grid_id;
            if (grid_id!=-1&&!GServer->allmaps[last_map].always_on&&GServer->gridmaps[grid_id].coords[last_coords]>0)
               GServer->gridmaps[grid_id].coords[last_coords]--;
        }

        //New coordinates
    	new_map=Position->Map;
    	grid_id=GServer->allmaps[new_map].grid_id;

        if (grid_id==-1)
        {
            Log(MSG_WARNING,"It seems you forgot to declare map %i in map_grid.csv",new_map);
        }

        new_coords=GServer->GetGridNumber(new_map,(UINT) floor(Position->current.x),(UINT) floor(Position->current.y));
    	last_map=new_map;
    	last_coords=new_coords;

    	//if (grid_id!=-1||!GServer->allmaps[new_map].always_on)
    	if (grid_id!=-1&&!GServer->allmaps[new_map].always_on)
           GServer->gridmaps[grid_id].coords[new_coords]++;

   	    is_done=true;
    }

    if(!IsMoving())
    {
        //osprose
        if(IsPlayer())
        {
            Position->current.x = Position->destiny.x;
            Position->current.y = Position->destiny.y;
            Position->lastMoveTime = clock();
        }
        //osprose end
        return;
    }

	float dx = Position->destiny.x - Position->current.x;
	float dy = Position->destiny.y - Position->current.y;
	float distance = sqrt( (dx*dx) + (dy*dy) );
	float ntime = ( distance / (float(Stats->Move_Speed)/100)) * CLOCKS_PER_SEC;
    clock_t etime = clock() - Position->lastMoveTime;

    //LMA: bad, that's bad...
	//if (ntime<=etime || distance<1.0 )
	if (ntime<=etime || distance<0.01 )
    {
        // if (IsPlayer()) printf("Arrived! X: %i, Y: %i\n", (int)Position->current.x, (int)Position->current.y);
        if(Position->Map==8&&IsMonster())
        {
            Log(MSG_INFO," Monster Arrived, J (%.2f:%.2f)->(%.2f:%.2f)",Position->current.x,Position->current.y,Position->destiny.x,Position->destiny.y);
        }

		Position->current.x = Position->destiny.x;
		Position->current.y = Position->destiny.y;
    }
	else
    {
		Position->current.x = dx*(etime/ntime) + Position->current.x;
		Position->current.y = dy*(etime/ntime) + Position->current.y;
	}

	Position->lastMoveTime = clock( );

	//LMA: maps (for player)
	if(!IsPlayer()||is_done)
	   return;

	//updating player's grid
	int new_coords=0;
	int new_map=0;
	int grid_id=0;

	new_map=Position->Map;
	grid_id=GServer->allmaps[new_map].grid_id;

	if (grid_id==-1)
	{
	    Log(MSG_WARNING,"It seems you forgot to declare map %i in map_grid.csv",new_map);
	}

	new_coords=GServer->GetGridNumber(new_map,(UINT) floor(Position->current.x),(UINT) floor(Position->current.y));
	//changed?
    if (last_map==new_map&&new_coords==last_coords)
         return;

     //Let's update.
	//if (grid_id!=-1||!GServer->allmaps[new_map].always_on)
	if (grid_id!=-1&&!GServer->allmaps[new_map].always_on)
	   GServer->gridmaps[grid_id].coords[new_coords]++;

   //deleting player from his previous map
   grid_id=GServer->allmaps[last_map].grid_id;
   if (grid_id!=-1&&!GServer->allmaps[last_map].always_on&&GServer->gridmaps[grid_id].coords[last_coords]>0)
      GServer->gridmaps[grid_id].coords[last_coords]--;

    //Log(MSG_INFO,"Now[%i,%i],Was[%i,%i]",new_map,new_coords,last_map,last_coords);
	last_map=new_map;
	last_coords=new_coords;
}