deltamud/deltamud/
deltamud/deltamud/bin/
deltamud/deltamud/cnf/
deltamud/deltamud/lib/
deltamud/deltamud/lib/etc/
deltamud/deltamud/lib/misc/
deltamud/deltamud/lib/plrobjs/
deltamud/deltamud/lib/text/
deltamud/deltamud/lib/text/help/
deltamud/deltamud/lib/world/
deltamud/deltamud/lib/world/trg/
/* ************************************************************************
   *   File: act.offensive.c                               Part of CircleMUD *
   *  Usage: player-level commands of an offensive nature                    *
   *                                                                         *
   *  All rights reserved.  See license.doc for complete information.        *
   *                                                                         *
   *  Copyright (C) 1993, 94 by the Trustees of the Johns Hopkins University *
   *  CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991.               *
   ************************************************************************ */

#include "conf.h"
#include "sysdep.h"

#include "structs.h"
#include "utils.h"
#include "comm.h"
#include "interpreter.h"
#include "handler.h"
#include "db.h"
#include "spells.h"
#include "olc.h"

/* extern variables */
extern byte pk_victim_min;       /* see config.c */
extern struct room_data *world;
extern struct descriptor_data *descriptor_list;
extern struct room_data *world;
extern int pk_allowed;
extern struct dex_skill_type dex_app_skill[];

/* extern functions */
bool check_perm_duration(struct char_data *ch, long bitvector);
void trans_to_preproom(struct char_data *);
void match_over(struct char_data *, struct char_data *, char *, int);
void raw_kill(struct char_data * ch, struct char_data * killer);
void check_killer (struct char_data *ch, struct char_data *vict);


ACMD (do_assist)
{
  struct char_data *helpee, *opponent;

  if (FIGHTING (ch))
    {
      send_to_char ("You're already fighting!  How can you assist someone else?\r\n", ch);
      return;
    }
  one_argument (argument, arg);

  if (!*arg)
    send_to_char ("Whom do you wish to assist?\r\n", ch);
  else if (!(helpee = get_char_room_vis (ch, arg)))
    send_to_char (NOPERSON, ch);
  else if (helpee == ch)
    send_to_char ("You can't help yourself any more than this!\r\n", ch);
  else
    {
      for (opponent = world[ch->in_room].people;
	   opponent && (FIGHTING (opponent) != helpee);
	   opponent = opponent->next_in_room)
	;

      if (!opponent)
	act ("But nobody is fighting $M!", FALSE, ch, 0, helpee, TO_CHAR);
      else if (!CAN_SEE (ch, opponent))
	act ("You can't see who is fighting $M!", FALSE, ch, 0, helpee, TO_CHAR);
      else if (!pk_allowed && !IS_NPC (opponent))	/* prevent accidental pkill */
	act ("Use 'murder' if you really want to attack $N.", FALSE,
	     ch, 0, opponent, TO_CHAR);
      else
	{
	  send_to_char ("You join the fight!\r\n", ch);
	  act ("$N assists you!", 0, helpee, 0, ch, TO_CHAR);
	  act ("$n assists $N.", FALSE, ch, 0, helpee, TO_NOTVICT);
	  hit (ch, opponent, TYPE_UNDEFINED);
	}
    }
}


ACMD (do_hit)
{
  struct char_data *vict;
  void deathblow (struct char_data *ch, struct char_data *victim, int dam, int attacktype);

  one_argument (argument, arg);

  if (!*arg)
    send_to_char ("Hit who?\r\n", ch);
  else if (!(vict = get_char_room_vis (ch, arg)))
    send_to_char ("They don't seem to be here.\r\n", ch);
  else if (vict == ch)
    {
      send_to_char ("You hit yourself...OUCH!.\r\n", ch);
      act ("$n hits $mself, and says OUCH!", FALSE, ch, 0, vict, TO_ROOM);
    }
  else if (IS_AFFECTED (ch, AFF_CHARM) && (ch->master == vict))
    act ("$N is just such a good friend, you simply can't hit $M.", FALSE, ch, 0, vict, TO_CHAR);
  else
    {
      if (!pk_allowed)
	{
	  if (!IS_NPC (vict) && !IS_NPC (ch))
	    {
	      /* Arena Mod - Thargor */
	      if (IS_ARENACOMBATANT(ch) && IS_ARENACOMBATANT(vict))
		subcmd = SCMD_MURDER;

	      if (subcmd != SCMD_MURDER && subcmd != SCMD_DEATHBLOW)
		{
		  send_to_char ("Use 'murder' to hit another player.\r\n", ch);
		  return;
		}
	      else
		{
		  if (!(!pk_allowed && !IS_NPC(vict) && !IS_NPC(ch)
			&& ((GET_LEVEL(vict) < pk_victim_min) 
			    || (GET_LEVEL(ch) < pk_victim_min))))
		    check_killer (ch, vict);
		}
	    }
	  if (IS_AFFECTED (ch, AFF_CHARM) && !IS_NPC (ch->master) && !IS_NPC (vict))
	    return;		/* you can't order a charmed pet to attack a
				 * player */
	}
      if ((GET_POS (ch) == POS_STANDING) && (vict != FIGHTING (ch)))
	{
          if (subcmd == SCMD_DEATHBLOW) {
            if (GET_HIT(vict) < 0 && GET_POS(vict) < POS_SLEEPING)
              deathblow (ch, vict, 100, GET_ATTACKTYPE(ch));
            else
              send_to_char("They aren't near death!\r\n", ch);
          }
          else {
	    hit (ch, vict, TYPE_UNDEFINED);
	    WAIT_STATE (ch, PULSE_VIOLENCE + 2);
          }
	}
      else
	send_to_char ("You do the best you can!\r\n", ch);
    }
}



