/* mercenary.c
 * A small combo move system for a Class i once had
 * called, err well, mercenary. Basicly, You can
 * do various combat moves, and if you do them in
 * a specific order, some sort of special happens.
 * This is relitivly simple.
 * Theres some work to be done to make this useful.
 * Try and play with it a bit before you use it =)
 *
 * Oh, in here are also some strange moves, that require
 * specific types of weapons. Try mixing it up if you keep
 * these, a combo that uses crushing blow, A combo that
 * starts off with a Garotte, etc.
 *
 * Enjoy =)
 *
 * This snippet uses the Modified BSD licence
 *
 *     Redistribution and use in source and binary forms, with or without modification,
 *     are permitted provided that the following conditions are met:
 *
 *   1. Redistributions of source code must retain the above copyright notice,
 *      this list of conditions and the following disclaimer.
 *   2. Redistributions in binary form must reproduce the above
 *      copyright notice, this list of conditions and the following disclaimer
 *      in the documentation and/or other materials provided with the distribution.
 *   3. The name of the author may not be used to endorse or promote products derived
 *      from this software without specific prior written permission.
 *
 *      THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
 *      INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 *      AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
 *      LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 *      (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 *      OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 *      CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 *      OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * -Thri
 * cyhawkx@sbcglobal.net
 * AIM: CalibanL
 */


#if defined(macintosh)
#include <types.h>
#else
#include <sys/types.h>
#endif
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "merc.h"
#include "interp.h"
#include "magic.h"

#define MAX_COMBO_MOVES     8

#define MOVE_SPINKICK       1
#define MOVE_SWEEPKICK      2
#define MOVE_AXEKICK        3
#define MOVE_KNEE           4
#define MOVE_BACKFIST       5
#define MOVE_FOREARM        6




