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

#define MPEDIT( fun )           bool fun(CHAR_DATA *ch, const char*argument)
#define OPEDIT( fun )           bool fun(CHAR_DATA *ch, const char*argument)
#define RPEDIT( fun )           bool fun(CHAR_DATA *ch, const char*argument)

void unlink_mprog(vnum_t pnum)
{
	PROG_LIST *list, *list_next;
	MOB_INDEX_DATA *pMob;
	vnum_t vnum = 0;
	int nMatch = 0, count;

	for (vnum = 0; nMatch < top_mob_index; vnum++)
	{
		if ((pMob = get_mob_index(vnum)) == NULL)
			continue;

		nMatch++;
		count = -1;
		for (list = pMob->first_mprog; list != NULL; list = list_next)
		{
			list_next = list->next;
			count++;

			if (list->vnum != pnum)
				continue;

			REMOVE_BIT(pMob->mprog_flags, list->trig_type);
			UNLINK(list, pMob->first_mprog, pMob->last_mprog, next, prev);
			free_prog(list);
		}
	}
}

void unlink_oprog(vnum_t pnum)
{
	PROG_LIST *list, *list_next;
	OBJ_INDEX_DATA *pObj;
	vnum_t vnum = 0;
	int nMatch = 0, count;

	for (vnum = 0; nMatch < top_obj_index; vnum++)
	{
		if ((pObj = get_obj_index(vnum)) == NULL)
			continue;

		nMatch++;
		count = -1;
		for (list = pObj->first_oprog; list != NULL; list = list_next)
		{
			list_next = list->next;
			count++;

			if (list->vnum != pnum)
				continue;

			REMOVE_BIT(pObj->oprog_flags, list->trig_type);
			UNLINK(list, pObj->first_oprog, pObj->last_oprog, next, prev);
			free_prog(list);
		}
	}
}

void unlink_rprog(vnum_t pnum)
{
	PROG_LIST *list, *list_next;
	ROOM_INDEX_DATA *pRoom;
	vnum_t vnum = 0;
	int nMatch = 0, count;

	for (vnum = 0; nMatch < top_room; vnum++)
	{
		if ((pRoom = get_room_index(vnum)) == NULL)
			continue;

		nMatch++;
		count = -1;
		for (list = pRoom->first_rprog; list != NULL; list = list_next)
		{
			list_next = list->next;
			count++;

			if (list->vnum != pnum)
				continue;

			REMOVE_BIT(pRoom->rprog_flags, list->trig_type);
			UNLINK(list, pRoom->first_rprog, pRoom->last_rprog, next, prev);
			free_prog(list);
		}
	}
}

void mpedit(CHAR_DATA * ch, char *argument)
{
	PROG_CODE *pMcode;
	AREA_DATA *ad;

	EDIT_MPCODE(ch, pMcode);

	if (pMcode)
	{
		ad = get_vnum_area(pMcode->vnum);

		if (ad == NULL)

		{
			edit_done(ch);
			return;
		}

		if (!IS_BUILDER(ch, ad))
		{
			chprintln(ch, "MPEdit: Insufficient security to modify code.");
			edit_done(ch);
			return;
		}
	}

	if (emptystring(argument))
	{
		mpedit_show(ch, argument);
		return;
	}

	if (!str_cmp(argument, "done"))
	{
		edit_done(ch);
		return;
	}

	if (!process_olc_command(ch, argument, mprog_olc_comm_table))
		interpret(ch, argument);

	return;
}

void opedit(CHAR_DATA * ch, char *argument)
{
	PROG_CODE *pOcode;
	AREA_DATA *ad;

	EDIT_OPCODE(ch, pOcode);

	if (pOcode)
	{
		ad = get_vnum_area(pOcode->vnum);

		if (ad == NULL)

		{
			edit_done(ch);
			return;
		}

		if (!IS_BUILDER(ch, ad))
		{
			chprintln(ch, "OPEdit: Insufficient security to modify code.");
			edit_done(ch);
			return;
		}
	}

	if (emptystring(argument))
	{
		opedit_show(ch, argument);
		return;
	}

	if (!str_cmp(argument, "done"))
	{
		edit_done(ch);
		return;
	}

	if (!process_olc_command(ch, argument, oprog_olc_comm_table))
		interpret(ch, argument);

	return;
}

