/*
Copyright (c) 1998 Michael Haar, Ulrich Haar, Michael Thayer,
  Tobias Mueller, Tobias Lenz
All rights reserved.
Terroid Programming by Michael Haar, Michael Thayer, Ulrich Haar
Terroid Graphics by Ulrich Haar, Michael Haar
Terroid Music by Michael Thayer
Terroid Level design by Michael Haar, Ulrich Haar, Tobias Lenz
Terroid Beta testing by Tobias Mueller, Tobias Lenz

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
   notice and credits, this unmodified list of conditions and the
   following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
   notice and credits, this unmodified list of conditions and the
   following disclaimer in the documentation and/or other materials
   provided with the distribution.
3. Any credits displayed during programme execution must include the
   above or an equivalent credit list.
4. The name of the author may not be used to endorse or promote products
   derived from this software without specific prior written permission.
5. The authors Michael Thayer and Michael Haar are to be informed,
   preferable by electronic mail, when this software is distributed
   commercially.  A single notification is required for any given
   distribution, and explicit copies of that distribution (e.g. for all
   resellers of a given Linux distribution).
6. If any modifications are made to the software, then a description of them
   must be included when the software is redistributed, or alternatively,
   the distributed binary or source code must be described as a product
   based on source code by Michael Haar, Michael Thayer and Ulrich Haar.

THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/**********************************/
/* ballerspiel-Objektsteuerungen  */
/* (C) April 1996 by Michael Haar */
/**********************************/

/* Änderungen: */

#include <stdlib.h>
#include <string.h>

#include <math.h>
#include <dn.h>
#include "DEFS.H"
#include "FUNCS.H"
#include "VARS.H"

#define DREHFAC 64
#define MAX_SPEED 64 * KURVENFAC

/* globale Variablen */

/* Funktionsprototypen */
int winkel(int dx, int dy);
void set_richtung(FLUGBAHN *bahn, unsigned char k, unsigned char r, unsigned char speed);
unsigned char get_richtung(FLUGBAHN *bahn, unsigned char k);
void standardsteuern(OBJEKT *obj);
void schnellanisteuern(OBJEKT *obj);
void kippsteuern(OBJEKT *obj);
void drehsteuern(OBJEKT *obj);
int ziel_richtung(FLUGBAHN *bahn);
void schiffrichtung_zielsteuern(OBJEKT *obj);
void spieler_zielraketen_steuern(OBJEKT *obj);
void raketenturmsteuern(OBJEKT *obj);
void zielraketensteuern(OBJEKT *obj);
void kanonenstellungsteuern(OBJEKT *obj);
void streusteuern(OBJEKT *obj);
void minesteuern(OBJEKT *obj);
void schrottsteuern(OBJEKT *obj);
void kettesteuern(OBJEKT *obj);
void restartsteuern(OBJEKT *obj);
void bisallestot_endgegnersteuern(OBJEKT *obj);
void spielersuchsteuern(OBJEKT *obj);
void abstossersteuern(OBJEKT *obj);
void zerbatzsteuern(OBJEKT *obj);
void mittelschnellsteuern(OBJEKT *obj);
void minilaunchersteuern(OBJEKT *obj);
void magnetsteuern(OBJEKT *obj);

/* Funktionen */
int winkel(int dx, int dy)
{
	int w;

	if(dy == 0)
	{
		if(dx > 0)
			w = 90;
		else
			w = 270;
	}
	else
	{
		w = -atan(dx / dy) * 180 / PI;
		if(dy > 0)
			w += 180;
		if(w < 0)
			w += 360;
	}
	return(w);
}		

void set_richtung(FLUGBAHN *bahn, unsigned char k, unsigned char r, unsigned char speed)
{
	bahn->kurve[k].xpl = 0;
	bahn->kurve[k].ypl = 0;
	bahn->kurve[k].xxpl = 0;
	bahn->kurve[k].yypl = 0;
	if(r == 0)
		bahn->kurve[k].ypl = -speed * KURVENFAC * KURVENFAC;
	else if(r == 1)
	{
		bahn->kurve[k].xpl = speed * 8 / 11 * KURVENFAC * KURVENFAC;
		bahn->kurve[k].ypl = -speed * 8 / 11 * KURVENFAC * KURVENFAC;
	}
	else if(r == 2)
		bahn->kurve[k].xpl = speed * KURVENFAC * KURVENFAC;
	else if(r == 3)
	{
		bahn->kurve[k].xpl = speed * 8 / 11 * KURVENFAC * KURVENFAC;
		bahn->kurve[k].ypl = speed * 8 / 11 * KURVENFAC * KURVENFAC;
	}
	else if(r == 4)
		bahn->kurve[k].ypl = speed * KURVENFAC * KURVENFAC;
	else if(r == 5)
	{
		bahn->kurve[k].xpl = -speed * 8 / 11 * KURVENFAC * KURVENFAC;
		bahn->kurve[k].ypl = speed * 8 / 11 * KURVENFAC * KURVENFAC;
	}
	else if(r == 6)
		bahn->kurve[k].xpl = -speed * KURVENFAC * KURVENFAC;
	else if(r == 7)
	{
		bahn->kurve[k].xpl = -speed * 8 / 11 * KURVENFAC * KURVENFAC;
		bahn->kurve[k].ypl = -speed * 8 / 11 * KURVENFAC * KURVENFAC;
	}
	bahn->kurve[k].xpl -=  KURVENFAC * KURVENFAC;
}