void check_combo (CHAR_DATA * ch, CHAR_DATA * victim, int current_move)
{
       char buf[MSL];
       int sn = -1;
       int dam = -1;


       place_moves_in_list(ch, current_move);


       sprintf(buf, "merc_combo_1 = %s\n\r", get_move_name(ch->merc_combo_1));       send_to_char(buf, ch);
       sprintf(buf, "merc_combo_2 = %s\n\r", get_move_name(ch->merc_combo_2));       send_to_char(buf, ch);
       sprintf(buf, "merc_combo_3 = %s\n\r", get_move_name(ch->merc_combo_3));       send_to_char(buf, ch);
       sprintf(buf, "merc_combo_4 = %s\n\r", get_move_name(ch->merc_combo_4));       send_to_char(buf, ch);
       sprintf(buf, "merc_combo_5 = %s\n\r", get_move_name(ch->merc_combo_5));       send_to_char(buf, ch);
       sprintf(buf, "merc_combo_6 = %s\n\r", get_move_name(ch->merc_combo_6));       send_to_char(buf, ch);
       sprintf(buf, "merc_combo_7 = %s\n\r", get_move_name(ch->merc_combo_7));       send_to_char(buf, ch);

       /* Move:      spinkick/axekick */

       if (
             ch->merc_combo_1 == MOVE_AXEKICK
          && ch->merc_combo_2 == MOVE_SPINKICK
          && ch->merc_combo_3 != MOVE_BACKFIST          // Oops, conflict with combo 5
       )
       {
              dam = number_range(250, 450);
              dam += GET_DAMROLL(ch);

              sn = skill_lookup ("finish axe/spin");

              act ("You roundhouse $N to the ground!",  ch, NULL, victim, TO_CHAR);
              act ("$n roundhouses you to the ground!", ch, NULL, victim, TO_VICT);
              act ("$n roundhouses $N to the ground!",  ch, NULL, victim, TO_NOTVICT);

              damage (ch, victim, dam, sn, DAM_NONE, TRUE);
              reset_combo(ch);
              return;
       }

       /* sweep, forearm */

       if (
             ch->merc_combo_1 == MOVE_FOREARM
          && ch->merc_combo_2 == MOVE_SWEEPKICK
          )

       {


              dam = number_range(100, 200);
              dam += GET_DAMROLL(ch);

              sn = skill_lookup ("finish sweepkick/forearm");

              send_to_char("\n\r", ch);
              send_to_char("\n\r", victim);

              act ("You stomp on $N!",  ch, NULL, victim, TO_CHAR);
              act ("$n stomps on you!", ch, NULL, victim, TO_VICT);
              act ("$n stomps on $N!",  ch, NULL, victim, TO_NOTVICT);

              act ("You grin and your body surges with power!",  ch, NULL, victim, TO_CHAR);
              act ("$n grins and $e's body surges with power!", ch, NULL, victim, TO_VICT);
              act ("$n grins and $e's body surges with power!",  ch, NULL, victim, TO_NOTVICT);

              ch->hit += dam;
              damage (ch, victim, dam, sn, DAM_NONE, TRUE);
              reset_combo(ch);
              return;
       }

       /* Backfist, axekick, Spinkick, Forearm */
       if (
             ch->merc_combo_1 == MOVE_FOREARM
          && ch->merc_combo_2 == MOVE_SPINKICK
          && ch->merc_combo_3 == MOVE_AXEKICK
          && ch->merc_combo_4 == MOVE_BACKFIST
          )

       {


              dam = number_range(400, 800);
              dam += GET_DAMROLL(ch);

              sn = skill_lookup ("finish back/spin/axe/forearm");

              send_to_char("\n\r", ch);
              send_to_char("\n\r", victim);

              act ("You grab $N and throw $E to the ground!",  ch, NULL, victim, TO_CHAR);
              act ("$n grabs you and throws you to the ground!", ch, NULL, victim, TO_VICT);
              act ("$n grabs $N and thows $E to the ground!",  ch, NULL, victim, TO_NOTVICT);
              WAIT_STATE(victim, number_range(5, 10));
              damage (ch, victim, dam, sn, DAM_NONE, TRUE);
              reset_combo(ch);
              return;
       }

       /* forearm, forearm, knee, spinkick */
       if (
             ch->merc_combo_1 == MOVE_SPINKICK
          && ch->merc_combo_2 == MOVE_KNEE
          && ch->merc_combo_3 == MOVE_FOREARM
          && ch->merc_combo_4 == MOVE_FOREARM
          )
       {

             dam = number_range(400, 800);
              dam += GET_DAMROLL(ch);

              sn = skill_lookup ("finish forearm/forearm/knee/spinkick");

              send_to_char("\n\r", ch);
              send_to_char("\n\r", victim);

              act ("You roundhouse $N while $E is spinning in the air!",  ch, NULL, victim, TO_CHAR);
              act ("$n roundhouses you while you are spinning in the air!", ch, NULL, victim, TO_VICT);
              act ("$n roundhouses $N while $E is spinning in the air",  ch, NULL, victim, TO_NOTVICT);

              DAZE_STATE(victim, number_range(10, 20));
              damage (ch, victim, dam, sn, DAM_NONE, TRUE);
              reset_combo(ch);
              return;
       }

       /* knee, spinkick, backfist, spinkic, axekick, forearm */
       if (
             ch->merc_combo_1 == MOVE_FOREARM
          && ch->merc_combo_2 == MOVE_AXEKICK
          && ch->merc_combo_3 == MOVE_SPINKICK
          && ch->merc_combo_4 == MOVE_BACKFIST
          && ch->merc_combo_5 == MOVE_SPINKICK
          && ch->merc_combo_6 == MOVE_KNEE
          )
       {
             dam = number_range(1000, 1500);
              dam += GET_DAMROLL(ch);

              sn = skill_lookup ("finish knee/spink/backf/spink/axek/forea");


              send_to_char("\n\r", ch);
              send_to_char("\n\r", victim);

              act ("You call forth a beam of light and strike $N!",  ch, NULL, victim, TO_CHAR);
              act ("$n calls forth a beam of light and strikes you!", ch, NULL, victim, TO_VICT);
              act ("$n calls forth a beam of light and strikes %N!",  ch, NULL, victim, TO_NOTVICT);

              DAZE_STATE(victim, number_range(10, 20));
              WAIT_STATE(victim, number_range(2, 4));
              damage (ch, victim, dam, sn, DAM_NONE, TRUE);
              reset_combo(ch);
              return;
       }



}




char * get_move_name(int move)
{
       if (move == MOVE_SPINKICK)
              return "spinkick";

       else if (move == MOVE_SWEEPKICK)
              return "sweep kick";

       else if (move == MOVE_AXEKICK)
              return "axe kick";

       else if (move == MOVE_KNEE)
              return "knee";

       else if (move == MOVE_BACKFIST)
              return "backfist";

       else if (move == MOVE_FOREARM)
              return "Forearm";

       else
              return "none";

}

void place_moves_in_list(CHAR_DATA * ch, int move)
{
       int old1, old2, old3, old4, old5, old6, old7;

       old1 = ch->merc_combo_1;
       old2 = ch->merc_combo_2;
       old3 = ch->merc_combo_3;
       old4 = ch->merc_combo_4;
       old5 = ch->merc_combo_5;
       old6 = ch->merc_combo_6;
       old7 = ch->merc_combo_7;


       ch->merc_combo_1 = move;
       ch->merc_combo_2 = old1;
       ch->merc_combo_3 = old2;
       ch->merc_combo_4 = old3;
       ch->merc_combo_5 = old4;
       ch->merc_combo_6 = old5;
       ch->merc_combo_7 = old6;


       return;
}





void reset_combo(CHAR_DATA * ch)
{

       ch->merc_combo_1     = 0;
       ch->merc_combo_2     = 0;
       ch->merc_combo_3     = 0;
       ch->merc_combo_4     = 0;
       ch->merc_combo_5     = 0;
       ch->merc_combo_6     = 0;
       ch->merc_combo_7     = 0;
       ch->in_combo         = 0;

       return;
}

