1stMUD/corefiles/
1stMUD/gods/
1stMUD/player/
1stMUD/win32/
1stMUD/win32/ROM/
/**************************************************************************
*  Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,        *
*  Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe.   *
*                                                                         *
*  Merc Diku Mud improvements copyright (C) 1992, 1993 by Michael         *
*  Chastain, Michael Quan, and Mitchell Tse.                              *
*                                                                         *
*  In order to use any part of this Merc Diku Mud, you must comply with   *
*  both the original Diku license in 'license.doc' as well the Merc       *
*  license in 'license.txt'.  In particular, you may not remove either of *
*  these copyright notices.                                               *
*                                                                         *
*  Much time and thought has gone into this software and you are          *
*  benefiting.  We hope that you share your changes too.  What goes       *
*  around, comes around.                                                  *
***************************************************************************
*       ROM 2.4 is copyright 1993-1998 Russ Taylor                        *
*       ROM has been brought to you by the ROM consortium                 *
*           Russ Taylor (rtaylor@hypercube.org)                           *
*           Gabrielle Taylor (gtaylor@hypercube.org)                      *
*           Brian Moore (zump@rom.org)                                    *
*       By using this code, you have agreed to follow the terms of the    *
*       ROM license, in the file Rom24/doc/rom.license                    *
***************************************************************************
*       1stMUD ROM Derivative (c) 2001-2002 by Ryan Jennings              *
*            http://1stmud.dlmud.com/  <r-jenn@shaw.ca>                   *
***************************************************************************/
#include <sys/types.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "merc.h"
#include "olc.h"
#include "lookup.h"
#include "recycle.h"
#include "interp.h"
#include "tables.h"
#include "magic.h"
#include "gsn.h"

const char *spell_fun_name args((SPELL_FUN * fun));
const char *skill_gsn_name args((int *pgsn));

#define SKEDIT(fun) bool fun (CHAR_DATA *ch, const char *argument)

CH_CMD(do_skcheck)
{
	int i, gsn, pos = 0;
	bool found = FALSE, any = FALSE;

	if (!str_cmp(argument, "gsns"))
	{
		chprintln(ch, "Missing gsn entries:");

		for (i = 0; gsn_table[i].pgsn != NULL; i++)
		{
			found = FALSE;
			for (gsn = 0; gsn < maxSkill; gsn++)
			{
				if (gsn_table[i].pgsn == skill_table[gsn].pgsn)
				{
					found = TRUE;
					break;
				}
			}
			if (!found)
			{
				any = TRUE;
				chprintf(ch, "%15s ", gsn_table[i].name);
				if (++pos % 4 == 0)
					chprintln(ch, "");
			}
		}
		if (pos % 4 != 0)
			chprintln(ch, "");
		if (!any)
			chprintln(ch, "None.");
	}
	else if (!str_cmp(argument, "spells"))
	{
		chprintln(ch, "Missing spell entries:");

		for (i = 0; spell_table[i].fun != NULL; i++)
		{
			found = FALSE;
			for (gsn = 0; gsn < maxSkill; gsn++)
			{
				if (spell_table[i].fun == skill_table[gsn].spell_fun)
				{
					found = TRUE;
					break;
				}
			}
			if (!found)
			{
				chprintf(ch, "%15s ", spell_table[i].name);
				if (++pos % 4 == 0)
					chprintln(ch, "");
			}
		}
	}
	else
		chprintln(ch, "Syntax: skcheck gsns/spells");
	return;
}

SKEDIT(skedit_show)
{
	int x;
	SKILL_DATA *pSkill;

	EDIT_SKILL(ch, pSkill);

	chprintln(ch, draw_line(NULL, 0));

	chprintlnf(ch, "Name: %s", pSkill->name);
	chprintln(ch, "Class Levels:");
	for (x = 0; x < maxClass; x++)
		chprintf(ch, "[%s: %3d] ", class_table[x].who_name,
				 pSkill->skill_level[x]);
	chprintln(ch, "");
	chprintln(ch, "Class Ratings:");
	for (x = 0; x < maxClass; x++)
		chprintf(ch, "[%s: %3d] ", class_table[x].who_name, pSkill->rating[x]);
	chprintln(ch, "");
	chprintlnf(ch, "Spell_Fun: %s", spell_fun_name(pSkill->spell_fun));
	chprintlnf(ch, "Target: %s", flag_string(target_flags, pSkill->target));
	chprintlnf(ch, "Minimum Position: %s",
			   flag_string(position_flags, pSkill->minimum_position));
	chprintlnf(ch, "GSN: %s", skill_gsn_name(pSkill->pgsn));
	chprintlnf(ch, "Minimum Mana: %d", pSkill->min_mana);
	chprintlnf(ch, "Beats: %d", pSkill->beats);
	chprintlnf(ch, "Damage Noun: %s", IS_STRSET(pSkill->noun_damage));
	chprintlnf(ch, "Message Off: %s", IS_STRSET(pSkill->msg_off));
	chprintlnf(ch, "Message Obj: %s", IS_STRSET(pSkill->msg_obj));
	chprintln(ch, draw_line(NULL, 0));
	return TRUE;
}