unsigned char get_richtung(FLUGBAHN *bahn, unsigned char k)
{
	int xpl, ypl;

	xpl = bahn->kurve[k].xpl / (2 * KURVENFAC);
	ypl = bahn->kurve[k].ypl / (2 * KURVENFAC);


	/* dies hat ulrich eingefuegt um beim nach unten fahren mit scrollen die richtige richtung zu kriegen*/
  xpl += 4;

	if((xpl == 0) && (ypl < 0))
		return(0);
	else if((xpl > 0) && (ypl < 0))
		return(1);
	else if((xpl > 0) && (ypl == 0))
		return(2);
	else if((xpl > 0) && (ypl > 0))
		return(3);
	else if((xpl == 0) && (ypl > 0))
		return(4);
	else if((xpl < 0) && (ypl > 0))
		return(5);
	else if((xpl < 0) && (ypl == 0))
		return(6);
	else
		return(7);
}

int ziel_richtung(FLUGBAHN *bahn)
{
	return(((winkel(spieler.x - bahn->x / KURVENFAC, spieler.y - bahn->y / KURVENFAC) + 22) / 45) % 8);	
}

void standardsteuern(OBJEKT *obj)
{
	if(!obj->startpause)
	{
		obj->anistufe++;
		if(obj->anistufe == obj->anz_anistufen * ANIFAC)
			obj->anistufe = 0;

		obj->bahn.x += obj->bahn.kurve[obj->bahn.akt].xpl / KURVENFAC;
		obj->bahn.y += obj->bahn.kurve[obj->bahn.akt].ypl / KURVENFAC;

		obj->bahn.kurve[obj->bahn.akt].xpl += obj->bahn.kurve[obj->bahn.akt].xxpl;
		obj->bahn.kurve[obj->bahn.akt].ypl += obj->bahn.kurve[obj->bahn.akt].yypl;
	
		obj->bahn.kurve[obj->bahn.akt].len--;
		if(obj->bahn.kurve[obj->bahn.akt].len == 0)
		{
			obj->bahn.akt++;
			if(obj->bahn.akt == obj->bahn.anz)
				delete_objekt(obj);
		}
	}
	else
		obj->startpause--;
}

void schnellanisteuern(OBJEKT *obj)
{
	if(!obj->startpause)
	{
		obj->anistufe += 3;
		if(obj->anistufe >= obj->anz_anistufen * ANIFAC)
			obj->anistufe = 0;

		obj->bahn.x += obj->bahn.kurve[obj->bahn.akt].xpl / KURVENFAC;
		obj->bahn.y += obj->bahn.kurve[obj->bahn.akt].ypl / KURVENFAC;
		obj->bahn.kurve[obj->bahn.akt].xpl += obj->bahn.kurve[obj->bahn.akt].xxpl;
		obj->bahn.kurve[obj->bahn.akt].ypl += obj->bahn.kurve[obj->bahn.akt].yypl;
	
		obj->bahn.kurve[obj->bahn.akt].len--;
		if(obj->bahn.kurve[obj->bahn.akt].len == 0)
		{
			obj->bahn.akt++;
			if(obj->bahn.akt == obj->bahn.anz)
				delete_objekt(obj);
		}
	}
	else
		obj->startpause--;
}

void kippsteuern(OBJEKT *obj)
{
	if(!obj->startpause)
	{
		if(obj->anistufe > 1 * ANIFAC)
			obj->anistufe--;
		else if(obj->anistufe < 1 * ANIFAC)
			obj->anistufe++;

		if(obj->bahn.kurve[obj->bahn.akt].ypl / (2 * KURVENFAC) < 0)
		{
			if(obj->anistufe > 1)
				obj->anistufe -= 2;
		}
		else if(obj->bahn.kurve[obj->bahn.akt].ypl / (2 * KURVENFAC) > 0)
		{
			if(obj->anistufe < 3 * ANIFAC - 2)
				obj->anistufe += 2;
		}

		obj->bahn.x += obj->bahn.kurve[obj->bahn.akt].xpl / KURVENFAC;
		obj->bahn.y += obj->bahn.kurve[obj->bahn.akt].ypl / KURVENFAC;
		obj->bahn.kurve[obj->bahn.akt].xpl += obj->bahn.kurve[obj->bahn.akt].xxpl;
		obj->bahn.kurve[obj->bahn.akt].ypl += obj->bahn.kurve[obj->bahn.akt].yypl;
	
		obj->bahn.kurve[obj->bahn.akt].len--;
		if(obj->bahn.kurve[obj->bahn.akt].len == 0)
		{
			obj->bahn.akt++;
			if(obj->bahn.akt == obj->bahn.anz)
				delete_objekt(obj);
		}
	}
	else
	{
		obj->anistufe = 1 * ANIFAC;
		obj->startpause--;
	}
}