void do_rage (CHAR_DATA * ch, char *argument)
{
    CHAR_DATA *victim;

    int wait = 10;


    if (!IS_NPC (ch) && ch->level < skill_table[gsn_rage].skill_level[ch->class])
    {
        send_to_char ("You screm in rage!\n\r", ch);
        return;
    }

    /* Prepare Wait state */
    if (!IS_AFFECTED2 (ch, AFF2_MERC_SPEED))
    {
	wait = 12;
    }
    else
    {
	wait = 6;
    }


    if ((victim = ch->fighting) == NULL)
    {
        send_to_char ("You aren't fighting anyone.\n\r", ch);
        return;
    }

    WAIT_STATE (ch, wait);

    if (get_skill (ch, gsn_rage) > number_percent ())
    {
        multi_hit (ch, victim, TYPE_UNDEFINED);
	 multi_hit (ch, victim, TYPE_UNDEFINED);
        check_improve (ch, gsn_rage, TRUE, 1);
    }
    else
    {
        damage (ch, victim, 0, gsn_rage, DAM_BASH, TRUE);
        check_improve (ch, gsn_rage, FALSE, 1);
    }
    check_killer (ch, victim);
    return;
}

void do_crushing_blow (CHAR_DATA * ch, char *argument)
{
       CHAR_DATA *victim;
       OBJ_DATA *wield;
       OBJ_DATA *wield2;
       int wait = 10;
       int dam, dam2 = 0;
       int sn;
       dam = 0;
       dam2 = 0;



       if (!IS_NPC (ch) && ch->level < skill_table[gsn_crushing_blow].skill_level[ch->class])
       {
              send_to_char ("Huh?\n\r", ch);
              return;
       }

       wield  = get_eq_char( ch, WEAR_WIELD );
       wield2 = get_eq_char( ch, WEAR_SECONDARY );

       if (wield == NULL)
       {
              send_to_char("You must be wielding a weapon to use crushing blow.\n\r", ch);
              return;
       }

       if (   wield->value[0] != WEAPON_MACE)
       {
              send_to_char("You must wield a mace to use crushing blow.\n\r", ch);
              return;
       }


       if (wield != NULL)
       {
              dam  = (number_range(wield->value[1], wield->value[2]));
              dam += GET_DAMROLL(ch);
              dam *= get_force(ch);
              dam = dam * 2 / 3;
       }

       if (wield2 != NULL)
       {
              dam2  = (number_range(wield2->value[1], wield2->value[2]));
              dam2 += GET_DAMROLL(ch);
              dam2 *= get_force(ch);
              dam2 = dam * 2 / 5;
       }



       /* Prepare Wait state */
       if (!IS_AFFECTED2 (ch, AFF2_MERC_SPEED))
       {
              wait = 12;
       }
       else
       {
              wait = 8;
       }


       if ((victim = ch->fighting) == NULL)
       {
              send_to_char ("You aren't fighting anyone.\n\r", ch);
              return;
       }

       WAIT_STATE (ch, wait);
       sn = skill_lookup ("crushing blow");


       if (get_skill (ch, gsn_crushing_blow) > number_percent ())
       {
              damage (ch, victim, dam, sn, DAM_BASH, TRUE);
              damage (ch, victim, dam, sn, DAM_BASH, TRUE);
              damage (ch, victim, dam, sn, DAM_BASH, TRUE);
              if (wield2 != NULL)
              {
                     damage (ch, victim, dam2, sn, DAM_BASH, TRUE);
                     damage (ch, victim, dam2, sn, DAM_BASH, TRUE);
              }

              check_improve (ch, gsn_crushing_blow, TRUE, 1);
       }
       else
       {
              damage (ch, victim, 0, sn, DAM_BASH, TRUE);
              check_improve (ch, sn, FALSE, 1);
       }

       check_killer (ch, victim);
       return;
}


