#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "emlen.h"

// some damage code from other codebase

char vs[STD_LENGTH];		/* You hit ... */
char vp[STD_LENGTH];		/* ... hit ... */
char vy[STD_LENGTH];		/* ... hit YOU. */
bool nocolor;
int rnd;

void 
mob_undef (int dam, CHAR_DATA * ch, CHAR_DATA * victim)
{
  int i;
  int option;
  if (dam == 0)
    {
      nocolor = TRUE;
      rnd = dice (1, 4);
      switch (rnd)
	{
	case 1:
	case 4:
	default:
	  {
	    if (RIDING (ch) == NULL)
	      {
		strcpy (vs, "You circle around $N, but you find no opening.");
		strcpy (vp, "$n circles $N, looking for an opening.");
		strcpy (vy, "$n can't find an opening in your defenses.");
	      }
	    else
	      {
		strcpy (vs, "You swing at $N, and miss wide.");
		strcpy (vp, "$n swings at $N, and misses wide.");
		strcpy (vy, "$n attacks you, but misses wide.");
	      }
	  }
	  break;
	case 2:
	  strcpy (vs, "You swing at $N, and miss wide.");
	  strcpy (vp, "$n swings at $N, and misses wide.");
	  strcpy (vy, "$n attacks you, but misses wide.");
	  break;
	case 3:
	  strcpy (vs, "You attack $N, but miss your target.");
	  strcpy (vp, "$n attacks $N, but misses the target.");
	  strcpy (vy, "$n attacks and misses.");
	  break;
	}
      return;
    }
  if (dam <= 1)
    {
      nocolor = TRUE;
      if (IS_PLAYER (victim))
	{
	  strcpy (vs, "Your %s is absorbed completely by $N's armor.");
	  strcpy (vp, "$n's %s is completely absorbed by $N's armor.");
	  strcpy (vy, "Your armor protects you from $n's %s.");
	}
      else
	{
	  strcpy (vs, "$N is hardly even bruised by your puny attack!");
	  strcpy (vp, "$N is lightly bruised by $n's puny attack.");
	  strcpy (vy, "You hardly notice $n's puny %s.");
	}
      return;
    }
  for (i = 0; i < 20; i++)
    {
      if (dam >= dmsg.generic_range[i][0] && dam <= dmsg.generic_range[i][1])
	{
	  if (dmsg.gen_m[i][1] != NULL)
	    option = number_range (1, 2);
	  else
	    option = 1;
	  strcpy (vs, dmsg.gen_m[i][option - 1]);
	  strcpy (vp, dmsg.gen_m1[i][option - 1]);
	  strcpy (vy, dmsg.gen_m2[i][option - 1]);
	  return;
	}

    }
  return;
}

void 
strike_body (int dam, CHAR_DATA * ch, CHAR_DATA * victim)
{
  int i;
  int option;
  if (dam == 0)
    {
      nocolor = TRUE;
      rnd = dice (1, 4);
      switch (rnd)
	{
	case 1:
	case 4:
	default:
	  {
	    if (RIDING (ch) == NULL)
	      {
		strcpy (vs, "You circle around $N, but you find no opening.");
		strcpy (vp, "$n circles $N, looking for an opening.");
		strcpy (vy, "$n can't find an opening in your defenses.");
	      }
	    else
	      {
		strcpy (vs, "You swing at $N, and miss wide.");
		strcpy (vp, "$n swings at $N, and misses wide.");
		strcpy (vy, "$n attacks you, but misses wide.");
	      }
	  }
	  break;
	case 2:
	  strcpy (vs, "You swing at $N, and miss wide.");
	  strcpy (vp, "$n swings at $N, and misses wide.");
	  strcpy (vy, "$n attacks you, but misses wide.");
	  break;
	case 3:
	  strcpy (vs, "You attack $N, but miss your target.");
	  strcpy (vp, "$n attacks $N, but misses the target.");
	  strcpy (vy, "$n attacks and misses.");
	  break;
	}
      return;
    }
  else if (dam <= 1)
    {
      nocolor = TRUE;
      if (IS_PLAYER (victim))
	{
	  strcpy (vs, "Your %s is absorbed completely by $N's body armor.");
	  strcpy (vp, "$n's %s is completely absorbed by $N's body armor.");
	  strcpy (vy, "Your body armor protects you from $n's %s.");
	}
      else
	{
	  strcpy (vs, "$N is hardly even bruised by your puny attack!");
	  strcpy (vp, "$N is lightly bruised by $n's puny attack.");
	  strcpy (vy, "You hardly notice $n's puny %s.");
	}
      return;
    }
  for (i = 0; i < 20; i++)
    {
      if (dam >= dmsg.body_range[i][0] && dam <= dmsg.body_range[i][1])
	{
	  if (dmsg.body_m[i][1] != NULL)
	    option = number_range (1, 2);
	  else
	    option = 1;
	  strcpy (vs, dmsg.body_m[i][option - 1]);
	  strcpy (vp, dmsg.body_m1[i][option - 1]);
	  strcpy (vy, dmsg.body_m2[i][option - 1]);
	  return;
	}
    }
  return;
}