void drehsteuern(OBJEKT *obj)
{
	if(!obj->startpause)
	{
		obj->anistufe = get_richtung(&obj->bahn, obj->bahn.akt) * ANIFAC;

		obj->bahn.x += obj->bahn.kurve[obj->bahn.akt].xpl / KURVENFAC;
		obj->bahn.y += obj->bahn.kurve[obj->bahn.akt].ypl / KURVENFAC;
		obj->bahn.kurve[obj->bahn.akt].xpl += obj->bahn.kurve[obj->bahn.akt].xxpl;
		obj->bahn.kurve[obj->bahn.akt].ypl += obj->bahn.kurve[obj->bahn.akt].yypl;
	
		obj->bahn.kurve[obj->bahn.akt].len--;
		if(obj->bahn.kurve[obj->bahn.akt].len == 0)
		{
			obj->bahn.akt++;
			if(obj->bahn.akt == obj->bahn.anz)
				delete_objekt(obj);
		}
	}
	else
	{
		obj->anistufe = 6 * ANIFAC;
		obj->startpause--;
		// Für die Fahrzeuge mitscrollen, damit Plattformpos ok
		if(obj->nr == GEGNERPICS + 99)
			obj->bahn.x -= MITTE_SCROLLGESCHW * KURVENFAC;
	}	
}

void schiffrichtung_zielsteuern(OBJEKT *obj)
{
	if(!obj->startpause)
	{
		obj->anistufe = ziel_richtung(&obj->bahn) * ANIFAC;

		obj->bahn.x += obj->bahn.kurve[obj->bahn.akt].xpl / KURVENFAC;
		obj->bahn.y += obj->bahn.kurve[obj->bahn.akt].ypl / KURVENFAC;
		obj->bahn.kurve[obj->bahn.akt].xpl += obj->bahn.kurve[obj->bahn.akt].xxpl;
		obj->bahn.kurve[obj->bahn.akt].ypl += obj->bahn.kurve[obj->bahn.akt].yypl;
	
		obj->bahn.kurve[obj->bahn.akt].len--;
		if(obj->bahn.kurve[obj->bahn.akt].len == 0)
		{
			obj->bahn.akt++;
			if(obj->bahn.akt == obj->bahn.anz)
			{
				if(obj->art != 62)
					delete_objekt(obj);
				else
					endgegner_restarten(obj); // Kanonen beim 9. Endgegner
			}
		}
	}
	else
	{
		obj->anistufe = 6 * ANIFAC;
		obj->startpause--;
	}
}

int gegner_richtung(FLUGBAHN *bahn, OBJEKT *ziel)
{
	return(((winkel(ziel->bahn.x - bahn->x, ziel->bahn.y - bahn->y) + 22) / 45) % 8);
}

void fliege_ziel(FLUGBAHN *bahn, OBJEKT *obj)
{
	int k;

	k = bahn->akt;
	bahn->kurve[k].xxpl = 0;
	bahn->kurve[k].yypl = 0;
	if(bahn->x / KURVENFAC > obj->bahn.x / KURVENFAC)
		if(bahn->kurve[k].xpl > -32 * KURVENFAC)
			bahn->kurve[k].xpl -= 2 * KURVENFAC;
	if(bahn->x / KURVENFAC < obj->bahn.x / KURVENFAC)
		if(bahn->kurve[k].xpl < 32 * KURVENFAC)
			bahn->kurve[k].xpl += 2 * KURVENFAC;
	if(bahn->y / KURVENFAC > obj->bahn.y / KURVENFAC)
		if(bahn->kurve[k].ypl > -32 * KURVENFAC)
			bahn->kurve[k].ypl -= 2 * KURVENFAC;
	if(bahn->y / KURVENFAC < obj->bahn.y / KURVENFAC)
		if(bahn->kurve[k].ypl < 32 * KURVENFAC)
			bahn->kurve[k].ypl += 2 * KURVENFAC;
}

void spieler_zielraketen_steuern(OBJEKT *obj)
{
	int wink, wink2, wink3;

	int ex,ey;

	if(!obj->startpause)
	{

		wink2 = obj->bahn.kurve[0].xpl; /* xpl und ypl mißbraucht   hi hi */
		wink3 = obj->bahn.kurve[0].ypl;

		obj->anistufe = (((wink3 + 22 ) / 45 ) % 8) * ANIFAC; 

		if((obj->weapon_fire >= 0) && (objekt[obj->weapon_fire].nr > 1))	// weapon_fire wird als Zielnr mißbraucht
			wink = winkel(objekt[obj->weapon_fire].bahn.x - obj->bahn.x , objekt[obj->weapon_fire].bahn.y - obj->bahn.y);
		else
		{
			// neues Ziel da?
			obj->weapon_fire = zielrakete_gegnersuchen();

			if(obj->weapon_fire == -1)
				wink = winkel(600 * KURVENFAC - obj->bahn.x, 100 * KURVENFAC - obj->bahn.y);

			wink = wink3;
		}

		if(wink - 180 > wink3) 
			wink -= 360;
		if(wink + 180 < wink3) 
			wink += 360;
		if(wink + 10 < wink3)
			wink3 -= 10;
		else if(wink - 10 > wink3)
			wink3 += 10;
		if (wink3 > 360 )
			wink3 -= 360;
		else if(wink3 < 0)
			wink3 += 360;

		if(wink - 180 > wink2) 
			wink -= 360;
		if(wink + 180 < wink2) 
			wink += 360;
		if(wink + 5 < wink2)
			wink2 -=5;
		else if(wink - 5 > wink2)
			wink2 +=5;
		if(wink2 > 360)
			wink2 -= 360;
		else if(wink2 < 0)
			wink2 += 360;

		obj->bahn.x += (int)((double)30 * sin((double)wink2 * 3.14 / 180));
		obj->bahn.y -= (int)((double)30 * cos((double)wink2 * 3.14 / 180));

	  obj->bahn.kurve[obj->bahn.akt].xpl = wink2;
	  obj->bahn.kurve[obj->bahn.akt].ypl = wink3;

		obj->bahn.kurve[obj->bahn.akt].len--;
		if(obj->bahn.kurve[obj->bahn.akt].len % 3 == 0)
		{
			wink3 += 180;
			ex = obj->bahn.x + (int)((double)60 * sin((double)wink3 * 3.14 / 180));
			ey = obj->bahn.y - (int)((double)60 * cos((double)wink3 * 3.14 / 180));
			explode(ex / KURVENFAC, ey / KURVENFAC, 0, 0, 1);
		}

		if(obj->bahn.kurve[obj->bahn.akt].len == 0)
		{
			obj->bahn.akt++;
			if(obj->bahn.akt == obj->bahn.anz)
			{
				delete_objekt(obj);
				explode(obj->bahn.x / KURVENFAC, obj->bahn.y / KURVENFAC, rand() % 50, rand() % 50, 0);
			}
		}
	}
	else
	{
		obj->anistufe = 2 * ANIFAC;
		obj->startpause--;
	}
}