void do_garrote (CHAR_DATA * ch, char *argument)
{
       CHAR_DATA *victim;
       OBJ_DATA *wield;
       OBJ_DATA *wield2;
       int wait = 10;
       int dam, dam2 = 0;
       int sn;
       dam = 0;
       dam2 = 0;



       if (!IS_NPC (ch) && ch->level < skill_table[gsn_garrote].skill_level[ch->class])
       {
              send_to_char ("Huh?\n\r", ch);
              return;
       }

       wield  = get_eq_char( ch, WEAR_WIELD );
       wield2 = get_eq_char( ch, WEAR_SECONDARY );

       if (wield == NULL)
       {
              send_to_char("You must be wielding a weapon to use garrote.\n\r", ch);
              return;
       }

       if (   wield->value[0] != WEAPON_WHIP)
       {
              send_to_char("You must wield a whip to use garrote.\n\r", ch);
              return;
       }


       if (wield != NULL)
       {
              dam  = (number_range(wield->value[1], wield->value[2]));
              dam += GET_DAMROLL(ch);
              dam *= get_force(ch);
              dam = dam;
       }

       if (wield2 != NULL)
       {
              dam2  = (number_range(wield2->value[1], wield2->value[2]));
              dam2 += GET_DAMROLL(ch);
              dam2 *= get_force(ch);
              dam2 = dam * 2 / 5;
       }



       /* Prepare Wait state */
       if (!IS_AFFECTED2 (ch, AFF2_MERC_SPEED))
       {
              wait = 12;
       }
       else
       {
              wait = 8;
       }


       if ((victim = ch->fighting) == NULL)
       {
              send_to_char ("You aren't fighting anyone.\n\r", ch);
              return;
       }

       WAIT_STATE (ch, wait);
       sn = skill_lookup ("garrote");


       if (get_skill (ch, gsn_garrote) > number_percent ())
       {
              damage (ch, victim, dam, sn, DAM_SLASH, TRUE);
              damage (ch, victim, dam, sn, DAM_SLASH, TRUE);
              if (wield2 != NULL)
              {
                     damage (ch, victim, dam2, sn, DAM_SLASH, TRUE);
                     damage (ch, victim, dam2, sn, DAM_SLASH, TRUE);
              }

              check_improve (ch, gsn_garrote, TRUE, 1);
       }
       else
       {
              damage (ch, victim, 0, sn, DAM_SLASH, TRUE);
              check_improve (ch, sn, FALSE, 1);
       }

       check_killer (ch, victim);
       return;
}

void do_thawck (CHAR_DATA * ch, char *argument)
{
       CHAR_DATA *victim;
       OBJ_DATA *wield;
       OBJ_DATA *wield2;
       int wait = 10;
       int dam, dam2 = 0;
       int sn;
       dam = 0;
       dam2 = 0;



       if (!IS_NPC (ch) && ch->level < skill_table[gsn_thawck].skill_level[ch->class])
       {
              send_to_char ("Huh?\n\r", ch);
              return;
       }

       wield  = get_eq_char( ch, WEAR_WIELD );
       wield2 = get_eq_char( ch, WEAR_SECONDARY );

       if (wield == NULL)
       {
              send_to_char("You must be wielding a weapon to use thawck.\n\r", ch);
              return;
       }

       if (   wield->value[0] != WEAPON_POLEARM)
       {
              send_to_char("You must wield a polearm to use thawck.\n\r", ch);
              return;
       }


       if (wield != NULL)
       {
              dam  = (number_range(wield->value[1], wield->value[2]));
              dam += GET_DAMROLL(ch);
              dam *= get_force(ch);
              dam = dam;
       }

       if (wield2 != NULL)
       {
              dam2  = (number_range(wield2->value[1], wield2->value[2]));
              dam2 += GET_DAMROLL(ch);
              dam2 *= get_force(ch);
              dam2 = dam * 2 / 5;
       }



       /* Prepare Wait state */
       if (!IS_AFFECTED2 (ch, AFF2_MERC_SPEED))
       {
              wait = 12;
       }
       else
       {
              wait = 8;
       }


       if ((victim = ch->fighting) == NULL)
       {
              send_to_char ("You aren't fighting anyone.\n\r", ch);
              return;
       }

       WAIT_STATE (ch, wait);
       sn = skill_lookup ("thawck");


       if (get_skill (ch, gsn_thawck) > number_percent ())
       {
              damage (ch, victim, dam, sn, DAM_SLASH, TRUE);
              damage (ch, victim, dam, sn, DAM_SLASH, TRUE);
              if (wield2 != NULL)
              {
                     damage (ch, victim, dam2, sn, DAM_SLASH, TRUE);
                     damage (ch, victim, dam2, sn, DAM_SLASH, TRUE);
              }

              check_improve (ch, gsn_thawck, TRUE, 1);
       }
       else
       {
              damage (ch, victim, 0, sn, DAM_SLASH, TRUE);
              check_improve (ch, sn, FALSE, 1);
       }

       check_killer (ch, victim);
       return;
}