SKEDIT(skedit_create)
{
	int j, i = maxSkill;
	SKILL_DATA *pSkill;
	struct skill_type *new_table;
	char buf[MIL];

	if (!IS_NULLSTR(argument) && skill_lookup(argument) == -1)
		sprintf(buf, argument);
	else
		sprintf(buf, "New Skill%d", maxSkill + 1);

	maxSkill++;

	alloc_mem(new_table, struct skill_type, maxSkill);

	if (!new_table)
	{
		chprintln(ch, "Memory Allocation Failed!!! Unable to create skill.");
		return FALSE;
	}

	for (j = 0; j < i; j++)
		new_table[j] = skill_table[j];

	free_mem(skill_table);
	skill_table = new_table;

	skill_table[i].name = str_dup(buf);

	skill_table[i].spell_fun = spell_null;
	skill_table[i].pgsn = &gsn_null;
	skill_table[i].min_mana = 0;
	skill_table[i].target = 0;
	skill_table[i].minimum_position = POS_STANDING;
	skill_table[i].beats = 0;
	skill_table[i].noun_damage = str_empty;
	skill_table[i].msg_off = str_empty;
	skill_table[i].msg_obj = str_empty;
	alloc_mem(skill_table[i].skill_level, int, maxClass);
	alloc_mem(skill_table[i].rating, int, maxClass);

	pSkill = &skill_table[i];
	edit_start(ch, pSkill, ED_SKILL);
	chprintln(ch, "Skill created.");
	return TRUE;
}

SKEDIT(skedit_levels)
{
	SKILL_DATA *pSkill;
	char arg1[MIL], arg2[MIL];
	int pClass;
	int lev;

	argument = one_argument(argument, arg1);
	one_argument(argument, arg2);

	EDIT_SKILL(ch, pSkill);

	if (IS_NULLSTR(arg1) || IS_NULLSTR(arg2))
	{
		chprintln(ch, "Syntax: levels <class> <level>");
		return FALSE;
	}

	if ((pClass = class_lookup(arg1)) == -1)
	{
		chprintln(ch, "That is not a valid class.");
		return FALSE;
	}

	if (!is_number(arg2) || (lev = atoi(arg2)) < 0 || lev > MAX_LEVEL)
	{
		chprintln(ch, "That is not a valid level.");
		return FALSE;
	}

	pSkill->skill_level[pClass] = lev;
	chprintlnf(ch, "Skill level for %s set to %d.", class_table[pClass].name,
			   lev);
	return TRUE;
}

SKEDIT(skedit_ratings)
{
	SKILL_DATA *pSkill;
	int pClass, lev;
	char arg1[MIL], arg2[MIL];

	EDIT_SKILL(ch, pSkill);

	argument = one_argument(argument, arg1);
	one_argument(argument, arg2);

	if (IS_NULLSTR(arg1) || IS_NULLSTR(arg2))
	{
		chprintln(ch, "Syntax: ratings <class> <rating>");
		return FALSE;
	}

	if ((pClass = class_lookup(arg1)) == -1)
	{
		chprintln(ch, "That is not a valid class.");
		return FALSE;
	}

	if (!is_number(arg2))
	{
		chprintln(ch, "That is not a valid rating.");
		return FALSE;
	}
	else
		lev = atoi(arg2);

	pSkill->rating[pClass] = lev;
	chprintlnf(ch, "Skill rating for %s set to %d.",
			   class_table[pClass].name, lev);
	return TRUE;
}

SKEDIT(skedit_spellfun)
{
	SKILL_DATA *pSkill;
	int i;

	EDIT_SKILL(ch, pSkill);

	if (IS_NULLSTR(argument))
	{
		chprintln(ch, "Syntax: spellfun <spell_function>");
		return FALSE;
	}

	if (is_name(argument, "none clear reset"))
	{
		pSkill->spell_fun = spell_null;
		chprintln(ch, "Spell value reset.");
		return TRUE;
	}

	for (i = 0; spell_table[i].name != NULL; i++)
	{
		if (!str_cmp(argument, spell_table[i].name))
		{
			pSkill->spell_fun = spell_table[i].fun;
			chprintlnf(ch, "%s now uses spell function '%s'.", pSkill->name,
					   spell_table[i].name);
			return TRUE;
		}
	}

	chprintln(ch, "That spell function hasn't been coded into the mud.");
	return FALSE;
}

SKEDIT(skedit_gsn)
{
	SKILL_DATA *pSkill;
	int i;

	EDIT_SKILL(ch, pSkill);

	if (IS_NULLSTR(argument))
	{
		chprintln(ch, "Syntax: gsn <gsn-name>");
		return FALSE;
	}

	if (is_name(argument, "clear reset none"))
	{
		pSkill->pgsn = &gsn_null;
		chprintln(ch, "GSN Entry cleared.");
		return TRUE;
	}

	for (i = 0; gsn_table[i].name != NULL; i++)
	{
		if (!str_cmp(argument, gsn_table[i].name))
		{
			pSkill->pgsn = gsn_table[i].pgsn;
			chprintlnf(ch, "%s now uses global skill pointer '%s'.",
					   pSkill->name, gsn_table[i].name);
			return TRUE;
		}
	}

	chprintln(ch, "That GSN hasn't been coded in yet.");
	return FALSE;
}

SKEDIT(skedit_delete)
{
	SKILL_DATA *pSkill;

	EDIT_SKILL(ch, pSkill);

	if (str_cmp(argument, "confirm"))
	{
		chprintln
			(ch, "Typing 'delete confirm' will permanetely remove this skill!");
		return FALSE;
	}
	else

	{
		int i, j = 0, c;
		struct skill_type *new_table;

		alloc_mem(new_table, struct skill_type, maxSkill);

		if (!new_table)
		{
			chprintln(ch, "Memory Allocation error!!! Unable to delete skill.");
			return FALSE;
		}

		c = skill_lookup(pSkill->name);

		for (i = 0; i < maxSkill; i++)
			if (i != c)
				new_table[j++] = skill_table[i];

		free_mem(skill_table);
		skill_table = new_table;
		maxSkill--;

		pSkill = &skill_table[0];
		edit_start(ch, pSkill, ED_SKILL);
		chprintln(ch, "Skill deleted.");
	}

	return TRUE;
}