ACMD (do_kill)
{
  struct char_data *vict;

  if ((GET_LEVEL (ch) < LVL_IMPL) || IS_NPC (ch))
    {
      do_hit (ch, argument, cmd, subcmd);
      return;
    }
  one_argument (argument, arg);

  if (!*arg)
    {
      send_to_char ("Kill who?\r\n", ch);
    }
  else
    {
      if (!(vict = get_char_room_vis (ch, arg)))
	send_to_char ("They aren't here.\r\n", ch);
      else if (ch == vict)
	send_to_char ("Your mother would be so sad.. :(\r\n", ch);
      else
	{
	  act ("You chop $M to pieces!  Ah!  The blood!", FALSE, ch, 0, vict, TO_CHAR);
	  act ("$N chops you to pieces!", FALSE, vict, 0, ch, TO_CHAR);
	  act ("$n brutally slays $N!", FALSE, ch, 0, vict, TO_NOTVICT);
         raw_kill(vict, ch);
	}
    }
}


/* Switch from fighting one character to fighting another character */
ACMD(do_target)
{
  int percent, prob;
  struct char_data *vict;
         
  one_argument(argument, arg);
  
  if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) {
    send_to_char("You'd better leave this skill to players.\r\n", ch);
    return;
  } else if (!IS_NPC(ch) && !GET_SKILL(ch, SKILL_TARGET)) {
    send_to_char("You don't know of that skill.\r\n", ch);
    return;
  }
     
//  if(check_state(ch) != 0) {
//    send_to_char("You are too engaged in combat to switch now!\r\n", ch);
//    return;
//        }
  
  if (!*arg)
    send_to_char("Hit who?\r\n", ch);
  else if (!(vict = get_char_room_vis(ch, arg)))
    send_to_char("They don't seem to be here.\r\n", ch);
  else if (vict == ch) {
    send_to_char("You hit yourself...OUCH!.\r\n", ch);
    act("$n hits $mself, and says OUCH!", FALSE, ch, 0, vict, TO_ROOM);
  } else if (IS_AFFECTED(ch, AFF_CHARM) && (ch->master == vict))
    act("$N is just such a good friend, you simply can't hit $M.", FALSE, ch, 0, vict, TO_CHAR);
  else {
    if (!pk_allowed) {
      if (!IS_NPC(vict) && !IS_NPC(ch) && (subcmd != SCMD_MURDER)) {
        send_to_char("Use 'murder' to hit another player.\r\n", ch);
        return;
      }
      if (IS_AFFECTED(ch, AFF_CHARM) && !IS_NPC(ch->master) && !IS_NPC(vict))
        return;                 /* you can't order a charmed pet to attack a
                                 * player */
          }
      percent = number(1, 401);     /* 101% is a complete failure */
      if (IS_NPC(ch))
         prob = 90;
       else
         prob = GET_SKILL(ch, SKILL_TARGET); /* very low success probability */
      prob+=chance(ch, vict, 0)*3; /* Bonuses are three times as important as how well you're learned in that skill */
      if (percent > prob) {
         act("You try to switch target, but your current opponent keep you busy!", FALSE, ch, 0, 0, TO_CHAR);
         act("$n makes some desperate attempts to attack another opponent!", FALSE, ch, 0, 0, TO_ROOM );
         WAIT_STATE (ch, PULSE_VIOLENCE * 2);
         return;
      }
      act("You start fighting $N!", FALSE, ch, 0, vict, TO_CHAR);
      act("$n starts fighting $N!", FALSE, ch, 0, vict, TO_NOTVICT);   
      act("$n starts fighting you!", FALSE, ch, 0, vict, TO_VICT);
      hit(ch, vict, TYPE_UNDEFINED);
      WAIT_STATE (ch, PULSE_VIOLENCE * 2);    
    }
        
}

