

/*********************************************************************************************/
/*                                                                                           */
/* Dragon Fire Control                                                                            */
/*                                                                                           */
/*********************************************************************************************/

/*---------------------------------------------------------------------------
 *	Import Headers
\*--------------------------------------------------------------------------*/

#ifdef PSX_VERSION
#include "../spec_psx/typedefs.h"
#else
#include "../specific/stypes.h"
#endif

#include "box.h"
#include "effect2.h"
#include "objects.h"
#include "lara.h"
#include "laraanim.h"
#include "control.h"
#include "sound.h"
#include "people.h"
#include "traps.h"
#include "sphere.h"

extern long wibble;

static void TriggerFlamethrowerHitFlame(long x, long y, long z);
static void TriggerFlamethrowerSmoke(long x, long y, long z, long uw);

/*---------------------------------------------------------------------------
 *	Constants
\*--------------------------------------------------------------------------*/

#define	MAX_TRIGGER_RANGE	0x4000

/*---------------------------------------------------------------------------
 *	Globals
\*--------------------------------------------------------------------------*/


#if defined(PSX_VERSION) && defined(RELOC)

void ControlFlameThrower(sint16 fx_number);

void *func[] = {
	&ControlFlameThrower,
};

#endif


void ControlFlameThrower(sint16 fx_number)
{
	FX_INFO *fx;
	FLOOR_INFO *floor;
	sint16 room_number;
	sint32 speed;

	fx = &effects[fx_number];

	fx->counter--;
	if (!fx->counter)
	{
		KillEffect(fx_number);
		return;
	}

	speed = (fx->speed * phd_cos(fx->pos.x_rot)) >> W2V_SHIFT;
	fx->pos.z_pos += (speed * phd_cos(fx->pos.y_rot)) >> W2V_SHIFT;
	fx->pos.x_pos += (speed * phd_sin(fx->pos.y_rot)) >> W2V_SHIFT;
	fx->pos.y_pos += -((fx->speed * phd_sin(fx->pos.x_rot)) >> W2V_SHIFT);

	room_number = fx->room_number;
	floor = GetFloor(fx->pos.x_pos, fx->pos.y_pos, fx->pos.z_pos, &room_number);

	/* Check for hitting something */
	if (room[room_number].flags & UNDERWATER && fx->flag1 == 0)
	{
		if (GetRandomControl()&1)
			TriggerFlamethrowerSmoke(fx->pos.x_pos, fx->pos.y_pos, fx->pos.z_pos, 1);
		KillEffect(fx_number);
		return;
	}

	if (fx->pos.y_pos >= GetHeight(floor, fx->pos.x_pos, fx->pos.y_pos, fx->pos.z_pos) ||
		 fx->pos.y_pos <= GetCeiling(floor, fx->pos.x_pos, fx->pos.y_pos, fx->pos.z_pos))
	{
		if (fx->flag1 == 0)
		{
			TriggerFlamethrowerHitFlame(fx->pos.x_pos, fx->pos.y_pos, fx->pos.z_pos);
			TriggerDynamic(fx->pos.x_pos, fx->pos.y_pos, fx->pos.z_pos, 24, 31, 24, GetRandomControl()&7);
		}
		KillEffect(fx_number);
		return;
	}

	if (room_number != fx->room_number)
		EffectNewRoom(fx_number, room_number);

	/* Check for hitting Lara */
	if (ItemNearLara(&fx->pos, 350))
	{
		if (fx->flag1 == 0) 	// Not lizard man gas.
		{
			lara_item->hit_points -= 3;
			lara_item->hit_status = 1;
			LaraBurn();
		}
		else
			lara.poisoned+=4;
		return;
	}
}

