/*******************************************************************************
Now, I assume you already know how to add skills.  All you need to do is put
this file (ribbon.c) in your src directory, add it to your makefile, if you're
using an older makefile, put an entry for mana ribbon in your skill table,
recompile, and copyover.  The skill entry should look something like this:

	{
     "mana ribbon", {1, 1, 1, 1}, {1, 1, 1, 1},
     spell_mana_ribbon, TAR_IGNORE, POS_FIGHTING,
     NULL, SLOT (0), 50, 12,
     "", "!Mana Ribbon!", ""},

You may also have to adjust the dice calculations.
--------------------------------------------------------------------------------
Here's a default helpfile.  I'd appreciate the credit, but you don't have to use
this file, or even mention me in it.  Just don't go claiming it as your own
work.
--------------------------------------------------------------------------------
-1 'MANA RIBBON'~
Syntax: c 'mana ribbon' [arg1, arg2, arg3, arg4, arg5, arg6]

The mana ribbon spell creates a ribbon of focused mana that can be used as a
whip.  The caster may add several enhancements if he or she desires; up to
one color, and five enhancements.

Colors cost 10 mana to add.  Available colors are:
    red         green       yellow      blue        pink        violet
    orange      brown       black       white

Enhancements have varying costs, from 35 to 95.  Available enhancements:
    flaming     shocking    freezing    vampiric    venomous    keen-edged
    hawkeye     dangerous   empowered

You must seperate your modifiers with commas.  You only need to specify as
many as you'd like, up to six, and they may come in any order.  This spell
was originally written by Midboss (eclipsing.souls@gmail.com).
~ 
--------------------------------------------------------------------------------
And now there's a reason for non-kinky players to use whips.  Enjoy!
*******************************************************************************/

/***************************************************************************
 * You may use this code as you see fit within any non-commercial MUD.  My *
 * conditions are that my comments remain in tact and that you don't claim *
 * this as your own work.  Enjoy it.                                       *
 *                                  -- Midboss (eclipsing.souls@gmail.com) *
 * *********************************************************************** *
 * Mana Ribbon spell -- creates a ribbon of pure mana that the caster may  *
 * use as a whip.  Provides something interesting for whip users, which    *
 * I've found most MUDs to be in dire need of.  I originally coded this    *
 * for a dancer-like class, but it could be used for just about anything.  *
 ***************************************************************************/
#include <stdio.h>
#include <ctype.h>
#include "merc.h"

extern char * target_name;

/*
 * Special ribbon types that may be added.
 */
struct ribbon_type
{
	char *	name;
	char *	flag;
	bool	color;
	long	to_weapon;
	int		to_dam;
	int		to_hit;
	int		mp_cost;
	int		level;
};

const struct ribbon_type ribbon_table[20] =
{
	{"red",			"{R",	TRUE,	0,					0, 0, 10, 1},
	{"green",		"{G",	TRUE,	0,					0, 0, 10, 1},
	{"yellow",		"{Y",	TRUE,	0,					0, 0, 10, 1},
	{"blue",		"{B",	TRUE,	0,					0, 0, 10, 1},
	{"pink",		"{M",	TRUE,	0,					0, 0, 10, 1},
	{"violet",		"{m",	TRUE,	0,					0, 0, 10, 1},
	{"orange",		"{y",	TRUE,	0,					0, 0, 10, 1},
	{"brown",		"{r",	TRUE,	0,					0, 0, 10, 1},
	{"black",		"{D",	TRUE,	0,					0, 0, 10, 1},
	{"white",		"{W",	TRUE,	0,					0, 0, 10, 1},
	{"flaming",		"",		FALSE,	WEAPON_FLAMING,		2, 0, 95, 5},
	{"shocking",	"",		FALSE,	WEAPON_SHOCKING,	0, 2, 95, 5},
	{"freezing",	"",		FALSE,	WEAPON_FROST,		1, 1, 95, 5},
	{"vampiric",	"",		FALSE,	WEAPON_VAMPIRIC,	0, 1, 70, 3},
	{"venomous",	"",		FALSE,	WEAPON_POISON,		0, 1, 70, 3},
	{"keen-edged",	"",		FALSE,	WEAPON_SHARP,		1, 0, 50, 3},
	{"hawkeye",		"",		FALSE,	0,					0, 5, 35, 2},
	{"dangerous",	"",		FALSE,	0,					5, 0, 35, 2},
	{"empowered",	"",		FALSE,	0,					3, 3, 80, 4},
	{"",			"",		FALSE,	0,					0, 0,  0, 0}
};