void raketenturmsteuern(OBJEKT *obj)
{
	if(!obj->startpause)
	{
		obj->anistufe = 0;
		if(obj->weapon_ok < 8 * 4)
			obj->anistufe = (8 - obj->weapon_ok / 4) * ANIFAC;
		else if(obj->weapon_ok > obj->weapon_fire - 2 * 4)
			obj->anistufe = (9 + (obj->weapon_fire - obj->weapon_ok) / 4) * ANIFAC;

		obj->bahn.x += obj->bahn.kurve[obj->bahn.akt].xpl / KURVENFAC;
		obj->bahn.y += obj->bahn.kurve[obj->bahn.akt].ypl / KURVENFAC;
		obj->bahn.kurve[obj->bahn.akt].xpl += obj->bahn.kurve[obj->bahn.akt].xxpl;
		obj->bahn.kurve[obj->bahn.akt].ypl += obj->bahn.kurve[obj->bahn.akt].yypl;
	
		obj->bahn.kurve[obj->bahn.akt].len--;
		if(obj->bahn.kurve[obj->bahn.akt].len == 0)
		{
			obj->bahn.akt++;
			if(obj->bahn.akt == obj->bahn.anz)
				delete_objekt(obj);
		}
	}
	else
		obj->startpause--;
}

void fliege_spieler(FLUGBAHN *bahn)
{
	int k;

	k = bahn->akt;
	bahn->kurve[k].xxpl = 0;
	bahn->kurve[k].yypl = 0;
	if(bahn->x / KURVENFAC > spieler.x)
		if(bahn->kurve[k].xpl > -32 * KURVENFAC)
			bahn->kurve[k].xpl -= 2 * KURVENFAC;
	if(bahn->x / KURVENFAC < spieler.x)
		if(bahn->kurve[k].xpl < 32 * KURVENFAC)
			bahn->kurve[k].xpl += 2 * KURVENFAC;
	if(bahn->y / KURVENFAC > spieler.y)
		if(bahn->kurve[k].ypl > -32 * KURVENFAC)
			bahn->kurve[k].ypl -= 2 * KURVENFAC;
	if(bahn->y / KURVENFAC < spieler.y)
		if(bahn->kurve[k].ypl < 32 * KURVENFAC)
			bahn->kurve[k].ypl += 2 * KURVENFAC;
}

void zielraketensteuern(OBJEKT *obj)
{
	int ex,ey;

	int wink, wink2, wink3;

	if(!obj->startpause)
	{
		wink2 = obj->bahn.kurve[0].xpl; /* xpl und ypl mißbraucht   hi hi */
		wink3 = obj->bahn.kurve[0].ypl;

		obj->anistufe = (((wink3 + 22) / 45) % 8) * ANIFAC; 

		wink = winkel(spieler.x * KURVENFAC - obj->bahn.x , spieler.y * KURVENFAC - obj->bahn.y) ;

		if (wink - 180 > wink2) 
			wink -= 360;
		if (wink + 180 < wink2) 
			wink += 360;
		if (wink + 5 < wink2 )
			wink2 -=5;
		else if( wink - 5 > wink2)
			wink2 +=5;
		if (wink2 > 360 )
			wink2 -= 360;
		else if ( wink2 < 0)
			wink2 += 360;

		if(wink - 180 > wink3) 
			wink -= 360;
		if(wink + 180 < wink3) 
			wink += 360;
		if(wink + 10 < wink3)
			wink3 -= 10;
		else if (wink - 10 > wink3)
			wink3 += 10;
		if (wink3 > 360 )
			wink3 -= 360;
		else if(wink3 < 0)
			wink3 += 360;

		obj->bahn.x += (int)((double)30 * sin( (double)wink2 * 3.14 / 180 ));
		obj->bahn.y -= (int)((double)30 * cos( (double)wink2 * 3.14 / 180 ));

		obj->bahn.kurve[obj->bahn.akt].xpl = wink2;
		obj->bahn.kurve[obj->bahn.akt].ypl = wink3;

		obj->bahn.kurve[obj->bahn.akt].len--;
		if(obj->art == 103)
			if(obj->bahn.kurve[obj->bahn.akt].len % 3 == 0)
			{
				// Raketen qualmen
				wink3 += 180;
				ex = obj->bahn.x + (int)((double)60 * sin( (double)wink3 * 3.14 / 180 ));
				ey = obj->bahn.y - (int)((double)60 * cos( (double)wink3 * 3.14 / 180 ));
				explode( ex / KURVENFAC , ey / KURVENFAC, 0, 0, 1);
			}

		if(obj->bahn.kurve[obj->bahn.akt].len == 0)
		{
			obj->bahn.akt++;
			if(obj->bahn.akt == obj->bahn.anz)
			{
				explode(obj->bahn.x / KURVENFAC, obj->bahn.y / KURVENFAC, rand() % 50, rand() % 50, 0);
				delete_objekt(obj);
			}
		}
	}
	else
	{
		obj->anistufe = 6 * ANIFAC;
		obj->startpause--;
	}
}

