//---------------------------------------------------------------------------
// SILVERCLAW
//---------------------------------------------------------------------------
#include "weapons.h"
#include "silverclaw.h"

//---------------------------------------------------------------------------
// weapon specific info
//---------------------------------------------------------------------------

#define OFS_SLASH             6
#define OFS_DAMAGE            8

// model defs
#define MDL_SLASH             MDL_SPECIAL+0

// sound defs
#define SND_SLASH1            0
#define SND_SLASH2            1
#define SND_HIT1              2
#define SND_HIT2              3
#define SND_HIT3              4
#define SND_HIT4              5
#define SND_HIT5              6
#define SND_HITSTONE1         7 
#define SND_HITSTONE2         8 
#define SND_HITSTONE3         9 

// frame defs
#define ANIM_SHOOT2           ANIM_SPECIAL+0
#define ANIM_AMBIENT2         ANIM_SPECIAL+1
#define ANIM_AMBIENT3         ANIM_SPECIAL+2
#define ANIM_SLASH            ANIM_SPECIAL+3

// weapon info def
weaponInfo_t silverclawWeaponInfo = {
      // names, net names, icon
      "weapon_silverclaw",
      "silverclaw",
      "ammo_none",
      "No Ammo",
      "iconname",

      // model files
      {"models/sglove/sglove.md2",
       "models/slash/slash.md2",
       NULL},

      // sound files
      {"weapons/silverclaw/clawattack.wav",
       "weapons/silverclaw/clawattack2.wav",
       "weapons/silverclaw/axehit1.wav",
       "weapons/silverclaw/axehit2.wav",
       "weapons/silverclaw/axehit3.wav",
       "weapons/silverclaw/axehit4.wav",
       "weapons/silverclaw/axehit5.wav",
       "weapons/silverclaw/axehitstone1.wav",
       "weapons/silverclaw/axehitstone2.wav",
       "weapons/silverclaw/axehitstone3.wav",
       NULL},

      // frame names
      {MDL_WEAPON_STD,"ready",0,0,
               -1,"away",0,0,
               -1,"shoota",0,0,
               -1,"amba",0,0,
               -1,"shootb",0,0,
               -1,"ambb",0,0,
               -1,"ambc",0,0,
       MDL_SLASH,"stand",0,0,
       0,NULL},

      // commands
      {"weapon_silverclaw",(void (*)())give,
       "select_silverclaw",(void (*)())select,
       NULL},

      use,
      command,
      sizeof(silverclaw_t),

      150,
};

// local weapon info access
static weaponInfo_t *winfo=&silverclawWeaponInfo;

//---------------------------------------------------------------------------
// give()
//---------------------------------------------------------------------------
static userInventory_t *give(userEntity_t *self)
{
   return(weaponGive(self,winfo,0));
}

//---------------------------------------------------------------------------
// select()
//---------------------------------------------------------------------------
static void select(userEntity_t *self)
{
   weaponSelect(self,winfo);
}

//---------------------------------------------------------------------------
// command()
//---------------------------------------------------------------------------
static void *command(struct userInventory_s *ptr, char *commandStr, void *data)
{
   userEntity_t *self=(userEntity_t *)data;
   playerHook_t *phook=(playerHook_t *)self->userHook;

	if (!stricmp(commandStr, "death_msg"))
	{
		killerInfo_t	*ki = (killerInfo_t *) data;
		char			msg [80];

		if (rnd () < 0.5)
			sprintf (msg, "%s takes %s's axe to the head.\n", ki->victim->netname, ki->attacker->netname);
		else
			sprintf (msg, "%s shoves an axe up %s's yam! (and he likes it! HEHE) .\n", ki->attacker->netname, ki->victim->netname);
	}
   else if (!stricmp(commandStr,"ambient"))
   {
      userEntity_t *went=(userEntity_t *)self->client->ps.weapon;
      short animlist[]={ANIM_AMBIENT_STD,ANIM_AMBIENT2,ANIM_AMBIENT3};
      short animnum;
      float animtime;

      animnum=animlist[(short)(rnd()*2.9)];
      animtime=winfoNumFrames(animnum)*.05;
      winfoAnim((userEntity_t *)data,animnum,.05);
      if (went->flags & FL_LOOPAMBIENT)
      {
         phook->ambient_time=gstate->time + animtime;
         if (winfo->flags2)
            winfoPlay(winfo->flags2, 255);
	  }
      else
         phook->ambient_time=gstate->time+animtime+2+(rnd()*6);
   }
   else
      winfoGenericCommand(winfo,ptr,commandStr,data);

	return(NULL);
}

