#include "Weapons.h"#include "WorldManager.h"#include "ObjectWrapper.h"#include <stdlib.h>void InitWeapon(VWeapon * w, int type) {	w->Type = type;	w->InitialPos.x = 0.0;	w->InitialPos.y = 0.0;	w->InitialPos.z = 0.0;	w->Target = w->InitialPos;	w->taggedForRemoval = 0;	w->next = NULL;	w->Trail = NULL;	InitObject(&w->Object);	switch (type) {		case WEAPONTYPEBULLET:			BuildBulletModel(&w->Object.Model);			w->Damage = 1;			w->Speed = BULLETSPEED;			w->MaxDistance = MAXBULLETDISTANCE;			break;		case WEAPONTYPEROCKET:			BuildRocketModel(&w->Object.Model);			w->Damage = 10;			w->Speed = ROCKETSPEED;			w->MaxDistance = MAXROCKETDISTANCE;			break;	}	CalculateRadius(&w->Object);}void CleanUpWeapon(VWeapon * w) {	CleanUpObject(&w->Object);	CleanUpTrail(w->Trail);}void StartWeapon(VWeapon * w, Vector * startPos, Vector * target, Vector * forward, Vector * up) {	w->InitialPos = *startPos;	w->Object.Position = *startPos;	if (target != NULL) w->Target = *target;	w->Object.Front = *forward;	w->Object.Up = *up;	CrossProduct(&w->Object.Up, &w->Object.Front, &w->Object.Right);	NormalizeVector(&w->Object.Right);	/* Start at the near clipping plane */	w->Object.Position.x += (w->Object.Front.x * 1.5);	w->Object.Position.y += (w->Object.Front.y * 1.5);	w->Object.Position.z += (w->Object.Front.z * 1.5);}void RunWeapon(VWeapon * w, float interval, void * TheWorld){	VWorld * world;	VObject * Object;	VObjectWrapper * ObjectList;		Vector Start;	Vector End;		world = (VWorld *) TheWorld;	ObjectList = world->Objects;		w->Target = w->Object.Front;	if (w->Type == WEAPONTYPEROCKET) {  	for (; ObjectList != NULL; ObjectList = ObjectList->next)	  {	  	if (ObjectList->Type != VENEMY && ObjectList->Type != VOBJECT)	  		continue;	  		  	WObjectObject(ObjectList, &Object);	  	if (Object != NULL) w->Target = Object->Position;	  	break;	  }	}	ObjectList = world->Objects;		switch (w->Type) {		case WEAPONTYPEBULLET:						break;		case WEAPONTYPEROCKET:			Start = w->Object.Position;			if (w->Target.x != w->Object.Front.x && w->Target.y != w->Object.Front.y && w->Target.z != w->Object.Front.z)			{				Vector intendedAngle;								SubtractVector(&w->Target, &w->Object.Position, &intendedAngle);								NormalizeVector(&intendedAngle);				intendedAngle.x *= (ROCKETROTATERATE / interval);				intendedAngle.y *= (ROCKETROTATERATE / interval);				intendedAngle.z *= (ROCKETROTATERATE / interval);				w->Object.Front.x += intendedAngle.x;				w->Object.Front.y += intendedAngle.y;				w->Object.Front.z += intendedAngle.z;				NormalizeVector(&w->Object.Front);				CrossProduct(&w->Object.Front, &w->Object.Right, &w->Object.Up);				CrossProduct(&w->Object.Up, &w->Object.Front, &w->Object.Right);				NormalizeVector(&w->Object.Right);				NormalizeVector(&w->Object.Up);			}			w->Speed += ROCKETACCELERATION;			if (w->Speed > MAXROCKETSPEED) w->Speed = MAXROCKETSPEED;						break;	}		w->Object.Position.x += ((w->Object.Front.x / interval) * w->Speed);	w->Object.Position.y += ((w->Object.Front.y / interval) * w->Speed);	w->Object.Position.z += ((w->Object.Front.z / interval) * w->Speed);		for (; ObjectList != NULL; ObjectList = ObjectList->next)	{		if (ObjectList->Type != VENEMY && ObjectList->Type != VOBJECT)			continue;		WObjectObject(ObjectList, &Object);		if (Object != NULL && fabs(((w->Object.Position.x - Object->Position.x) * 			(w->Object.Position.x - Object->Position.x)) +			((w->Object.Position.y - Object->Position.y) * 			(w->Object.Position.y - Object->Position.y)) + 			((w->Object.Position.z - Object->Position.z) * 			(w->Object.Position.z - Object->Position.z))) <= 			(w->Object.Radius + Object->Radius))		{			if(ObjectList->Type == VENEMY)			{				HitEnemy(ObjectList->e, w->Damage);				if(ObjectList->e->Shields <= 0)				{					ObjectList->taggedForRemoval = true;					ObjectList->exploded = 1;					ObjectList->explosionLevel = 7;				}				else				{					ObjectList->exploded = 2;					ObjectList->explosionLevel = 1;				}			} else			{				ObjectList->o->Durability -= w->Damage;				if (ObjectList->o->Durability <= 0) {					ObjectList->taggedForRemoval = true;					ObjectList->exploded = 1;				} else {					ObjectList->exploded = 2;				}			}			w->taggedForRemoval = true;			break;		}	}	if ((((w->Object.Position.x - w->InitialPos.x) * 		(w->Object.Position.x - w->InitialPos.x)) + 		((w->Object.Position.y - w->InitialPos.y) * 		(w->Object.Position.y - w->InitialPos.y)) + 		((w->Object.Position.z - w->InitialPos.z) * 		(w->Object.Position.z - w->InitialPos.z))) > w->MaxDistance)	{		w->taggedForRemoval = 2;	}		if (!w->taggedForRemoval) {	  if (fabs(((w->Object.Position.x - world->Camera.Position.x) * 		(w->Object.Position.x - world->Camera.Position.x)) +		((w->Object.Position.y - world->Camera.Position.y) * 		(w->Object.Position.y - world->Camera.Position.y)) + 		((w->Object.Position.z - world->Camera.Position.z) * 		(w->Object.Position.z - world->Camera.Position.z))) <= 		(w->Object.Radius + PLAYERSHIPRADIUS)) {			world->Player.Shields -= w->Damage;		  w->taggedForRemoval = 1;		}	}		if(w->Type == WEAPONTYPEROCKET)	{		End = w->Object.Position;		if(w->Trail)		{			if(w->Trail->TimeLeft < w->Trail->duration - 0.15)				NewTrail(&w->Trail, &Start);		}		else			NewTrail(&w->Trail, &Start);				RunTrail(w->Trail, interval);	}		if(!InBounds(world, w->Object.Position))	{		w->Object.Position.x -= ((w->Object.Front.x / interval) * w->Speed * 3);		w->Object.Position.y -= ((w->Object.Front.y / interval) * w->Speed * 3);		w->Object.Position.z -= ((w->Object.Front.z / interval) * w->Speed * 3);		w->taggedForRemoval = 2;	}}void DrawWeapon(VWeapon * w) {	DrawObject(&w->Object);	DrawTrail(w->Trail);}void NewTrail(VTrail ** t, Vector * Start){	VTrail * theTrail;	theTrail = (VTrail *) NewPtr(sizeof(VTrail));		InitObject(&theTrail->Object);	BuildTrailModel(&theTrail->Object.Model);	theTrail->Object.Position = *Start;	theTrail->duration = 3;	theTrail->TimeLeft = 3;	theTrail->previous = NULL;	theTrail->next = *t;	theTrail->Direction.x = ((float)(Random() % 40)) / 10000;	theTrail->Direction.y = ((float)(Random() % 40)) / 10000;	theTrail->Direction.z = ((float)(Random() % 40)) / 10000;	switch (abs(Random() % 3)) {	  case 0:	    theTrail->Object.Model.Color[1] = 0.4;	    break;	  case 1:	    theTrail->Object.Model.Color[1] = 0.6;	    break;	  case 2:	    theTrail->Object.Model.Color[1] = 0.8;	    break;	}		if(*t)		(*t)->previous = theTrail;	*t = theTrail;}void DrawTrail(VTrail * t){	VTrail * theTrail;	theTrail = t;	while(theTrail != NULL)	{		DrawObject(&theTrail->Object);		theTrail = theTrail->next;	}}void RunTrail(VTrail * t, float interval){	VTrail * theTrail;	VTrail * tempTrail;	theTrail = t;	while(theTrail != NULL)	{		theTrail->TimeLeft -= interval;		if(theTrail->TimeLeft < 0)		{			tempTrail = theTrail->next;			RemoveTrail(&theTrail);			theTrail = tempTrail;			continue;		}		AddVector(&theTrail->Object.Position, &theTrail->Direction, &theTrail->Object.Position);		theTrail->Object.Model.Color[3] -= 1 / (theTrail->duration / interval);		theTrail = theTrail->next;	}}void CleanUpTrail(VTrail * t){	VTrail * theTrail;	VTrail * tempTrail;	theTrail = t;	while(theTrail != NULL)	{		tempTrail = theTrail;		theTrail = theTrail->next;		CleanUpObject(&tempTrail->Object);		DisposePtr((Ptr)tempTrail);	}}void RemoveTrail(VTrail ** trail){	VTrail * t;	t = *trail;	if(t->previous)		t->previous->next = t->next;	if(t->next)		t->next->previous = t->previous;		*trail = NULL;	CleanUpObject(&t->Object);	DisposePtr((Ptr)t);}