ACMD (do_backstab)
{
  struct char_data *vict;
  int percent, prob;

  one_argument (argument, buf);

  if (!(vict = get_char_room_vis (ch, buf)))
    {
      send_to_char ("Backstab who?\r\n", ch);
      return;
    }
  if (vict == ch)
    {
      send_to_char ("How can you sneak up on yourself?\r\n", ch);
      return;
    }
  if (!GET_EQ (ch, WEAR_WIELD))
    {
      send_to_char ("You need to wield a weapon to make it a success.\r\n", ch);
      return;
    }
  if (GET_OBJ_VAL (GET_EQ (ch, WEAR_WIELD), 3) != TYPE_PIERCE - TYPE_HIT)
    {
      send_to_char ("Only piercing weapons can be used for backstabbing.\r\n", ch);
      return;
    }
  if (FIGHTING (vict))
    {
      send_to_char ("You can't backstab a fighting person -- they're too alert!\r\n", ch);
      return;
    }

  if (MOB_FLAGGED (vict, MOB_AWARE))
    {
      act ("You notice $N lunging at you!", FALSE, vict, 0, ch, TO_CHAR);
      act ("$e notices you lunging at $m!", FALSE, vict, 0, ch, TO_VICT);
      act ("$n notices $N lunging at $m!", FALSE, vict, 0, ch, TO_NOTVICT);
      hit (vict, ch, TYPE_UNDEFINED);
      return;
    }

  percent = number(1, 101);
  if (IS_NPC(ch))
     prob = 90;
   else
     prob = GET_SKILL(ch, SKILL_BACKSTAB);

  if (AWAKE (vict) && (percent > prob))
    damage (ch, vict, 0, SKILL_BACKSTAB);
  else
    hit (ch, vict, SKILL_BACKSTAB);

  WAIT_STATE(ch, PULSE_VIOLENCE * 2)
}



ACMD (do_order)
{
  char name[100], message[256];
  char buf[256];
  bool found = FALSE;
  int org_room;
  struct char_data *vict;
  struct follow_type *k;

  half_chop (argument, name, message);

  if (!*name || !*message)
    send_to_char ("Order who to do what?\r\n", ch);
  else if (!(vict = get_char_room_vis (ch, name)) && !is_abbrev (name, "followers"))
    send_to_char ("That person isn't here.\r\n", ch);
  else if (ch == vict)
    send_to_char ("You obviously suffer from skitzofrenia.\r\n", ch);

  else
    {
      if (IS_AFFECTED (ch, AFF_CHARM))
	{
	  send_to_char ("Your superior would not aprove of you giving orders.\r\n", ch);
	  return;
	}
      if (vict)
	{
	  sprintf (buf, "$N orders you to '%s'", message);
	  act (buf, FALSE, vict, 0, ch, TO_CHAR);
	  act ("$n gives $N an order.", FALSE, ch, 0, vict, TO_ROOM);

	  if ((vict->master != ch) || !IS_AFFECTED (vict, AFF_CHARM))
	    act ("$n has an indifferent look.", FALSE, vict, 0, 0, TO_ROOM);
	  else
	    {
	      send_to_char (OK, ch);
	      command_interpreter (vict, message);
	    }
	}
      else
	{			/* This is order "followers" */
	  sprintf (buf, "$n issues the order '%s'.", message);
	  act (buf, FALSE, ch, 0, vict, TO_ROOM);

	  org_room = ch->in_room;

	  for (k = ch->followers; k; k = k->next)
	    {
	      if (org_room == k->follower->in_room)
		if (IS_AFFECTED (k->follower, AFF_CHARM))
		  {
		    found = TRUE;
		    command_interpreter (k->follower, message);
		  }
	    }
	  if (found)
	    send_to_char (OK, ch);
	  else
	    send_to_char ("Nobody here is a loyal subject of yours!\r\n", ch);
	}
    }
}



ACMD (do_flee)
{
  int i, attempt, loss, minlevel;
  struct char_data *was_fighting;
  extern char *numdisplay(int number);

  if (GET_POS (ch) < POS_FIGHTING)
    {
      send_to_char ("You are in pretty bad shape, unable to flee!\r\n", ch);
      return;
    }

  was_fighting = FIGHTING(ch);

  if (IS_ARENACOMBATANT(ch))
    minlevel= 1;
  else
    minlevel = 15;

  for (i = 0; i < 6; i++)
    {
      attempt = number (0, NUM_OF_DIRS - 1);	/* Select a random direction */
      if (CAN_GO (ch, attempt) &&
	  !IS_SET (ROOM_FLAGS (EXIT (ch, attempt)->to_room), ROOM_DEATH))
	{
	  act ("$n panics, and attempts to flee!", TRUE, ch, 0, 0, TO_ROOM);
	  if (do_simple_move (ch, attempt, TRUE))
	    {
	      send_to_char ("You flee head over heels.\r\n", ch);
	      if (was_fighting && !IS_NPC(ch) && GET_LEVEL(ch) >= minlevel) {
		loss = GET_MAX_HIT(was_fighting) - GET_HIT(was_fighting);
		loss *= GET_LEVEL(was_fighting);
		if (!IS_NPC(ch) 
		    && IS_ARENACOMBATANT(ch)){
		  sprintf(buf, "&RYou would have lost %s experience points "
			  "for fleeing if this wasn't an arena.&n\r\n", numdisplay(loss));
		  send_to_char(buf, ch);
		  LASTFIGHTING(ch) = was_fighting;
		  GET_ARENAFLEETIMER(ch) = 1; /* start flee timer */
		  send_to_char("Starting Flee-Recall timer. If you recall before the timer expires, you concede the match!\r\n", ch);
		  /* match_over(was_fighting, ch, "(Fled)", 0);
		  if (GET_ARENASTAT(ch) == ARENA_COMBATANTZ)
		    trans_to_preproom(ch);
		    */
		}else{
		  gain_exp(ch, -loss);
		  sprintf(buf, "&RYou lost %s experience points for "
			  "fleeing!&n\r\n", numdisplay(loss));
		  send_to_char(buf, ch);
		}
	      }
	    }
	  else
	    {
	      act ("$n tries to flee, but can't!", TRUE, ch, 0, 0, TO_ROOM);
	    }
	  return;
	}
    }
  send_to_char ("PANIC!  You couldn't escape!\r\n", ch);
}