void rpedit(CHAR_DATA * ch, char *argument)
{
	PROG_CODE *pRcode;
	AREA_DATA *ad;

	EDIT_RPCODE(ch, pRcode);

	if (pRcode)
	{
		ad = get_vnum_area(pRcode->vnum);

		if (ad == NULL)

		{
			edit_done(ch);
			return;
		}

		if (!IS_BUILDER(ch, ad))
		{
			chprintln(ch, "RPEdit: Insufficient security to modify code.");
			edit_done(ch);
			return;
		}
	}

	if (emptystring(argument))
	{
		rpedit_show(ch, argument);
		return;
	}

	if (!str_cmp(argument, "done"))
	{
		edit_done(ch);
		return;
	}

	if (!process_olc_command(ch, argument, rprog_olc_comm_table))
		interpret(ch, argument);

	return;
}

CH_CMD(do_mpedit)
{
	PROG_CODE *pMcode;
	char command[MIL];

	argument = one_argument(argument, command);

	if (is_number(command))
	{
		vnum_t vnum = atol(command);
		AREA_DATA *ad;

		if ((pMcode = get_prog_index(vnum, PRG_MPROG)) == NULL)
		{
			chprintln(ch, "MPEdit : That vnum does not exist.");
			return;
		}

		ad = get_vnum_area(vnum);

		if (ad == NULL)
		{
			chprintln(ch, "MPEdit : Vnum is not assigned an area.");
			return;
		}

		if (!IS_BUILDER(ch, ad))
		{
			chprintln(ch, "MPEdit : Insufficient security to modify area.");
			return;
		}

		edit_start(ch, pMcode, ED_MPCODE);
		return;
	}

	if (!str_cmp(command, "create"))
	{
		if (IS_NULLSTR(argument))
		{
			chprintln(ch, "Syntax : mpedit create [vnum]");
			return;
		}

		mpedit_create(ch, argument);
		return;
	}
	if (!str_cmp(command, "delete"))
	{
		if (IS_NULLSTR(argument))
		{
			chprintln(ch, "Syntax: mpedit delete [vnum]");
			return;
		}
		mpedit_delete(ch, argument);
		return;
	}
	chprintln(ch, "Syntax : mpedit [vnum]");
	chprintln(ch, "         mpedit create [vnum]");
	chprintln(ch, "         mpedit delete [vnum]");

	return;
}

CH_CMD(do_opedit)
{
	PROG_CODE *pOcode;
	char command[MIL];

	argument = one_argument(argument, command);

	if (is_number(command))
	{
		vnum_t vnum = atol(command);
		AREA_DATA *ad;

		if ((pOcode = get_prog_index(vnum, PRG_OPROG)) == NULL)
		{
			chprintln(ch, "OPEdit : That vnum does not exist.");
			return;
		}

		ad = get_vnum_area(vnum);

		if (ad == NULL)
		{
			chprintln(ch, "OPEdit : Vnum is not assigned an area.");
			return;
		}

		if (!IS_BUILDER(ch, ad))
		{
			chprintln(ch, "OPEdit : Insufficient security to modify area.");
			return;
		}

		edit_start(ch, pOcode, ED_OPCODE);
		return;
	}

	if (!str_cmp(command, "create"))
	{
		if (IS_NULLSTR(argument))
		{
			chprintln(ch, "Syntax : opedit create [vnum]");
			return;
		}

		opedit_create(ch, argument);
		return;
	}
	if (!str_cmp(command, "delete"))
	{
		if (IS_NULLSTR(argument))
		{
			chprintln(ch, "Syntax: opedit delete [vnum]");
			return;
		}
		opedit_delete(ch, argument);
		return;
	}

	chprintln(ch, "Syntax : opedit [vnum]");
	chprintln(ch, "         opedit create [vnum]");
	chprintln(ch, "         opedit delete [vnum]");

	return;
}

CH_CMD(do_rpedit)
{
	PROG_CODE *pRcode;
	char command[MIL];

	argument = one_argument(argument, command);

	if (is_number(command))
	{
		vnum_t vnum = atol(command);
		AREA_DATA *ad;

		if ((pRcode = get_prog_index(vnum, PRG_RPROG)) == NULL)
		{
			chprintln(ch, "RPEdit : That vnum does not exist.");
			return;
		}

		ad = get_vnum_area(vnum);

		if (ad == NULL)
		{
			chprintln(ch, "RPEdit : Vnum is not assigned an area.");
			return;
		}

		if (!IS_BUILDER(ch, ad))
		{
			chprintln(ch, "RPEdit : Insufficient security to modify area.");
			return;
		}

		edit_start(ch, pRcode, ED_RPCODE);
		return;
	}

	if (!str_cmp(command, "create"))
	{
		if (IS_NULLSTR(argument))
		{
			chprintln(ch, "Syntax : rpedit create [vnum]");
			return;
		}

		rpedit_create(ch, argument);
		return;
	}
	if (!str_cmp(command, "delete"))
	{
		if (IS_NULLSTR(argument))
		{
			chprintln(ch, "Syntax: rpedit delete [vnum]");
			return;
		}
		rpedit_delete(ch, argument);
		return;
	}

	chprintln(ch, "Syntax : rpedit [vnum]");
	chprintln(ch, "         rpedit create [vnum]");
	chprintln(ch, "         rpedit delete [vnum]");

	return;
}

