/*
	I've looked at other codebases that include a monk class but most of them
	are severly hacked up. I haven't attempted this before but I put all of the
	base code into one file that I call fight.monk.c. The main code below is
	just a very quick hack of Rom24b6's mob_hit function. I'm using Merc 2.2
	but I have also incorporated the get_skill and check_improve functions
	as well so this should work fairly easy in Rom.
 
	Everything below is pretty much self contained other than adding code
	to const.c, and the gsn declares to db.c and merc.h. I have included
	all needed code below.
 */

/*
I use erwins online skill spell settings but here it the output of
do_slist to give you an idea of the levels I've given skills to monks
along with some original skills from merc / rom

Lv          Abilities

 1:         open hand
 3:      fast healing        meditation
 4:             dodge
 7:              kick
10:  mantis technique
11:          snapkick
12:              trip
15:     inner balance
23:            rescue
24:             sneak
25:       inner focus    bear technique
27:         whirlwind
35: serpent technique
50:mongoose technique
 */


/*  EXAMPLE OUTPUT from my mud. ( Below is just one round....)

a level 55 dragon claws you in the forearm with *DECIMATING* ferocity!
You have set a new personal record for damage done.
You slice a level 55 dragon in the leg with ***DEVATATING*** ferocity!
You slice a level 55 dragon in the foot with ***DEVATATING*** brutality!
You slice a level 55 dragon in the forearm with ***DEVATATING*** power.
You slice a level 55 dragon in the arm with **DEVATATING** viciousness.
You slice a level 55 dragon in the leg with ***DEVATATING*** savagery!
You have become better at open hand!
a level 55 dragon spins around and blocks your attack.
You slice a level 55 dragon in the knee with ***DEVATATING*** rage!
You slice a level 55 dragon in the thigh with ***DEVATATING*** brutality!
You slice a level 55 dragon in the hand with ***DEVATATING*** ferocity!
You slice a level 55 dragon in the hand with ***DEVATATING*** passion.
You kick a level 55 dragon in the face with mauling passion.
You snapkick a level 55 dragon in the thigh with **DEVATATING** brutality!
You whirlwind a level 55 dragon in the foot with *DEVATATING* passion.
a level 55 dragon winces in pain. 

*/


// In const.c, add the following: // NOTE: I use erwin's online skill setting..

/* Quick code for quickly created monk class */
/* Quick code for quickly created monk class */

	/* Open hand is Monk First Attack */
    {
	"open hand",			{ },
	spell_null,				TAR_IGNORE,		POS_FIGHTING,
	&gsn_open_hand,			SLOT( 0),	0,	0,
	"open hand",			"!Open Hand!"
    },

	/* Allows open hand to land more often */
    {
	"inner balance",		{ },
	spell_null,				TAR_IGNORE,		POS_FIGHTING,
	&gsn_inner_balance,		SLOT( 0),	0,	0,
	"inner balance",		"!Inner Balance!"
    },

	/* Allows open hand to land more often */
    {
	"inner focus",			{ },
	spell_null,				TAR_IGNORE,		POS_FIGHTING,
	&gsn_inner_focus,		SLOT( 0),	0,	0,
	"inner focus",			"!Inner Focus!"
    },

	/* Mantis Technique is Monk Second Attack */
    {
	"mantis technique",		{ },
	spell_null,				TAR_IGNORE,		POS_FIGHTING,
	&gsn_mantis_technique,	SLOT( 0),	0,	0,
	"mantis technique",		"!Mantis Technique!"
    },

	/* Bear Technique is Monk Third Attack */
    {
	"bear technique",		{ },
	spell_null,				TAR_IGNORE,		POS_FIGHTING,
	&gsn_bear_technique,	SLOT( 0),	0,	0,
	"bear technique",		"!Bear Technique!"
    },

	/* Serpent Technique is Monk Forth Attack */
    {
	"serpent technique",		{ },
	spell_null,					TAR_IGNORE,		POS_FIGHTING,
	&gsn_serpent_technique,		SLOT( 0),	0,	0,
	"serpent technique",		"!Serpent Technique!"
    },

	/* Mongoose Technique is Monk Fifth Attack */
    {
	"mongoose technique",			{ },
	spell_null,						TAR_IGNORE,		POS_FIGHTING,
	&gsn_mongoose_technique,		SLOT( 0),	0,	0,
	"mongoose technique",			"!Mongoose Technique!"
    },

    {
	"whirlwind",			{ },
	spell_null,				TAR_IGNORE,		POS_FIGHTING,
	&gsn_whirlwind,			SLOT( 0),	0,	0,
	"whirlwind",			"!Whirlwind Kick!"
    },

    {
	"snapkick",				{ },
	spell_null,				TAR_IGNORE,		POS_FIGHTING,
	&gsn_snapkick,			SLOT( 0),	0,	0,
	"snapkick",				"!Snap Kick!"
    }

