MuckyFoot-UrbanChaos/thrust/tb.cpp
2017-05-20 11:14:17 +10:00

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);
}