void do_cleave (CHAR_DATA * ch, char *argument)
{
       CHAR_DATA *victim;
       OBJ_DATA *wield;
       OBJ_DATA *wield2;
       int wait = 10;
       int dam, dam2 = 0;
       int sn;
       dam = 0;
       dam2 = 0;



       if (!IS_NPC (ch) && ch->level < skill_table[gsn_cleave].skill_level[ch->class])
       {
              send_to_char ("Huh?\n\r", ch);
              return;
       }

       wield  = get_eq_char( ch, WEAR_WIELD );
       wield2 = get_eq_char( ch, WEAR_SECONDARY );

       if (wield == NULL)
       {
              send_to_char("You must be wielding a weapon to use cleave.\n\r", ch);
              return;
       }

       if (   wield->value[0] != WEAPON_AXE)
       {
              send_to_char("You must wield an axe to use cleave.\n\r", ch);
              return;
       }


       if (wield != NULL)
       {
              dam  = (number_range(wield->value[1], wield->value[2]));
              dam += GET_DAMROLL(ch);
              dam *= get_force(ch);
              dam = dam;
       }

       if (wield2 != NULL)
       {
              dam2  = (number_range(wield2->value[1], wield2->value[2]));
              dam2 += GET_DAMROLL(ch);
              dam2 *= get_force(ch);
              dam2 = dam * 2 / 5;
       }



       /* Prepare Wait state */
       if (!IS_AFFECTED2 (ch, AFF2_MERC_SPEED))
       {
              wait = 12;
       }
       else
       {
              wait = 8;
       }


       if ((victim = ch->fighting) == NULL)
       {
              send_to_char ("You aren't fighting anyone.\n\r", ch);
              return;
       }

       WAIT_STATE (ch, wait);
       sn = skill_lookup ("cleave");


       if (get_skill (ch, gsn_cleave) > number_percent ())
       {
              damage (ch, victim, dam, sn, DAM_SLASH, TRUE);
              damage (ch, victim, dam, sn, DAM_SLASH, TRUE);
              if (wield2 != NULL)
              {
                     damage (ch, victim, dam2, sn, DAM_SLASH, TRUE);
                     damage (ch, victim, dam2, sn, DAM_SLASH, TRUE);
              }

              check_improve (ch, gsn_cleave, TRUE, 1);
       }
       else
       {
              damage (ch, victim, 0, sn, DAM_SLASH, TRUE);
              check_improve (ch, sn, FALSE, 1);
       }

       check_killer (ch, victim);
       return;
}

void do_slice (CHAR_DATA * ch, char *argument)
{
       CHAR_DATA *victim;
       OBJ_DATA *wield;
       OBJ_DATA *wield2;
       int wait = 10;
       int dam, dam2 = 0;
       int sn;
       dam = 0;
       dam2 = 0;



       if (!IS_NPC (ch) && ch->level < skill_table[gsn_slice].skill_level[ch->class])
       {
              send_to_char ("Huh?\n\r", ch);
              return;
       }

       wield  = get_eq_char( ch, WEAR_WIELD );
       wield2 = get_eq_char( ch, WEAR_SECONDARY );

       if (wield == NULL)
       {
              send_to_char("You must be wielding a weapon to use slice.\n\r", ch);
              return;
       }

       if (   wield->value[0] != WEAPON_SWORD)
       {
              send_to_char("You must wield a sword to use slice.\n\r", ch);
              return;
       }


       if (wield != NULL)
       {
              dam  = (number_range(wield->value[1], wield->value[2]));
              dam += GET_DAMROLL(ch);
              dam *= get_force(ch);
              dam = dam;
       }

       if (wield2 != NULL)
       {
              dam2  = (number_range(wield2->value[1], wield2->value[2]));
              dam2 += GET_DAMROLL(ch);
              dam2 *= get_force(ch);
              dam2 = dam * 2 / 5;
       }



       /* Prepare Wait state */
       if (!IS_AFFECTED2 (ch, AFF2_MERC_SPEED))
       {
              wait = 12;
       }
       else
       {
              wait = 8;
       }


       if ((victim = ch->fighting) == NULL)
       {
              send_to_char ("You aren't fighting anyone.\n\r", ch);
              return;
       }

       WAIT_STATE (ch, wait);
       sn = skill_lookup ("slice");


       if (get_skill (ch, gsn_slice) > number_percent ())
       {
              damage (ch, victim, dam, sn, DAM_SLASH, TRUE);
              damage (ch, victim, dam, sn, DAM_SLASH, TRUE);
              if (wield2 != NULL)
              {
                     damage (ch, victim, dam2, sn, DAM_SLASH, TRUE);
                     damage (ch, victim, dam2, sn, DAM_SLASH, TRUE);
              }

              check_improve (ch, gsn_slice, TRUE, 1);
       }
       else
       {
              damage (ch, victim, 0, sn, DAM_SLASH, TRUE);
              check_improve (ch, sn, FALSE, 1);
       }

       check_killer (ch, victim);
       return;
}