static void TriggerFlamethrowerHitFlame(long x, long y, long z)
{
	long		size;
	SPARKS	*sptr;
	long		dx,dz;

	dx = lara_item->pos.x_pos - x;
	dz = lara_item->pos.z_pos - z;

	if (dx < -MAX_TRIGGER_RANGE || dx > MAX_TRIGGER_RANGE || dz < -MAX_TRIGGER_RANGE || dz > MAX_TRIGGER_RANGE)
		return;

	sptr = &spark[GetFreeSpark()];

	sptr->On = 1;
	sptr->sR = 255;
	sptr->sG = 48+(GetRandomControl()&31);
	sptr->sB = 48;

	sptr->dR = 192+(GetRandomControl()&63);
	sptr->dG = 128+(GetRandomControl()&63);
	sptr->dB = 32;

	sptr->ColFadeSpeed = 8 + (GetRandomControl()&3);
	sptr->FadeToBlack = 8;
	sptr->sLife = sptr->Life = (GetRandomControl()&7)+20;

	sptr->TransType = COLADD;

	sptr->extras = 0;
	sptr->Dynamic = -1;

	sptr->x = x + ((GetRandomControl()&31)-16);
	sptr->y = y;
	sptr->z = z + ((GetRandomControl()&31)-16);
	sptr->Xvel = ((GetRandomControl()&255)-128);
	sptr->Yvel = -(GetRandomControl()&15)-16;
	sptr->Zvel = ((GetRandomControl()&255)-128);
	sptr->Friction = 5;

	if (GetRandomControl()&1)
	{
		sptr->Gravity = -(GetRandomControl()&31)-16;
		sptr->MaxYvel = -(GetRandomControl()&7)-16;
		sptr->Flags = SP_SCALE|SP_DEF|SP_ROTATE|SP_EXPDEF;
		sptr->RotAng = GetRandomControl()&4095;
		if (GetRandomControl()&1)
			sptr->RotAdd = -(GetRandomControl()&15)-16;
		else
			sptr->RotAdd = (GetRandomControl()&15)+16;
	}
	else
	{
		sptr->Flags = SP_SCALE|SP_DEF|SP_EXPDEF;
		sptr->Gravity = -(GetRandomControl()&31)-16;
		sptr->MaxYvel = -(GetRandomControl()&7)-16;
	}

	sptr->Def = objects[EXPLOSION1].mesh_index;
	sptr->Scalar = 2;
	size = (GetRandomControl()&31)+128;
	sptr->Width = sptr->sWidth = size;
 	sptr->Height = sptr->sHeight = size;
	sptr->dWidth = size>>4;
	sptr->dHeight = size>>4;
}


static void TriggerFlamethrowerSmoke(long x, long y, long z, long uw)
{
	long		size;
	SPARKS	*sptr;
	long		dx,dz;

	dx = lara_item->pos.x_pos - x;
	dz = lara_item->pos.z_pos - z;

	if (dx < -MAX_TRIGGER_RANGE || dx > MAX_TRIGGER_RANGE || dz < -MAX_TRIGGER_RANGE || dz > MAX_TRIGGER_RANGE)
		return;

	sptr = &spark[GetFreeSpark()];

	sptr->On = 1;
	if (uw)
	{
		sptr->sR = 0;
		sptr->sG = 0;
		sptr->sB = 0;
		sptr->dR = 192;
		sptr->dG = 192;
		sptr->dB = 208;
	}
	else
	{
		sptr->sR = 144;
		sptr->sG = 144;
		sptr->sB = 144;
		sptr->dR = 64;
		sptr->dG = 64;
		sptr->dB = 64;
	}

	sptr->ColFadeSpeed = 8;
	sptr->FadeToBlack = 23;
	sptr->sLife = sptr->Life = (GetRandomControl()&15)+32;
	if (uw)
		sptr->TransType = COLADD;
	else
		sptr->TransType = COLSUB;

	sptr->extras = 0;
	sptr->Dynamic = -1;

	sptr->x = x+(GetRandomControl()&31)-16;
	sptr->y = y+(GetRandomControl()&31)-16;
	sptr->z = z+(GetRandomControl()&31)-16;
	sptr->Xvel = ((GetRandomControl()&4095)-2048)>>2;
	sptr->Yvel = (GetRandomControl()&255)-128;
	sptr->Zvel = ((GetRandomControl()&4095)-2048)>>2;

	if (uw)
	{
		sptr->Yvel >>= 4;
		sptr->y +=32;
		sptr->Friction = 4|(1<<4);
	}
	else
		sptr->Friction = 6;

	sptr->Flags = SP_SCALE|SP_DEF|SP_ROTATE|SP_EXPDEF;
	sptr->RotAng = GetRandomControl()&4095;
	if (GetRandomControl()&1)
		sptr->RotAdd = -(GetRandomControl()&15)-16;
	else
		sptr->RotAdd = (GetRandomControl()&15)+16;

	sptr->Def = objects[EXPLOSION1].mesh_index;
	sptr->Scalar = 3;
	if (uw)
		sptr->Gravity = sptr->MaxYvel = 0;
	else
	{
		sptr->Gravity = -(GetRandomControl()&3)-3;
		sptr->MaxYvel = -(GetRandomControl()&3)-4;
	}
	size = (GetRandomControl()&31)+128;
	sptr->Width = sptr->sWidth = size>>2;
	sptr->dWidth = size;
	size += (GetRandomControl()&31)+32;
 	sptr->Height = sptr->sHeight = size>>3;
	sptr->dHeight = size;
}


