#include <windows.h>
#include <stdio.h>

#include	"p_user.h"
#include	"hooks.h"
#include	"common.h"
#include	"weapon_funcs.h"

///////////////////////////////////////////////
// include files for each weapon
///////////////////////////////////////////////

#include	"celestril.h"
#include	"discus.h"
#include	"glock.h"
#include	"ionblaster.h"
#include	"meta.h"
#include	"midas.h"
#include	"shotcycler6.h"
#include	"tazerhook.h"
#include	"wyndrax.h"
#include	"c4.h"
#include	"bolter.h"
#include	"sidewinder.h"
#include	"greekfire.h"
#include	"kineticore.h"
#include "shockwave.h"
#include "silverclaw.h"
#include "ripgun.h"
#include "zeus.h"
#include "novabeam.h"
#include "nightmare.h"
#include "stavros.h"
#include "trident.h"
#include "venomous.h"
#include "disruptor.h"
#include	"testweapon.h"

#include	"dk_dll.h"

/////////////////////////////////////////////////////////////////////
//	exports
/////////////////////////////////////////////////////////////////////

DllExport	void	*dll_Query(void);
DllExport	BOOL	dll_Entry (HINSTANCE hParent, DWORD dwReasonForCall, PVOID pvData);

/////////////////////////////////////////////////////////////////////
//	globals
/////////////////////////////////////////////////////////////////////

common_export_t *com;

serverState_t	*gstate;
Vector			forward, up, right;
userTrace_t		trace;
vec3_t			zero_vector = {0, 0, 0};

char	*dll_Description = "WEAPONS.DLL.  Client weapons.\n";

/////////////////////////////////////////////////////////////////////
// Epairs for Katana Ed
//
// Katana Ed loads this DLL and executes dll_Query, which returns
// a pointer to the epair structure which describes entity types
// which can be included in Daikatana maps
/////////////////////////////////////////////////////////////////////