void do_slash (CHAR_DATA * ch, char *argument)
{
       CHAR_DATA *victim;
       OBJ_DATA *wield;
       OBJ_DATA *wield2;
       int wait = 10;
       int dam, dam2 = 0;
       int sn;
       dam = 0;
       dam2 = 0;



       if (!IS_NPC (ch) && ch->level < skill_table[gsn_slash].skill_level[ch->class])
       {
              send_to_char ("Huh?\n\r", ch);
              return;
       }

       wield  = get_eq_char( ch, WEAR_WIELD );
       wield2 = get_eq_char( ch, WEAR_SECONDARY );

       if (wield == NULL)
       {
              send_to_char("You must be wielding a weapon to use slash.\n\r", ch);
              return;
       }

       if (   wield->value[0] != WEAPON_POLEARM)
       {
              send_to_char("You must wield a polearm to use slash.\n\r", ch);
              return;
       }


       if (wield != NULL)
       {
              dam  = (number_range(wield->value[1], wield->value[2]));
              dam += GET_DAMROLL(ch);
              dam *= get_force(ch);
              dam = dam;
       }

       if (wield2 != NULL)
       {
              dam2  = (number_range(wield2->value[1], wield2->value[2]));
              dam2 += GET_DAMROLL(ch);
              dam2 *= get_force(ch);
              dam2 = dam * 2 / 5;
       }



       /* Prepare Wait state */
       if (!IS_AFFECTED2 (ch, AFF2_MERC_SPEED))
       {
              wait = 12;
       }
       else
       {
              wait = 8;
       }


       if ((victim = ch->fighting) == NULL)
       {
              send_to_char ("You aren't fighting anyone.\n\r", ch);
              return;
       }

       WAIT_STATE (ch, wait);
       sn = skill_lookup ("slash");


       if (get_skill (ch, gsn_slash) > number_percent ())
       {
              damage (ch, victim, dam, sn, DAM_SLASH, TRUE);
              damage (ch, victim, dam, sn, DAM_SLASH, TRUE);
              if (wield2 != NULL)
              {
                     damage (ch, victim, dam2, sn, DAM_SLASH, TRUE);
                     damage (ch, victim, dam2, sn, DAM_SLASH, TRUE);
              }

              check_improve (ch, gsn_slash, TRUE, 1);
       }
       else
       {
              damage (ch, victim, 0, sn, DAM_SLASH, TRUE);
              check_improve (ch, sn, FALSE, 1);
       }

       check_killer (ch, victim);
       return;
}



void do_thrust (CHAR_DATA * ch, char *argument)
{
       CHAR_DATA *victim;
       OBJ_DATA *wield;
       OBJ_DATA *wield2;
       int wait = 10;
       int dam, dam2 = 0;
       int sn;
       dam = 0;
       dam2 = 0;



       if (!IS_NPC (ch) && ch->level < skill_table[gsn_thrust].skill_level[ch->class])
       {
              send_to_char ("Huh?\n\r", ch);
              return;
       }

       wield  = get_eq_char( ch, WEAR_WIELD );
       wield2 = get_eq_char( ch, WEAR_SECONDARY );

       if (wield == NULL)
       {
              send_to_char("You must be wielding a weapon to use thrust.\n\r", ch);
              return;
       }

       if (   wield->value[0] != WEAPON_DAGGER)
       {
              send_to_char("You must wield a dagger to use thrust.\n\r", ch);
              return;
       }


       if (wield != NULL)
       {
              dam  = (number_range(wield->value[1], wield->value[2]));
              dam += GET_DAMROLL(ch);
              dam *= get_force(ch);
              dam = dam;
       }

       if (wield2 != NULL)
       {
              dam2  = (number_range(wield2->value[1], wield2->value[2]));
              dam2 += GET_DAMROLL(ch);
              dam2 *= get_force(ch);
              dam2 = dam * 2 / 5;
       }



       /* Prepare Wait state */
       if (!IS_AFFECTED2 (ch, AFF2_MERC_SPEED))
       {
              wait = 12;
       }
       else
       {
              wait = 8;
       }


       if ((victim = ch->fighting) == NULL)
       {
              send_to_char ("You aren't fighting anyone.\n\r", ch);
              return;
       }

       WAIT_STATE (ch, wait);
       sn = skill_lookup ("thrust");


       if (get_skill (ch, gsn_thrust) > number_percent ())
       {
              damage (ch, victim, dam, sn, DAM_PIERCE, TRUE);
              damage (ch, victim, dam, sn, DAM_PIERCE, TRUE);
              if (wield2 != NULL)
              {
                     damage (ch, victim, dam2, sn, DAM_PIERCE, TRUE);
                     damage (ch, victim, dam2, sn, DAM_PIERCE, TRUE);
              }

              check_improve (ch, gsn_thrust, TRUE, 1);
       }
       else
       {
              damage (ch, victim, 0, sn, DAM_PIERCE, TRUE);
              check_improve (ch, sn, FALSE, 1);
       }

       check_killer (ch, victim);
       return;
}
















void do_spinkick (CHAR_DATA * ch, char *argument)
{
       CHAR_DATA *victim;
       int wait = 10;
       int sn;

       int move = MOVE_SPINKICK;

       int dam;

       dam = number_range(get_skill (ch, gsn_spin_kick) / 2, get_skill (ch, gsn_spin_kick));
       dam += GET_DAMROLL(ch);
       dam *= get_force(ch);
       dam /= 3;



       if (!IS_NPC (ch) && ch->level < skill_table[gsn_spin_kick].skill_level[ch->class])
       {
              send_to_char ("Huh?\n\r", ch);
              return;
       }

       /* Prepare Wait state */
       if (!IS_AFFECTED2 (ch, AFF2_MERC_SPEED))
              wait = 10;
       else
              wait = 5;


       if ((victim = ch->fighting) == NULL)
       {
              send_to_char ("You aren't fighting anyone.\n\r", ch);
              return;
       }

       WAIT_STATE (ch, wait);
       sn = skill_lookup ("spin kick");


       if (get_skill (ch, gsn_spin_kick) > number_percent ())
       {
              damage (ch, victim, dam, sn, DAM_NONE, TRUE);
              check_improve (ch, gsn_spin_kick, TRUE, 1);
       }
       else
       {
              damage (ch, victim, 0, sn, DAM_NONE, TRUE);
              check_improve (ch, sn, FALSE, 1);
       }


       /* combo stuff */

       check_combo(ch, victim, move);
       ch->merc_last_move = move;

       check_killer (ch, victim);
       return;
}