MPEDIT(mpedit_create)
{
	PROG_CODE *pMcode;
	vnum_t value = atol(argument);
	AREA_DATA *ad;

	if (IS_NULLSTR(argument) || value < 1)
	{
		chprintln(ch, "Syntax : mpedit create [vnum]");
		return FALSE;
	}

	ad = get_vnum_area(value);

	if (ad == NULL)
	{
		chprintln(ch, "MPEdit : Vnum is not assigned an area.");
		return FALSE;
	}

	if (!IS_BUILDER(ch, ad))
	{
		chprintln(ch, "MPEdit : Insufficient security to create MobProgs.");
		return FALSE;
	}

	if (get_prog_index(value, PRG_MPROG))
	{
		chprintln(ch, "MPEdit: Code vnum already exists.");
		return FALSE;
	}

	pMcode = new_pcode();
	pMcode->vnum = value;
	LINK(pMcode, mprog_first, mprog_last, next, prev);
	edit_start(ch, pMcode, ED_MPCODE);
	chprintln(ch, "MobProgram Code Created.");

	return TRUE;
}

MPEDIT(mpedit_delete)
{
	PROG_CODE *curr, *next;
	vnum_t value = atol(argument);
	AREA_DATA *ad;

	if (IS_NULLSTR(argument) || value < 1)
	{
		if (ch)
			chprintln(ch, "Syntax : mpedit create [vnum]");
		return FALSE;
	}

	if (get_prog_index(value, PRG_MPROG) == NULL)
	{
		if (ch)
			chprintln(ch, "MPEdit : Mob program not found.");
		return FALSE;
	}

	ad = get_vnum_area(value);
	if (ad == NULL)
	{
		if (ch)
			chprintln(ch, "MPEdit : Mob program not assigned to an area.");
		return FALSE;
	}

	if (ch && !IS_BUILDER(ch, ad))
	{
		chprintln(ch, "MPEdit : Insufficient security to create MobProgs.");
		return FALSE;
	}

	unlink_mprog(value);
	for (curr = mprog_first; curr != NULL; curr = next)
	{
		next = curr->next;

		if (curr->vnum != value)
			continue;

		UNLINK(curr, mprog_first, mprog_last, next, prev);

		free_pcode(curr);
	}
	SET_BIT(ad->area_flags, AREA_CHANGED);
	if (ch)
		chprintln(ch, "MobProgram Code Deleted.");

	return TRUE;
}

OPEDIT(opedit_create)
{
	PROG_CODE *pOcode;
	vnum_t value = atol(argument);
	AREA_DATA *ad;

	if (IS_NULLSTR(argument) || value < 1)
	{
		chprintln(ch, "Syntax : opedit create [vnum]");
		return FALSE;
	}

	ad = get_vnum_area(value);

	if (ad == NULL)
	{
		chprintln(ch, "OPEdit : Vnum is not assigned an area.");
		return FALSE;
	}

	if (!IS_BUILDER(ch, ad))
	{
		chprintln(ch, "OPEdit : Insufficient security to create ObjProgs.");
		return FALSE;
	}

	if (get_prog_index(value, PRG_OPROG))
	{
		chprintln(ch, "OPEdit: Code vnum already exists.");
		return FALSE;
	}

	pOcode = new_pcode();
	pOcode->vnum = value;
	LINK(pOcode, oprog_first, oprog_last, next, prev);
	edit_start(ch, pOcode, ED_OPCODE);
	chprintln(ch, "ObjProgram Code Created.");

	return TRUE;
}