// NOTE: you should already have kick.. no changes are needed to use that.

// In db.c add the following:

/* Hackish Monk Skills */
int		gsn_open_hand;
int		gsn_mantis_technique;
int		gsn_bear_technique;
int		gsn_serpent_technique;
int		gsn_mongoose_technique;
int		gsn_inner_balance;
int		gsn_inner_focus;
int		gsn_whirlwind;
int		gsn_snapkick;

// In merc.h add the following

/* Hackish Monk Skills */
extern int	gsn_open_hand;
extern int	gsn_mantis_technique;
extern int	gsn_bear_technique;
extern int	gsn_serpent_technique;
extern int	gsn_mongoose_technique;
extern int	gsn_inner_balance;
extern int	gsn_inner_focus;
extern int	gsn_whirlwind;
extern int	gsn_snapkick;

// Open up fight.c and look for this bit of code in  void multi_hit
// You should see where it checks for NPC and does the mob_hit.. Right below that
// that bit of code, add the one for monks. Note: I have CLASS_MONK defined in merc.h
// as well.

!    if (IS_NPC(ch))
!    {
!	mob_hit(ch, victim, dt);
!	return;
!    }

+    if (IS_SET(ch->class,CLASS_MONK))
+    {
+    bare_hit(ch, victim, dt); // If using Dual Wield, use bare_hit(ch, victim, dt, TRUE);
+    if ( ch->fighting != victim )
+    return;
+    }

// In fight.c one_hit function just below the bonuses check for enhanced_damage
// Look for

!    if ( !IS_AWAKE(victim) )
!	dam *= 2;
!     else if (victim->position < POS_FIGHTING)
!	dam = dam * 3 / 2;

// Add this below it - Otherwise, bare-handed hits do little damage
// and new chars get tore up by level 1 newbie monsters...

+	if (IS_SET(ch->class,CLASS_MONK) )
+	dam *= 2;
+     else if (victim->position < POS_FIGHTING)
+	dam = dam * 3 / 2;

/*
I was never brave enough to try making changes to the combat system. But you
can see that by adding a few lines of code to multi_hit, you can check for
a certain type of class and give them their own fight code and combat abilities.

Ok, Here is the code.. Just remember.. I threw this together in less than 10
minutes. It may not be the best way to do it but it's working fine for me
and there are no problems at all. Email me if you have any ideas.


// BTW:  You don't need to add my header or give me credit.. This was a quick
// hack based on an idea after looking at mob_hit. Nothing else.

//--------- cut here for fight.monk.c -----------


/***************************************************************************
*  ALTERED VISION MUD (c) Nov 2006 by Chris Bunting						   *
*  Codebase being developed on the side in the evenings simply to pass	   *
*  time. That and I also enjoy messing with various code bases.		       *
*	Current Email: cbunting99@gmail.com									   *
***************************************************************************/

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

/* 
 *	This isn't anything fancy. I just had the idea when looking over the mob_hit
 *	function to change it around for bare handed attacks only. I also didn't want
 *	the code to be dependent on anything but a few gsn's and the code for const.c
 *  (12/13/2006)
 */