void 
strike_legs (int dam, CHAR_DATA * ch, CHAR_DATA * victim)
{
  int i;
  int option;
  if (dam == 0)
    {
      nocolor = TRUE;
      rnd = dice (1, 4);
      switch (rnd)
	{
	case 1:
	case 4:
	default:
	  {
	    if (RIDING (ch) == NULL)
	      {
		strcpy (vs, "You circle around $N, but you find no opening.");
		strcpy (vp, "$n circles $N, looking for an opening.");
		strcpy (vy, "$n can't find an opening in your defenses.");
	      }
	    else
	      {
		strcpy (vs, "You swing at $N, and miss wide.");
		strcpy (vp, "$n swings at $N, and misses wide.");
		strcpy (vy, "$n attacks you, but misses wide.");
	      }
	  }
	  break;
	case 2:
	  strcpy (vs, "You swing low at $N's legs, but miss wide.");
	  strcpy (vp, "$n swings low at $N's legs, but misses wide.");
	  strcpy (vy, "$n tries to attack your legs, but misses.");
	  break;
	case 3:
	  strcpy (vs, "You attack $N, but miss your target.");
	  strcpy (vp, "$n attacks $N, but misses the target.");
	  strcpy (vy, "$n attacks and misses.");
	  break;
	}
      return;
    }
  else if (dam <= 1)
    {
      nocolor = TRUE;
      if (IS_PLAYER (victim))
	{
	  strcpy (vs, "Your %s is absorbed completely by $N's armor.");
	  strcpy (vp, "$n's %s is completely absorbed by $N's armor.");
	  strcpy (vy, "Your armor protects you from $n's %s.");
	}
      else
	{
	  strcpy (vs, "$N is hardly even bruised by your puny attack!");
	  strcpy (vp, "$N is lightly bruised by $n's puny attack.");
	  strcpy (vy, "You hardly notice $n's puny %s.");
	}
      return;
    }
  for (i = 0; i < 20; i++)
    {
      if (dam >= dmsg.leg_range[i][0] && dam <= dmsg.leg_range[i][1])
	{
	  if (dmsg.leg_m[i][1] != NULL)
	    option = number_range (1, 2);
	  else
	    option = 1;
	  strcpy (vs, dmsg.leg_m[i][option - 1]);
	  strcpy (vp, dmsg.leg_m1[i][option - 1]);
	  strcpy (vy, dmsg.leg_m2[i][option - 1]);
	  return;
	}
    }

  return;
}