ACMD (do_chain_footing)
{
  struct char_data *vict;
  int percent, prob;
  struct affected_type *h;
   
  one_argument (argument, arg);

  if (GET_CLASS (ch) != CLASS_WARRIOR && GET_LEVEL(ch) < LVL_IMMORT)
    {
      send_to_char ("You'd better leave all the martial arts to fighters.\r\n", ch);
      return;
    }
  if (!(vict = get_char_room_vis (ch, arg)))
    {
      if (FIGHTING (ch))
        vict = FIGHTING (ch);
      else {
	  send_to_char ("Chain who's feet?\r\n", ch);
	  return;
      }
    }
  if (FIGHTING(ch) && FIGHTING(ch)!=vict) {
    send_to_char ("You're too busy fighting to throw yourself at ANOTHER person!\r\n", ch);
    return;
  }
  if (vict == ch)
    {
      send_to_char ("You chain your own feet! Wait... AHHHHHHh\r\n", ch);
      return;
    }
  
  if (ROOM_FLAGGED(ch->in_room, ROOM_PEACEFUL)) {
    send_to_char("This room just has such a peaceful, easy feeling...\r\n", ch);
    return;
  }

  percent = number(1, 401);
  if (IS_NPC(ch))
     prob = 90;
   else
     prob = GET_SKILL(ch, SKILL_CHAIN_FOOTING);
  prob+=chance(ch, vict, 0)*3;

  for (h = vict->affected; h; h = h->next) {
    if (h->type == SKILL_CHAIN_FOOTING) {
      send_to_char ("Whoops, they're already chained. Doh.\r\n", ch);
      return;
    }
    if (!(h->next)) break;
  }

  if (GET_MOVE(ch) < 25 && GET_LEVEL(ch) < LVL_IMMORT) {
    send_to_char("You're too exhausted for such action!\r\n", ch);
    return;
  }
  else if (GET_LEVEL(ch) < LVL_IMMORT)
    GET_MOVE(ch)-=25;

  if (percent > prob)
    {
      act ("$N lunges at you, but you step aside and laugh at $e.", FALSE, vict, 0, ch, TO_CHAR);
      act ("$n lunges at $N, but gets a face full of dirt instead!", FALSE, ch, 0, vict, TO_NOTVICT);
      act ("You lunge at $N, but get a face full of dirt instead!", FALSE, ch, 0, vict, TO_CHAR);
      GET_POS (ch) = POS_SITTING;
    }
  else
    {
      act ("$N lunges at you and skillfully chains your feet together!", FALSE, vict, 0, ch, TO_CHAR);
      act ("$n lunges at $N and skillfully chains $S feet together!", FALSE, ch, 0, vict, TO_NOTVICT);
      act ("You lunge at $N and skillfully chain $S feet together!", FALSE, ch, 0, vict, TO_CHAR);
      if (h) {
        CREATE(h->next, struct affected_type, 1);
        h=h->next;
      }
      else {
        CREATE(h, struct affected_type, 1);
        vict->affected=h;
      }
      h->duration = 2;
      h->bitvector = AFF_CHAINED;
      h->type = SKILL_CHAIN_FOOTING;
      SET_BIT(AFF_FLAGS(vict), AFF_CHAINED);
    }
  if (!FIGHTING(ch))
  set_fighting (ch, vict);
  WAIT_STATE (ch, PULSE_VIOLENCE * 2);
}

