1stMUD/corefiles/
1stMUD/gods/
1stMUD/notes/
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"
#include "recycle.h"

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

RAEDIT(raedit_create)
{
	RACE_DATA *pRace;
	char buf[MIL];

	if (!IS_NULLSTR(argument) && race_lookup(argument) == NULL)
		sprintf(buf, argument);
	else
		sprintf(buf, "New Race%d", maxRace + 1);

	pRace = new_race();
	replace_string(pRace->name, buf);
	LINK(pRace, race_first, race_last, next, prev);
	edit_start(ch, pRace, ED_RACE);
	chprintln(ch, "Race created.");
	return TRUE;
}

RAEDIT(raedit_list)
{
	RACE_DATA *i;
	int count = 0;

	chprintln(ch, "Num  Race Name\n\r"
			  "-----------------------------------------------");

	for (i = race_first; i; i = i->next)
	{
		if (!IS_NULLSTR(i->name))
		{
			count++;
			chprintlnf(ch, "[%2d]  %-30s", count, i->name);
		}
	}

	chprintln(ch, "\n\r-----------------------------------------------");

	return FALSE;
}

RAEDIT(raedit_show)
{
	RACE_DATA *pRace;
	int x;

	EDIT_RACE(ch, pRace);

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

	chprintlnf(ch, "Name:\t[%s] Who Name: [%s] PC Race: [%s]", pRace->name,
			   pRace->who_name, pRace->pc_race == 0 ? "{WNO{w" : "{RYES{w");

	chprintlnf(ch, "Act:\t[%s]", flag_string(act_flags, pRace->act));
	chprintlnf(ch, "Aff:\t[%s]", flag_string(affect_flags, pRace->aff));
	chprintlnf(ch, "Off:\t[%s]", flag_string(off_flags, pRace->off));

	chprintlnf(ch, "Imm:\t[%s]", flag_string(imm_flags, pRace->imm));

	chprintlnf(ch, "Res:\t[%s]", flag_string(res_flags, pRace->res));

	chprintlnf(ch, "Vuln:\t[%s]", flag_string(vuln_flags, pRace->vuln));

	chprintlnf(ch, "Form:\t[%s]", flag_string(form_flags, pRace->form));

	chprintlnf(ch, "Parts:\t[%s]", flag_string(part_flags, pRace->parts));

	chprintlnf(ch, "Points:\t[%d]", pRace->points);

	chprint(ch, "ClassX:\t");

	for (x = 0; x < maxClass; x++)
	{
		chprintf(ch, "%s [%d] ", class_table[x].name, pRace->class_mult[x]);
	}
	chprintln(ch, "");

	chprint(ch, "Skills:\t");

	for (x = 0; x < 5; x++)
	{
		if (pRace->skills[x] && skill_lookup(pRace->skills[x]) > -1)
		{
			chprintf(ch, "[%s] ", pRace->skills[x]);
		}
	}
	chprintln(ch, "");

	chprintlnf
		(ch, "Stats\tSTR[%d] INT[%d] WIS[%d] DEX[%d] CON[%d]",
		 pRace->stats[STAT_STR], pRace->stats[STAT_INT],
		 pRace->stats[STAT_WIS], pRace->stats[STAT_DEX],
		 pRace->stats[STAT_CON]);

	chprintlnf
		(ch, "MStats\tSTR[%d] INT[%d] WIS[%d] DEX[%d] CON[%d]",
		 pRace->max_stats[STAT_STR], pRace->max_stats[STAT_INT],
		 pRace->max_stats[STAT_WIS], pRace->max_stats[STAT_DEX],
		 pRace->max_stats[STAT_CON]);

	chprintlnf(ch, "Size:\t[%s]", flag_string(size_flags, pRace->size));

	chprintln(ch, draw_line(ch, NULL, 0));
	return FALSE;
}

