Exemplo n.º 1
0
 /// This shows how to apply a concept to a collection of entities.
 void check_entity_collection_example()
 {
     std::vector<entity> elist = { /* ... lots of entities ... */ };
     
     /// Check is elist contains AT LEAST one entity that satisfys
     /// the concept
     bool result = IsMonster().contains(elist);
     
     /// Try and find the first entity in a list that satisfys the concept.
     /// Return an iterator at the position of the entity 
     /// (or end() if none is found)
     std::vector<entity>::iterator pos = IsHero().find(elist);
     
     /// Try and find the first entity that satisfys the concept.
     /// return a reference to that entity. Throw if not found.
     entity & hero = IsHero().get(elist);
     
     /// Create a "filtered_view" of a list of entities that contains
     /// only the entities that satisfy the concept.
     /// NOTE: filtered_view only provides iterators over the filtered view
     ///       NO COPYS ARE MADE. 
     auto view = IsMonster().filter(elist);
     
     /// Views can be used to iterator over matching entities
     for (auto & monster : view)
     {
         // this never fires
         REQUIRE_CONCEPT(monster, IsMonster);
     }
     
     /// Same as above, but iterators it reverse order
     auto rview = IsMonster().rfilter(elist);
     
     /// "apply" a filter to a given list. DO NOT modify the list.
     /// instead return a vector of reference's to entities that match.
     /// This is useful when you want to sort the matching entities.
     std::vector<std::reference<entity>> 
     matching_entities = IsMonster().apply_filter(elist);
 }
Exemplo n.º 2
0
// do buff skill
bool CCharacter::BuffSkill( CCharacter* Target, CSkills* skill )
{
    Position->destiny = Position->current;
    //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;
    //Log(MSG_DEBUG,"applied buff skill %i",skill->id);
    UseBuffSkill( Target, skill );
    Stats->MP -= (skill->mp - (skill->mp * Stats->MPReduction / 100));
    if(Stats->MP < 0) Stats->MP = 0;
    GServer->DoSkillScript( this, skill ); //summons a monster. Why do we do this for all skills?
    if(!IsMonster())
    {
        ClearBattle( Battle ); // clear battle for players when they use buff skills
        //Battle->bufftarget = 0;
        //Battle->skilltarget = 0;
        //Battle->skillid = 0;
        //Battle->atktype = NORMAL_ATTACK;
    }
    else //Monsters need to be reset to normal attack and clear skill attacks.
    {
        //Battle->atktarget = Battle->target;
        //Battle->bufftarget = 0;
        //Battle->skilltarget = 0;
        //Battle->skillid = 0;
        //Battle->atktype = NORMAL_ATTACK;
        //StartAction(Target, NORMAL_ATTACK);
    }
    Battle->lastAtkTime = clock( );
    Battle->iscasting = 1;
    return true;
}
Exemplo n.º 3
0
const std::string& Ship::PublicName(int empire_id) const {
    // Disclose real ship name only to fleet owners. Rationale: a player who
    // doesn't know the design for a particular ship can easily guess it if the
    // ship's name is "Scout"
    // An exception is made for unowned monsters.
    if (GetUniverse().AllObjectsVisible() || empire_id == ALL_EMPIRES || OwnedBy(empire_id) || (IsMonster() && Owner() == ALL_EMPIRES))
        return Name();
    const ShipDesign* design = Design();
    if (design)
        return design->Name();
    else if (IsMonster())
        return UserString("SM_MONSTER");
    else if (!Unowned())
        return UserString("FW_FOREIGN_SHIP");
    else if (Unowned() && GetVisibility(empire_id) > VIS_NO_VISIBILITY)
        return UserString("FW_ROGUE_SHIP");
    else
        return UserString("OBJ_SHIP");
}
Exemplo n.º 4
0
// 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();    
}
Exemplo n.º 5
0
// 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;
}
Exemplo n.º 6
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.º 7
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.º 8
0
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;
}