ACMD (do_bash)
{
  struct char_data *vict;
  int percent, prob;

  one_argument (argument, arg);

  if (GET_CLASS (ch) != CLASS_WARRIOR && GET_LEVEL(ch) < LVL_IMMORT)
    {
      send_to_char ("You'd better leave all the martial arts to fighters.\r\n", ch);
      return;
    }
  if (!(vict = get_char_room_vis (ch, arg)))
    {
      if (FIGHTING (ch))
	{
	  vict = FIGHTING (ch);
	}
      else
	{
	  send_to_char ("Bash who?\r\n", ch);
	  return;
	}
    }
  if (vict == ch)
    {
      send_to_char ("Aren't we funny today...\r\n", ch);
      return;
    }
  if (!GET_EQ (ch, WEAR_WIELD))
    {
      send_to_char ("You need to wield a weapon to make it a success.\r\n", ch);
      return;
    }
  
  if (ROOM_FLAGGED(ch->in_room, ROOM_PEACEFUL)) {
  send_to_char("This room just has such a peaceful, easy feeling...\r\n", ch);
  return;
  }

  percent = number(1, 401);
  if (IS_NPC(ch))
     prob = 90;
   else
     prob = GET_SKILL(ch, SKILL_BASH);
  prob+=chance(ch, vict, 0)*3;

  if (MOB_FLAGGED (vict, MOB_NOBASH))
    percent = 401;

  if (percent > prob)
    {
      damage (ch, vict, 0, SKILL_BASH);
      GET_POS (ch) = POS_SITTING;
    }
  else
    {
      damage (ch, vict, 1, SKILL_BASH);
      GET_POS (vict) = POS_SITTING;
      WAIT_STATE (vict, PULSE_VIOLENCE);
    }
  WAIT_STATE (ch, PULSE_VIOLENCE * 2);
}


ACMD (do_rescue)
{
  struct char_data *vict, *tmp_ch;
  int percent, prob;

  one_argument (argument, arg);

  if (!(vict = get_char_room_vis (ch, arg)))
    {
      send_to_char ("Whom do you want to rescue?\r\n", ch);
      return;
    }
  if (vict == ch)
    {
      send_to_char ("What about fleeing instead?\r\n", ch);
      return;
    }
  if (FIGHTING (ch) == vict)
    {
      send_to_char ("How can you rescue someone you are trying to kill?\r\n", ch);
      return;
    }
  for (tmp_ch = world[ch->in_room].people; tmp_ch &&
       (FIGHTING (tmp_ch) != vict); tmp_ch = tmp_ch->next_in_room);

  if (!tmp_ch)
    {
      act ("But nobody is fighting $M!", FALSE, ch, 0, vict, TO_CHAR);
      return;
    }
  if (GET_CLASS (ch) != CLASS_WARRIOR && GET_LEVEL(ch) < LVL_IMMORT)
    send_to_char ("But only true warriors can do this!", ch);
  else
    {
      percent = number (1, 101);	/* 101% is a complete failure */
      prob = GET_SKILL (ch, SKILL_RESCUE);

      if (percent > prob)
	{
	  send_to_char ("You fail the rescue!\r\n", ch);
	  return;
	}
      send_to_char ("Banzai!!  To the rescue!!!\r\n", ch);
      act ("You are rescued by $N, leaving you confused.", FALSE, vict, 0, ch, TO_CHAR);
      act ("$n heroically rescues $N!", FALSE, ch, 0, vict, TO_NOTVICT);

      if (FIGHTING (vict) == tmp_ch)
	stop_fighting (vict);
      if (FIGHTING (tmp_ch))
	stop_fighting (tmp_ch);
      if (FIGHTING (ch))
	stop_fighting (ch);

      set_fighting (ch, tmp_ch);
      set_fighting (tmp_ch, ch);

      WAIT_STATE (vict, 2 * PULSE_VIOLENCE);
    }

}



ACMD (do_kick)
{
  struct char_data *vict;
  int percent, prob;

  if (GET_CLASS (ch) != CLASS_WARRIOR && GET_LEVEL(ch) < LVL_IMMORT)
    {
      send_to_char ("You'd better leave all the martial arts to fighters.\r\n", ch);
      return;
    }
  one_argument (argument, arg);

  if (!(vict = get_char_room_vis (ch, arg)))
    {
      if (FIGHTING (ch))
	{
	  vict = FIGHTING (ch);
	}
      else
	{
	  send_to_char ("Kick who?\r\n", ch);
	  return;
	}
    }
  if (vict == ch)
    {
      send_to_char ("Aren't we funny today...\r\n", ch);
      return;
    }
  percent = number(1, 401);
  if (IS_NPC(ch))
     prob = 90;
   else
     prob = GET_SKILL(ch, SKILL_KICK);
  prob+=chance(ch, vict, 0)*3;

  if (percent > prob)
    {
      damage (ch, vict, 0, SKILL_KICK);
    }
  else
    damage (ch, vict, GET_LEVEL (ch) >> 1, SKILL_KICK);
  WAIT_STATE (ch, PULSE_VIOLENCE * 3);
}

