277 lines
3.6 KiB
C++
277 lines
3.6 KiB
C++
//
|
|
// Tractor beams!
|
|
//
|
|
|
|
#include "always.h"
|
|
#include "orb.h"
|
|
#include "os.h"
|
|
#include "ship.h"
|
|
#include "tb.h"
|
|
|
|
|
|
//
|
|
// The tractor beams.
|
|
//
|
|
|
|
TB_Tb TB_tb[TB_MAX_TBS];
|
|
|
|
|
|
//
|
|
// The texture we use to draw the tractor beams.
|
|
//
|
|
|
|
OS_Texture *TB_ot;
|
|
|
|
|
|
void TB_init()
|
|
{
|
|
memset(TB_tb, 0, sizeof(TB_tb));
|
|
|
|
TB_ot = OS_texture_create("orb.tga");
|
|
}
|
|
|
|
|
|
TB_Tb *TB_create(SHIP_Ship *ss, float length)
|
|
{
|
|
SLONG i;
|
|
|
|
float dx;
|
|
float dy;
|
|
float dist;
|
|
|
|
ORB_Orb *oo;
|
|
TB_Tb *tt;
|
|
|
|
//
|
|
// Look for an orb close to the ship.
|
|
//
|
|
|
|
for (i = 0; i < ORB_MAX_ORBS; i++)
|
|
{
|
|
oo = &ORB_orb[i];
|
|
|
|
if (oo->flag & ORB_FLAG_USED)
|
|
{
|
|
dx = oo->x - ss->x;
|
|
dy = oo->y - ss->y;
|
|
|
|
dist = sqrt(dx*dx + dy*dy);
|
|
|
|
if (dist < length)
|
|
{
|
|
goto found_an_orb;
|
|
}
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
|
|
found_an_orb:;
|
|
|
|
//
|
|
// Create a tractor beam between the ship and orb.
|
|
//
|
|
|
|
for (i = 0; i < TB_MAX_TBS; i++)
|
|
{
|
|
tt = &TB_tb[i];
|
|
|
|
if (tt->flag & TB_FLAG_USED)
|
|
{
|
|
//
|
|
// Already in use.
|
|
//
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Inialise the new tractor beam.
|
|
//
|
|
|
|
tt->flag = TB_FLAG_USED;
|
|
tt->length = length;
|
|
tt->ship = ss - SHIP_ship;
|
|
tt->orb = oo - ORB_orb;
|
|
|
|
return tt;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
void TB_destroy(TB_Tb *tt)
|
|
{
|
|
//
|
|
// Easy!
|
|
//
|
|
|
|
tt->flag = 0;
|
|
}
|
|
|
|
|
|
void TB_process_one(TB_Tb *tt)
|
|
{
|
|
float dlen;
|
|
float dx;
|
|
float dy;
|
|
float dist;
|
|
float force;
|
|
|
|
SHIP_Ship *ss = &SHIP_ship[tt->ship];
|
|
ORB_Orb *oo = &ORB_orb [tt->orb ];
|
|
|
|
//
|
|
// How far apart are this tractor beams ship and orb.
|
|
//
|
|
|
|
dx = ss->x - oo->x;
|
|
dy = ss->y - oo->y;
|
|
|
|
dist = sqrt(dx*dx + dy*dy);
|
|
|
|
if (!(tt->flag & TB_FLAG_LOCKED))
|
|
{
|
|
//
|
|
// Wait until the ship and the orb are too far apart before applying
|
|
// any force.
|
|
//
|
|
|
|
if (dist > tt->length)
|
|
{
|
|
tt->flag |= TB_FLAG_LOCKED;
|
|
}
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Too far apart or too close together?
|
|
//
|
|
|
|
dlen = dist - tt->length;
|
|
|
|
//
|
|
// And what's the force associated with change of length?
|
|
//
|
|
|
|
force = dlen * 0.25F;
|
|
|
|
dx = dx * force / dist;
|
|
dy = dy * force / dist;
|
|
|
|
//
|
|
// Accelerate the ship and orb.
|
|
//
|
|
|
|
ss->dx -= dx / ss->mass;
|
|
ss->dy -= dy / ss->mass;
|
|
|
|
oo->dx += dx / oo->mass;
|
|
oo->dy += dy / oo->mass;
|
|
}
|
|
|
|
|
|
void TB_process_all()
|
|
{
|
|
SLONG i;
|
|
|
|
TB_Tb *tt;
|
|
|
|
//
|
|
// Process all the tractor beams.
|
|
//
|
|
|
|
for (i = 0; i < TB_MAX_TBS; i++)
|
|
{
|
|
tt = &TB_tb[i];
|
|
|
|
if (tt->flag & TB_FLAG_USED)
|
|
{
|
|
TB_process_one(tt);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Draws the tractor beams.
|
|
//
|
|
|
|
void TB_draw_all(float mid_x, float mid_y, float zoom)
|
|
{
|
|
SLONG i;
|
|
SLONG j;
|
|
|
|
float x;
|
|
float y;
|
|
|
|
TB_Tb *tt;
|
|
SHIP_Ship *ss;
|
|
ORB_Orb *oo;
|
|
OS_Buffer *ob;
|
|
|
|
//
|
|
// Draw all the tractor beams.
|
|
//
|
|
|
|
ob = OS_buffer_new();
|
|
|
|
for (i = 0; i < TB_MAX_TBS; i++)
|
|
{
|
|
tt = &TB_tb[i];
|
|
|
|
if (tt->flag & TB_FLAG_USED)
|
|
{
|
|
ss = &SHIP_ship[tt->ship];
|
|
oo = &ORB_orb [tt->orb ];
|
|
|
|
#ifndef USE_DOTS
|
|
|
|
OS_buffer_add_line_2d(
|
|
ob,
|
|
0.5F + (ss->x - mid_x) * zoom,
|
|
0.5F - (ss->y - mid_y) * zoom * 1.33F,
|
|
0.5F + (oo->x - mid_x) * zoom,
|
|
0.5F - (oo->y - mid_y) * zoom * 1.33F,
|
|
0.1F * zoom,
|
|
0.0F, 0.0F,
|
|
1.0F, 1.0F,
|
|
0.0F,
|
|
(tt->flag & TB_FLAG_LOCKED) ? 0x00ff5522 : 0x00888822);
|
|
|
|
#else
|
|
|
|
#define TB_DOTS_ALONG 32
|
|
|
|
for (j = 0; j < TB_DOTS_ALONG; j++)
|
|
{
|
|
x = ss->x + (oo->x - ss->x) * float(j) / float(TB_DOTS_ALONG);
|
|
y = ss->y + (oo->y - ss->y) * float(j) / float(TB_DOTS_ALONG);
|
|
|
|
OS_buffer_add_sprite_rot(
|
|
ob,
|
|
0.5F + (x - mid_x) * zoom,
|
|
0.5F - (y - mid_y) * zoom * 1.33F,
|
|
0.1F * zoom,
|
|
0.0F,
|
|
0.0F, 0.0F,
|
|
1.0F, 1.0F,
|
|
0.0F,
|
|
(tt->flag & TB_FLAG_LOCKED) ? 0x00665522 : 0x00888822);
|
|
}
|
|
|
|
#endif
|
|
}
|
|
}
|
|
|
|
OS_buffer_draw(ob, TB_ot, NULL, OS_DRAW_ADD | OS_DRAW_DOUBLESIDED);
|
|
}
|
|
|
|
|
|
|