/*
 * Looks up a ribbon modifier.
 */
int ribbon_lookup (char * name)
{
	int i;

	for (i = 0; ribbon_table[i].name[0] != '\0'; i++)
		if (!str_prefix (name, ribbon_table[i].name))
			return i;

	return -1;
}

/*
 * Hack of the stock ROM one_argument() function.
 * Picks off one argument, up to a comma, for argument lists.
 */
char *next_argument (char *argument, char *arg_first)
{
    char cEnd;

    while (isspace (*argument))
        argument++;

    cEnd = ',';

    while (*argument != '\0')
    {
        if (*argument == cEnd)
        {
            argument++;
            break;
        }
        *arg_first = LOWER (*argument);
        arg_first++;
        argument++;
    }
    *arg_first = '\0';

    while (isspace (*argument))
        argument++;

    return argument;
}


/*
 * Creates a ribbon of focused mana that the caster may use as a whip.
 * The caster may specifiy a color, or type.  Colors are added for
 * free, but each flag adds additional mana cost.
 */
void spell_mana_ribbon
				(int sn, int level, CHAR_DATA * ch, void *vo, int target)
{
	OBJ_DATA * obj;
    AFFECT_DATA af;
	char arg[MIL];
	int mp_cost = 0;
	int color = -1;
	int flags[5] = { -1 };
	int i, n = 0, args = 0, value = -1;
	int level_change = 0;

	/*
	 * Can it be cast?
	 */
    if (get_eq_char (ch, WEAR_WIELD) != NULL)
	{
		/*
		 * Because we failed, let's not force the wait state.
         * And, just because we can, let's give back the mana.
		 */
		ch->wait = 0;
        ch->mana = UMIN (ch->max_mana, ch->mana +
							UMAX (skill_table[sn].min_mana,
							100 / (2 + ch->level -
							skill_table[sn].skill_level[ch->class])));

		send_to_char ("You need at least one hand free to create a"
						" mana ribbon!\n\r", ch);
		return;
	}

	/*
	 * Loop through the entire argument list for flags to add.
	 */
	while (ch)
	{
		/*
		 * Limit it to six arguments.
		 */
		target_name = next_argument (target_name, arg);

		if (arg[0] == '\0')
			break;

		/*
		 * What flag do we have?
		 */
		value = ribbon_lookup (arg);

		if (value != -1)
		{
			/*
			 * Assign the flag.
			 */
			if (ribbon_table[value].color)
				color = value;
			else if (n < 5)
				flags[n++] = value;

			/*
			 * Add up the MP cost.
			 */
			mp_cost += ribbon_table[value].mp_cost;
			level_change += ribbon_table[value].level;
		}
		else
		{
			char buf[MSL];

			sprintf (buf, "You failed: %s is an unknown flag.\n\r",
							arg);
			send_to_char (buf, ch);
			ch->wait = 0;
			ch->mana = UMIN (ch->max_mana, ch->mana +
								UMAX (skill_table[sn].min_mana,
								100 / (2 + ch->level -
								skill_table[sn].skill_level[ch->class])));
			return;
		}

		++args;

		if (args > 6)
			break;
	}

	/*
	 * Do we have enough mana?
	 */
	if (ch->mana < mp_cost)
	{
		send_to_char ("You don't have enough mana to finish "
						"your ribbon.\n\r", ch);
		return;
	}

	ch->mana = UMAX (0, ch->mana - mp_cost);

	/*
	 * Set up the default mana ribbon.  It works off the dummy object to
	 * save you some work.
	 */
    obj = create_object (get_obj_index (OBJ_VNUM_DUMMY), 0);

	/*
	 * Weapon values.
	 */
	obj->item_type = ITEM_WEAPON;
	obj->value[0] = WEAPON_WHIP;
	obj->value[1] = URANGE (5, level * 50 / 100, 18);
	obj->value[2] = URANGE (3, level / 10, 5);
	obj->value[3] = attack_lookup ("whip");

	/*
	 * Free the strings.
	 */
	free_string (obj->name);
	free_string (obj->short_descr);
	free_string (obj->description);

	/*
	 * Colored whip?
	 */
	if (color != -1)
	{
		char str[MSL];


		sprintf (str, "%s mana ribbon", ribbon_table[color].name);
		obj->name = str_dup (str);

		sprintf (str, "%sa %s mana ribbon{x",
					ribbon_table[color].flag, ribbon_table[color].name);
		obj->short_descr = str_dup (str);

		sprintf (str, "%sA %s ribbon of focused mana is coiled here.{x",
					ribbon_table[color].flag, ribbon_table[color].name);
		obj->description = str_dup (str);
	}

	/*
	 * Plain whip...
	 */
	else
	{
		obj->name = str_dup ("mana ribbon");
		obj->short_descr = str_dup ("a mana ribbon");
		obj->description = 
				str_dup ("A ribbon of focused mana is coiled here.");
	}

	/*
	 * Other values.
	 */
	obj->extra_flags = ITEM_GLOW | ITEM_HUM | ITEM_MAGIC |
					   ITEM_NODROP | ITEM_NOUNCURSE | ITEM_NOREMOVE;
	obj->wear_flags = ITEM_TAKE | ITEM_WIELD;
	obj->enchanted = TRUE;
	obj->timer = UMAX (1, level / 3);

	/*
	 * The level.
	 */
	obj->level = (level / 2) + level_change;

	/*
	 * Now assign the flags, 5 maximum.
	 */
	for (i = 0; i < 5; i++)
	{
		if (flags[i] == -1)
			continue;

		/*
		 * Do we need to add a weapon flag?
		 */
		if (ribbon_table[flags[i]].to_weapon != 0)
		{
			af.where = TO_WEAPON;
			af.type = 0;
			af.level = level;
			af.duration = -1;
			af.bitvector = ribbon_table[flags[i]].to_weapon;
			af.location = APPLY_NONE;
			af.modifier = 0;
			affect_to_obj (obj, &af);
		}

		/*
		 * Hitroll.
		 */
		if (ribbon_table[flags[i]].to_hit > 0)
		{
			af.where = TO_OBJECT;
			af.type = 0;
			af.level = level;
			af.duration = -1;
			af.bitvector = 0;
			af.location = APPLY_HITROLL;
			af.modifier = ribbon_table[flags[i]].to_hit;
			affect_to_obj (obj, &af);
		}

		/*
		 * Damroll.
		 */
		if (ribbon_table[flags[i]].to_dam > 0)
		{
			af.where = TO_OBJECT;
			af.type = 0;
			af.level = level;
			af.duration = -1;
			af.bitvector = 0;
			af.location = APPLY_DAMROLL;
			af.modifier = ribbon_table[flags[i]].to_dam;
			affect_to_obj (obj, &af);
		}
	}

	/*
	 * Give them the whip, and equip it.
	 */
    obj_to_char (obj, ch);
	equip_char (ch, obj, WEAR_WIELD);
    act ("$n focuses $s mana into $p.", ch, obj, NULL, TO_ROOM);
    act ("You focus your mana into $p.", ch, obj, NULL, TO_CHAR);
	return;
}