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 "interp.h"
#include "tables.h"

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

CLEDIT(cledit_create)
{
	int j, i = maxClass;
	int x = 0;
	CLASS_DATA *pClass;
	struct class_type *new_table;
	char buf[MIL];

	if (!IS_NULLSTR(argument) && class_lookup(argument) == -1)
		sprintf(buf, argument);
	else
		sprintf(buf, "New Class%d", maxClass + 1);

	maxClass++;

	alloc_mem(new_table, struct class_type, maxClass);

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

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

	for (x = 0; x < maxSkill; x++)
	{
		realloc_mem(skill_table[x].rating, int, maxClass);
		skill_table[x].rating[i] = 0;
		realloc_mem(skill_table[x].skill_level, int, maxClass);
		skill_table[x].skill_level[i] = ANGEL;
	}

	for (x = 0; x < maxRace; x++)
	{
		realloc_mem(race_table[x].class_mult, int, maxClass);
		race_table[x].class_mult[i] = 100;
	}

	for (x = 0; x < maxGroup; x++)
	{
		realloc_mem(group_table[x].rating, int, maxClass);
		group_table[x].rating[i] = 0;
	}

	free_mem(class_table);
	class_table = new_table;

	class_table[i].name = str_dup(buf);
	class_table[i].who_name = str_dup("");
	pClass = &class_table[i];
	edit_start(ch, pClass, ED_CLASS);
	chprintln(ch, "Class created.");
	return TRUE;
}

CLEDIT(cledit_delete)
{
	CLASS_DATA *pClass;

	EDIT_CLASS(ch, pClass);

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

	{
		int i, j = 0, c;
		struct class_type *new_table;
		CHAR_DATA *pch;
		int iClass;
		bool invalid;

		alloc_mem(new_table, struct class_type, maxClass);

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

		c = class_lookup(pClass->name);

		for (pch = player_first; pch != NULL; pch = pch->next_player)
		{
			invalid = FALSE;

			for (iClass = 0; iClass < MAX_MCLASS; iClass++)
			{
				if (invalid)
				{
					pch->Class[iClass - 1] = pch->Class[iClass];
					pch->Class[iClass] = -1;
					continue;
				}
				if (pch->Class[iClass] == c)
				{
					pch->Class[iClass] = -1;
					invalid = TRUE;
				}
			}
		}
		for (i = 0; i < maxClass; i++)
			if (i != c)
				new_table[j++] = class_table[i];

		free_mem(class_table);
		class_table = new_table;
		maxClass--;

		for (i = 0; i < maxSkill; i++)
		{
			realloc_mem(skill_table[i].rating, int, maxClass);
			realloc_mem(skill_table[i].skill_level, int, maxClass);
		}

		for (i = 0; i < maxGroup; i++)
			realloc_mem(group_table[i].rating, int, maxClass);

		for (i = 0; i < maxRace; i++)
			realloc_mem(race_table[i].class_mult, int, maxClass);

		pClass = &class_table[0];
		edit_start(ch, pClass, ED_CLASS);
		chprintln(ch, "Class deleted.");
	}

	return TRUE;
}

char *stat_name(int stat)
{
	switch (stat)
	{
	case STAT_STR:
		return "strength";
	case STAT_INT:
		return "intelligence";
	case STAT_WIS:
		return "wisdom";
	case STAT_DEX:
		return "dexterity";
	case STAT_CON:
		return "consitution";
	default:
		return "unknown";
	}
}

CLEDIT(cledit_show)
{
	CLASS_DATA *pClass;
	int i;

	EDIT_CLASS(ch, pClass);

	chprintln(ch, draw_line(NULL, 0));
	chprintlnf(ch, "Name           : %s", pClass->name);
	chprintlnf(ch, "Who Name       : %s", pClass->who_name);
	chprintlnf(ch, "Prime Attribute: %s", stat_name(pClass->attr_prime));
	chprintlnf(ch, "Weapon Vnum    : %ld", pClass->weapon);
	chprintlnf(ch, "Skill Adept    : %d", pClass->skill_adept);
	chprint(ch, "Guild          : ");
	for (i = 0; i < MAX_GUILD; i++)
		chprintf(ch, "%ld ", pClass->guild[i]);
	chprintln(ch, "");
	chprintlnf(ch, "Thac00         : %d", pClass->thac0_00);
	chprintlnf(ch, "Thac32         : %d", pClass->thac0_32);
	chprintlnf(ch, "HP Min         : %d", pClass->hp_min);
	chprintlnf(ch, "HP Max         : %d", pClass->hp_max);
	chprintlnf(ch, "Uses spells    : %s", pClass->fMana ? "TRUE" : "FALSE");
	chprintlnf(ch, "Base Group     : %s", pClass->base_group);
	chprintlnf(ch, "Default Group  : %s", pClass->default_group);
	chprintln(ch, draw_line(NULL, 0));
	return TRUE;
}

