#include <stdio.h>
#include <dos.h>
#include <math.h>
#include <string.h>
#include <malloc.h>
#include "3dproj.h"
#include "3ddefs.h"
#include "3dprep.h"
#include "3dvarse.h"

void createtorus(int complexity ,float x, float y, float z, float sx, float sy, float sz)
{
  int f;
  float aroundz,aroundy;
  float cx,cy,cz;
  float ssx,ssy,ssz;
  aroundz=0;aroundy=0;
  cx=sx; cy=sy; cz=sz;
  ssx=0; ssy=0; ssz=25;
  for (f=0; f<complexity; f++)
  {
    rotatesummat(&cx,&cy,&cz,0,aroundy,aroundz);
    rotatesummat(&ssx,&ssy,&ssz,0,aroundy,aroundz);
    createobject(22+apirandom(4), x+cx,y+cy,z+cz, ssx,ssy,ssz ,0 , -1);
    aroundy=aroundy+4;
    aroundz=aroundz+2;
  }
}

void  createexplosion(int complexity ,float x, float y, float z, float sx, float sy, float sz)
{
  int f;
  float xold,yold,zold;
  if (soundblaster==1) playsoundeffect(9, pythag3d(x,y,z)/1.5 );
  createobject(101, x,y,z, 0,0,0, 0 , -1);
  if (sparks==0) return;
  for (f=0; f<complexity; f++)
  {
    xold=saferandom(sx);
    yold=saferandom(sy);
    zold=saferandom(sz);
    createobject(20, x+xold,y+yold,z+zold ,xold,yold,zold ,0,-1);
    createobject(21, x+xold,y+yold,z+zold ,xold*2,-yold*2,-zold*2 ,0,-1);
  }
}

void  createcomm(int from, int type, int side, char msg[120])
{
  int f;

  c[currentcomm].newcomm=1;
  currentcomm++;
  if (currentcomm>comms-1)
  {
    currentcomm=0;
    currentprintcomm=0;
    for (f=0; f<comms; f++) c[f].newcomm=0;
  }
  c[currentcomm].from=from;
  c[currentcomm].type=type;
  c[currentcomm].side=side;
  strcpy(c[currentcomm].msg,msg);
  if (c[currentprintcomm].from==0) commtimer=0;
}

void  createcommevent( int f, long time, int from, int side, char msg[120] )
{
  ce[f].time=time;
  ce[f].from=from;
  ce[f].side=side;
  strcpy(ce[f].msg, msg );
}

void createdebrisfield(void)
{
  int f;
  for (f=0; f<100; f++)
  {
    d[f].x=apirandom(1000)-500;
    d[f].y=apirandom(1000)-500;
    d[f].z=apirandom(1000)-500;
    d[f].rsx=saferandom(10);
    d[f].rsy=saferandom(10);
    d[f].rsz=saferandom(10);
    d[f].rx=0;
    d[f].ry=0;
    d[f].rz=0;
    d[f].dx[0]=1;   d[f].dy[0]=1;   d[f].dz[0]=100;
    d[f].dx[1]=1;   d[f].dy[1]=100; d[f].dz[1]=1;
    d[f].dx[2]=100; d[f].dy[2]=1;   d[f].dz[2]=1;
    d[f].shape=43+apirandom(4);
    d[f].object=dddLoad(shapedata[d[f].shape].filename);
  }
}

void createstarfield(void)
{
  int f;
  float aroundz,aroundy;
  float starx,stary,starz;
  aroundz=0;aroundy=0;
  for (f=0; f<maxstars; f++)
  {
    starx=saferandom(100);
    stary=saferandom(100);
    starz=100;
    star[f].c=apirandom(4);
    if (star[f].c==1 && apirandom(100)<96) star[f].c=3;
    if (star[f].c==0) star[f].object=dddLoad("star1.3dw");
    else if (star[f].c==1) star[f].object=dddLoad("star2.3dw");
    else if (star[f].c==2) star[f].object=dddLoad("star3.3dw");
    else star[f].object=dddLoad("star4.3dw");
    rotatesummat(&starx,&stary,&starz,0,aroundy,aroundz);

//    star[f].c=0;star[f].object=dddLoad("star1.3dw");
    star[f].x=starx*120;
    star[f].y=stary*120;
    star[f].z=starz*120;
    aroundy=aroundy+10;
    aroundz=aroundz+1;
  }
}