void 
strike_arms (int dam, CHAR_DATA * ch, CHAR_DATA * victim)
{
  int i;
  int option;
  if (dam == 0)
    {
      nocolor = TRUE;
      rnd = dice (1, 4);
      switch (rnd)
	{
	case 1:
	case 4:
	default:
	  {
	    if (RIDING (ch) == NULL)
	      {
		strcpy (vs, "You circle around $N, but you find no opening.");
		strcpy (vp, "$n circles $N, looking for an opening.");
		strcpy (vy, "$n can't find an opening in your defenses.");
	      }
	    else
	      {
		strcpy (vs, "You swing at $N, and miss wide.");
		strcpy (vp, "$n swings at $N, and misses wide.");
		strcpy (vy, "$n attacks you, but misses wide.");
	      }
	  }
	  break;
	case 2:
	  strcpy (vs, "You swing at $N, but miss wide.");
	  strcpy (vp, "$n swings at $N, but misses wide.");
	  strcpy (vy, "$n tries to attack your arm, but misses.");
	  break;
	case 3:
	  strcpy (vs, "You attack $N, but miss your target.");
	  strcpy (vp, "$n attacks $N, but misses the target.");
	  strcpy (vy, "$n attacks and misses.");
	  break;
	}
      return;
    }
  else if (dam <= 1)
    {
      nocolor = TRUE;
      if (IS_PLAYER (victim))
	{
	  strcpy (vs, "Your %s is absorbed completely by $N's armor.");
	  strcpy (vp, "$n's %s is completely absorbed by $N's armor.");
	  strcpy (vy, "Your armor protects you from $n's %s.");
	}
      else
	{
	  strcpy (vs, "$N is hardly even bruised by your puny attack!");
	  strcpy (vp, "$N is lightly bruised by $n's puny attack.");
	  strcpy (vy, "You hardly notice $n's puny %s.");
	}
      return;
    }
  for (i = 0; i < 20; i++)
    {
      if (dam >= dmsg.arm_range[i][0] && dam <= dmsg.arm_range[i][1])
	{
	  if (dmsg.arm_m[i][1] != NULL)
	    option = number_range (1, 2);
	  else
	    option = 1;
	  strcpy (vs, dmsg.arm_m[i][option - 1]);
	  strcpy (vp, dmsg.arm_m1[i][option - 1]);
	  strcpy (vy, dmsg.arm_m2[i][option - 1]);
	  return;
	}
    }
  return;
}

void 
strike_head (int dam, CHAR_DATA * ch, CHAR_DATA * victim)
{
  int i;
  int option;
  if (dam == 0)
    {
      nocolor = TRUE;
      rnd = dice (1, 4);
      switch (rnd)
	{
	case 1:
	case 4:
	default:
	  {
	    if (RIDING (ch) == NULL)
	      {
		strcpy (vs, "You circle around $N, but you find no opening.");
		strcpy (vp, "$n circles $N, looking for an opening.");
		strcpy (vy, "$n can't find an opening in your defenses.");
	      }
	    else
	      {
		strcpy (vs, "You swing at $N, and miss wide.");
		strcpy (vp, "$n swings at $N, and misses wide.");
		strcpy (vy, "$n attacks you, but misses wide.");
	      }
	  }
	  break;
	case 2:
	  strcpy (vs, "You swings at $N's head, but miss wide.");
	  strcpy (vp, "$n swings at $N's head, but misses wide.");
	  strcpy (vy, "$n tries to attack your head, but misses.");
	  break;
	case 3:
	  strcpy (vs, "You attack $N, but miss your target.");
	  strcpy (vp, "$n attacks $N, but misses the target.");
	  strcpy (vy, "$n attacks and misses.");
	  break;
	}
      return;
    }
  else if (dam <= 1)
    {
      nocolor = TRUE;
      if (IS_PLAYER (victim))
	{
	  strcpy (vs, "Your %s is absorbed completely by $N's armor.");
	  strcpy (vp, "$n's %s is completely absorbed by $N's armor.");
	  strcpy (vy, "Your armor protects you from $n's %s.");
	}
      else
	{
	  strcpy (vs, "$N is hardly even bruised by your puny attack!");
	  strcpy (vp, "$N is lightly bruised by $n's puny attack.");
	  strcpy (vy, "You hardly notice $n's puny %s.");
	}
      return;
    }
  for (i = 0; i < 20; i++)
    {
      if (dam >= dmsg.head_range[i][0] && dam <= dmsg.head_range[i][1])
	{
	  if (dmsg.head_m[i][1] != NULL)
	    option = number_range (1, 2);
	  else
	    option = 1;
	  strcpy (vs, dmsg.head_m[i][option - 1]);
	  strcpy (vp, dmsg.head_m1[i][option - 1]);
	  strcpy (vy, dmsg.head_m2[i][option - 1]);
	  return;
	}
    }
  return;
}