void kanonenstellungsteuern(OBJEKT *obj)
{
	if(!obj->startpause)
	{
		obj->anistufe = 0;
		if(obj->weapon_ok < 8 * 4)
			obj->anistufe = (7 - obj->weapon_ok / 4) * ANIFAC;
		else if(obj->weapon_ok > obj->weapon_fire - 7 * 4)
			obj->anistufe = ((obj->weapon_ok - (obj->weapon_fire - 7 * 4)) / 4) * ANIFAC;			

		obj->bahn.x += obj->bahn.kurve[obj->bahn.akt].xpl / KURVENFAC;
		obj->bahn.y += obj->bahn.kurve[obj->bahn.akt].ypl / KURVENFAC;
		obj->bahn.kurve[obj->bahn.akt].xpl += obj->bahn.kurve[obj->bahn.akt].xxpl;
		obj->bahn.kurve[obj->bahn.akt].ypl += obj->bahn.kurve[obj->bahn.akt].yypl;
	
		obj->bahn.kurve[obj->bahn.akt].len--;
		if(obj->bahn.kurve[obj->bahn.akt].len == 0)
		{
			obj->bahn.akt++;
			if(obj->bahn.akt == obj->bahn.anz)
				delete_objekt(obj);
		}
	}
	else
		obj->startpause--;
}
void streusteuern(OBJEKT *obj)
{
	if(!obj->startpause)
	{
		if(obj->weapon_ok == 0)
		{
			obj->anistufe += ANIFAC;
			if(obj->anistufe > 7 * ANIFAC)
				obj->anistufe = 0;
		}
		
		obj->bahn.x += obj->bahn.kurve[obj->bahn.akt].xpl / KURVENFAC;
		obj->bahn.y += obj->bahn.kurve[obj->bahn.akt].ypl / KURVENFAC;
		obj->bahn.kurve[obj->bahn.akt].xpl += obj->bahn.kurve[obj->bahn.akt].xxpl;
		obj->bahn.kurve[obj->bahn.akt].ypl += obj->bahn.kurve[obj->bahn.akt].yypl;
		
		obj->bahn.kurve[obj->bahn.akt].len--;
		if(obj->bahn.kurve[obj->bahn.akt].len == 0)
		{
			obj->bahn.akt++;
			if(obj->bahn.akt == obj->bahn.anz)
				delete_objekt(obj);
		}
	}
	else
		obj->startpause--;
}
void minesteuern(OBJEKT *obj)
{
	if(!obj->startpause)
	{
		obj->anistufe += 2;
		if(obj->anistufe >= obj->anz_anistufen * ANIFAC)
			obj->anistufe = 0;

/*		obj->anistufe += 1;
		if(obj->anistufe % 2 == 1)
		{
			obj->anistufe += 1;
			if(obj->anistufe >= obj->anz_anistufen * ANIFAC)
				obj->anistufe = obj->anz_anistufen * ANIFAC - 1;
		}
		else
		{
			obj->anistufe -= 3;
			if(obj->anistufe < 0)
				obj->anistufe = -0;
		} */

		obj->bahn.x += obj->bahn.kurve[obj->bahn.akt].xpl / KURVENFAC;
		obj->bahn.y += obj->bahn.kurve[obj->bahn.akt].ypl / KURVENFAC;

		obj->bahn.kurve[obj->bahn.akt].xpl += obj->bahn.kurve[obj->bahn.akt].xxpl;
		obj->bahn.kurve[obj->bahn.akt].ypl += obj->bahn.kurve[obj->bahn.akt].yypl;
		
		obj->bahn.kurve[obj->bahn.akt].len--;
		if(obj->bahn.kurve[obj->bahn.akt].len == 0)
		{
			obj->bahn.akt++;
			if(obj->bahn.akt == obj->bahn.anz)
			{
				// Spieler treffen
				if(abs(spieler.x - obj->bahn.x / KURVENFAC) < 60)
					if(abs(spieler.y - obj->bahn.y / KURVENFAC) < 60)
						if((spieler.schild <= 0) && (level_over == 100))
						{
							spieler.x += (rand() % 11) - 5;
							spieler.y += (rand() % 11) - 5;
							spieler.energie -= 50;
							spieler.schild = -5 * SPEED_FAC;
						}
/*				// Alles im Umkreis toeten!
				alles_sprengen(obj->bahn.x, obj->bahn.y, 50); */
				explode(obj->bahn.x / KURVENFAC, obj->bahn.y / KURVENFAC, 0, 0, 3);
				delete_objekt(obj);
			}
		}
	}
	else
		obj->startpause--;
}