OPEDIT(opedit_delete)
{
	PROG_CODE *curr, *next;
	vnum_t value = atol(argument);
	AREA_DATA *ad;

	if (IS_NULLSTR(argument) || value < 1)
	{
		if (ch)
			chprintln(ch, "Syntax : opedit create [vnum]");
		return FALSE;
	}

	if (get_prog_index(value, PRG_OPROG) == NULL)
	{
		if (ch)
			chprintln(ch, "OPEdit : Obj program not found.");
		return FALSE;
	}

	ad = get_vnum_area(value);
	if (ad == NULL)
	{
		if (ch)
			chprintln(ch, "OPEdit : Obj program not assigned to an area.");
		return FALSE;
	}

	if (ch && !IS_BUILDER(ch, ad))
	{
		chprintln(ch, "OPEdit : Insufficient security to create ObjProgs.");
		return FALSE;
	}

	unlink_oprog(value);
	for (curr = oprog_first; curr != NULL; curr = next)
	{
		next = curr->next;

		if (curr->vnum != value)
			continue;

		UNLINK(curr, oprog_first, oprog_last, next, prev);

		free_pcode(curr);
	}
	SET_BIT(ad->area_flags, AREA_CHANGED);
	if (ch)
		chprintln(ch, "Obj Program Code Deleted.");

	return TRUE;
}

RPEDIT(rpedit_create)
{
	PROG_CODE *pRcode;
	vnum_t value = atol(argument);
	AREA_DATA *ad;

	if (IS_NULLSTR(argument) || value < 1)
	{
		chprintln(ch, "Syntax : rpedit create [vnum]");
		return FALSE;
	}

	ad = get_vnum_area(value);

	if (ad == NULL)
	{
		chprintln(ch, "RPEdit : Vnum is not assigned an area.");
		return FALSE;
	}

	if (!IS_BUILDER(ch, ad))
	{
		chprintln(ch, "RPEdit : Insufficient security to create RoomProgs.");
		return FALSE;
	}

	if (get_prog_index(value, PRG_RPROG))
	{
		chprintln(ch, "RPEdit: Code vnum already exists.");
		return FALSE;
	}

	pRcode = new_pcode();
	pRcode->vnum = value;
	LINK(pRcode, rprog_first, rprog_last, next, prev);
	edit_start(ch, pRcode, ED_RPCODE);
	chprintln(ch, "RoomProgram Code Created.");

	return TRUE;
}

RPEDIT(rpedit_delete)
{
	PROG_CODE *curr, *next;
	vnum_t value = atol(argument);
	AREA_DATA *ad;

	if (IS_NULLSTR(argument) || value < 1)
	{
		if (ch)
			chprintln(ch, "Syntax : rpedit create [vnum]");
		return FALSE;
	}

	if (get_prog_index(value, PRG_RPROG) == NULL)
	{
		if (ch)
			chprintln(ch, "RPEdit : Room program not found.");
		return FALSE;
	}

	ad = get_vnum_area(value);
	if (ad == NULL)
	{
		if (ch)
			chprintln(ch, "RPEdit : Room program not assigned to an area.");
		return FALSE;
	}

	if (ch && !IS_BUILDER(ch, ad))
	{
		chprintln(ch, "RPEdit : Insufficient security to create RoomProgs.");
		return FALSE;
	}

	unlink_rprog(value);
	for (curr = rprog_first; curr != NULL; curr = next)
	{
		next = curr->next;

		if (curr->vnum != value)
			continue;
		UNLINK(curr, rprog_first, rprog_last, next, prev);

		free_pcode(curr);
	}
	SET_BIT(ad->area_flags, AREA_CHANGED);
	if (ch)
		chprintln(ch, "Room Program Code Deleted.");

	return TRUE;
}

MPEDIT(mpedit_show)
{
	PROG_CODE *pMcode;
	BUFFER *buffer;
	char buf[MSL];

	EDIT_MPCODE(ch, pMcode);

	buffer = new_buf();

	add_buf(buffer, draw_line(ch, NULL, 0));
	add_buf(buffer, "\n\r");
	sprintf(buf, "Vnum:       [%ld]\n\r"
			"Code:\n\r%s", pMcode->vnum, pMcode->code);
	add_buf(buffer, buf);
	add_buf(buffer, draw_line(ch, NULL, 0));
	add_buf(buffer, "\n\r");
	page_to_char(buf_string(buffer), ch);
	free_buf(buffer);
	return FALSE;
}

OPEDIT(opedit_show)
{
	PROG_CODE *pOcode;
	BUFFER *buffer;
	char buf[MSL];

	EDIT_OPCODE(ch, pOcode);

	buffer = new_buf();

	add_buf(buffer, draw_line(ch, NULL, 0));
	add_buf(buffer, "\n\r");
	sprintf(buf, "Vnum:       [%ld]\n\r"
			"Code:\n\r%s", pOcode->vnum, pOcode->code);
	add_buf(buffer, buf);
	add_buf(buffer, draw_line(ch, NULL, 0));
	add_buf(buffer, "\n\r");
	page_to_char(buf_string(buffer), ch);
	free_buf(buffer);
	return FALSE;
}