void  createstellar(int f,int t,int shape, float x, float y, float z, float rx, float ry, float rz, float rsx,float rsy,float rsz, float sx,float sy,float sz )
{
  p[f].type=t;
  p[f].owner=-1;
  p[f].shape=shape;
  p[f].object=dddLoad(shapedata[p[f].shape].filename);
  p[f].dx[0]=1;   p[f].dy[0]=1;   p[f].dz[0]=100;p[f].dx[1]=1;   p[f].dy[1]=100;   p[f].dz[1]=1;p[f].dx[2]=100 ;   p[f].dy[2]=1;   p[f].dz[2]=1;
  p[f].cx=x;p[f].cy=y;p[f].cz=z;
  p[f].rsx=rsx;p[f].rsy=rsy;p[f].rsz=rsz;
  p[f].sx=sx;p[f].sy=sy;p[f].sz=sz;
  p[f].frame1=p[f].frame2=p[f].frame3=0;
  p[f].target=-1;  p[f].speed=0;
  p[f].toprevs=1; p[f].topspeed=1;
  p[f].currentrevs=0;
  spinprojectile(f, x,y,z, rx,ry,rz ,0 );
}

void  createobject(int type, float x,float y,float z, float sx,float sy,float sz,       float target,int owner)
{
  int f,g;
  float distance1;
  distance1=pythag3d(x,y,z)-pythag3d(viewx,viewy,viewz);
  if (distance1<0) distance1=-distance1;
  f=ccpp;
  for(g=0;g<shapes-10;g++)
  {
    f++;
    if (f>shapes-10) f=0;
    if (p[f].type==-1)
    {
      p[f].cx=x;     p[f].cy=y;     p[f].cz=z;
      p[f].sx=sx;    p[f].sy=sy;    p[f].sz=sz;
      p[f].rx=0;     p[f].ry=0;     p[f].rz=0;
      p[f].rsx=0;    p[f].rsy=0;    p[f].rsz=0;
      p[f].dx[0]=sx; p[f].dy[0]=sy; p[f].dz[0]=sz;
      p[f].dx[1]=sy; p[f].dy[1]=sz; p[f].dz[1]=sx;
      p[f].dx[2]=sz; p[f].dy[2]=sx; p[f].dz[2]=sy;
      p[f].frame1=0; p[f].frame2=0; p[f].frame3=0;
      p[f].side=0;
      p[f].target=target;
      p[f].owner=owner;
      p[f].currentrevs=0;
      switch(type)
      {
        case 1:
          p[f].type=100; // The laser
          p[f].shape=1;
          p[f].farobject=dddLoad("line1.3dw");
          break;
        case 2:
        case 0:
          p[f].type=100; // The laser
          p[f].shape=2;
          p[f].farobject=dddLoad("line2.3dw");
          break;
        case 3:
          p[f].type=101; // The long beam.
          if(p[f].target==2) p[f].shape=73;
          else p[f].shape=5;
          break;
        case 4:
          p[f].type=101; // The alien long beam.
          p[f].shape=6;
          break;
        case 5:
          p[f].type=102; // The ion chunk.
          p[f].shape=7;
          p[f].farobject=dddLoad("star3.3dw");
          break;
        case 6:
          p[f].type=103; // The small bomb
          p[f].shape=58;
          p[f].toprevs=0.1;
          break;
        case 7:
          p[f].type=104; // The nuke bomb
          p[f].shape=59;
          p[f].toprevs=0.05;
          break;
        case 8:
          p[f].type=105; // The torpedo
          p[f].shape=57;
          p[f].toprevs=0.35;
          p[f].farobject=dddLoad("star2.3dw");
          break;
        case 9:
          p[f].type=106; // missile
          p[f].shape=56;
          p[f].toprevs=1;
          break;
        case 10:
          p[f].type=110; // summat Smoke. Yeah.
          p[f].shape=9;
          break;
        case 11:
          p[f].type=111; //Turbolaser
          p[f].shape=39;
          p[f].farobject=dddLoad("line3.3dw");
          break;
        case 12:
          p[f].type=112;
          p[f].shape=72;
          p[f].toprevs=1.4;
          break;
        case 13: // Chaingun round
          p[f].type=113;
          p[f].shape=41+apirandom(2);
          p[f].farobject=dddLoad("star2.3dw");
          break;
        case 20: // yellow spark
          p[f].type=120;
          p[f].shape=41;
          p[f].frame1=apirandom(20);
          p[f].farobject=dddLoad("star4.3dw");
          break;
        case 21: // red spark
          p[f].type=121;
          p[f].shape=42;
          p[f].frame1=apirandom(40);
          p[f].farobject=dddLoad("star2.3dw");
          break;
        case 22: // wreckage
        case 23:
        case 24:
        case 25:
        case 26:
        case 27:
          p[f].type=122;
          p[f].shape=43+(type-22);
          p[f].dx[0]=0;   p[f].dy[0]=0;   p[f].dz[0]=100;
          p[f].dx[1]=0;   p[f].dy[1]=100;   p[f].dz[1]=0;
          p[f].dx[2]=100;   p[f].dy[2]=0;   p[f].dz[2]=0;
          p[f].rsx=(apirandom(11)-5);
          p[f].rsy=(apirandom(11)-5);
          p[f].rsz=(apirandom(11)-5);
          break;
        case  100: // big boom
          p[f].farobject=dddCreateLight(OMNI_LIGHT,100,0);
          p[f].type=200;
          p[f].shape=62;
          p[f].frame1=0;
          p[f].frame2=0;
          break;
        case 101: // Bigger
          if (soundblaster==1) playsoundeffect(9, distance1/1.5 );
          p[f].farobject=dddCreateLight(OMNI_LIGHT,150,0);
          p[f].type=201;
          p[f].shape=63;
          p[f].frame1=0;
          p[f].frame2=0;
          break;
        case 102: // little boom
          p[f].farobject=dddCreateLight(OMNI_LIGHT,50,0);
          p[f].type=202;
          p[f].shape=64;
          p[f].frame1=0;
          p[f].frame2=0;
          break;
        case 103: // Biggest boom
          if (soundblaster==1) playsoundeffect(9, distance1/1.5 );
          p[f].farobject=dddCreateLight(OMNI_LIGHT,255,0);
          p[f].type=202;
          p[f].shape=78;
          p[f].frame1=0;
          p[f].frame2=0;
          break;
        case 200: // Api inhanced functions. The spark
          p[f].type=250;
          p[f].shape=8;
          p[f].frame1=2;
          break;
        case 201: // Api inhanced functions. The blue boom.
          p[f].type=251;
          p[f].shape=80;
          p[f].frame1=-1;
          break;
        case 202: // Api inhanced functions. The torus.
          p[f].type=252;
          p[f].shape=81;
          p[f].frame1=-1;
          //apirandom(20);
          break;
      };
      break;
    } // End of if
  } // End of while
  p[f].object=dddLoad(shapedata[p[f].shape].filename);
  ccpp=f;
}
void  createobjectevent(int f, long time, int no,
int type, int doing, int side, int target, int topspeed,
int toprevs,
int shields, int maxshields, int armour, int maxarmour,
int stubborn, int wingleader, int wingtype,
float wingx,float wingy,float wingz,
int destination,int rank )
{
  oe[f].time=time;
  oe[f].no=no;
  oe[f].type=type;
  oe[f].doing=doing;
  oe[f].side=side;
  oe[f].target=target;
  oe[f].topspeed=topspeed;
  oe[f].toprevs=toprevs;
  oe[f].shields=shields;
  oe[f].maxshields=maxshields;
  oe[f].armour=armour;
  oe[f].maxarmour=maxarmour;
  oe[f].stubborn=stubborn;
  oe[f].wingleader=wingleader;
  oe[f].wingtype=wingtype;
  oe[f].wingx=wingx;
  oe[f].wingy=wingy;
  oe[f].wingz=wingz;
  oe[f].destination=destination;
  oe[f].rank=rank;
}
void  createcreateobject(
int f, long time, int no,
int shape, int type, int side, int target,
float cx, float cy, float cz, float sx, float sy, float sz,
float rx, float ry, float rz, float rsx, float rsy, float rsz,
int stubborn, int wingleader, int wingtype,
float wingx,float wingy,float wingz,
int destination,char name[40], int rank, int mother, int motherhangerzone )
{
  co[f].time=time;
  co[f].no=no;
  co[f].shape=shape;
  co[f].object=dddLoad(shapedata[co[f].shape].filename);
  co[f].type=type;
  co[f].side=side;
  co[f].target=target;
  co[f].cx=cx;    co[f].cy=cy;    co[f].cz=cz;
  co[f].sx=sx;    co[f].sy=sy;    co[f].sz=sz;
  co[f].rx=rx;    co[f].ry=ry;    co[f].rz=rz;
  co[f].rsx=rsx;  co[f].rsy=rsy;  co[f].rsz=rsz;
  co[f].stubborn=stubborn;
  co[f].wingleader=wingleader;
  co[f].wingtype=wingtype;
  co[f].wingx=wingx;
  co[f].wingy=wingy;
  co[f].wingz=wingz;
  co[f].destination=destination;
  strcpy (co[f].name,name);
  co[f].rank=rank;
  co[f].dx[0]=1;   co[f].dy[0]=1;   co[f].dz[0]=100;
  co[f].dx[1]=1;   co[f].dy[1]=100; co[f].dz[1]=1;
  co[f].dx[2]=100; co[f].dy[2]=1;   co[f].dz[2]=1;
  co[f].mother=mother;
  co[f].motherhangerzone=motherhangerzone;
  spincreateobjects(f,co[f].cx,co[f].cy,co[f].cz,
  co[f].rx,co[f].ry,co[f].rz);
  co[f].dpt=0;
}
void  createship(
int f,int t,int shape, float x, float y, float z, float rx,
float ry, float rz,
float rsx,float rsy,float rsz, float sx,float sy,float sz,
int stubborn, int wingleader, int wingtype,
float wingx,float wingy,float wingz,
int destination,
char name[40], int rank, int target, int mother, int motherhangerzone)
{
  o[f].type=t;
  o[f].shape=shape;
  o[f].object=dddLoad(shapedata[o[f].shape].filename);
  o[f].farobject=dddLoad(shapedata[61].filename);
  o[f].spark=dddLoad(shapedata[8].filename);
  o[f].dx[0]=1;  o[f].dy[0]=1;   o[f].dz[0]=100;
  o[f].dx[1]=1;  o[f].dy[1]=100; o[f].dz[1]=1;
  o[f].dx[2]=100;o[f].dy[2]=1;   o[f].dz[2]=1;
  o[f].cx=x;o[f].cy=y;o[f].cz=z;
  o[f].rsx=rsx;o[f].rsy=rsy;o[f].rsz=rsz;
  o[f].sx=sx;o[f].sy=sy;o[f].sz=sz;
  o[f].frame1=o[f].frame2=o[f].frame3=0;
  o[f].target=target;  o[f].speed=0; o[f].smoking=0; o[f].sparking=0;
  o[f].doing=0;
  o[f].maxarmour=0; o[f].maxshields=0;
  o[f].sparkx=0; o[f].sparky=0; o[f].sparkz=0;
  o[f].toprevs=1; o[f].topspeed=1;
  o[f].currentrevs=0;
  o[f].crashzones=0;
  o[f].turrets=0;
  o[f].guns=0;
  o[f].stubborn=stubborn; o[f].wingleader=wingleader; o[f].wingtype=wingtype;
  o[f].wingx=wingx;o[f].wingy=wingy;o[f].wingz=wingz;
  o[f].destination=destination;
  o[f].rank=rank;
  o[f].thingys=0;
  strcpy(o[f].name, name );
  o[f].mother=mother;
  o[f].motherhangerzone=motherhangerzone;
  o[f].dpt=0;
  if ( o[f].shape==10 ) shape10(f);
  if ( o[f].shape==11 ) shape11(f);
  if ( o[f].shape==12 ) shape12(f);
  if ( o[f].shape==13 ) shape13(f);
  if ( o[f].shape==14 ) shape14(f);
  if ( o[f].shape==15 ) shape15(f);
  if ( o[f].shape==16 ) shape16(f);
  if ( o[f].shape==17 ) shape17(f);
  if ( o[f].shape==18 ) shape18(f);
  if ( o[f].shape==19 ) shape19(f);
  if ( o[f].shape==20 ) shape20(f);
  if ( o[f].shape==21 ) shape21(f);
  if ( o[f].shape==22 ) shape22(f);
  if ( o[f].shape==23 ) shape23(f);
  if ( o[f].shape==24 ) shape24(f);
  if ( o[f].shape==25 ) shape25(f);
  if ( o[f].shape==26 ) shape26(f);
  if ( o[f].shape==27 ) shape27(f);
  if ( o[f].shape==28 ) shape28(f);
  if ( o[f].shape==36 ) shape36(f);
  if ( o[f].shape==37 ) shape37(f);
  if ( o[f].shape==38 ) shape38(f);
  if ( o[f].shape==71 ) shape71(f);
  if ( o[f].shape==76 ) shape76(f);
  if ( o[f].shape==77 ) shape77(f);
  if ( o[f].shape==79 ) shape79(f);
  if ( o[f].shape==84 ) shape84(f);
  if ( o[f].shape==85 ) shape85(f);
  if ( o[f].shape==86 ) shape86(f);
  if ( o[f].shape==87 ) shape87(f);
  if ( o[f].shape==88 ) shape88(f);
  if ( o[f].shape==89 ) shape89(f);
  if ( o[f].shape==90 ) shape90(f);
  if ( o[f].shape==91 ) shape91(f);
  if ( o[f].shape==92 ) shape92(f);
  if ( o[f].shape==93 ) shape93(f);
  if ( o[f].shape==98 ) shape98(f);

  if ( o[f].shape==99 ) shape99(f);
  if ( o[f].shape==100 ) shape100(f);
  o[f].shields=o[f].maxshields;
  o[f].armour=o[f].maxarmour;
  spinobject(f, x,y,z, rx,ry,rz ,0 );
}
////////////////////////
// END OF CREATE SHIP //
////////////////////////