void schrottsteuern(OBJEKT *obj)
{
	int geschw,wink;

	obj->anistufe += ANIFAC / 4;
	if(obj->anistufe >= obj->anz_anistufen * ANIFAC)
		obj->anistufe = 0;

	obj->bahn.kurve[0].xpl--;
	geschw = obj->bahn.kurve[0].xpl;
	wink = obj->bahn.kurve[0].ypl;
	if(geschw <= 0)
		delete_objekt(obj);

	// alles zweckentfremdungen
	obj->bahn.kurve[0].xxpl++;	
	obj->bahn.kurve[0].yypl += obj->bahn.kurve[0].xxpl;	
		
	obj->bahn.x += ((sintab[wink] * geschw) >> SINFAC) - KURVENFAC;
	obj->bahn.y -= ((sintab[wink + 90] * geschw) >> SINFAC);
}

void kettesteuern(OBJEKT *obj)
{
	// fuer die drehende kette
	int ent,wink;

	if(!obj->startpause)
	{
		ent = obj->bahn.kurve[0].xxpl;           //steht fuer ent von mitte
		obj->bahn.kurve[0].yypl += obj->weapon_ok;           //yypl steht fuer winkel w ok steht fuer winkel plus

		if(obj->bahn.kurve[0].yypl > 360)
			obj->bahn.kurve[0].yypl -= 360;

		wink = obj->bahn.kurve[0].yypl;

		obj->bahn.kurve[0].xpl -= 1 * KURVENFAC;  //steht fuer koordinate von mitte
		
		obj->bahn.x = obj->bahn.kurve[0].xpl + ((sintab[wink] * ent) >> SINFAC);
		obj->bahn.y = obj->bahn.kurve[0].ypl - ((sintab[wink + 90] * ent) >> SINFAC);

		
		if(obj->bahn.kurve[0].xpl < -200)
			delete_objekt(obj);
	}
	else
		obj->startpause--;
}

void restartsteuern(OBJEKT *obj)
{
	if(!obj->startpause)
	{
		if(obj->art != 60)
		{
			obj->anistufe++;
			if(obj->anistufe == obj->anz_anistufen * ANIFAC)
				obj->anistufe = 0;
		}
		else
		{
			// Pyramide von Endgegner 9
			obj->anistufe = obj->weapon_ok / (obj->weapon_fire / 9);	// 9 Stufen
			// Feuern bei 0 -> Stufe 0
			// Stufe 4-1: Öffnen
			if(obj->anistufe < 5)
				obj->anistufe = 4 - obj->anistufe;
			// Stufe 8 - 5: Schließen
			if(obj->anistufe >= 5)
				obj->anistufe = obj->anistufe - 4;
			if(obj->anistufe < 0)
				obj->anistufe = 0;
			if(obj->anistufe > 4)
				obj->anistufe = 4;
			obj->anistufe *= ANIFAC;
		}

		obj->bahn.x += obj->bahn.kurve[obj->bahn.akt].xpl / KURVENFAC;
		obj->bahn.y += obj->bahn.kurve[obj->bahn.akt].ypl / KURVENFAC;

		obj->bahn.kurve[obj->bahn.akt].xpl += obj->bahn.kurve[obj->bahn.akt].xxpl;
		obj->bahn.kurve[obj->bahn.akt].ypl += obj->bahn.kurve[obj->bahn.akt].yypl;
	
		obj->bahn.kurve[obj->bahn.akt].len--;
		if(obj->bahn.kurve[obj->bahn.akt].len == 0)
		{
			obj->bahn.akt++;
			if(obj->bahn.akt == obj->bahn.anz)
				endgegner_restarten(obj);
		}
	}
	else
		obj->startpause--;
}

void bisallestot_endgegnersteuern(OBJEKT *obj)
{
	int i, old_energie;

	if(!obj->startpause)
	{
		obj->anistufe = get_richtung(&obj->bahn, obj->bahn.akt) * ANIFAC;

		obj->bahn.x += obj->bahn.kurve[obj->bahn.akt].xpl / KURVENFAC;
		obj->bahn.y += obj->bahn.kurve[obj->bahn.akt].ypl / KURVENFAC;
		obj->bahn.kurve[obj->bahn.akt].xpl += obj->bahn.kurve[obj->bahn.akt].xxpl;
		obj->bahn.kurve[obj->bahn.akt].ypl += obj->bahn.kurve[obj->bahn.akt].yypl;
	
		obj->bahn.kurve[obj->bahn.akt].len--;
		if(obj->bahn.kurve[obj->bahn.akt].len == 0)
		{
			obj->bahn.akt++;
			if(obj->bahn.akt == obj->bahn.anz)
				// Startkette suchen und neustarten ...
				for(i = 0; i < anz_ketten; i++)
					if(startkette[i].start_x && (startkette[i].obj.nr == obj->nr))
					{
						old_energie = obj->energie;
						*obj = startkette[i].obj;
						obj->energie = old_energie;
					}
		}
	}
	else
	{
		obj->anistufe = 6 * ANIFAC;
		obj->startpause--;
		// Für die Fahrzeuge
		obj->bahn.x -= MITTE_SCROLLGESCHW * KURVENFAC;
	}
}

