Jump to content
SubSpace Forum Network

Recommended Posts

Posted (edited)

The ship is the player. I want to put the bot in A,B,and C to fire weapons. I need to know how to get each A(x,y) B(x,y) and C(x,y).

 

Whats given is Player(x,y) and Rotation(0-39). Distance between Player(x,y) and each of the points.

 

how to?

Rotate1.png

Rotate2.png

Edited by PsyOps
Posted

Use a slope formula.

 

a^2 + b^2 = c^2

 

If the distance between A<->player and player<->C is 64 pixels on a horizontal axis, a=0 b=64 and thus c must equal 64.

 

However, I am sure there are other and better ways of doing this.

Posted

For the bots for fly 'naturally' you will need some kind of correction algorithm, as SubSpace ships typically don't strafe left/right. If you don't apply something like that, it will simply look like the surrounding ships are attached to the centre ship.

 

If that's not something you're worried about, then I'd suggest using the equation of a circle in parametric form. For best effects, you'll probably need to convert the rotation angle from SubSpace (which I'm guessing from your question is between 0-39) into radians. Also, as speed is clearly going to be important (as I recall MERVBots aren't terribly fast) you'll probably want to be using both sine and cosine in the equation.

 

If you're still struggling I'll post up a pseudo-code solution of what I think might work tomorrow after my exams are done. ^_^

Posted

If Offset(angle=0) = (OffX, OffY), you can calculate the offset at any angle with:

 

Offset(angle) = ( OffX*cos(angle)-OffY*sin(angle) ; OffX*sin(angle)+OffY*cos(angle) )

 

So let's see if that works...

Say you have A at (-40,0) from the player's ship,

 

A.X = -40 * cos(angle) - 0*sin(angle)

A.Y = -40 * sin(angle) + 0*cos(angle)

 

So if you rotate 90 degrees:

 

A.X = 0

A.Y = -40

 

Seems to make sense...

 

Of course you need to convert 0-39 rotation steps to 0-2*PI:

0 -> 0rads

40-> 2*PI rads

 

So realangle(step) = step * 2.0 * PI / 40.0 = step * PI / 20.0

Posted

i should have explained a little better.

 

Cool Cat is inside of a box, he can not move only rotate. The "Boss" is also fixed. They both just rotate. What I know is that the Boss axis is (x,y). I know Cool Cat's rotation. Now I need to know where to put the bot to shoot from under the image of the terrier, and make it look like it is shooting. I could get a distance from Boss.Axis, but I'm not sure. I will have to test diff distances. I just needed the expression to plug into the bot. That way on startup it can do all the math and store the numbers in an array for later use.

 

Posted

I'm confused... do you want to put 3 bots in there? If so, do you need these bots to move to follow the wings like the attached screenshots of your first post?

 

 

 

If so... my equation does exactly that... add the distance between the center of "boss" and "player", and it would do that.

 

 

See my image:

 

Blue line = PlayerBossOffset ( .x and .y )

The 3 red lines = BossBotOffsetA,B,C (.x and .y ) , one for each bot you want to place

 

double angle = p->position.rotation * PI / 20.0;

BotA->position.x = p->position.x + PlayerBossOffset.x + ( BossBotOffsetA.x * cos(angle) - BossBotOffsetA.y * sin(angle) );
BotA->position.y = p->position.y + PlayerBossOffset.y + ( BossBotOffsetA.x * sin(angle) + BossBotOffsetA.y * cos(angle) );
BotA->position.rotation = p->position.rotation;

//Repeat for BotB and BotC

pewpew.png

Posted (edited)

This is a snippit of a module (by d1st0rt) in which I had to add that same formula.

#include <math.h>
static double sintabf[40];

typedef struct GunTurretInfo
{
   char name[20]; // name of the turret
   byte ship;     // what ship it should use
   int x;         // relative X to it's master
   int y;         // relative Y to it's master
   int rot;       // relative rotation to it's master
   struct Weapons weapon; // What weapon to fire
} GunTurretInfo;

static void LOAD()
{
   int i;

   for (i = 0; i < 40; i++)
       sintabf[i] = sin(i * PI / 20);
}