userEpair_t eclassStr[] =
{
	{"classname",    "weapon_barrier"},
	{"color",        "0.0 0.5 0.8"},
	{"size",         "-16 -16 0 16 16 56"},
	{"rem",          "Celestril's Barrier"},

	{"classname",    "weapon_discus"},
	{"color",        "0.0 0.5 0.8"},
	{"size",         "-16 -16 0 16 16 56"},
	{"rem",          "Discus of Daedalus"},

	{"classname",    "weapon_dragon"},
	{"color",        "0.0 0.5 0.8"},
	{"size",         "-16 -16 0 16 16 56"},
	{"rem",          "Sabikkis' Dragon"},

	{"classname",    "ammo_rockets"},
	{"color",        "0.0 0.5 0.8"},
	{"size",         "-16 -16 -24 16 16 32"},
	{"rem",          "10 rockets."},

	{"classname",    "weapon_glock"},
	{"color",        "0.0 0.5 0.8"},
	{"size",         "-16 -16 0 16 16 56"},
	{"rem",          "Glock Pistol of Love"},

	{"classname",    "ammo_bullets"},
	{"color",        "0.0 0.5 0.8"},
	{"size",         "-16 -16 -24 16 16 32"},
	{"rem",          "20 bullets."},

	{"classname",    "weapon_ionblaster"},
	{"color",        "0.0 0.5 0.8"},
	{"size",         "-16 -16 0 16 16 56"},
	{"rem",          "ION blaster thingy"},

	{"classname",    "ammo_ionpack"},
	{"color",        "0.0 0.5 0.8"},
	{"size",         "-16 -16 -24 16 16 32"},
	{"rem",          "30 ion cells."},

	{"classname",    "weapon_metamaser"},
	{"color",        "0.0 0.5 0.8"},
	{"size",         "-16 -16 0 16 16 32"},

	{"classname",    "ammo_metacubes"},
	{"color",        "0.0 0.5 0.8"},
	{"size",         "-16 -16 -24 16 16 32"},
	{"rem",          "4 meta cubes"},

	{"classname",    "weapon_midasgrasp"},
	{"color",        "0.0 0.5 0.8"},
	{"size",         "-16 -16 0 16 16 56"},
	{"rem",          "midas Pistol of Love"},
	{"rem",          "Impact damage:20 "},

	{"classname",    "weapon_pulserifle"},
	{"color",        "0.0 0.5 0.8"},
	{"size",         "-16 -16 0 16 16 56"},
	{"rem",          "Pulse Rifle"},

	{"classname",    "ammo_cordite"},
	{"color",        "0.0 0.5 0.8"},
	{"size",         "-16 -16 0 16 16 56"},
	{"rem",          "5 cordite grenades."},

	{"classname",    "ammo_pulse"},
	{"color",        "0.0 0.5 0.8"},
	{"size",         "-16 -16 0 16 16 56"},
	{"rem",          "50 pulse bullets."},

	{"classname",    "shotcycler6"},
	{"color",        "0.0 0.5 0.8"},
	{"size",         "-16 -16 0 16 16 56"},

	{"classname",    "ammo_shells"},
	{"color",        "0.0 0.5 0.8"},
	{"size",         "-16 -16 0 16 16 56"},
	{"rem",          "24 shotcycler shells."},

	{"classname",    "weapon_tazerhook"},
	{"color",        "0.0 0.5 0.8"},
	{"size",         "-16 -16 0 16 16 56"},

	{"classname",    "weapon_wyndrax"},
	{"color",        "0.0 0.5 0.8"},
	{"size",         "-16 -16 0 16 16 56"},

	{"classname",    "weapon_c4viz"},
	{"color",        "0.0 0.5 0.8"},
	{"size",         "-16 -16 0 16 16 56"},

	{"classname",    "ammo_c4"},
	{"color",        "0.0 0.5 0.8"},
	{"size",         "-4 -4 -4 4 4 4"},
	{"rem",          "4 C4 Modules "},

	{"classname",    "weapon_bolter"},
	{"color",        "0.0 0.5 0.8"},
	{"size",         "-16 -16 0 16 16 56"},

	{"classname",    "ammo_bolts"},
	{"color",        "0.0 0.5 0.8"},
	{"size",         "-4 -4 -4 4 4 4"},
	{"rem",          "crossbow bolts "},

	{"classname",    "weapon_sidewinder"},
	{"color",        "0.0 0.5 0.8"},
	{"size",         "-16 -16 0 16 16 56"},

	{"classname",    "weapon_rocket"},
	{"color",        "0.0 0.5 0.8"},
	{"size",         "-16 -16 0 16 16 56"},

	{"classname",    "ammo_dogs"},
	{"color",        "0.0 0.5 0.8"},
	{"size",         "-16 -16 -24 16 16 32"},
	{"rem",          "10 dogs"},

	{"classname",    "weapon_greekfire"},
	{"color",        "0.0 0.5 0.8"},
	{"size",         "-16 -16 0 16 16 56"},

	{"classname",    "weapon_shockwave"},
	{"color",        "0.0 0.5 0.8"},
	{"size",         "-16 -16 0 16 16 56"},

	{"classname",    "weapon_silverclaw"},
	{"color",        "0.0 0.5 0.8"},
	{"size",         "-16 -16 0 16 16 56"},

	{"classname",    "weapon_ripgun"},
	{"color",        "0.0 0.5 0.8"},
	{"size",         "-16 -16 0 16 16 56"},

	{"classname",    "weapon_zeus"},
	{"color",        "0.0 0.5 0.8"},
	{"size",         "-16 -16 0 16 16 56"},

	{"classname",    "weapon_novabeam"},
	{"color",        "0.0 0.5 0.8"},
	{"size",         "-16 -16 0 16 16 56"},

	{"classname",    "weapon_nightmare"},
	{"color",        "0.0 0.5 0.8"},
	{"size",         "-16 -16 0 16 16 56"},

	{"classname",    "weapon_stavros"},
	{"color",        "0.0 0.5 0.8"},
	{"size",         "-16 -16 0 16 16 56"},

	{"classname",    "weapon_trident"},
	{"color",        "0.0 0.5 0.8"},
	{"size",         "-16 -16 0 16 16 56"},

	{"classname",    "weapon_venomous"},
	{"color",        "0.0 0.5 0.8"},
	{"size",         "-16 -16 0 16 16 56"},

	{"classname",    "weapon_disruptor"},
	{"color",        "0.0 0.5 0.8"},
	{"size",         "-16 -16 0 16 16 56"},

	{NULL,			NULL},
};

#define WP_NUM_EPISODES    4
#define WP_WEAPONS_PER_EP  6

weaponInfo_t *weaponList[WP_NUM_EPISODES][WP_WEAPONS_PER_EP] = {
   // episode 1 weapons
   {&disruptorWeaponInfo,
    &ionblasterWeaponInfo,
    NULL,
    NULL,
    &sidewinderWeaponInfo,
    &shockwaveWeaponInfo,
   },

   // episode 2 weapons
   {&discusWeaponInfo,
    NULL,
    NULL,
    &venomousWeaponInfo,
    &tridentWeaponInfo,
    &zeusWeaponInfo,
   },

   // episode 3 weapons
   {&silverclawWeaponInfo,
    &bolterWeaponInfo,
    &stavrosWeaponInfo,
    NULL,
    NULL,
    &nightmareWeaponInfo,
   },

   // episode 4 weapons
   {&glockWeaponInfo,
    &ripgunWeaponInfo,
    NULL,
    &kineticoreWeaponInfo,
    &novabeamWeaponInfo,
    NULL,
   },
};