//---------------------------------------------------------------------------
// use()
//---------------------------------------------------------------------------
static void use(userInventory_s *ptr, userEntity_t *self)
{
   playerHook_t *phook=(playerHook_t *)self->userHook;
   int hit,animnum;
   char shootList[]={ANIM_SHOOT_STD,ANIM_SHOOT2};

   animnum=shootList[(short)(rnd()*1.9)];
   winfoAnimDelay(self,winfo,animnum,.05);

   // set fx func for damage
   phook->fxFrameNum=winfoFirstFrame(animnum)+OFS_SLASH;
   phook->fxFrameFunc=think;
}

//---------------------------------------------------------------------------
// kill_slash()
//---------------------------------------------------------------------------
static void kill_slash(userEntity_t *self)
{
   silverclaw_t *silverclaw=(silverclaw_t *)self->owner->curWeapon;

   Vector pos=Vector(self->owner->s.origin) + Vector(16,4,26);

   if (silverclaw->starttrack)
   {
      trackInfo_t tinfo;
      
      self->s.renderfx &= ~RF_NODRAW;

      // send 'track entity' msg to client
      tinfo.ent=self;
      tinfo.srcent=self->owner;
      tinfo.fru[0]=4;
      tinfo.fru[1]=0;
      tinfo.fru[2]=0;
      tinfo.dstent=0;
      tinfo.flags=RF_TRANSLUCENT|RF_MINLIGHT|RF_WEAPONMODEL|TEF_SRCINDEX|TEF_FRU;
      trackEntity(&tinfo,UNICAST_ENT);

      silverclaw->starttrack=false;
   }

   pos.set(self->s.origin);

   self->s.frame++;
   if (self->s.frame > winfoLastFrame(ANIM_SLASH))
   {
      untrackEntity(self,self->owner,UNICAST_ENT);
      gstate->RemoveEntity(self);
      return;
   }

   self->nextthink=gstate->time+.05;
}

//---------------------------------------------------------------------------
// think()
//---------------------------------------------------------------------------
static void think(userEntity_t *self)
{
   silverclaw_t *silverclaw=(silverclaw_t *)self->curWeapon;
   userEntity_t *slash;
   playerHook_t *phook=(playerHook_t *)self->userHook;
   trackInfo_t tinfo;
   Vector org;
   int hit;

   if (phook->fxFrameNum==winfoFirstFrame(ANIM_SHOOT_STD)+OFS_SLASH)
   {
      slash=gstate->SpawnEntity();
      slash->owner=self;
      slash->movetype=MOVETYPE_FLY;
      slash->solid=SOLID_NOT;
      slash->className="silverclaw_slash";
      slash->s.effects=256;
      slash->s.renderfx=RF_TRACKENT|RF_NODRAW;                     // special draw
      slash->s.alpha=.25;

      silverclaw->starttrack=true;

      winfoSetModel(slash,MDL_SLASH);
      slash->s.frame=winfoFirstFrame(ANIM_SLASH);
      slash->think=kill_slash;
      slash->nextthink=gstate->time+.1;

      gstate->LinkEntity(slash);		

      phook->fxFrameNum=winfoFirstFrame(ANIM_SHOOT_STD)+OFS_DAMAGE;
   }
   else
   {
      // close attack
      winfoPlay(SND_SLASH1 + rnd()*1.9,255);
   	if ((hit=weapon_trace_attack(self,25,1,62)) > 0)
	   	if(hit>1)
            winfoPlay(SND_HIT1 + rnd()*5,255);
         else
            winfoPlay(SND_HITSTONE1 + rnd()*3,255);

      phook->fxFrameFunc=NULL;
   }
}