ACMD (do_berserk)
{
  struct char_data *vict;
  int percent, prob, dmg, multiplier;
  float factor;
  struct obj_data *wielded = GET_EQ (ch, WEAR_WIELD);

  if ((GET_CLASS (ch) != CLASS_WARRIOR) && (GET_LEVEL(ch) < LVL_IMMORT))
    {
      send_to_char ("But only true warriors can do this!", ch);
      return;
    }
  if (GET_MOVE(ch) < 50)
    {
      send_to_char ("But you're out of breath!", ch);
      return;
    }

  one_argument (argument, arg);

  if (!(vict = get_char_room_vis (ch, arg)))
    {
      if (FIGHTING (ch))
	{
	  vict = FIGHTING (ch);
	}
      else
	{
	  send_to_char ("Berserk attack who?\r\n", ch);
	  return;
	}
    }
  if (vict == ch)
    {
      send_to_char ("You can't possibly be that insane???\r\n", ch);
      return;
    } 

  GET_MOVE(ch) -= 50;
  /* 101% is a complete failure */
  prob = GET_SKILL(ch, SKILL_BERSERK);
  percent = number((int)(prob * 0.4), 101) 
    + (GET_LEVEL(vict)/number(6, 12))
    - (GET_LEVEL(ch)/number(4, 10));

  /* prob is also a factor of hp/maxhp */
  factor = ((float)GET_HIT(ch))/((float)GET_MAX_HIT(ch));  
  if (factor < 0.6)
    factor = 0.6; /* lowest factor = 0.6 */
  prob = (int) (prob*factor);

  if (percent < 0)
    percent = 0;

  dmg = 1;
  if (wielded && GET_OBJ_TYPE (wielded) == ITEM_WEAPON){
    /* Add weapon-based damage if a weapon is being wielded */
    dmg += dice (GET_OBJ_VAL (wielded, 1), GET_OBJ_VAL (wielded, 2));
  }

  multiplier = number (2,5); 
  dmg *= multiplier;
  if (dmg > 200)
    dmg = 250;


  /*
  sprintf(buf, "%s: prob %d (factor %g) percent %d - Berserk %s."
	  " Berserk dmg %d (multiplier %d), normal dmg %d\r\n",
	  GET_NAME(ch), prob, factor, percent,
	  (percent>prob)?"FAILED":"SUCCEEDED",
	  dmg, multiplier, (int)(dmg/multiplier));
  log(buf);
  */

  if (percent > prob){
    damage (ch, vict, 0, SKILL_BERSERK);
    WAIT_STATE (ch, PULSE_VIOLENCE * 4);
  }else{
    damage (ch, vict, dmg, SKILL_BERSERK);
    WAIT_STATE (ch, PULSE_VIOLENCE * 2);
  }
}

/* Remove the victim's weapon */
ACMD(do_disarm)
{
  struct obj_data *obj;   
  struct char_data *vict;
  int percent, prob;
      
  one_argument(argument, arg);
   
  if(!ch)
    return;
    
  /* Who are we trying to disarm? */
  if (!(vict = get_char_room_vis(ch, arg))) {
    if (FIGHTING(ch)) {
      vict = FIGHTING(ch);
    } else {
      send_to_char("Disarm who?\r\n", ch);
      return;
    }
  }
  
  /* Can't order charmed mobs to disarm. */
  if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) {
    send_to_char("You'd better leave this skill to players.\r\n", ch);
    return;
    
  } else
    /* Doesn't know how */
    if (   !IS_NPC(ch)
        && !GET_SKILL(ch, SKILL_DISARM)) {
     
      /* If the disarmer is wielding, then he loses his weapon */
      if(ch->equipment[WEAR_WIELD]) {
        obj=unequip_char(ch, WEAR_WIELD);  
        obj_to_room(obj, ch->in_room);
        act("While trying to disarm $N, you lose your own weapon.",
            TRUE, ch, 0, vict, TO_CHAR);
        act("While trying to disarm you, $n loses $s own weapon.",
            TRUE, ch, 0, vict, TO_VICT);
        act("While trying to disarm $N, $n loses $s own weapon.",
            TRUE, ch, 0, vict, TO_NOTVICT);
      } else
        /* If he's not wielding, he just gets tooled on */
        send_to_char("You dont know of that skill.\r\n", ch);
     
      return;
  }
        
  /* You are your own victim? */
  if (vict == ch) {
    send_to_char("Aren't we funny today...\r\n", ch);
    return;
  }
        
  /* Victim isn't wielding... */
  if (!vict->equipment[WEAR_WIELD]) {
    send_to_char("Disarm what weapon?!\r\n", ch);
    return;
  }  
      
  /* Can't disarm while whomping. */
  /* if(CHECK_FIGHT(ch) != 0) {
    send_to_char("You are too engaged in combat to disarm now!\r\n", ch);
    return;
  }*/
        
  percent = number(1, 401);
  if (IS_NPC(ch))
     prob = 90;
   else
     prob = GET_SKILL(ch, SKILL_DISARM);
  prob+=chance(ch, vict, 0)*3;
    
  if (   percent > prob
      && GET_POS(vict) > POS_SLEEPING) {
    act("$n tries to disarm $N but fails.", TRUE, ch, 0, vict, TO_NOTVICT);
    act("You try to disarm $N but fail.", TRUE, ch, 0, vict, TO_CHAR);
    act("$n tries to disarm you but fails.", TRUE, ch, 0, vict, TO_VICT);
    if (!FIGHTING(vict))
    hit(vict, ch, TYPE_UNDEFINED);   
  } else {
    act("$n makes $N drop his weapon to the ground with some fast moves.", 
        TRUE, ch, 0, vict, TO_NOTVICT);
    act("With some fast moves you manage to make $N drop the weapon.",
        TRUE, ch, 0, vict, TO_CHAR);
    act("$n performs some fast moves, and makes you drop your weapon.",
        TRUE, ch, 0, vict, TO_VICT);
    obj = unequip_char(vict, WEAR_WIELD);
    obj_to_room(obj, vict->in_room);
    if (!FIGHTING(vict))
    hit(vict, ch, TYPE_UNDEFINED);
  }
    
  WAIT_STATE(ch, PULSE_VIOLENCE);
}