static void PPK(Player *p /* The boss*/ , const struct C2SPosition *pos)
{
   gtppd *data;
   Link *link;
   gt *turret;
   struct C2SPosition ppk;
   int rot;

   switch(pos->weapon.type)
   {
       // player is firing
       case W_BULLET:
       case W_BOUNCEBULLET:
       case W_BOMB:
       case W_PROXBOMB:
           pthread_mutex_lock(&globalmutex);

           memset(&ppk, 0, sizeof(ppk));
           ppk.type = C2S_POSITION;
           ppk.rotation = pos->rotation;
           ppk.time = pos->time;
           ppk.y = pos->y;
           ppk.x = pos->x;
           ppk.xspeed = pos->xspeed;
           ppk.yspeed = pos->yspeed;
           ppk.energy = pos->energy;
           ppk.status = STATUS_UFO | STATUS_CLOAK | STATUS_STEALTH;

           data = (gtppd *)PPDATA(p, pdkey);
           FOR_EACH(&data->turrets, turret, link) // The bosses' minions
           {
               if(turret->p && !turret->coast)
               {
                   ppk.y = pos->y;
                   ppk.x = pos->x;
                   rot = pos->rotation;
                   
                   rot += turret->type->rot;
                   rot %= 40;
                   if (rot < 0)
                   	rot += 40;
                   
                   ppk.x += (int)round(  turret->type->x * sintabf[(rot + 10) % 40] - turret->type->y * sintabf[rot % 40]  );
                   ppk.y += (int)round(  turret->type->x * sintabf[rot % 40]        + turret->type->y * sintabf[(rot + 10) % 40]  );
                                       
                   ppk.rotation = rot;
                   memcpy(&ppk.weapon, &turret->type->weapon, sizeof(struct Weapons));
                   game->FakePosition(turret->p, &ppk, sizeof(ppk));
                   turret->lastpkt = current_ticks();
               }
           }

           pthread_mutex_unlock(&globalmutex);
       break;
   }
}

Edited by JoWie
Posted (edited)

I wrote the code for Psy tonight and it works... here it is:

I did conversion to degrees because I it makes it a little easier to follow. There's other bloatedness that I have because I was changing as little of his code as possible to help him learn.

 

One note is that this code creates negative values for degrees and radians. Which works fine.

 

EDIT: This is an alphacore bot, on a subgame (SVS) server.

 

       // Bot positions for the 40 rotation points
       // Right Gun
       ushort[] BossGunRightX = new ushort[40];
       ushort[] BossGunRightY = new ushort[40];
       // Left Gun
       ushort[] BossGunLeftX = new ushort[40];
       ushort[] BossGunLeftY = new ushort[40];
       // Nose
       ushort[] BossNoseX = new ushort[40];
       ushort[] BossNoseY = new ushort[40];
       ushort offsetNose = 128;
       ushort offsetGuns = 128;
ushort angleNose2Guns = 75;

               ushort bossX = BossManager.List["Main"].CenterMass[0];
               ushort bossY = BossManager.List["Main"].CenterMass[1];
               for (int i = 0; i < 40; i++)
               {
                       int angleDegrees = (-i+10)*9;
		double angleRadians = (Math.PI / 180) * angleDegrees;
		double angle = angleRadians;
				
		//OLD BROKED CODE BELOW
		//double angle = Math.Sin(i * Math.PI / 20.0);
				
		BossNoseX[i] = bossX + (ushort)Math.Floor(Math.Cos(angle) * offsetNose);
		BossNoseY[i] = bossY + (ushort)Math.Floor(-Math.Sin(angle) * offsetNose);

		//for the left gun we rework the angle by adding degrees from nose
		//and this time we use offsetGuns when multiplying out the formula results
		//for x and y
		angleRadians = (Math.PI / 180) * (angleDegrees + angleNose2Guns);
		angle = angleRadians;
		BossGunLeftX[i] = bossX + (ushort)Math.Floor(Math.Cos(angle) * offsetGuns);
		BossGunLeftY[i] = bossY + (ushort)Math.Floor(-Math.Sin(angle) * offsetGuns);

                       //for right gun we do the same thing, but subtract degrees this time
		//uses same offset as left gun
		angleRadians = (Math.PI / 180) * (angleDegrees - angleNose2Guns);
		angle = angleRadians;
		BossGunRightX[i] = bossX + (ushort)Math.Floor(Math.Cos(angle) * offsetGuns);
		BossGunRightY[i] = bossY + (ushort)Math.Floor(-Math.Sin(angle) * offsetGuns);
				
		//OLD BROKED CODE BELOW
		//BossGunRightX[i] = (ushort)Math.Floor(((bossX + offsetGuns) * Math.Cos(angle) - (0 * Math.Sin(angle))));
                       //BossGunRightY[i] = (ushort)Math.Floor(((bossX + offsetGuns) * Math.Sin(angle)) - (0 * Math.Cos(angle)));
                       //BossGunLeftX[i] = (ushort)Math.Floor(((bossX - offsetGuns) * Math.Cos(angle)) - (0 * Math.Sin(angle)));
                       //BossGunLeftY[i] = (ushort)Math.Floor(((bossX - offsetGuns) * Math.Sin(angle)) - (0 * Math.Cos(angle)));
                       //BossNoseX[i] = (ushort)Math.Floor((0 * Math.Cos(angle)) - ((bossY - offsetNose) * Math.Sin(angle)));
                       //BossNoseY[i] = (ushort)Math.Floor((0 * Math.Sin(angle)) - ((bossY - offsetNose) * Math.Cos(angle)));
               }

Edited by Arry

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...