RAEDIT(raedit_classx)
{

	char clas[MSL];
	char value[MSL];
	RACE_DATA *pRace;

	EDIT_RACE(ch, pRace);

	if (!pRace->pc_race)
	{
		chprintln(ch, "Race must be a PC race first.");
		return FALSE;
	}

	if (!IS_NULLSTR(argument))
	{

		argument = one_argument(argument, clas);
		argument = one_argument(argument, value);

		if (class_lookup(clas) < 0)
		{
			chprintln(ch, "That class does not exist.");
			return FALSE;
		}

		if (!is_number(value))
		{
			chprintln(ch, "Second argument must be numeric.");
			return FALSE;
		}

		if (atoi(value) < 75)
		{
			chprintln(ch, "{RWARNING!{x Class modifier should be at least 75.");
		}
		pRace->class_mult[class_lookup(clas)] = atoi(value);
		chprintlnf(ch, "Race modifier for class %s is set to %d.", clas,
				   atoi(value));
		return TRUE;
	}

	chprintln(ch, "Syntax: classx class value");
	return FALSE;
}

RAEDIT(raedit_skills)
{

	int x;
	RACE_DATA *pRace;

	EDIT_RACE(ch, pRace);

	if (!pRace->pc_race)
	{
		chprintln(ch, "Race must be a PC race first.");
		return FALSE;
	}

	if (skill_lookup(argument) != -1)
	{
		if (pRace->skills[0] != NULL && pRace->skills[1] != NULL
			&& pRace->skills[2] != NULL && pRace->skills[3] != NULL
			&& pRace->skills[4] != NULL && pRace->skills[5] != NULL)
		{
			chprintln(ch, "No avaliable slot for the skill");
			return FALSE;
		}

		for (x = 0; x < 5; x++)
		{
			if (!str_cmp(pRace->skills[x], argument))
			{
				pRace->skills[x] = NULL;
				chprintlnf(ch, "Skill %s deleted.", argument);
				return TRUE;
			}
			if (pRace->skills[x] == NULL)
			{
				replace_string(pRace->skills[x], argument);
				chprintlnf(ch, "Skill %s set.", argument);
				return TRUE;
			}
		}
	}
	chprintln(ch, "Syntax: skills skill");
	return FALSE;

}

RAEDIT(raedit_stats)
{
	char str[MSL];
	char inte[MSL];
	char wis[MSL];
	char dex[MSL];
	char con[MSL];
	RACE_DATA *pRace;

	EDIT_RACE(ch, pRace);

	if (!pRace->pc_race)
	{
		chprintln(ch, "Race must be a PC race first.");
		return FALSE;
	}

	if (!IS_NULLSTR(argument))
	{

		argument = one_argument(argument, str);
		argument = one_argument(argument, inte);
		argument = one_argument(argument, wis);
		argument = one_argument(argument, dex);
		argument = one_argument(argument, con);

		if (!str || !is_number(str))
		{
			chprintln(ch, "Syntax: stats str int wis dex con.");
			return FALSE;
		}

		if (!inte || !is_number(inte))
		{
			chprintln(ch, "Syntax: stats str int wis dex con.");
			return FALSE;
		}
		if (!wis || !is_number(wis))
		{
			chprintln(ch, "Syntax: stats str int wis dex con.");
			return FALSE;
		}
		if (!dex || !is_number(dex))
		{
			chprintln(ch, "Syntax: stats str int wis dex con.");
			return FALSE;
		}
		if (!con || !is_number(con))
		{
			chprintln(ch, "Syntax: stats str int wis dex con.");
			return FALSE;
		}

		pRace->stats[STAT_STR] = atoi(str);
		pRace->stats[STAT_INT] = atoi(inte);
		pRace->stats[STAT_WIS] = atoi(wis);
		pRace->stats[STAT_DEX] = atoi(dex);
		pRace->stats[STAT_CON] = atoi(con);
		chprintlnf
			(ch, "Stats set to: str[%d] int[%d] wis[%d] dex[%d] con[%d]",
			 atoi(str), atoi(inte), atoi(wis), atoi(dex), atoi(con));
		return TRUE;
	}
	chprintln(ch, "Syntax: stats str int wis dex con.");
	return FALSE;
}