void spielersuchsteuern(OBJEKT *obj)
{
	int wink, wink2, wink3;

	if(!obj->startpause)
	{
		wink2 = obj->bahn.kurve[0].xpl; /* xpl und ypl mißbraucht   hi hi */
		wink3 = obj->bahn.kurve[0].ypl;

		obj->anistufe = (((wink3 + 22 ) / 45 ) % 8) * ANIFAC; 

		wink = winkel( spieler.x * KURVENFAC  - obj->bahn.x , spieler.y * KURVENFAC - obj->bahn.y ) ;

		if (wink - 180 > wink2) 
			wink -= 360;
		if (wink + 180 < wink2) 
			wink += 360;
		if (wink + 5 < wink2 )
			wink2 -= 5;
		else if ( wink - 5 > wink2 )
			wink2 += 5;
		if (wink2 > 360 )
			wink2 -= 360;
		else if ( wink2 < 0 )
			wink2 += 360;

		if (wink - 180 > wink3) 
			wink -= 360;
		if (wink + 180 < wink3) 
			wink += 360;
		if (wink + 10 < wink3 )
			wink3 -= 10;
		else if ( wink - 10 > wink3 )
			wink3 += 10;
		if (wink3 > 360 )
			wink3 -= 360;
		else if ( wink3 < 0 )
			wink3 += 360;


		obj->bahn.x += (int)((double)(2 * SPEED_FAC * KURVENFAC) * sin((double)wink2 * 3.14 / 180 ));
		obj->bahn.y -= (int)((double)(2 * SPEED_FAC * KURVENFAC) * cos((double)wink2 * 3.14 / 180 ));

		obj->bahn.kurve[obj->bahn.akt].xpl = wink2;
		obj->bahn.kurve[obj->bahn.akt].ypl = wink3;

		obj->bahn.kurve[obj->bahn.akt].len--;
		if(obj->bahn.kurve[obj->bahn.akt].len == 0)
		{
			obj->bahn.akt++;
			if(obj->bahn.akt == obj->bahn.anz)
			{
				delete_objekt(obj);
				explode(obj->bahn.x / KURVENFAC, obj->bahn.y / KURVENFAC, 0, 0, 1);
			}
		}
	}
	else
	{
		obj->startpause--;
		obj->bahn.x -= MITTE_SCROLLGESCHW * KURVENFAC;
	}
}

void abstossersteuern(OBJEKT *obj)
{
	int dx, dy;

	if(!obj->startpause)
	{
		// Spieler abstossen
		if((spieler.x > clip_x1) && (spieler.y > clip_y1) && (spieler.x < clip_x2) && (spieler.y < clip_y2))
		{
			dx = spieler.x - obj->bahn.x / KURVENFAC;
			dy = spieler.y - obj->bahn.y / KURVENFAC;

			if(abs(dy) < screen_height / 2)
			{
				if((dx < screen_width / 4) && (dx > 0))
					spieler.xpl += 2;
				else if((dx > -screen_width / 4) && (dx < 0))
					spieler.xpl -= 2;
				else if((dx < screen_width / 2) && (dx > 0))
					spieler.xpl++;
				else if((dx > -screen_width / 2) && (dx < 0))
					spieler.xpl--;
			}
			if(abs(dx) < screen_width / 2)
			{
				if((dy < screen_height / 4) && (dy > 0))
					spieler.ypl += 2;
				else if((dy > -screen_height / 4) && (dy < 0))
					spieler.ypl -= 2;
				else if((dy < screen_height / 2) && (dy > 0))
					spieler.ypl++;
				else if((dy > -screen_height / 2) && (dy < 0))
					spieler.ypl--;
			}
		}

		// Animation und Bewegung
		obj->anistufe++;
		if(obj->anistufe == obj->anz_anistufen * ANIFAC)
			obj->anistufe = 0;

		obj->bahn.x += obj->bahn.kurve[obj->bahn.akt].xpl / KURVENFAC;
		obj->bahn.y += obj->bahn.kurve[obj->bahn.akt].ypl / KURVENFAC;

		obj->bahn.kurve[obj->bahn.akt].xpl += obj->bahn.kurve[obj->bahn.akt].xxpl;
		obj->bahn.kurve[obj->bahn.akt].ypl += obj->bahn.kurve[obj->bahn.akt].yypl;
	
		obj->bahn.kurve[obj->bahn.akt].len--;
		if(obj->bahn.kurve[obj->bahn.akt].len == 0)
		{
			obj->bahn.akt++;
			if(obj->bahn.akt == obj->bahn.anz)
				delete_objekt(obj);
		}
	}
	else
		obj->startpause--;
}

void zerbatzsteuern(OBJEKT *obj)
{
	int r;

	if(!obj->startpause)
	{
		obj->anistufe++;
		if(obj->anistufe == obj->anz_anistufen * ANIFAC)
			obj->anistufe = 0;

		obj->bahn.x += obj->bahn.kurve[obj->bahn.akt].xpl / KURVENFAC;
		obj->bahn.y += obj->bahn.kurve[obj->bahn.akt].ypl / KURVENFAC;

		obj->bahn.kurve[obj->bahn.akt].xpl += obj->bahn.kurve[obj->bahn.akt].xxpl;
		obj->bahn.kurve[obj->bahn.akt].ypl += obj->bahn.kurve[obj->bahn.akt].yypl;
	
		obj->bahn.kurve[obj->bahn.akt].len--;
		if(obj->bahn.kurve[obj->bahn.akt].len == 0)
		{
			obj->bahn.akt++;
			if(obj->bahn.akt == obj->bahn.anz)
			{
				// Wegbatzen
				explode(obj->bahn.x / KURVENFAC, obj->bahn.y / KURVENFAC, 0, 0, 0);
				for(r = 0; r < 8; r++)
					neuer_schuss(obj->bahn.x / KURVENFAC, obj->bahn.y / KURVENFAC, r, 10);

				delete_objekt(obj);
			}
		}
	}
	else
		obj->startpause--;
}