void do_axekick (CHAR_DATA * ch, char *argument)
{
       CHAR_DATA *victim;
       int wait = 10;
       int sn;
       int move = MOVE_AXEKICK;

       int dam;

       dam = number_range(get_skill (ch, gsn_axe_kick) / 2, get_skill (ch, gsn_axe_kick));
       dam += GET_DAMROLL(ch);
       dam *= get_force(ch);
       dam /= 3;



       if (!IS_NPC (ch) && ch->level < skill_table[gsn_axe_kick].skill_level[ch->class])
       {
              send_to_char ("Huh?\n\r", ch);
              return;
       }

       /* Prepare Wait state */
       if (!IS_AFFECTED2 (ch, AFF2_MERC_SPEED))
              wait = 10;
       else
              wait = 5;


       if ((victim = ch->fighting) == NULL)
       {
              send_to_char ("You aren't fighting anyone.\n\r", ch);
              return;
       }

       WAIT_STATE (ch, wait);
       sn = skill_lookup ("axe kick");


       if (get_skill (ch, gsn_axe_kick) > number_percent ())
       {
              damage (ch, victim, dam, sn, DAM_NONE, TRUE);
              check_improve (ch, gsn_axe_kick, TRUE, 1);
       }
       else
       {
              damage (ch, victim, 0, sn, DAM_NONE, TRUE);
              check_improve (ch, sn, FALSE, 1);
       }


       check_combo(ch, victim, move);
       ch->merc_last_move = move;

       check_killer (ch, victim);
       return;
}



void do_sweepkick (CHAR_DATA * ch, char *argument)
{
       CHAR_DATA *victim;
       int wait = 10;
       int sn;
       int move = MOVE_SWEEPKICK;

       int dam;

       dam = number_range(get_skill (ch, gsn_sweep_kick) / 2, get_skill (ch, gsn_sweep_kick));
       dam += GET_DAMROLL(ch);
       dam *= get_force(ch);
       dam /= 3;



       if (!IS_NPC (ch) && ch->level < skill_table[gsn_sweep_kick].skill_level[ch->class])
       {
              send_to_char ("Huh?\n\r", ch);
              return;
       }

       /* Prepare Wait state */
       if (!IS_AFFECTED2 (ch, AFF2_MERC_SPEED))
              wait = 10;
       else
              wait = 5;


       if ((victim = ch->fighting) == NULL)
       {
              send_to_char ("You aren't fighting anyone.\n\r", ch);
              return;
       }

       WAIT_STATE (ch, wait);
       sn = skill_lookup ("sweep kick");


       if (get_skill (ch, gsn_sweep_kick) > number_percent ())
       {
              damage (ch, victim, dam, sn, DAM_NONE, TRUE);
              check_improve (ch, gsn_sweep_kick, TRUE, 1);
       }
       else
       {
              damage (ch, victim, 0, sn, DAM_NONE, TRUE);
              check_improve (ch, sn, FALSE, 1);
       }

       check_combo(ch, victim, move);
       ch->merc_last_move = move;

       check_killer (ch, victim);
       return;
}


void do_forearm (CHAR_DATA * ch, char *argument)
{
       CHAR_DATA *victim;
       int wait = 10;
       int sn;
       int move = MOVE_FOREARM;

       int dam;

       dam = number_range(get_skill (ch, gsn_forearm) / 2, get_skill (ch, gsn_forearm));
       dam += GET_DAMROLL(ch);
       dam *= get_force(ch);
       dam /= 3;



       if (!IS_NPC (ch) && ch->level < skill_table[gsn_forearm].skill_level[ch->class])
       {
              send_to_char ("Huh?\n\r", ch);
              return;
       }

       /* Prepare Wait state */
       if (!IS_AFFECTED2 (ch, AFF2_MERC_SPEED))
              wait = 10;
       else
              wait = 5;


       if ((victim = ch->fighting) == NULL)
       {
              send_to_char ("You aren't fighting anyone.\n\r", ch);
              return;
       }

       WAIT_STATE (ch, wait);
       sn = skill_lookup ("forearm");


       if (get_skill (ch, gsn_forearm) > number_percent () )
       {
              damage (ch, victim, dam, sn, DAM_NONE, TRUE);
              check_improve (ch, gsn_forearm, TRUE, 1);
       }
       else
       {
              damage (ch, victim, 0, sn, DAM_NONE, TRUE);
              check_improve (ch, sn, FALSE, 1);
       }

       check_combo(ch, victim, move);
       ch->merc_last_move = move;

       check_killer (ch, victim);
       return;
}

