Server Help

ASSS Questions - Fake Players

gilder - Sun Nov 05, 2006 8:27 am
Post subject: Fake Players
There isn't much information about making fake players (visible ones). Only thing than i found helpful was bak's and smong's drone codes. Those modules got plenty of code with player locating other luxuries. As not so pro programmer, it is hard to understand the main point of making those fakes.

So, I think this thread would be helpful for starting coders to have fun with fake players. icon_smile.gif

With the fake interface you can create the fake, but making the fake move and shoot, needs packet editing and that caused problems.
Code: Show/Hide
        arenadata->fakeplayer=fake->CreateFakePlayer("<Fake Player>", arena, SHIP_WARBIRD, 0);
        pos->type = C2S_POSITION;
        pos->rotation = 0;
        pos->x = 500;
        pos->y = 500;
        pos->xspeed = 0;
        pos->yspeed = 0;
        pos->status = 0;
        pos->bounty = 0;

       pos->weapon.type = 0;
       pos->weapon.level = 1;
       pos->weapon.shraplevel = 1;
       pos->weapon.shrap = 0;
       pos->weapon.alternate = 0;   

        game->FakePosition(arenadata->fakeplayer, pos, 22);

That was my first hopeless try, that "suprisingly" crashed the zone.

How often FakePosition needs to be called?
If you want to make the fake accelerate, do you need to calculate the new speed and position yourself?

Any useful information is welcome.
Bak - Sun Nov 05, 2006 3:18 pm
Post subject:
anywhere from 20 times a second to 4 times a second should work (use timers)

yes, you need to do the calculations yourself.
Smong - Sun Nov 05, 2006 7:09 pm
Post subject:
It might be crashing if you didn't assign a value to pos properly.

I would recommend editing autoturret.c, look at mlfunc and comment out the weapon firing, target lock, etc.

Generally you should send positions around 10-20 ticks (depends on Misc:SendPositionDelay setting), but it also depends on how the ship is moving.
gilder - Tue Nov 14, 2006 1:38 pm
Post subject:
I have had some lag problems with fakes. When i make the fake, i can't see the fake move for about 2 seconds. If refresh rate is 10cs, fake is moving smoothly after that spike. With 5 centiseconds, it keeps spiking.


Creation:
Code: Show/Hide
        arenadata->update = current_ticks();
       
        arenadata->fakeplayer=fake->CreateFakePlayer("<Fake>", arena, SHIP_WARBIRD, 0);

        pos.type = C2S_POSITION;
        pos.rotation = 0;
        pos.x = 500*16;
        pos.y = 520*16;
       
        arenadata->x = (double) pos.x;
        arenadata->y = (double) pos.y;   
       
        srand(time(NULL));     
       
        pos.xspeed = -100 + rand() % 200;
        pos.yspeed = -100 + rand() % 200;
       
       
        pos.status = S_PLAYING;
        pos.bounty = 0;

       pos.weapon.type = 0;
       pos.weapon.level = 1;
       pos.weapon.shraplevel = 1;
       pos.weapon.shrap = 0;
       pos.weapon.alternate = 0;      
      

        game->FakePosition(arenadata->fakeplayer, &pos, 22);


Refresh function:
Code: Show/Hide
        int update = current_ticks() - arenadata->update;
        arenadata->update = current_ticks();
       
        struct C2SPosition pos;
       
        pos.type = C2S_POSITION;
       
        //pixels
        arenadata->x += ((double)arenadata->fakeplayer->position.xspeed * (double)update/100.0);
        arenadata->y += ((double)arenadata->fakeplayer->position.yspeed * (double)update/100.0);
       
        pos.x = (int)arenadata->x;
        pos.y = (int)arenadata->y;
 
        //pixels per second
        pos.xspeed = arenadata->fakeplayer->position.xspeed;
        pos.yspeed = arenadata->fakeplayer->position.yspeed;
       
        pos.status = S_PLAYING;
        pos.bounty = 1337;
   
       pos.weapon.type = 0;
       pos.weapon.level = 1;
       pos.weapon.shraplevel = 1;
       pos.weapon.shrap = 0;
       pos.weapon.alternate = 0;   

        // Rotate the fake
        if(pos.xspeed==0)
        {
            if(pos.yspeed >= 0) pos.rotation = 0;
            else pos.rotation = 20;
        }
        else if(pos.yspeed == 0)
        {
            if(pos.xspeed<0) pos.rotation = 30;
            else pos.rotation = 10;
        }
        else if(pos.xspeed > 0 && pos.yspeed > 0)
            pos.rotation = 20.5 - atan((double)pos.xspeed/(double)pos.yspeed)*40.0/2.0/pi;
        else if(pos.xspeed > 0 && pos.yspeed < 0)
            pos.rotation = 0.5 + atan((double)pos.xspeed/-(double)pos.yspeed)*40.0/2.0/pi;
        else if(pos.xspeed < 0 && pos.yspeed > 0)
            pos.rotation = 20.5 + atan(-(double)pos.xspeed/(double)pos.yspeed)*40.0/2.0/pi;
        else if(pos.xspeed < 0 && pos.yspeed < 0)
            pos.rotation = 40.5 - atan(-(double)pos.xspeed/-(double)pos.yspeed)*40.0/2.0/pi;
           

       
        game->FakePosition(arenadata->fakeplayer, &pos, 22); 

Dr Brain - Tue Nov 14, 2006 2:30 pm
Post subject:
Don't use centiseconds, ever. Don't use centi anything except with meters.
gilder - Tue Nov 14, 2006 4:21 pm
Post subject:
I feel more comfortable with millis too, but decided to use centi, because many asss times are in centiseconds. SetTimer for example.

This didn't solve the problem. Should i put some more info to the position packet when i call FakePosition?
Smong - Tue Nov 14, 2006 4:50 pm
Post subject:
For the time I call them ticks.

If you look at autoturret.c you can see each bots position is stored inside the TurretData struct, which each bot has. When enough time has passed a fake position will be sent using data directly from the pos struct, no need to copy it again:
Code: Show/Hide
struct TurretData
{
   Player *p;
   int interval, weapon;
   ticks_t endtime, tofire, tosend;
   struct C2SPosition pos; //<-- look here
};

//global list of turret data (but you can make this per-arena if you feel you really must)
local LinkedList turrets;

//inside create_turret:
   struct C2SPosition *pos;
   struct TurretData *td = amalloc(sizeof(*td));
...
   pos = &td->pos;
   pos->type = C2S_POSITION;
   //blah blah more initialisation of the pos
...
   LLAdd(&turrets, td);

//inside mlfunc:
   for (l = LLGetHead(&turrets); l; l = next)
   {
      struct TurretData *td = l->data;
...
      else if (TICK_GT(now, td->tosend))
      {
...
         //you must update the pos's time to the current time before "sending" it
         td->pos.time = now;
...
         //here you can stick your math calculations
         td->pos.rotation = ...
...
         game->FakePosition(td->p, &td->pos, sizeof(td->pos));


Also note in autoturret.c positions are only sent from the mlfunc, not when the bot is being created.
All times are -5 GMT
View topic
Powered by phpBB 2.0 .0.11 © 2001 phpBB Group