/////////////////////////////////
// dll_Query
/////////////////////////////////

void *dll_Query(void)
{
	return (eclassStr);
}

/////////////////////////////////
// dll_ServerLoad
// 
// initialization functions called
// when the DLL is loaded
/////////////////////////////////

void	dll_ServerLoad (serverState_t *state)
{
   short first,last,ep,wp;
   weaponInfo_t **winfo;
   char *test;

	gstate = state;

	gstate->Con_Printf ("* Loaded WEAPONS.DLL, %i\n", sizeof (playerHook_t));

/*
	shotcycler6_load_init ();
	c4_load_init ();
	midas_load_init ();
	wyndrax_load_init ();
	greekfire_load_init ();
	barrier_load_init ();
	metamaser_load_init ();
	tazerhook_load_init ();
*/

   first=0;
   last=WP_NUM_EPISODES-1;
   for (ep=first; ep<=last; ep++)
   {
      winfo=weaponList[ep];
      for (wp=0; wp<WP_WEAPONS_PER_EP; wp++)
      {
         if (*winfo)
            weaponDllInit(*winfo);
         winfo++;
      }
   }

	tw_load_init ();
}

/////////////////////////////////
// dll_LevelLoad
//
// initialization functions called
// when a level starts
/////////////////////////////////

void dll_LevelLoad (void)
{
   weaponInfo_t **winfo;
   short first,last,wp,ep;

/*	shotcycler6_level_init ();
	c4_level_init ();
	midas_level_init ();
	wyndrax_level_init ();
	greekfire_level_init ();
	barrier_level_init ();
	metamaser_level_init ();
	tazerhook_level_init ();
*/

   first=last=atoi(gstate->mapName+1)-1;
   if (first<0 || first>3)
   {
      first=0;
      last=WP_NUM_EPISODES-1;
   }

   for (ep=first; ep<=last; ep++)
   {
      winfo=weaponList[ep];
      for (wp=0; wp<WP_WEAPONS_PER_EP; wp++)
      {
         if (*winfo)
            weaponLevelInit(*winfo);
         winfo++;
      }
   }

	tw_level_init ();
}

///////////////////////////////////////////////////////////////////////////////
//	dll_Version
//
//	returns TRUE if size == IONSTORM_DLL_INTERFACE_VERSION
///////////////////////////////////////////////////////////////////////////////

int dll_Version	(int size)
{
	if (size == IONSTORM_DLL_INTERFACE_VERSION)
		return	TRUE;
	else
		return	FALSE;
}

/////////////////////////////////
//	dll_ServerKill
//
/////////////////////////////////

void 	dll_ServerKill (void)
{
}

/////////////////////////////////
//	dll_ServerInit
//
/////////////////////////////////

void	dll_ServerInit (void)
{
   com=(common_export_t *)gstate->common_exports;
}

/////////////////////////////////
//	dll_LevelExit
//
/////////////////////////////////

void	dll_LevelExit (void)
{
}

///////////////////////////////////////////////////////////////////////////////
//	dll_Entry
//
//
/////////////////////////////////////////////////////////////////////////////////

BOOL dll_Entry (HINSTANCE hParent, DWORD dwReasonForCall, PVOID pvData)
{
	int			size;

	switch (dwReasonForCall)
	{
		case	QDLL_VERSION:
			size = *(int *) pvData;
			return	dll_Version (size);
			break;
		
		case	QDLL_QUERY:
			pvData = eclassStr;
         return(TRUE);
         break;

		case	QDLL_DESCRIPTION:
			pvData = dll_Description;
         return(TRUE);
			break;

		case	QDLL_SERVER_INIT:
			dll_ServerInit ();
         return(TRUE);
			break;

		case	QDLL_SERVER_KILL:
			dll_ServerKill ();
         return(TRUE);
			break;

		case	QDLL_SERVER_LOAD:
			dll_ServerLoad ((serverState_t *) pvData);
         return(TRUE);
			break;

		case	QDLL_LEVEL_LOAD:
			dll_LevelLoad ();
         return(TRUE);
			break;

		case	QDLL_LEVEL_EXIT:
			dll_LevelExit ();
         return(TRUE);
			break;
	}

	return	FALSE;
}