ACMD(do_trip)
{       
  struct char_data *vict;
  int percent, prob;
    
  one_argument(argument, arg);
        
  if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) {
    send_to_char("You'd better leave this skill to players.\r\n", ch);
    return;
  } else if (!IS_NPC(ch) && !GET_SKILL(ch, SKILL_TRIP)) {
    send_to_char("You dont know of that skill.\r\n", ch);
    return;
  }

  if (!(vict = get_char_room_vis(ch, arg))) {
    if (FIGHTING(ch)) {  
      vict = FIGHTING(ch);
    } else {
      send_to_char("Trip who?\r\n", ch);
      return;
    }
  }
  if (vict == ch) {
    send_to_char("Aren't we funny today...\r\n", ch);
    return;
  }

  if (IS_NPC(vict) && MOB_FLAGGED(vict, MOB_NOBASH)) {
    act("You try to trip $N but can't.", TRUE, ch, 0, vict, TO_CHAR);
    act("$n tries to trip you, but you are unmovable.", TRUE, ch, 0, vict, TO_VICT);
    act("$n tries to trip $N, but can't.", TRUE, ch, 0, vict, TO_NOTVICT);
    return;
     }
  percent = number(1, 501);
  if (IS_NPC(ch))
     prob = 90;
   else
     prob = GET_SKILL(ch, SKILL_TRIP);
  prob+=chance(ch, vict, 0)*3;
    
  if (percent > prob) {
    damage(ch, vict, 0, SKILL_TRIP);
  } else {
    damage(ch, vict, 2, SKILL_TRIP);
    WAIT_STATE(vict, PULSE_VIOLENCE * 2);
    WAIT_STATE(ch, PULSE_VIOLENCE);
    return;
  }
  WAIT_STATE(ch, PULSE_VIOLENCE * 2);
}

ACMD (do_camouflage)
{
  byte percent, prob;
  struct char_data *vict;
  float factor;

  if ((GET_CLASS(ch) != CLASS_THIEF || GET_SKILL(ch, SKILL_CAMOUFLAGE) <= 0)
      && GET_LEVEL(ch) < LVL_IMMORT){
    send_to_char("You don't seem to have the camouflage ability.\r\n", ch);
    return;
  }

  if (GET_POS (ch) != POS_FIGHTING){
    send_to_char("You can only camouflage yourself when fighting.\r\n", ch);
    return;
  }

  if (GET_MOVE(ch) < 25)
    {
      send_to_char ("You're too tired to do that!", ch);
      return;
    }

  send_to_char ("You attempt to camouflage yourself with your surroundings.\r\n", ch);
  GET_MOVE(ch) -= 25;

  if (IS_AFFECTED (ch, AFF_HIDE) && !check_perm_duration(ch, AFF_HIDE))
    REMOVE_BIT (AFF_FLAGS (ch), AFF_HIDE);

  /* 101% is a complete failure */
  prob = GET_SKILL (ch, SKILL_CAMOUFLAGE) + dex_app_skill[GET_DEX (ch)].hide;
  percent = number ((int)(prob*0.6), 101) - (GET_LEVEL(ch)/number(10, 15));
  if (percent <= 0)
    percent = 0;

  /* prob is also a factor of hp/maxhp */
  factor = ((float)GET_HIT(ch))/((float)GET_MAX_HIT(ch));  
  if (factor < 0.6)
    factor = 0.6; /* lowest factor = 0.6 */
  prob = (int) (prob*factor);
  
  /*
  sprintf(buf, "%s: prob %d (factor %g) percent %d - Camouflage %s\r\n",
	  GET_NAME(ch), prob, factor, percent, 
	  (percent>prob)?"FAILED":"SUCCEEDED");
  log(buf);
  */

  if (percent > prob)
    return;

  sprintf(buf, "%s has disappeared from view!\r\n", GET_NAME(ch));
  act (buf, TRUE, ch, 0, 0, TO_ROOM);
  if (FIGHTING (ch)){
    vict = FIGHTING (ch);
    stop_fighting (vict);
    stop_fighting (ch);
    sprintf(buf, "%s is befuddled, having lost sight of his target.\r\n", 
	    GET_NAME(vict));
    send_to_room (buf , ch->in_room);
  }
  SET_BIT (AFF_FLAGS (ch), AFF_HIDE);
  WAIT_STATE(ch, PULSE_VIOLENCE*2);
}