void bare_hit (CHAR_DATA *ch, CHAR_DATA *victim, int dt)
{
    int chance;

	if (IS_SET(ch->class,CLASS_MONK) || (get_weapon_sn(ch) != gsn_open_hand))
    one_hit(ch,victim,dt,FALSE);

    if (ch->fighting != victim)
	return;

/*
 *	Open hand attacks.. Up to 10 hits per round..
 */

	/* Monk Second Attack */
    chance = get_skill(ch,gsn_mantis_technique)/2;
    if (number_percent() < chance)
    {
	one_hit(ch,victim,dt,FALSE);
	check_improve(ch,gsn_mantis_technique,TRUE,5);
	if (ch->fighting != victim)
	    return;
    } 

	/* Monk Third Attack */
    chance = get_skill(ch,gsn_bear_technique)/2;
    if (number_percent() < chance)
    {
	one_hit(ch,victim,dt,FALSE);
	check_improve(ch,gsn_bear_technique,TRUE,5);
	if (ch->fighting != victim)
	    return;
    }

	/* Monk Forth Attack */
	chance = get_skill(ch,gsn_serpent_technique)/4;
    if ( number_percent( ) < chance )
    {
	one_hit( ch, victim, dt, FALSE );
	check_improve(ch,gsn_serpent_technique,TRUE,5);
	if ( ch->fighting != victim )
	    return;
    }

	/* Monk Fifth Attack */
	chance = get_skill(ch,gsn_mongoose_technique)/4;
    if ( number_percent( ) < chance )
    {
	one_hit( ch, victim, dt, FALSE );
	check_improve(ch,gsn_mongoose_technique,TRUE,5);
	if ( ch->fighting != victim )
	    return;
    }


/*	These are not standard attacks like above. Inner Balance is moreless
	an open hand second attack. Tested on my mud at level 15. It's replicated
	twice since monks use both hands automaticly. So the replication = left/right
	hand.

	Inner focus is the same as inner balance... It just adds two more hits at
	an even higher level.. Not yet tried but maybe level 45 or even HERO.
*/

    chance = get_skill(ch,gsn_inner_balance)/4;
    if (number_percent() < chance)
    {
	one_hit(ch,victim,dt,FALSE);
	check_improve(ch,gsn_inner_balance,TRUE,5);
	if (ch->fighting != victim)
	    return;
    } 

	chance = get_skill(ch,gsn_inner_balance)/4;
    if ( number_percent( ) < chance )
    {
	one_hit( ch, victim, dt, FALSE );
	check_improve(ch,gsn_inner_balance,TRUE,5);
	if ( ch->fighting != victim )
	    return;
    }

    chance = get_skill(ch,gsn_inner_focus)/4;
    if (number_percent() < chance)
    {
	one_hit(ch,victim,dt,FALSE);
	check_improve(ch,gsn_inner_focus,TRUE,5);
	if (ch->fighting != victim)
	    return;
    } 

	chance = get_skill(ch,gsn_inner_focus)/4;
    if ( number_percent( ) < chance )
    {
	one_hit( ch, victim, dt, FALSE );
	check_improve(ch,gsn_inner_focus,TRUE,5);
	if ( ch->fighting != victim )
	    return;
    }
}

/*
	I just use do_kick with checks to make the additional monk kicks are automatic.

	Here are the modified versions of Kick..
*/

// Also.. In interp.c below kick add
	{ "snapkick",	do_snapkick,	POS_FIGHTING,	 0,  LOG_NORMAL, 1	},
	{ "whirlwind",	do_whirlwind,	POS_FIGHTING,	 0,  LOG_NORMAL, 1	},

// In interp.h add
DECLARE_DO_FUN(	do_snapkick		);
DECLARE_DO_FUN(	do_whirlwind		);

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

    if ( !IS_NPC(ch)
    &&   ch->level < skill_table[gsn_snapkick].skill_level[ch->class] )
    {
	send_to_char( "You better leave the martial arts to fighters.\n\r", ch );
	return;
    }

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

    WAIT_STATE( ch, skill_table[gsn_snapkick].beats );
    if ( get_skill(ch,gsn_snapkick) > number_percent())
    {
	damage(ch,victim,number_range(2, 30 + 2 * ch->level),gsn_snapkick);
	check_improve(ch,gsn_snapkick,TRUE,1);
    }
    else
    {
	damage( ch, victim, 0, gsn_snapkick);
	check_improve(ch,gsn_snapkick,FALSE,1);
    }
	check_killer(ch,victim);
    return;
}

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

    if ( !IS_NPC(ch)
    &&   ch->level < skill_table[gsn_whirlwind].skill_level[ch->class] )
    {
	send_to_char( "You better leave the martial arts to fighters.\n\r", ch );
	return;
    }

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

    WAIT_STATE( ch, skill_table[gsn_whirlwind].beats );
    if ( get_skill(ch,gsn_whirlwind) > number_percent())
    {
	damage(ch,victim,number_range(2, 30 + 2 * ch->level),gsn_whirlwind);
	check_improve(ch,gsn_whirlwind,TRUE,1);
    }
    else
    {
	damage( ch, victim, 0, gsn_whirlwind);
	check_improve(ch,gsn_whirlwind,FALSE,1);
    }
	check_killer(ch,victim);
    return;
}