void  createguiobject(int f,int t,int shape, float x, float y, float z, float rx, float ry, float rz, float rsx,float rsy,float rsz, float sx,float sy,float sz )
{
  gui[f].type=t;
  gui[f].shape=shape;
//  jjjtargt_open("OBJECTS.GUN");
//  jjjtargt_tempextract(shapedata[gui[f].shape].filename);
  gui[f].object=dddLoad(shapedata[gui[f].shape].filename);
//  jjjtargt_close();
  gui[f].dx[0]=1;   gui[f].dy[0]=1;   gui[f].dz[0]=100;
  gui[f].dx[1]=1;   gui[f].dy[1]=100; gui[f].dz[1]=1;
  gui[f].dx[2]=100; gui[f].dy[2]=1;   gui[f].dz[2]=1;
  gui[f].cx=x; gui[f].cy=y; gui[f].cz=z;
  gui[f].rsx=rsx; gui[f].rsy=rsy; gui[f].rsz=rsz;
  gui[f].sx=sx; gui[f].sy=sy; gui[f].sz=sz;
  gui[f].speed=0; gui[f].toprevs=1; gui[f].topspeed=1; gui[f].currentrevs=0;
  spinguiobject(f, x,y,z, rx,ry,rz ,0 );
}

void createground(int type,float height)
{
  int f,g,h;
  int inte;
  inte=15995;
  for(f=0;f<9;f++)
  {
    p[shapes-1].type=-1;
    if(type==1)
    {
      gr[f].object=dddLoad("ground1.3dw");
      createstellar(shapes-1,0,97, 0,0,0 ,0,0,0 ,0,0,0 ,0,0,0);
      gr[f].shape=94;
    }
    else if(type==2)
    {
      gr[f].object=dddLoad("ground2.3dw");
      createstellar(shapes-1,0,97, 0,0,0 ,0,0,0 ,0,0,0 ,0,0,0);
      gr[f].shape=95;
    }
    else if(type==3)
    {
      gr[f].object=dddLoad("ground3.3dw");
      createstellar(shapes-1,0,97, 0,0,0 ,0,0,0 ,0,0,0 ,0,0,0);
      gr[f].shape=96;
    }
    gr[f].dx[0]=0;   gr[f].dy[0]=0;   gr[f].dz[0]=1000;
    gr[f].dx[1]=0;   gr[f].dy[1]=1000; gr[f].dz[1]=0;
    gr[f].dx[2]=1000; gr[f].dy[2]=0;   gr[f].dz[2]=0;
    gr[f].rx=1; gr[f].ry=1;   gr[f].rz=1;
    gr[f].thingys=0; // thingy thingytype
    for(g=0;g<10;g++) for(h=0;h<10;h++)
    {
      gr[f].height[g][h]=0;
    }
  }
  dddAttach(gr[0].object,gr[4].object,"0",-inte,0,-inte,0,0,0);
  dddAttach(gr[1].object,gr[4].object,"1",0,0,-inte,0,0,0);
  dddAttach(gr[2].object,gr[4].object,"2",inte,0,-inte,0,0,0);
  dddAttach(gr[3].object,gr[4].object,"3",-inte,0,0,0,0,0);
  dddAttach(gr[5].object,gr[4].object,"5",inte,0,0,0,0,0);
  dddAttach(gr[6].object,gr[4].object,"6",-inte,0,inte,0,0,0);
  dddAttach(gr[7].object,gr[4].object,"7",0,0,inte,0,0,0);
  dddAttach(gr[8].object,gr[4].object,"8",inte,0,inte,0,0,0);

  gr[0].cx=-inte;
  gr[0].cy=height;
  gr[0].cz=-inte;

  gr[1].cx=0;
  gr[1].cy=height;
  gr[1].cz=-inte;

  gr[2].cx=inte;
  gr[2].cy=height;
  gr[2].cz=-inte;

  gr[3].cx=-inte;
  gr[3].cy=height;
  gr[3].cz=0;

  gr[4].cx=0;
  gr[4].cy=height;
  gr[4].cz=0;

  gr[5].cx=inte;
  gr[5].cy=height;
  gr[5].cz=0;

  gr[6].cx=-inte;
  gr[6].cy=height;
  gr[6].cz=inte;

  gr[7].cx=0;
  gr[7].cy=height;
  gr[7].cz=inte;

  gr[8].cx=inte;
  gr[8].cy=height;
  gr[8].cz=inte;

  ground=type;
  sortgroundout();

}

void sortgroundout(void)
{
int f=0;
  if(ground==0) return;
  if(planets==2) f=1;
  dddSetShapeFlags(gr[0].object,f);
  dddSetShapeFlags(gr[1].object,f);
  dddSetShapeFlags(gr[2].object,f);
  dddSetShapeFlags(gr[3].object,f);
  dddSetShapeFlags(gr[5].object,f);
  dddSetShapeFlags(gr[6].object,f);
  dddSetShapeFlags(gr[7].object,f);
  dddSetShapeFlags(gr[8].object,f);

}