void 
dam_message (CHAR_DATA * ch, CHAR_DATA * victim, int dam, int dt, int p)
{
  char buf[256], buf1[256], buf2[256], buf3[256];
  char rvp[2000];
  char rvs[2000];
  char *tt;
  int ty;
  char rvy[2000];
  char subbuf[256], *bufptr;
  char attack[256];
  char bare[256];
  char punct;
  SINGLE_OBJECT *obj = NULL;
  vs[0] = '\0';
  bare[0] = '\0';
  attack[0] = '\0';
  vp[0] = '\0';
  vy[0] = '\0';
  nocolor = FALSE;
  if (FIGHTING (ch) != NULL && FIGHTING (ch)->position == POSITION_GROUNDFIGHTING && dam < 3)
    dam += 3;

  if (IS_MOB (victim) || p < 1 || p > 4)
    {
      mob_undef (dam, ch, victim);
    }
  else if (p == STRIKE_BODY)
    {
      strike_body (dam, ch, victim);
    }
  else if (p == STRIKE_LEGS)
    {
      strike_legs (dam, ch, victim);
    }
  else if (p == STRIKE_ARMS)
    {
      strike_arms (dam, ch, victim);
    }
  else if (p == STRIKE_HEAD)
    {
      strike_head (dam, ch, victim);
    }

  ty = 0;
  for (tt = vs; *tt != '\0'; tt++)
    {
      if (*tt == '*')
	{
	  tt++;
	  if (*tt == 'a')
	    {
	      strcat (rvs, (star_a (dam, victim->max_hit)));
	      ty = strlen (rvs);
	    }
	  if (*tt == 'b')
	    {
	      strcat (rvs, (star_b (dam, victim->max_hit)));
	      ty = strlen (rvs);
	    }
	}
      else
	{
	  rvs[ty] = *tt;
	  rvs[ty + 1] = '\0';
	  ty++;
	}
    }

  ty = 0;
  for (tt = vy; *tt != '\0'; tt++)
    {
      if (*tt == '*')
	{
	  tt++;
	  if (*tt == 'a')
	    {
	      strcat (rvy, (star_a (dam, victim->max_hit)));
	      ty = strlen (rvy);
	    }
	  if (*tt == 'b')
	    {
	      strcat (rvy, (star_b (dam, victim->max_hit)));
	      ty = strlen (rvy);
	    }
	}
      else
	{
	  rvy[ty] = *tt;
	  rvy[ty + 1] = '\0';
	  ty++;
	}
    }

  ty = 0;
  for (tt = vp; *tt != '\0'; tt++)
    {
      if (*tt == '*')
	{
	  tt++;
	  if (*tt == 'a')
	    {
	      strcat (rvp, (star_a (dam, victim->max_hit)));
	      ty = strlen (rvp);
	    }
	  if (*tt == 'b')
	    {
	      strcat (rvp, (star_b (dam, victim->max_hit)));
	      ty = strlen (rvp);
	    }
	}
      else
	{
	  rvp[ty] = *tt;
	  rvp[ty + 1] = '\0';
	  ty++;
	}
    }

  punct = (dam <= 20) ? '.' : '!';
  if (IS_MOB (ch))
    {
      if (!ch->pIndexData->attackname || !str_cmp ("(null)", ch->pIndexData->attackname) || !str_cmp ("N/A", ch->pIndexData->attackname) || ch->pIndexData->attackname == NULL || ch->pIndexData->attackname[0] == ' ')
	{
	  if (!str_cmp (mob_type_attack (ch->pIndexData->mobtype), "punch") && FIGHTING (ch) != NULL &&
	      FIGHTING (ch)->position == POSITION_GROUNDFIGHTING)
	    strcpy (bare, "stomp");
	  else
	    strcpy (bare, mob_type_attack (ch->pIndexData->mobtype));
	}
      else
	{
	  if (!str_cmp (ch->pIndexData->attackname, "punch") && FIGHTING (ch) != NULL && FIGHTING (ch)->position == POSITION_GROUNDFIGHTING)
	    strcpy (bare, "stomp");
	  else
	    strcpy (bare, ch->pIndexData->attackname);
	}
    }
  else
    {
      if (FIGHTING (ch) != NULL && FIGHTING (ch)->position == POSITION_GROUNDFIGHTING)
	strcpy (bare, "stomp");
      else
	strcpy (bare, "punch");
    }
  if (dt == gsn_circle)
    {
      if ((obj = get_item_held (ch, ITEM_WEAPON)) == NULL)
	return;
      if (dam > 0)
	{
	  sprintf (buf1, "\x1B[1m$n\x1B[0m sneaks up on $N... $n thrusts $p\x1B[0m into $S back!");
	  if (dam < 20)
	    sprintf (buf2, "You circle and thrust $p\x1B[0m into \x1B[1m$N\x1B[0m's back.");
	  if ((dam > 19) && (dam < 50))
	    sprintf (buf2, "You circle and thrust $p\x1B[0m into \x1B[1m$N\x1B[0m's back, causing cries of agony and pain.");
	  if ((dam > 49) && (dam < 99))
	    sprintf (buf2, "You circle your opponent.... $p\x1B[0m finds its mark in \x1B[1m$N\x1B[0m's back, causing $S body to spasm in pain.");
	  if ((dam > 98) && (dam < 190))
	    sprintf (buf2, "You circle your opponent.... $p\x1B[0m sinks deeply into \x1B[1m$N\x1B[0m's back, and blood runs over your hands.");
	  if ((dam > 189) && (dam < 420))
	    sprintf (buf2, "You circle your opponent.... $p\x1B[0m has struck a pressure point in \x1B[1m$N\x1B[0m's back!\n\rThat's gotta hurt!");
	  if (dam > 319)
	    sprintf (buf2, "You circle around and twist $p\x1B[0m around several times in \x1B[1m$N\x1B[0m's back! That's gotta hurt!");
	  sprintf (buf3, "\x1B[1m$n\x1B[0m is behind you before you know it, and slips $p\x1B[0m into your back.\n\r");
	}
    }
  else if (dt == gsn_backstab)
    {
      if ((obj = get_item_held (ch, ITEM_WEAPON)) == NULL)
	return;
      if (dam > 2)
	{
	  sprintf (buf1, "\x1B[1m$n\x1B[0m thrusts $p\x1B[0m into \x1B[1m$N\x1B[0m's back.\n\r");
	  if (dam < 20)
	    sprintf (buf2, "You thrust $p\x1B[0m into \x1B[1m$N\x1B[0m's back.");
	  if ((dam > 19) && (dam < 50))
	    sprintf (buf2, "You thrust $p\x1B[0m into \x1B[1m$N\x1B[0m's back, causing cries of agony and pain.");
	  if ((dam > 49) && (dam < 99))
	    sprintf (buf2, "$p\x1B[0m finds its mark in \x1B[1m$N\x1B[0m's back, causing $s body to spasm.");
	  if ((dam > 98) && (dam < 190))
	    sprintf (buf2, "$p\x1B[0m sinks deeply into \x1B[1m$N\x1B[0m's back, and blood runs over your hands.");
	  if ((dam > 189) && (dam < 420))
	    sprintf (buf2, "$p\x1B[0m has struck a pressure point in \x1B[1m$N\x1B[0m's back! That's gotta hurt!");
	  if (dam > 419)
	    sprintf (buf2, "You twist $p\x1B[0m around several times in \x1B[1m$N\x1B[0m's back!\n\rThat's gotta hurt!");
	  sprintf (buf3, "Before you know what's going on, \x1B[1m$n\x1B[0m\n\ris behind you, and you suddenly feel $p\x1B[0m\n\rbeing thrust into your back.\n\r");
	}
      else
	{
	  sprintf (buf1, "\x1B[1m$n\x1B[0m fails to lunge $p\x1B[0m in \x1B[1m$N\x1B[0m's back.");
	  sprintf (buf2, "You fail to place $p\x1B[0m into \x1B[1m$N\x1B[0m's back.");
	  sprintf (buf3, "\x1B[1m$n\x1B[0m's \x1B[1;30mbackstab\x1B[0m just barely misses you.");
	}
    }
  else if (dt == TYPE_HIT || dt < 0)
    {
      if (nocolor)
	{
	  sprintf (buf, "%s", rvp);
	  sprintf (buf1, buf, bare);
	  sprintf (buf, "%s", rvs);
	  sprintf (buf2, buf, bare);
	  sprintf (buf, "%s", rvy);
	  sprintf (buf3, buf, bare);
	  if (RIDING (ch) != NULL)
	    {
	      send_to_char ("ACK! You are having problems punching while riding!\n\r", ch);
	    }
	}
      else
	{
	  sprintf (buf, "\x1B[1;37m%s\x1B[0m", rvp);
	  sprintf (buf1, buf, bare);
	  sprintf (buf, "\x1B[1;35m%s\x1B[0m", rvs);
	  sprintf (buf2, buf, bare);
	  sprintf (buf, "\x1B[1;36m%s\x1B[0m", rvy);
	  sprintf (buf3, buf, bare);
	}
    }
  else
    {
      if (dt >= 0 && dt < SKILL_COUNT)
	{
	  SPELL_DATA *spell;
	  if ((spell = skill_lookup (NULL, dt)) == NULL)
	    return;
	  strcpy (attack, spell->noun_damage);
	}
      else if ((dt - TYPE_HIT) < MAX_ATTACK)
	{
	  strcpy (attack, attack_table[dt - TYPE_HIT].name);
	}
      else
	{
	  bug ("Dam_message: bad dt %d.", dt);
	  dt = TYPE_HIT;
	  strcpy (attack, attack_table[0].name);
	}
      if (nocolor)
	{
	  sprintf (buf, "%s", rvp);
	  sprintf (buf1, buf, attack);
	  sprintf (buf, "%s", rvs);
	  sprintf (buf2, buf, attack);
	  sprintf (buf, "%s", rvy);
	  sprintf (buf3, buf, attack);
	}
      else
	{
	  sprintf (buf, "\x1B[1;37m%s\x1B[0m", rvp);
	  sprintf (buf1, buf, attack);
	  sprintf (buf, "\x1B[1;35m%s\x1B[0m", rvs);
	  sprintf (buf2, buf, attack);
	  sprintf (buf, "\x1B[1;36m%s\x1B[0m", rvy);
	  sprintf (buf3, buf, attack);
	}
    }
  if ((bufptr = strstr (buf1, "hs ")))
    {
      sprintf (subbuf, bufptr + 2);
      *(bufptr + 1) = 'e';
      *(bufptr + 2) = 's';
      *(bufptr + 3) = '\0';
      strcat (buf1, subbuf);
    }
  if ((bufptr = strstr (buf2, "hs ")))
    {
      sprintf (subbuf, bufptr + 2);
      *(bufptr + 1) = 'e';
      *(bufptr + 2) = 's';
      *(bufptr + 3) = '\0';
      strcat (buf2, subbuf);
    }
  if ((bufptr = strstr (buf3, "hs ")))
    {
      sprintf (subbuf, bufptr + 2);
      *(bufptr + 1) = 'e';
      *(bufptr + 2) = 's';
      *(bufptr + 3) = '\0';
      strcat (buf3, subbuf);
    }
  if (dam <= 1)
    {
      act (buf1, ch, obj, victim, TO_NOTVICT_SPAM + 1000);
      act (buf2, ch, obj, victim, TO_CHAR_SPAM + 1000);
      act (buf3, ch, obj, victim, TO_VICT_SPAM + 1000);
    }
  else
    {
     java_cc(ch,(char) 2);
     java_cc(victim,(char) 4);
      act (buf1, ch, obj, victim, TO_NOTVICT + 1000);
      act (buf2, ch, obj, victim, TO_CHAR + 1000);
      act (buf3, ch, obj, victim, TO_VICT + 1000);
    }
  if (dt == gsn_backstab && dam > 0)
    check_social (victim, "wince", "");
  return;
}