ACMD (do_blanket)
{
  byte percent, prob;
  float factor;
  struct char_data *vict;
  struct char_data *k;
  struct follow_type *f;
  int grpsize = 0;
  int befuddled = 1;

  if ((GET_CLASS(ch) != CLASS_THIEF || GET_SKILL(ch, SKILL_BLANKET) <= 0)
      && GET_LEVEL(ch) < LVL_IMMORT){
    send_to_char("You don't seem to have the blanket camouflage ability.\r\n", ch);
    return;
  }

  if (GET_POS (ch) != POS_FIGHTING){
    send_to_char("You can only blanket comouflage your group when fighting.\r\n", ch);
    return;
  }

  if (GET_MOVE(ch) < 25)
    {
      send_to_char ("You're too tired to do that!", ch);
      return;
    }

  send_to_char ("You attempt to blanket camouflage your group.\r\n", ch);
  GET_MOVE(ch) -= 25;

  if (ch->master)
    k = ch->master;
  else
    k = ch;

  /* First un-hide everyone in the group */
  if ((get_char_room (GET_NAME(k), ch->in_room) != NULL) | (k == ch)){
    if (IS_AFFECTED (k, AFF_HIDE) && !check_perm_duration(k, AFF_HIDE))
      REMOVE_BIT (AFF_FLAGS (k), AFF_HIDE);
  }
  for (f = k->followers; f; f = f->next)
    if (IS_AFFECTED (f->follower, AFF_GROUP)){
      if (get_char_room (GET_NAME(f->follower), ch->in_room) != NULL){	
	grpsize++;
	if (IS_AFFECTED (f->follower, AFF_HIDE) && !check_perm_duration(f->follower, AFF_HIDE))
	  REMOVE_BIT (AFF_FLAGS(f->follower), AFF_HIDE);
      }
    }

  /* 101% is a complete failure */
  prob = GET_SKILL (ch, SKILL_CAMOUFLAGE) 
    + dex_app_skill[GET_DEX (ch)].hide - grpsize;
  percent = number ((int)(prob*0.6), 101) - (GET_LEVEL(ch)/number(10, 15));
  if (percent <= 0)
    percent = 0;

  /* prob is also a factor of hp/maxhp */
  factor = ((float)GET_HIT(ch))/((float)GET_MAX_HIT(ch));  
  if (factor < 0.55)
    factor = 0.55; /* lowest factor = 0.55 */
  prob = (int) (prob*factor);

  /*
  sprintf(buf, "%s: prob %d (factor %g) percent %d - Blanket %s\r\n",
	  GET_NAME(ch), prob, factor, percent, 
	  (percent>prob)?"FAILED":"SUCCEEDED");
  log(buf);
  */

  if (percent > prob)
    return;

  /* Now blanket is succesful, so everyone in the group is hidden */
  if ((get_char_room (GET_NAME(k), ch->in_room) != NULL) | (k == ch)){
    sprintf(buf, "%s has disappeared from view!\r\n", GET_NAME(k));
    act (buf, TRUE, k, 0, 0, TO_ROOM);
    if (FIGHTING (k)){
      vict = FIGHTING (k);
      stop_fighting (vict);
      stop_fighting (k);
      if (!befuddled){
	sprintf(buf, "%s is befuddled, having lost sight of his target.\r\n", 
		GET_NAME(vict));
	send_to_room (buf , ch->in_room);
	befuddled = 1;
      }
    }
    SET_BIT (AFF_FLAGS (k), AFF_HIDE);
  }

  for (f = k->followers; f; f = f->next)
    if (IS_AFFECTED (f->follower, AFF_GROUP)){
      if (get_char_room (GET_NAME(f->follower), ch->in_room) != NULL){	
	if (FIGHTING (f->follower)){
	  vict = FIGHTING (f->follower);
	  stop_fighting (vict);
	  stop_fighting (f->follower);
	  sprintf(buf, "%s has disappeared from view!\r\n", GET_NAME(f->follower));
	  act (buf, TRUE, f->follower, 0, 0, TO_ROOM);
	  if (!befuddled){
	    sprintf(buf, "%s is befuddled, having lost sight of his target.\r\n", 
		    GET_NAME(vict));
	    send_to_room (buf , ch->in_room);
	    befuddled = 1;
	  }
	}
	SET_BIT (AFF_FLAGS (f->follower), AFF_HIDE);
      }
    }
  WAIT_STATE(ch, PULSE_VIOLENCE*2);
}