void mittelschnellsteuern(OBJEKT *obj)
{
	if(!obj->startpause)
	{
		obj->anistufe += 2;
		if(obj->anistufe >= obj->anz_anistufen * ANIFAC)
			obj->anistufe = 0;

		obj->bahn.x += obj->bahn.kurve[obj->bahn.akt].xpl / KURVENFAC;
		obj->bahn.y += obj->bahn.kurve[obj->bahn.akt].ypl / KURVENFAC;
		obj->bahn.kurve[obj->bahn.akt].xpl += obj->bahn.kurve[obj->bahn.akt].xxpl;
		obj->bahn.kurve[obj->bahn.akt].ypl += obj->bahn.kurve[obj->bahn.akt].yypl;
	
		obj->bahn.kurve[obj->bahn.akt].len--;
		if(obj->bahn.kurve[obj->bahn.akt].len == 0)
		{
			obj->bahn.akt++;
			if(obj->bahn.akt == obj->bahn.anz)
				delete_objekt(obj);
		}
	}
	else
		obj->startpause--;
}

void minilaunchersteuern(OBJEKT *obj)
{
	if(!obj->startpause)
	{
		// Nur eventuell oeffnen, wenn noch zu
		if(obj->anistufe < 5 * ANIFAC - 1)
		{
			if(obj->weapon_ok == 0)
			{
				obj->anistufe = 5 * ANIFAC - 1;
				// ab jetzt immer schiessen
				obj->weapon_ok = obj->weapon_fire = 8;
			}
			else if(obj->weapon_ok < 5 * (ANIFAC / 2) - 1)
				obj->anistufe = ((5 * (ANIFAC / 2) - 1) - obj->weapon_ok) * 2;
			else
				obj->anistufe = 0;
		}

		obj->bahn.x += obj->bahn.kurve[obj->bahn.akt].xpl / KURVENFAC;
		obj->bahn.y += obj->bahn.kurve[obj->bahn.akt].ypl / KURVENFAC;
		obj->bahn.kurve[obj->bahn.akt].xpl += obj->bahn.kurve[obj->bahn.akt].xxpl;
		obj->bahn.kurve[obj->bahn.akt].ypl += obj->bahn.kurve[obj->bahn.akt].yypl;
	
		obj->bahn.kurve[obj->bahn.akt].len--;
		if(obj->bahn.kurve[obj->bahn.akt].len == 0)
		{
			obj->bahn.akt++;
			if(obj->bahn.akt == obj->bahn.anz)
				delete_objekt(obj);
		}
	}
	else
		obj->startpause--;
}

void magnetsteuern(OBJEKT *obj)
{
	int dx, dy;

	if(!obj->startpause)
	{
		// Spieler anziehen
		if((spieler.x > clip_x1) && (spieler.y > clip_y1) && (spieler.x < clip_x2) && (spieler.y < clip_y2))
		{
			dx = spieler.x - obj->bahn.x / KURVENFAC;
			dy = spieler.y - obj->bahn.y / KURVENFAC;

			if(abs(dy) < screen_height / 2)
			{
				if((dx < screen_width / 4) && (dx > 0))
					spieler.xpl -= 2;
				else if((dx > -screen_width / 4) && (dx < 0))
					spieler.xpl += 2;
				else if((dx < screen_width / 2) && (dx > 0))
					spieler.xpl--;
				else if((dx > -screen_width / 2) && (dx < 0))
					spieler.xpl++;
			}
			if(abs(dx) < screen_width / 2)
			{
				if((dy < screen_height / 4) && (dy > 0))
					spieler.ypl -= 2;
				else if((dy > -screen_height / 4) && (dy < 0))
					spieler.ypl += 2;
				else if((dy < screen_height / 2) && (dy > 0))
					spieler.ypl--;
				else if((dy > -screen_height / 2) && (dy < 0))
					spieler.ypl++;
			}
		}

		// Animation und Bewegung
		obj->anistufe++;
		if(obj->anistufe == obj->anz_anistufen * ANIFAC)
			obj->anistufe = 0;

		obj->bahn.x += obj->bahn.kurve[obj->bahn.akt].xpl / KURVENFAC;
		obj->bahn.y += obj->bahn.kurve[obj->bahn.akt].ypl / KURVENFAC;

		obj->bahn.kurve[obj->bahn.akt].xpl += obj->bahn.kurve[obj->bahn.akt].xxpl;
		obj->bahn.kurve[obj->bahn.akt].ypl += obj->bahn.kurve[obj->bahn.akt].yypl;
	
		obj->bahn.kurve[obj->bahn.akt].len--;
		if(obj->bahn.kurve[obj->bahn.akt].len == 0)
		{
			obj->bahn.akt++;
			if(obj->bahn.akt == obj->bahn.anz)
				delete_objekt(obj);
		}
	}
	else
		obj->startpause--;
}