void do_knee (CHAR_DATA * ch, char *argument)
{
       CHAR_DATA *victim;
       int wait = 10;
       int sn;
       int move = MOVE_KNEE;

       int dam;

       dam = number_range(get_skill (ch, gsn_knee) / 2, get_skill (ch, gsn_knee));
       dam += GET_DAMROLL(ch);
       dam *= get_force(ch);
       dam /= 3;



       if (!IS_NPC (ch) && ch->level < skill_table[gsn_knee].skill_level[ch->class])
       {
              send_to_char ("Huh?\n\r", ch);
              return;
       }

       /* Prepare Wait state */
       if (!IS_AFFECTED2 (ch, AFF2_MERC_SPEED))
              wait = 10;
       else
              wait = 5;


       if ((victim = ch->fighting) == NULL)
       {
              send_to_char ("You aren't fighting anyone.\n\r", ch);
              return;
       }

       WAIT_STATE (ch, wait);
       sn = skill_lookup ("knee");


       if (get_skill (ch, gsn_knee) > number_percent () )
       {
              damage (ch, victim, dam, sn, DAM_NONE, TRUE);
              check_improve (ch, gsn_knee, TRUE, 1);
       }
       else
       {
              damage (ch, victim, 0, sn, DAM_NONE, TRUE);
              check_improve (ch, sn, FALSE, 1);
       }

       check_combo(ch, victim, move);
       ch->merc_last_move = move;

       check_killer (ch, victim);
       return;
}

void do_backfist (CHAR_DATA * ch, char *argument)
{
       CHAR_DATA *victim;
       int wait = 10;
       int sn;
       int move = MOVE_BACKFIST;

       int dam;

       dam = number_range(get_skill (ch, gsn_backfist) / 2, get_skill (ch, gsn_backfist));
       dam += GET_DAMROLL(ch);
       dam *= get_force(ch);
       dam /= 3;



       if (!IS_NPC (ch) && ch->level < skill_table[gsn_backfist].skill_level[ch->class])
       {
              send_to_char ("Huh?\n\r", ch);
              return;
       }

       /* Prepare Wait state */
       if (!IS_AFFECTED2 (ch, AFF2_MERC_SPEED))
              wait = 10;
       else
              wait = 5;


       if ((victim = ch->fighting) == NULL)
       {
              send_to_char ("You aren't fighting anyone.\n\r", ch);
              return;
       }

       WAIT_STATE (ch, wait);
       sn = skill_lookup ("backfist");


       if (get_skill (ch, gsn_backfist) > number_percent () )
       {
              damage (ch, victim, dam, sn, DAM_NONE, TRUE);
              check_improve (ch, gsn_backfist, TRUE, 1);
       }
       else
       {
              damage (ch, victim, 0, sn, DAM_NONE, TRUE);
              check_improve (ch, sn, FALSE, 1);
       }

       check_combo(ch, victim, move);
       ch->merc_last_move = move;

       check_killer (ch, victim);
       return;
}



void spell_incressed_speed (int sn, int level, CHAR_DATA * ch, void *vo,
                            int target)
{
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    AFFECT_DATA af;

    if (IS_AFFECTED2 (victim, AFF2_MERC_SPEED))
    {
        if (victim == ch)
            send_to_char ("Your are already as fast as can be.\n\r", ch);
        else
            act ("$N is already as fast as can be.", ch, NULL, victim, TO_CHAR);
        return;
    }

    af.where = TO_AFFECTS2;
    af.type = sn;
    af.level = level;
    af.duration = get_skill (ch, gsn_incressed_speed) / 2;
    af.location = 0;
    af.modifier = -1;
    af.bitvector = AFF2_MERC_SPEED;
    affect_to_char (victim, &af);
    send_to_char ("Your body shudders... You are now extremely fast!\n\r", victim);
    if (ch != victim)
        act ("$N's body shudders.", ch, NULL, victim, TO_CHAR);
    return;
}



void do_incresse_speed(CHAR_DATA * ch, char * argument)
{

       int sn;
       SPELL_FUN *spell;
       char *words;


       if (!IS_NPC (ch) && ch->level < skill_table[gsn_incressed_speed].skill_level[ch->class])
       {
              send_to_char ("Huh?\n\r", ch);
              return;
       }

       spell = spell_incressed_speed;
       sn = skill_lookup ("increased speed");
       words = "of the wind";

       WAIT_STATE (ch, PULSE_VIOLENCE);
       spell (sn, ch->level, ch, ch, TARGET_CHAR);
       check_improve (ch, gsn_incressed_speed, TRUE, 5);

       return;
}