RPEDIT(rpedit_show)
{
	PROG_CODE *pRcode;
	BUFFER *buffer;
	char buf[MSL];

	EDIT_RPCODE(ch, pRcode);

	buffer = new_buf();
	add_buf(buffer, draw_line(ch, NULL, 0));
	add_buf(buffer, "\n\r");
	sprintf(buf, "Vnum:       [%ld]\n\r"
			"Code:\n\r%s", pRcode->vnum, pRcode->code);
	add_buf(buffer, buf);
	add_buf(buffer, draw_line(ch, NULL, 0));
	add_buf(buffer, "\n\r");
	page_to_char(buf_string(buffer), ch);
	free_buf(buffer);
	return FALSE;
}

MPEDIT(mpedit_list)
{
	int count = 1;
	PROG_CODE *mprg;
	BUFFER *buffer;
	char buf[MSL];
	bool fAll = !str_cmp(argument, "all");
	char blah;
	AREA_DATA *ad;

	buffer = new_buf();

	for (mprg = mprog_first; mprg != NULL; mprg = mprg->next)
		if (fAll
			|| ENTRE(ch->in_room->area->min_vnum - 1, mprg->vnum,
					 ch->in_room->area->max_vnum + 1))
		{
			ad = get_vnum_area(mprg->vnum);

			if (ad == NULL)
				blah = '?';
			else if (IS_BUILDER(ch, ad))
				blah = '*';
			else
				blah = ' ';

			sprintf(buf, "[%3d] (%c) %5ld", count, blah, mprg->vnum);
			add_buf(buffer, buf);

			count++;
		}

	if (count == 1)
	{
		if (fAll)
			add_buf(buffer, "No existing MobPrograms.");
		else
			add_buf(buffer, "No existing MobPrograms in this area.");
	}

	page_to_char(buf_string(buffer), ch);
	free_buf(buffer);

	return FALSE;
}

OPEDIT(opedit_list)
{
	int count = 1;
	PROG_CODE *oprg;
	BUFFER *buffer;
	char buf[MSL];
	bool fAll = !str_cmp(argument, "all");
	char blah;
	AREA_DATA *ad;

	buffer = new_buf();

	for (oprg = oprog_first; oprg != NULL; oprg = oprg->next)
		if (fAll
			|| ENTRE(ch->in_room->area->min_vnum - 1, oprg->vnum,
					 ch->in_room->area->max_vnum + 1))
		{
			ad = get_vnum_area(oprg->vnum);

			if (ad == NULL)
				blah = '?';
			else if (IS_BUILDER(ch, ad))
				blah = '*';
			else
				blah = ' ';

			sprintf(buf, "[%3d] (%c) %5ld", count, blah, oprg->vnum);
			add_buf(buffer, buf);

			count++;
		}

	if (count == 1)
	{
		if (fAll)
			add_buf(buffer, "No existing ObjPrograms.");
		else
			add_buf(buffer, "No existing ObjPrograms in this area.");
	}

	page_to_char(buf_string(buffer), ch);
	free_buf(buffer);

	return FALSE;
}

RPEDIT(rpedit_list)
{
	int count = 1;
	PROG_CODE *rprg;
	BUFFER *buffer;
	char buf[MSL];
	bool fAll = !str_cmp(argument, "all");
	char blah;
	AREA_DATA *ad;

	buffer = new_buf();

	for (rprg = rprog_first; rprg != NULL; rprg = rprg->next)
		if (fAll
			|| ENTRE(ch->in_room->area->min_vnum - 1, rprg->vnum,
					 ch->in_room->area->max_vnum + 1))
		{
			ad = get_vnum_area(rprg->vnum);

			if (ad == NULL)
				blah = '?';
			else if (IS_BUILDER(ch, ad))
				blah = '*';
			else
				blah = ' ';

			sprintf(buf, "[%3d] (%c) %5ld\n\r", count, blah, rprg->vnum);
			add_buf(buffer, buf);
			count++;
		}

	if (count == 1)
	{
		if (fAll)
			add_buf(buffer, "No existing RoomPrograms.");
		else
			add_buf(buffer, "No existing RoomPrograms in this area.");
	}

	page_to_char(buf_string(buffer), ch);
	free_buf(buffer);

	return FALSE;
}