VALIDATE_FUN(validate_whoname)
{
	if (strlen((const char *) arg) != 3)
	{
		chprintln(ch, "Please limit who name to 3 characters.");
		return FALSE;
	}
	return TRUE;
}

CLEDIT(cledit_prime)
{
	CLASS_DATA *pClass;
	char arg[MIL];
	int stat;

	EDIT_CLASS(ch, pClass);
	one_argument(argument, arg);

	if (IS_NULLSTR(arg))
	{
		chprintln(ch, "Syntax: cledit prime [str|int|wiz|dex|con]");
		return FALSE;
	}

	if (!str_cmp(arg, "str"))
		stat = STAT_STR;
	else if (!str_cmp(arg, "int"))
		stat = STAT_INT;
	else if (!str_cmp(arg, "wis"))
		stat = STAT_WIS;
	else if (!str_cmp(arg, "dex"))
		stat = STAT_DEX;
	else if (!str_cmp(arg, "con"))
		stat = STAT_CON;
	else
	{
		chprintln(ch, "Syntax: cledit prime [str|int|wiz|dex|con]");
		return FALSE;
	}

	pClass->attr_prime = stat;
	chprintln(ch, "Prime attribute changed.");
	return TRUE;
}

VALIDATE_FUN(validate_weapon)
{
	OBJ_INDEX_DATA *obj;

	if ((obj = get_obj_index(*(vnum_t *) arg)) == NULL)
	{
		chprintln(ch, "Invalid vnum.");
		return FALSE;
	}

	if (obj->item_type != ITEM_WEAPON)
	{
		chprintln(ch, "Thats not a vnum of a weapon.");
		return FALSE;
	}
	return TRUE;
}

VALIDATE_FUN(validate_adept)
{
	int value = *(int *) arg;

	if (value < 20 || value > 90)
	{
		chprintln(ch, "Please choose a value between 20 & 90");
		return FALSE;
	}

	return TRUE;
}

VALIDATE_FUN(validate_hmv)
{
	int *value = (int *) arg;

	if (*value < 1 || *value > 100)
	{
		chprintln(ch, "Please choose a value from 1-100.");
		return FALSE;
	}
	return TRUE;
}

VALIDATE_FUN(validate_group)
{
	int g;

	g = group_lookup((const char *) arg);

	if (g < 0 || g >= maxGroup)
	{
		chprintln(ch, "That group doesn't exist");
		return FALSE;
	}
	return TRUE;
}

CLEDIT(cledit_skill)
{
	int sn;
	CLASS_DATA *pClass;
	int Class;
	int value;
	bool pLevel;
	char arg1[MIL], arg2[MIL], arg3[MIL];

	EDIT_CLASS(ch, pClass);

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

	if (IS_NULLSTR(arg1) || IS_NULLSTR(arg2) || IS_NULLSTR(arg3))
	{
		chprintln(ch, "Syntax: cledit skill <skill> rating|level <value>");
		return FALSE;
	}

	if ((sn = skill_lookup(arg1)) < 0 || sn >= maxSkill)
	{
		chprintln(ch, "Thats not a valid skill.");
		return FALSE;
	}

	if (!str_cmp(arg2, "rating"))
		pLevel = FALSE;
	else if (!str_cmp(arg2, "level"))
		pLevel = TRUE;
	else
	{
		chprintln(ch, "Please choose either a skill 'rating' or 'level'.");
		return FALSE;
	}

	value = atoi(arg3);
	if (pLevel && (value < 1 || value > MAX_LEVEL))
	{
		chprintlnf(ch, "Please choose a level between 1 and %d.", MAX_LEVEL);
		return FALSE;
	}

	Class = class_lookup(pClass->name);

	if (pLevel)
	{
		skill_table[sn].skill_level[Class] = value;
		chprintln(ch, "Class skill level set.");
	}
	else
	{
		skill_table[sn].rating[Class] = value;
		chprintln(ch, "Class rating set.");
	}
	return TRUE;
}

VALIDATE_FUN(validate_classname)
{
	if (class_lookup((const char *) arg) != -1)
	{
		chprintln(ch, "A class with that name already exits.");
		return FALSE;
	}
	return TRUE;
}

CLEDIT(cledit_guilds)
{
	int slot;
	vnum_t guild;
	CLASS_DATA *pClass;
	char arg[MIL];

	EDIT_CLASS(ch, pClass);

	argument = one_argument(argument, arg);

	if (IS_NULLSTR(arg) || IS_NULLSTR(argument))
	{
		chprintln(ch, "Syntax: guild <slot> <room vnum>");
		return FALSE;
	}

	slot = atoi(arg);

	if (slot < 1 || slot > MAX_GUILD)
	{
		chprintlnf(ch, "Valid slots are 1 - %d.", MAX_GUILD);
		return FALSE;
	}

	guild = atol(argument);

	if (get_room_index(guild) == NULL)
	{
		chprintln(ch, "That is not a valid room vnum.");
		return FALSE;
	}

	pClass->guild[slot] = guild;
	chprintln(ch, "Guild set.");
	return TRUE;
}