RAEDIT(raedit_mstats)
{
	char str[MSL];
	char inte[MSL];
	char wis[MSL];
	char dex[MSL];
	char con[MSL];
	RACE_DATA *pRace;

	EDIT_RACE(ch, pRace);

	if (!pRace->pc_race)
	{
		chprintln(ch, "Race must be a PC race first.");
		return FALSE;
	}

	if (!IS_NULLSTR(argument))
	{

		argument = one_argument(argument, str);
		argument = one_argument(argument, inte);
		argument = one_argument(argument, wis);
		argument = one_argument(argument, dex);
		argument = one_argument(argument, con);

		if (!str || !is_number(str))
		{
			chprintln(ch, "Syntax: stats str int wis dex con.");
			return FALSE;
		}

		if (!inte || !is_number(inte))
		{
			chprintln(ch, "Syntax: stats str int wis dex con.");
			return FALSE;
		}
		if (!wis || !is_number(wis))
		{
			chprintln(ch, "Syntax: stats str int wis dex con.");
			return FALSE;
		}
		if (!dex || !is_number(dex))
		{
			chprintln(ch, "Syntax: stats str int wis dex con.");
			return FALSE;
		}
		if (!con || !is_number(con))
		{
			chprintln(ch, "Syntax: stats str int wis dex con.");
			return FALSE;
		}

		pRace->max_stats[STAT_STR] = atoi(str);
		pRace->max_stats[STAT_INT] = atoi(inte);
		pRace->max_stats[STAT_WIS] = atoi(wis);
		pRace->max_stats[STAT_DEX] = atoi(dex);
		pRace->max_stats[STAT_CON] = atoi(con);
		chprintlnf
			(ch, "Max Stats set to: str[%d] int[%d] wis[%d] dex[%d] con[%d]",
			 atoi(str), atoi(inte), atoi(wis), atoi(dex), atoi(con));
		return TRUE;
	}
	chprintln(ch, "Syntax: mstats str int wis dex con.");
	return FALSE;
}

RAEDIT(raedit_delete)
{
	RACE_DATA *pRace;
	CHAR_DATA *rch;
	MOB_INDEX_DATA *mch;
	int ihash;

	EDIT_RACE(ch, pRace);

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

	{
		for (ihash = 0; ihash < MAX_KEY_HASH; ihash++)
		{
			for (mch = mob_index_hash[ihash]; mch; mch = mch->next)
			{
				if (mch->race == pRace)
				{
					mch->race = race_lookup("unique");
					SET_BIT(mch->area->area_flags, AREA_CHANGED);
				}
			}
		}

		for (rch = char_first; rch != NULL; rch = rch->next)
		{
			if (rch->race == pRace)
			{
				if (IS_NPC(rch))
					rch->race = race_lookup("unique");
				else
					rch->race = race_lookup("human");
			}
		}

		UNLINK(pRace, race_first, race_last, next, prev);
		free_race(pRace);
		pRace = race_first;
		edit_start(ch, pRace, ED_RACE);
		chprintln(ch, "Race deleted.");
	}

	return TRUE;
}

RAEDIT(raedit_name)
{
	RACE_DATA *pRace;
	MOB_INDEX_DATA *pMob;
	int ihash;
	char arg[MIL];

	EDIT_RACE(ch, pRace);

	first_arg(argument, arg, FALSE);

	if (IS_NULLSTR(arg))
	{
		chprintln(ch, "Change name to what?");
		return FALSE;
	}

	if (race_lookup(arg) != NULL)
	{
		chprintln(ch, "A race with that name already exists.");
		return FALSE;
	}

	if (str_cmp(arg, pRace->name))
	{
		for (ihash = 0; ihash < MAX_KEY_HASH; ihash++)
		{
			for (pMob = mob_index_hash[ihash]; pMob; pMob = pMob->next)
			{
				if (pMob->race == pRace)
					SET_BIT(pMob->area->area_flags, AREA_CHANGED);
			}
		}
	}
	replace_string(pRace->name, arg);
	chprintln(ch, "Name set.");
	return TRUE;
}