muddy/
muddy/CVS/
muddy/area/
muddy/area/CVS/
muddy/clans/CVS/
muddy/classes/CVS/
muddy/doc/
muddy/doc/CVS/
muddy/etc/CVS/
muddy/etc/i3/
muddy/etc/i3/CVS/
muddy/imc/CVS/
muddy/lang/CVS/
muddy/licenses/CVS/
muddy/msgdb/CVS/
muddy/new/CVS/
muddy/notes/
muddy/player/
muddy/races/CVS/
muddy/religions/CVS/
muddy/src/CVS/
muddy/src/comm/CVS/
muddy/src/db/CVS/
muddy/src/intermud/
muddy/src/intermud/CVS/
muddy/src/irc/CVS/
muddy/src/olc/CVS/
/* $Id: olc_mob.c,v 1.666 2004/09/20 10:50:30 shrike Exp $ */

/************************************************************************************
 *    Copyright 2004 Astrum Metaphora consortium                                    *
 *                                                                                  *
 *    Licensed under the Apache License, Version 2.0 (the "License");               *
 *    you may not use this file except in compliance with the License.              *
 *    You may obtain a copy of the License at                                       *
 *                                                                                  *
 *    http://www.apache.org/licenses/LICENSE-2.0                                    *
 *                                                                                  *
 *    Unless required by applicable law or agreed to in writing, software           *
 *    distributed under the License is distributed on an "AS IS" BASIS,             *
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.      *
 *    See the License for the specific language governing permissions and           *
 *    limitations under the License.                                                *
 *                                                                                  *
 ************************************************************************************/
/************************************************************************************
 *     ANATOLIA 2.1 is copyright 1996-1997 Serdar BULUT, Ibrahim CANPUNAR           *
 *     ANATOLIA has been brought to you by ANATOLIA consortium                      *
 *       Serdar BULUT {Chronos}         bulut@rorqual.cc.metu.edu.tr                *
 *       Ibrahim Canpunar  {Asena}      canpunar@rorqual.cc.metu.edu.tr             *
 *       Murat BICER  {KIO}             mbicer@rorqual.cc.metu.edu.tr               *
 *       D.Baris ACAR {Powerman}        dbacar@rorqual.cc.metu.edu.tr               *
 *     By using this code, you have agreed to follow the terms of the               *
 *     ANATOLIA license, in the file Anatolia/anatolia.licence                      *
 ***********************************************************************************/

/************************************************************************************
 *  Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,                 *
 *  Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe.            *
 *                                                                                  *
 *  Merc Diku Mud improvments 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                   *
 *  benefitting.  We hope that you share your changes too.  What goes               *
 *  around, comes around.                                                           *
 ************************************************************************************/

/************************************************************************************
*       ROM 2.4 is copyright 1993-1995 Russ Taylor                                  *
*       ROM has been brought to you by the ROM consortium                           *
*           Russ Taylor (rtaylor@pacinfo.com)                                       *
*           Gabrielle Taylor (gtaylor@pacinfo.com)                                  *
*           Brian Moore (rom@rom.efn.org)                                           *
*       By using this code, you have agreed to follow the terms of the              *
*       ROM license, in the file Rom24/doc/rom.license                              *
*************************************************************************************/

/************************************************************************************
 * Copyright (c) 1998 fjoe <fjoe@iclub.nsu.ru>                                      *
 * All rights reserved.                                                             *
 *                                                                                  *
 * Redistribution and use in source and binary forms, with or without               *
 * modification, are permitted provided that the following conditions               *
 * are met:                                                                         *
 * 1. Redistributions of source code must retain the above copyright                *
 *    notice, this list of conditions and the following disclaimer.                 *
 * 2. Redistributions in binary form must reproduce the above copyright             *
 *    notice, this list of conditions and the following disclaimer in the           *
 *    documentation and/or other materials provided with the distribution.          *
 *                                                                                  *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND           *
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE            *
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE       *
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE          *
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL       *
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS          *
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)            *
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT       *
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY        *
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF           *
 * SUCH DAMAGE.                                                                     *
 ************************************************************************************/
 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "merc.h"
#include "olc.h"
#include "db/db.h"

#define EDIT_MOB(ch, mob)	(mob = (MOB_INDEX_DATA*) ch->desc->pEdit)

/*
 * Mobile Editor Prototypes
 */
DECLARE_OLC_FUN(mobed_create		);
DECLARE_OLC_FUN(mobed_edit		);
DECLARE_OLC_FUN(mobed_touch		);
DECLARE_OLC_FUN(mobed_show		);
DECLARE_OLC_FUN(mobed_list		);

DECLARE_OLC_FUN(mobed_name		);
DECLARE_OLC_FUN(mobed_short		);
DECLARE_OLC_FUN(mobed_long		);
DECLARE_OLC_FUN(mobed_shop		);
DECLARE_OLC_FUN(mobed_desc		);
DECLARE_OLC_FUN(mobed_level		);
DECLARE_OLC_FUN(mobed_align		);
DECLARE_OLC_FUN(mobed_spec		);

DECLARE_OLC_FUN(mobed_sex		);  /* ROM */
DECLARE_OLC_FUN(mobed_act		);  /* ROM */
DECLARE_OLC_FUN(mobed_affect		);  /* ROM */
DECLARE_OLC_FUN(mobed_ac		);  /* ROM */
DECLARE_OLC_FUN(mobed_form		);  /* ROM */
DECLARE_OLC_FUN(mobed_part		);  /* ROM */
DECLARE_OLC_FUN(mobed_imm		);  /* ROM */
DECLARE_OLC_FUN(mobed_res		);  
//DECLARE_OLC_FUN(mobed_vuln		);  /* ROM */
DECLARE_OLC_FUN(mobed_material		);  /* ROM */
DECLARE_OLC_FUN(mobed_off		);  /* ROM */
DECLARE_OLC_FUN(mobed_size		);  /* ROM */
DECLARE_OLC_FUN(mobed_hitdice		);  /* ROM */
DECLARE_OLC_FUN(mobed_manadice		);  /* ROM */
DECLARE_OLC_FUN(mobed_damdice		);  /* ROM */
DECLARE_OLC_FUN(mobed_race		);  /* ROM */
DECLARE_OLC_FUN(mobed_startpos		);  /* ROM */
DECLARE_OLC_FUN(mobed_defaultpos	);  /* ROM */
DECLARE_OLC_FUN(mobed_gold		);  /* ROM */
DECLARE_OLC_FUN(mobed_hitroll		);  /* ROM */
DECLARE_OLC_FUN(mobed_damtype		);  /* ROM */
DECLARE_OLC_FUN(mobed_group		);  /* ROM */
DECLARE_OLC_FUN(mobed_trigadd		);  /* ROM */
DECLARE_OLC_FUN(mobed_trigdel		);  /* ROM */
DECLARE_OLC_FUN(mobed_prac		); 
DECLARE_OLC_FUN(mobed_clan		);
DECLARE_OLC_FUN(mobed_clone		);
DECLARE_OLC_FUN(mobed_invis		);
DECLARE_OLC_FUN(mobed_listendata);
DECLARE_OLC_FUN(mobed_autostat);
//DECLARE_OLC_FUN(mobed_fvnum	);

//DECLARE_VALIDATE_FUN(validate_fvnum	);

olc_cmd_t olc_cmds_mob[] =
{
/*	{ command	    function		args        		}, */
	{ "create",	    mobed_create,	  5  				},
	{ "edit",	    mobed_edit,	      0			        },
	{ "touch",	    mobed_touch, 	  0		        	},
	{ "show",	    mobed_show,	      0	        		},
	{ "list",	    mobed_list,	      0  				},

	{ "alignment",	mobed_align,	  5			        },
	{ "desc",	    mobed_desc,	      0		        	},
	{ "level",	    mobed_level,	  5	        		},
	{ "long",	    mobed_long,	      0  				},
	{ "name",	    mobed_name,	      0				    },
	{ "shop",	    mobed_shop,	      5			    	},
	{ "short",	    mobed_short,	  0		    		},
	{ "spec",	    mobed_spec,	      5	    			},

	{ "sex",	    mobed_sex,	      0, sex_table	    },
	{ "act",	    mobed_act,	      5, act_flags	    },
	{ "affect",	    mobed_affect,	  5, affect_flags	},
	{ "prac",	    mobed_prac,	      5, skill_groups	},
	{ "armor",	    mobed_ac,	      5				    },
	{ "form",	    mobed_form,	      0, form_flags	    },
	{ "part",       mobed_part,	      5, part_flags	    },
	{ "imm",	    mobed_imm,	      5, imm_flags	    },
	{ "res",	    mobed_res,	      5, dam_flags	    },
/*	{ "vuln",	    mobed_vuln,	      5, vuln_flags	    },*/
	{ "material",	mobed_material,	  5				    },
	{ "off",	    mobed_off,	      5, off_flags	    },
	{ "size",	    mobed_size,	      0			        },
	{ "hitdice",	mobed_hitdice,	  5		        	},
	{ "manadice",	mobed_manadice,	  5  				},
	{ "damdice",	mobed_damdice,	  5			        },
	{ "race",	    mobed_race,	0			        	},
	{ "startpos",	mobed_startpos,	  5, position_table	},
	{ "defaultpos",	mobed_defaultpos, 5, position_table	},
	{ "wealth",	    mobed_gold,	      5			    	},
	{ "hitroll",	mobed_hitroll,	  5	        		},
	{ "damtype",	mobed_damtype,	  5		        	},
	{ "group",	    mobed_group,	  5			        },
	{ "clan",	    mobed_clan,	      5			        },
	{ "trigadd",	mobed_trigadd,	  5	    			},
	{ "trigdel",	mobed_trigdel,	  5		    		},
	{ "clone",      mobed_clone,	  5			    	},
	{ "invis",	    mobed_invis,	  5				    },
    { "listendata", mobed_listendata, 0                 },
//	{ "fvnum",  mobed_fvnum,	5,       validate_fvnum  },
    { "autostat", mobed_autostat,     5                 },

	{ "commands",	show_commands,	  0  				},
	{ "version",	show_version,	  0	        		},

	{ NULL }
};

static void show_spec_cmds(CHAR_DATA *ch);

OLC_FUN(mobed_create)
{
	MOB_INDEX_DATA *pMob;
	AREA_DATA *pArea;
	int  value;
	int  iHash;
	char arg[MAX_STRING_LENGTH];

	one_argument(argument, arg, sizeof(arg));
	value = atoi(arg);
	if (!value) {
		do_help(ch, "'OLC CREATE'");
		return FALSE;
	}

	pArea = area_vnum_lookup(value);
	if (!pArea) {
		char_puts("MobEd: That vnum is not assigned an area.\n", ch);
		return FALSE;
	}

	if (!IS_BUILDER(ch, pArea)) {
		char_puts("MobEd: Insufficient security.\n", ch);
		return FALSE;
	}

	if (get_mob_index(value)) {
		char_puts("MobEd: Mobile vnum already exists.\n", ch);
		return FALSE;
	}

	pMob			= new_mob_index();
	pMob->vnum		= value;
		 
	if (value > top_vnum_mob)
		top_vnum_mob = value;        

	pMob->act		= ACT_NPC;
	iHash			= value % MAX_KEY_HASH;
	pMob->next		= mob_index_hash[iHash];
	mob_index_hash[iHash]	= pMob;

	ch->desc->pEdit		= (void *)pMob;
	OLCED(ch)   = olced_lookup(ED_MOB);
	touch_area(pArea);
	char_puts("MobEd: Mobile created.\n", ch);
	return FALSE;
}

OLC_FUN(mobed_edit)
{
	MOB_INDEX_DATA *pMob;
	AREA_DATA *pArea;
	int value;
	char arg[MAX_INPUT_LENGTH];

	one_argument(argument, arg, sizeof(arg));
	if (arg[0] == '\0') {
		do_help(ch, "'OLC EDIT'");
		return FALSE;
	}

	value = atoi(arg);
	if ((pMob = get_mob_index(value)) == NULL) {
		char_puts("MobEd: Vnum does not exist.\n", ch);
		return FALSE;
	}

	pArea = area_vnum_lookup(pMob->vnum);
	if (!IS_BUILDER(ch, pArea)) {
		char_puts("MobEd: Insufficient security.\n", ch);
	       	return FALSE;
	}

	ch->desc->pEdit = (void*) pMob;
	OLCED(ch)   = olced_lookup(ED_MOB);
	return FALSE;
}

OLC_FUN(mobed_touch)
{
	MOB_INDEX_DATA *pMob;
	EDIT_MOB(ch, pMob);
	return touch_vnum(pMob->vnum);
}

OLC_FUN(mobed_show)
{
	char arg[MAX_INPUT_LENGTH];
	MOB_INDEX_DATA	*pMob;
	AREA_DATA	*pArea;
	MPTRIG *mptrig;
	BUFFER *buf;
	clan_t *clan;
	race_t *race;
	int i;

	one_argument(argument, arg, sizeof(arg));
	if (arg[0] == '\0') {
		if (IS_EDIT(ch, ED_MOB))
			EDIT_MOB(ch, pMob);
		else {
			do_help(ch, "'OLC ASHOW'");
			return FALSE;
		}
	}
	else {
		int value = atoi(arg);
		if ((pMob = get_mob_index(value)) == NULL) 
        {
			char_puts("MobEd: Vnum does not exist.\n", ch);
			return FALSE;
		}
	}

	pArea = area_vnum_lookup(pMob->vnum);

	if (!IS_BUILDER(ch, pArea)) {
		char_puts("MobEd: Insufficient security.\n", ch);
	       	return FALSE;
	}

	buf = buf_new(-1);

	buf_printf(buf, "Name:        [%s]\nArea:        [%5d] %s\n",
		pMob->name, pArea->vnum, pArea->name);

	buf_printf(buf, "Act:         [%s]\n",
		flag_string(act_flags, pMob->act));

	buf_printf(buf, "Vnum:        [%5d] Sex:   [%s]   Race: [%s]\n",
		pMob->vnum,
		flag_string(sex_table, pMob->sex),
		race_name(pMob->race));

	if (pMob->clan && (clan = clan_lookup(pMob->clan))) 
		buf_printf(buf, "Clan:        [%s]\n", clan->name);

	buf_printf(buf, "Level:       [%2d]    Align: [%4d]      Hitroll: [%2d] Dam Type:    [%s]\n",
		pMob->level,	pMob->alignment,
		pMob->hitroll,	attack_table[pMob->dam_type].name);

	if (pMob->group)
		buf_printf(buf, "Group:       [%5d]\n", pMob->group);

	buf_printf(buf, "Hit dice:    [%2dd%-3d+%4d] ",
			 pMob->hit[DICE_NUMBER],
			 pMob->hit[DICE_TYPE],
			 pMob->hit[DICE_BONUS]);

	buf_printf(buf, "Damage dice: [%2dd%-3d+%4d] ",
			 pMob->damage[DICE_NUMBER],
			 pMob->damage[DICE_TYPE],
			 pMob->damage[DICE_BONUS]);

	buf_printf(buf, "Mana dice:   [%2dd%-3d+%4d]\n",
			 pMob->mana[DICE_NUMBER],
			 pMob->mana[DICE_TYPE],
			 pMob->mana[DICE_BONUS]);

/* ROM values end */

	buf_printf(buf, "Affected by: [%s]\n",
		flag_string(affect_flags, pMob->affected_by));

/* ROM values: */

	buf_printf(buf, "Armor:       [pierce: %d  bash: %d  slash: %d  magic: %d]\n",
		pMob->ac[AC_PIERCE], pMob->ac[AC_BASH],
		pMob->ac[AC_SLASH], pMob->ac[AC_EXOTIC]);

	buf_printf(buf, "Form:        [%s]\n",
		flag_string(form_flags, pMob->form));

	buf_printf(buf, "Parts:       [%s]\n",
		flag_string(part_flags, pMob->parts));

	buf_printf(buf, "Immunes:     [%s]\n",
		flag_string(imm_flags, pMob->immunes));

	if ((race = race_lookup(pMob->race)) != NULL)
	{
		if (race->immunes &~ pMob->immunes)
		    buf_printf(buf, "    and:     [%s]\n",
				flag_string(imm_flags, race->immunes &~ pMob->immunes));
		if (race->immunes & pMob->immunes)
			buf_printf(buf, "(common:     [%s])\n",
				flag_string(imm_flags, race->immunes & pMob->immunes));
	}	
	
	for (i = 0; i < MAX_DAM; i++)
	    if (pMob->resists[i])
		buf_printf(buf, "Res:         [%-16.16s:%4d%%]\n",
		    flag_string(dam_flags, i), pMob->resists[i]);

	buf_printf(buf, "Off:         [%s]\n",
		flag_string(off_flags,  pMob->off_flags));

	buf_printf(buf, "Size:        [%d]\n", pMob->size);

	buf_printf(buf, "Material:    [%s]\n",
		 pMob->material);

	buf_printf(buf, "Start pos:   [%s]\n",
		flag_string(position_table, pMob->start_pos));

	buf_printf(buf, "Default pos: [%s]\n",
		flag_string(position_table, pMob->default_pos));

	buf_printf(buf, "Wealth:      [%5d]\n", pMob->wealth);

	if (pMob->invis_level)
		buf_printf(buf, "Invis level: [%d]\n", pMob->invis_level);

//	if (pMob->fvnum)
//		buf_printf(buf, "Female vnum: [%d]\n", pMob->fvnum);
		
/* ROM values end */

	if (pMob->spec_fun)
		buf_printf(buf, "Spec fun:    [%s]\n",  spec_name(pMob->spec_fun));
	if (pMob->practicer)
		buf_printf(buf, "Practicer:   [%s]\n",
			flag_string(skill_groups, pMob->practicer));

	mlstr_dump(buf, "Short descr: ", pMob->short_descr);
	mlstr_dump(buf, "Long descr: ", pMob->long_descr);
	mlstr_dump(buf, "Description: ", pMob->description);
    mlstr_dump(buf, "Listen data: ", pMob->listen_data); 

	if (pMob->pShop) {
		SHOP_DATA *pShop;
		int iTrade;

		pShop = pMob->pShop;

		buf_printf(buf, "Shop data for [%5d]:\n"
				"  Markup for purchaser: %d%%\n"
				"  Markdown for seller:  %d%%\n",
			pShop->keeper, pShop->profit_buy, pShop->profit_sell);
		buf_printf(buf, "  Hours: %d to %d.\n",
			pShop->open_hour, pShop->close_hour);

		for (iTrade = 0; iTrade < MAX_TRADE; iTrade++) 
        {
			if (pShop->buy_type[iTrade] != 0) {
			if (iTrade == 0) {
				buf_add(buf, "  Number Trades Type\n");
				buf_add(buf, "  ------ -----------\n");
			}
			buf_printf(buf, "  [%4d] %s\n", iTrade,
				flag_string(item_types, pShop->buy_type[iTrade]));
			}
		}
	}

	if (pMob->mptrig_list) 
    {
		int cnt = 0;

		buf_printf(buf, "\nMOBPrograms for [%5d]:\n", pMob->vnum);

		for (mptrig = pMob->mptrig_list; mptrig; mptrig = mptrig->next) 
        {
			if (cnt ==0) {
				buf_add(buf, " Number Vnum Trigger Phrase [Flags]\n");
				buf_add(buf, " ------ ---- ------- ----------------------------------------------------------\n");
			}

			buf_printf(buf, "[%5d] %4d %7s %s [%s]\n", cnt,
			mptrig->vnum, flag_string(mptrig_types, mptrig->type),
			mptrig->phrase,
			flag_string(mptrig_flags, mptrig->flags));
			cnt++;
		}
	}

	page_to_char(buf_string(buf), ch);
	buf_free(buf);

	return FALSE;
}

OLC_FUN(mobed_list)
{
	MOB_INDEX_DATA	*pMobIndex;
	AREA_DATA	*pArea;
	BUFFER		*buffer;
	char		arg  [MAX_INPUT_LENGTH];
	bool fAll, found;
	int vnum;
	int  col = 0;

	one_argument(argument, arg, sizeof(arg));
	if (arg[0] == '\0') {
		do_help(ch, "'OLC ALIST'");
		return FALSE;
	}

	if ((pArea = get_edited_area(ch)) == NULL)
		pArea = ch->in_room->area;

	if (!IS_BUILDER(ch, pArea)) {
		char_puts("MobEd: Insufficient security.\n", ch);
	       	return FALSE;
	}
	
	buffer = buf_new(-1);
	fAll    = !str_cmp(arg, "all");
	found   = FALSE;

	for (vnum = pArea->min_vnum; vnum <= pArea->max_vnum; vnum++) {
		if ((pMobIndex = get_mob_index(vnum)) != NULL) {
			if (fAll || is_name(arg, pMobIndex->name)) {
				found = TRUE;
				buf_printf(buffer, "{x[%5d] %s {x",
					   pMobIndex->vnum,
					   fmt_color_str(mlstr_mval(pMobIndex->short_descr), 16));
				if (++col % 3 == 0)
					buf_add(buffer, "\n");
			}
		}
	}

	if (!found) 
		char_puts("MobEd: No mobiles in this area.\n", ch);
	else {
		if (col % 3 != 0)
			buf_add(buffer, "\n");

		page_to_char(buf_string(buffer), ch);
	}

	buf_free(buffer);
	return FALSE;
}

OLC_FUN(mobed_spec)
{
	MOB_INDEX_DATA *pMob;
	EDIT_MOB(ch, pMob);

	if (argument[0] == '\0') {
		char_puts("Syntax:  spec [special function]\n", ch);
		return FALSE;
	}

	if (!str_cmp(argument, "?")) {
		show_spec_cmds(ch);
		return FALSE;
	}

	if (!str_cmp(argument, "none")) {
		 pMob->spec_fun = NULL;

		 char_puts("Spec removed.\n", ch);
		 return TRUE;
	}

	if (spec_lookup(argument)) {
		pMob->spec_fun = spec_lookup(argument);
		char_puts("Spec set.\n", ch);
		return TRUE;
	}

	char_puts("MobEd: No such special function.\n", ch);
	return FALSE;
}

OLC_FUN(mobed_damtype)
{
	char arg[MAX_INPUT_LENGTH];
	int dt;
	MOB_INDEX_DATA *pMob;
	EDIT_MOB(ch, pMob);

	one_argument(argument, arg, sizeof(arg));
	if (arg[0] == '\0') {
		char_puts("Syntax: damtype [damage message]\n", ch);
		char_puts("Syntax: damtype ?\n", ch);
		return FALSE;
	}

	if (!str_cmp(arg, "?")) {
		BUFFER *output = buf_new(-1);
		show_attack_types(output);
		page_to_char(buf_string(output), ch);
		buf_free(output);
		return FALSE;
	}

	if ((dt = attack_lookup(arg)) < 0) {
		char_printf(ch, "MobEd: %s: unknown damtype.\n", arg);
		return FALSE;
	}

	pMob->dam_type = dt;
	char_puts("Damage type set.\n", ch);
	return TRUE;
}

OLC_FUN(mobed_align)
{
	MOB_INDEX_DATA *pMob;
	EDIT_MOB(ch, pMob);
	return olced_number(ch, argument, cmd, &pMob->alignment);
}

OLC_FUN(mobed_level)
{
	MOB_INDEX_DATA *pMob;
	EDIT_MOB(ch, pMob);
	return olced_number(ch, argument, cmd, &pMob->level);
}

OLC_FUN(mobed_desc)
{
	MOB_INDEX_DATA *pMob;
	EDIT_MOB(ch, pMob);
	return olced_mlstr_text(ch, argument, cmd, &pMob->description);
}

OLC_FUN(mobed_long)
{
	MOB_INDEX_DATA *pMob;
	EDIT_MOB(ch, pMob);
	return olced_mlstrnl(ch, argument, cmd, &pMob->long_descr);
}

OLC_FUN(mobed_short)
{
	MOB_INDEX_DATA *pMob;
	EDIT_MOB(ch, pMob);
	return olced_mlstr(ch, argument, cmd, &pMob->short_descr);
}

OLC_FUN(mobed_name)
{
	MOB_INDEX_DATA *pMob;
	EDIT_MOB(ch, pMob);
	return olced_name(ch, argument, cmd, &pMob->name);
}

OLC_FUN(mobed_shop)
{
	MOB_INDEX_DATA *pMob;
	char command[MAX_INPUT_LENGTH];
	char arg1[MAX_INPUT_LENGTH];

	argument = one_argument(argument, command, sizeof(command));
	argument = one_argument(argument, arg1, sizeof(arg1));

	EDIT_MOB(ch, pMob);

	if (command[0] == '\0')
	{
		char_puts("Syntax:  shop hours [#xopening] [#xclosing]\n", ch);
		char_puts("         shop profit [#xbuying%] [#xselling%]\n", ch);
		char_puts("         shop type [#x0-4] [item type]\n", ch);
		char_puts("         shop assign\n", ch);
		char_puts("         shop remove\n", ch);
		return FALSE;
	}


	if (!str_cmp(command, "hours"))
	{
		if (arg1[0] == '\0' || !is_number(arg1)
		|| argument[0] == '\0' || !is_number(argument))
		{
			char_puts("Syntax:  shop hours [#xopening] [#xclosing]\n", ch);
			return FALSE;
		}

		if (!pMob->pShop)
		{
			char_puts("MobEd:  Debes crear un shop primero (shop assign).\n", ch);
			return FALSE;
		}

		pMob->pShop->open_hour = atoi(arg1);
		pMob->pShop->close_hour = atoi(argument);

		char_puts("Shop hours set.\n", ch);
		return TRUE;
	}


	if (!str_cmp(command, "profit"))
	{
		if (arg1[0] == '\0' || !is_number(arg1)
		|| argument[0] == '\0' || !is_number(argument))
		{
			char_puts("Syntax:  shop profit [#xbuying%] [#xselling%]\n", ch);
			return FALSE;
		}

		if (!pMob->pShop)
		{
			char_puts("MobEd:  Debes crear un shop primero (shop assign).\n", ch);
			return FALSE;
		}

		pMob->pShop->profit_buy     = atoi(arg1);
		pMob->pShop->profit_sell    = atoi(argument);

		char_puts("Shop profit set.\n", ch);
		return TRUE;
	}


	if (!str_cmp(command, "type"))
	{
		int value;

		if (arg1[0] == '\0' || !is_number(arg1)
		|| argument[0] == '\0')
		{
			char_puts("Syntax:  shop type [#x0-4] [item type]\n", ch);
			return FALSE;
		}

		if (atoi(arg1) >= MAX_TRADE)
		{
			char_printf(ch, "MobEd:  May sell %d items max.\n", MAX_TRADE);
			return FALSE;
		}

		if (!pMob->pShop)
		{
			char_puts("MobEd:  Debes crear un shop primero (shop assign).\n", ch);
			return FALSE;
		}

		if ((value = flag_value(item_types, argument)) == 0)
		{
			char_puts("MobEd:  That type of item is not known.\n", ch);
			return FALSE;
		}

		pMob->pShop->buy_type[atoi(arg1)] = value;

		char_puts("Shop type set.\n", ch);
		return TRUE;
	}

	/* shop assign && shop delete by Phoenix */

	if (!str_prefix(command, "assign"))
	{
		if (pMob->pShop)
		{
		 	char_puts("Mob already has a shop assigned to it.\n", ch);
		 	return FALSE;
		}

		pMob->pShop		= new_shop();
		if (!shop_first)
		 	shop_first	= pMob->pShop;
		if (shop_last)
			shop_last->next	= pMob->pShop;
		shop_last		= pMob->pShop;

		pMob->pShop->keeper	= pMob->vnum;

		char_puts("New shop assigned to mobile.\n", ch);
		return TRUE;
	}

	if (!str_prefix(command, "remove"))
	{
		SHOP_DATA *pShop;

		pShop		= pMob->pShop;
		pMob->pShop	= NULL;

		if (pShop == shop_first)
		{
			if (!pShop->next)
			{
			shop_first = NULL;
			shop_last = NULL;
			}
			else
			shop_first = pShop->next;
		}
		else
		{
			SHOP_DATA *ipShop;

			for (ipShop = shop_first; ipShop; ipShop = ipShop->next)
			{
			if (ipShop->next == pShop)
			{
				if (!pShop->next)
				{
					shop_last = ipShop;
					shop_last->next = NULL;
				}
				else
					ipShop->next = pShop->next;
			}
			}
		}

		free_shop(pShop);

		char_puts("Mobile is no longer a shopkeeper.\n", ch);
		return TRUE;
	}

	mobed_shop(ch, str_empty, cmd);
	return FALSE;
}

OLC_FUN(mobed_sex)
{
	MOB_INDEX_DATA *pMob;
	EDIT_MOB(ch, pMob);
	return olced_flag64(ch, argument, cmd, &pMob->sex);
}

OLC_FUN(mobed_act)
{
	MOB_INDEX_DATA *pMob;
	EDIT_MOB(ch, pMob);
	return olced_flag64(ch, argument, cmd, &pMob->act);
}

OLC_FUN(mobed_affect)
{
	MOB_INDEX_DATA *pMob;
	EDIT_MOB(ch, pMob);
	return olced_flag64(ch, argument, cmd, &pMob->affected_by);
}

OLC_FUN(mobed_prac) 
{
	MOB_INDEX_DATA *pMob;
	EDIT_MOB(ch, pMob);
	return olced_flag64(ch, argument, cmd, &pMob->practicer);
}

OLC_FUN(mobed_ac)
{
	MOB_INDEX_DATA *pMob;
	char arg[MAX_INPUT_LENGTH];
	int pierce, bash, slash, exotic;

	do   /* So that I can use break and send the syntax in one place */
	{
		if (argument[0] == '\0')  break;

		EDIT_MOB(ch, pMob);
		argument = one_argument(argument, arg, sizeof(arg));

		if (!is_number(arg))  break;
		pierce = atoi(arg);
		argument = one_argument(argument, arg, sizeof(arg));

		if (arg[0] != '\0')
		{
			if (!is_number(arg))  break;
			bash = atoi(arg);
			argument = one_argument(argument, arg, sizeof(arg));
		}
		else
			bash = pMob->ac[AC_BASH];

		if (arg[0] != '\0')
		{
			if (!is_number(arg))  break;
			slash = atoi(arg);
			argument = one_argument(argument, arg, sizeof(arg));
		}
		else
			slash = pMob->ac[AC_SLASH];

		if (arg[0] != '\0')
		{
			if (!is_number(arg))  break;
			exotic = atoi(arg);
		}
		else
			exotic = pMob->ac[AC_EXOTIC];

		pMob->ac[AC_PIERCE] = pierce;
		pMob->ac[AC_BASH]   = bash;
		pMob->ac[AC_SLASH]  = slash;
		pMob->ac[AC_EXOTIC] = exotic;
		
		char_puts("Ac set.\n", ch);
		return TRUE;
	} while (FALSE);    /* Just do it once.. */

	char_puts("Syntax:  ac [ac-pierce [ac-bash [ac-slash [ac-exotic]]]]\n"
			  "help MOB_AC  gives a list of reasonable ac-values.\n", ch);
	return FALSE;
}

OLC_FUN(mobed_form)
{
	MOB_INDEX_DATA *pMob;
	EDIT_MOB(ch, pMob);
	return olced_flag64(ch, argument, cmd, &pMob->form);
}

OLC_FUN(mobed_part)
{
	MOB_INDEX_DATA *pMob;
	EDIT_MOB(ch, pMob);
	return olced_flag64(ch, argument, cmd, &pMob->parts);
}

OLC_FUN(mobed_imm)
{
	MOB_INDEX_DATA *pMob;
	EDIT_MOB(ch, pMob);
	return olced_flag64(ch, argument, cmd, &pMob->immunes);
}

OLC_FUN(mobed_res)
{
    MOB_INDEX_DATA *pMob;
    int dam_type;
    char arg[MAX_INPUT_LENGTH];
    
    EDIT_MOB(ch, pMob);
    argument = one_argument(argument, arg, MAX_INPUT_LENGTH);
    
    if (olced_flag32(ch, arg, cmd, &dam_type) && is_number(argument))
    {
		pMob->resists[dam_type] = atoi(argument);
		return TRUE;
    }
    
    return FALSE;
}

OLC_FUN(mobed_material)
{
	MOB_INDEX_DATA *pMob;
	EDIT_MOB(ch, pMob);
	return olced_str(ch, argument, cmd, &pMob->material);
}

OLC_FUN(mobed_off)
{
	MOB_INDEX_DATA *pMob;
	EDIT_MOB(ch, pMob);
	return olced_flag64(ch, argument, cmd, &pMob->off_flags);
}

OLC_FUN(mobed_size)
{
	MOB_INDEX_DATA *pMob;
	EDIT_MOB(ch, pMob);
	return olced_number(ch, argument, cmd, &pMob->size);
}

OLC_FUN(mobed_hitdice)
{
	MOB_INDEX_DATA *pMob;
	EDIT_MOB(ch, pMob);
	return olced_dice(ch, argument, cmd, pMob->hit);
}

OLC_FUN(mobed_manadice)
{
	MOB_INDEX_DATA *pMob;
	EDIT_MOB(ch, pMob);
	return olced_dice(ch, argument, cmd, pMob->mana);
}

OLC_FUN(mobed_damdice)
{
	MOB_INDEX_DATA *pMob;
	EDIT_MOB(ch, pMob);
	return olced_dice(ch, argument, cmd, pMob->damage);
}

OLC_FUN(mobed_race)
{
	MOB_INDEX_DATA *pMob;
	int race = 0;

	if (argument[0] != '\0' &&  (!str_prefix(argument, "unique") || (race = rn_lookup(argument)))) 
	{
		race_t *r;
		EDIT_MOB(ch, pMob);

		pMob->race = race;
		r = RACE(race);
		pMob->act	  |= r->act;
		pMob->affected_by |= r->aff;
		pMob->off_flags   |= r->off;
		pMob->form        |= r->form;
		pMob->parts       |= r->parts;

		char_puts("Race set.\n", ch);
		return TRUE;
	}

	if (argument[0] == '?') {
		char_puts("Available races are:", ch);

		for (race = 0; race < races.nused; race++) 
		{
			if ((race % 3) == 0)
				char_puts("\n", ch);
			char_printf(ch, " %-15s", RACE(race)->name);
		}

		char_puts("\n", ch);
		return FALSE;
	}

	char_puts("Syntax:  race [race]\n"
		  "Type 'race ?' for a list of races.\n", ch);
	return FALSE;
}

OLC_FUN(mobed_startpos)
{
	MOB_INDEX_DATA *pMob;
	EDIT_MOB(ch, pMob);
	return olced_flag64(ch, argument, cmd, &pMob->start_pos);
}

OLC_FUN(mobed_defaultpos)
{
	MOB_INDEX_DATA *pMob;
	EDIT_MOB(ch, pMob);
	return olced_flag64(ch, argument, cmd, &pMob->default_pos);
}

OLC_FUN(mobed_gold)
{
	MOB_INDEX_DATA *pMob;
	EDIT_MOB(ch, pMob);
	return olced_number(ch, argument, cmd, &pMob->wealth);
}

OLC_FUN(mobed_hitroll)
{
	MOB_INDEX_DATA *pMob;
	EDIT_MOB(ch, pMob);
	return olced_number(ch, argument, cmd, &pMob->hitroll);
}

OLC_FUN(mobed_group)
{
	MOB_INDEX_DATA *pMob;
	MOB_INDEX_DATA *pMTemp;
	char arg[MAX_STRING_LENGTH];
	int i;
	BUFFER *buffer;
	bool found = FALSE;
	
	EDIT_MOB(ch, pMob);
	
	if (argument[0] == '\0') {
		char_puts("Syntax: group [number]\n", ch);
		char_puts("        group show [number]\n", ch);
		return FALSE;
	}
	
	if (is_number(argument))
	{
		pMob->group = atoi(argument);
		char_puts("Group set.\n", ch);
		return TRUE;
	}
	
	argument = one_argument(argument, arg, sizeof(arg));
	
	if (!strcmp(arg, "show") && is_number(argument)) {
		if (atoi(argument) == 0) {
			char_puts("Are you crazy?\n", ch);
			return FALSE;
		}

		buffer = buf_new(-1);

		for (i = 0; i < MAX_KEY_HASH; i++)
			for (pMTemp = mob_index_hash[i]; pMTemp; pMTemp = pMTemp->next)
			{	
				if (pMTemp->group == atoi(argument)) 
				{
					found = TRUE;
					buf_printf(buffer, "[%5d] %s\n",
					   pMTemp->vnum, pMTemp->name);
				}
			}

		if (found)
			page_to_char(buf_string(buffer), ch);
		else
			char_puts("No mobs in that group.\n", ch);

		buf_free(buffer);
		return FALSE;
	}
	
	return FALSE;
}

OLC_FUN(mobed_clan)
{
	MOB_INDEX_DATA *pMob;
	EDIT_MOB(ch, pMob);
	return olced_clan(ch, argument, cmd, &pMob->clan);
}

OLC_FUN(mobed_trigadd)
{
	int value;
	MOB_INDEX_DATA *pMob;
	MPTRIG *mptrig;
	MPCODE *mpcode;
	char trigger[MAX_STRING_LENGTH];
	char num[MAX_STRING_LENGTH];

	EDIT_MOB(ch, pMob);
	argument = one_argument(argument, num, sizeof(num));
	argument = one_argument(argument, trigger, sizeof(trigger));

	if (!str_cmp(num, "?")) {
		show_flags(ch, mptrig_types);
		return FALSE;
	}

	if (!is_number(num) || trigger[0] =='\0' || argument[0] =='\0') {
		 char_puts("Syntax: trigadd [vnum] [trigger] [phrase]\n",ch);
		 return FALSE;
	}

	if ((value = flag_value(mptrig_types, trigger)) < 0) {
		char_puts("Invalid trigger type.\n"
			  "Use 'trigadd ?' for list of triggers.\n", ch);
		return FALSE;
	}

	if ((mpcode = mpcode_lookup(atoi(num))) == NULL) {
		 char_puts("No such MOBProgram.\n", ch);
		 return FALSE;
	}

	mptrig = mptrig_new(value, argument, atoi(num));
	mptrig_add(pMob, mptrig);
	char_puts("Trigger added.\n",ch);
	return TRUE;
}

OLC_FUN(mobed_trigdel)
{
	MOB_INDEX_DATA *pMob;
	MPTRIG *mptrig;
	MPTRIG *mptrig_next;
	char mprog[MAX_STRING_LENGTH];
	int value;
	int cnt = 0;

	EDIT_MOB(ch, pMob);

	one_argument(argument, mprog, sizeof(mprog));
	if (!is_number(mprog) || mprog[0] == '\0') {
		char_puts("Syntax:  trigdel [#mprog]\n",ch);
		return FALSE;
	}

	value = atoi (mprog);

	if (value < 0) 
    {
		 char_puts("Only non-negative mprog-numbers allowed.\n",ch);
		 return FALSE;
	}

	if (!(mptrig = pMob->mptrig_list)) 
    {
		 char_puts("MobEd:  Nonexistent trigger.\n",ch);
		 return FALSE;
	}

	if (value == 0) 
    {
		REMOVE_BIT(pMob->mptrig_types, pMob->mptrig_list->type);
		mptrig = pMob->mptrig_list;
		pMob->mptrig_list = mptrig->next;
		mptrig_free(mptrig);
	}
	else
    {
		while ((mptrig_next = mptrig->next) && (++cnt < value))
			mptrig = mptrig_next;

		if (mptrig_next) 
        {
			REMOVE_BIT(pMob->mptrig_types, mptrig_next->type);
		    mptrig->next = mptrig_next->next;
			mptrig_free(mptrig_next);
		}
		else
        {
		        char_puts("No such trigger.\n",ch);
		        return FALSE;
		}
	}
	mptrig_fix(pMob);

	char_puts("Trigger removed.\n", ch);
	return TRUE;
}

OLC_FUN(mobed_clone)
{
	MOB_INDEX_DATA *pMob;
	MOB_INDEX_DATA *pFrom;
	AREA_DATA	*pArea;
	char arg[MAX_INPUT_LENGTH];
	int i;

	one_argument(argument, arg, sizeof(arg));
	if (!is_number(arg)) {
		char_puts("Syntax: clone <vnum>\n", ch);
		return FALSE;
	}

	i = atoi(arg);
	if ((pFrom = get_mob_index(i)) == NULL) {
		char_printf(ch, "MobEd: %d: Vnum does not exist.\n", i);
		return FALSE;
	}

	pArea = area_vnum_lookup(pFrom->vnum);
	if (!IS_BUILDER(ch, pArea)) {
		char_puts("MobEd: Insufficient security.\n", ch);
	       	return FALSE;
	}

	EDIT_MOB(ch, pMob);
	if (pMob == pFrom) 
		return FALSE;

	free_string(pMob->name);
	pMob->name		= str_qdup(pFrom->name);
	free_string(pMob->material);
	pMob->material		= str_qdup(pFrom->material);
	mlstr_free(pMob->short_descr);
	pMob->short_descr	= mlstr_dup(pFrom->short_descr);
	mlstr_free(pMob->long_descr);
	pMob->long_descr	= mlstr_dup(pFrom->long_descr);
	mlstr_free(pMob->description);
	pMob->description	= mlstr_dup(pFrom->description);

	pMob->spec_fun		= pFrom->spec_fun;
	pMob->group		= pFrom->group;
	pMob->act		= pFrom->act;
	pMob->affected_by	= pFrom->affected_by;
	pMob->alignment		= pFrom->alignment;
	pMob->level		= pFrom->level;
	pMob->hitroll		= pFrom->hitroll;
	pMob->dam_type		= pFrom->dam_type;
	pMob->off_flags		= pFrom->off_flags;

	for (i = 0; i < MAX_DAM; i++)
	    pMob->resists[i]    = pFrom->resists[i];
	
	pMob->start_pos		= pFrom->start_pos;
	pMob->default_pos	= pFrom->default_pos;
	pMob->sex		= pFrom->sex;
	pMob->race		= pFrom->race;
	pMob->wealth		= pFrom->wealth;
	pMob->form		= pFrom->form;
	pMob->parts		= pFrom->parts;
	pMob->size		= pFrom->size;
	pMob->practicer		= pFrom->practicer;
	pMob->clan		= pFrom->clan;
	pMob->invis_level   = pFrom->invis_level;
//	pMob->fvnum     = pFrom->fvnum;
	//	
	for (i = 0; i < 3; i++)
		pMob->hit[i]	= pFrom->hit[i];
	for (i = 0; i < 3; i++)
		pMob->mana[i]	= pFrom->mana[i];
	for (i = 0; i < 3; i++)
		pMob->damage[i]	= pFrom->damage[i];
	for (i = 0; i < 4; i++)
		pMob->ac[i]	= pFrom->ac[i];

	return TRUE;
}

OLC_FUN(mobed_invis)
{
	MOB_INDEX_DATA *pMob;
	EDIT_MOB(ch, pMob);
	return olced_number(ch, argument, cmd, &pMob->invis_level);
}

OLC_FUN(mobed_fvnum)
{
    MOB_INDEX_DATA *pMob;
    EDIT_MOB(ch, pMob);
    return olced_number(ch, argument, cmd, &pMob->fvnum);
}

OLC_FUN(mobed_listendata)
{
	MOB_INDEX_DATA *pMob;
	EDIT_MOB(ch, pMob);
	return olced_mlstr_text(ch, argument, cmd, &pMob->listen_data);
}

/* Local functions */

static void show_spec_cmds(CHAR_DATA *ch)
{
	int  spec;
	int  col;
	BUFFER *output;

	output = buf_new(-1);
	col = 0;
	buf_add(output, "Preceed special functions with 'spec_'\n\n");
	for (spec = 0; spec_table[spec].function != NULL; spec++) {
		buf_printf(output, "%-19.18s", &spec_table[spec].name[5]);
		if (++col % 4 == 0)
			buf_add(output, "\n");
	}
 
	if (col % 4 != 0)
		buf_add(output, "\n");

	char_puts(buf_string(output), ch);
	buf_free(output);
}

/*
VALIDATE_FUN(validate_fvnum)
{
	int fvnum = *(int*) arg;

	if (!get_mob_index(fvnum)) {
		char_printf(ch, "MobEd: %d: no such vnum.\n", fvnum);
		return FALSE;
	}

	return TRUE;
}
*/
//--------------------------------------------------------------------------------
// Welesh : added for autostat
//--------------------------------------------------------------------------------

struct mob_stats_data {
    int level;

    int hit_number;
    int hit_type;
    int hit_bonus;

    int hitroll;

    int dam_number;
    int dam_type;
    int dam_bonus;

    int mana_number;
    int mana_type;
    int mana_bonus;

    int ac_pierce;
    int ac_bash;
    int ac_slash;
    int ac_exotic;
};
typedef struct mob_stats_data MOB_STATS_DATA;

static MOB_STATS_DATA strong_mob_stats[] = {
//    level|hitpoints[3]     |hitroll|dam[3]           |mana[3]          |ac[4]                  
    { 9999, 99999,99999,99999,99999,  99999,99999,99999,99999,99999,99999,99999,99999,99999,99999},
    { 0 }
};

static MOB_STATS_DATA normal_mob_stats[] = {
//    level|hitpoints[3]     |hitroll|dam[3]           |mana[3]          |ac[4]               
    { 1,    5,    2,    4,    2,      1,    4,    2,    1,    1,    99,   70,   70,   70,   70},
//          7-12 (9.5)                3-6 (4.5)        |
    { 3,    3,    3,    30,   4,      1,    6,    1,    1,    1,    99,   90,   90,   90,   90},
//          33-39(36)                 2-7(4.5)         |
    { 5,    5,    5,    55,   4,      1,    6,    3,    1,    1,    99,   100,  100,  100,  100},
//          60-80(70)                 4-9(6,5)         |
    { 7,    4,    6,    95,   5,      2,    3,    4,    1,    1,    99,   110,  110,  110,  110},
//          99-119(109)               6-10(8)          |
    { 10,   2,    7,    121,  6,      2,    4,    4,    2,    10,   99,   125,  125,  125,  125},
//          123-135(129)              6-12(9)          |
    { 13,   10,   15,   180,  8,      3,    4,    6,    2,    10,   99,   135,  135,  135,  135},
//          190-330(260)              9-18(13,5)       |
    { 16,   15,   12,   220,  12,     5,    3,    8,    10,   20,   100,  150,  150,  150,  150},
//          235-400(317,5)            13-23(18)        |
    { 20,   12,   10,   380,  12,     5,    3,    8,    10,   20,   100,  160,  160,  160,  160},    
//          392-500(446)              12-27(19,5)      |
    { 24,   5,    10,   500,  16,     10,   2,    6,    12,   30,   100,  180,  180,  180,  180},
//          505-550(527,5)            16-26(21)        |
    { 29,   15,   16,   580,  20,     5,    5,    13,   14,   30,   120,  210,  210,  210,  210},
//          595-820(707,5)            18-38(28)        |
    { 38,   20,   17,   2200, 32,     7,    7,    40,   14,   30,   120,  310,  310,  310,  310},
//          2220-2540(2380)           47-89(68)        |
    { 48,   25,   10,   4750, 46,     8,    8,    92,   16,   30,   400,  530,  530,  530,  530},
//          4775-5000(4887,5)         100-156(128)     |
    { 55,   50,   10,   8000, 70,     10,   7,    130,  20,   30,   500,  300,  300,  300,  300},
//          7580-8860(8220)           140-200(170)                    
    { 60,   50,   10,   9999, 1,      8,    6,    175,  3,    400,  580,  470,  470,  470,  470},
    { 65,   10,   10,   11000,50,     10,   10,   250,  10,   10,   5000, 700,  700,  700,  300},
    { 70,   75,   10,   8750, 0,      9,    7,    40,   1,    10,   600,  1400, 1400, 1400, 1400},
    { 75,   60,   10,   9000, 6,      50,   4,    85,   65,   10,   100,  350,  350,  350,  350},
    { 85,   10,   1000, 10000,27,     50,   7,    90,   85,   10,   100,  430,  430,  430,  160},
    { 92,   5,    10,   19500,0,      15,   10,   62,   10,   10,   5200, 620,  620,  620,  290},
    { 95,   1,    1000, 10000,20,     8,    8,    20,   60,   10,   3000, 1900, 1900, 1900, 1900},
    { 106,  1,    1,    29000,50,     50,   4,    80,   1,    1,    11039,2120, 2120, 2120, 2120},
    { 110,  50,   10,   28000,50,     20,   15,   90,   10,   10,   10000,770,  770,  700,  400},
    { 117,  1,    1000, 25000,40,     12,   12,   50,   1,    100,  4250, 2340, 2340, 2340, 2340},
    { 120,  10,   1000, 12000,200,    50,   10,   50,   10,   100,  1000, 2400, 2400, 2400, 2400},
    { 9999, 99999,99999,99999,99999,  99999,99999,99999,99999,99999,99999,99999,99999,99999,99999},
    { 0 }
};

static MOB_STATS_DATA weak_mob_stats[] = {
//    level|hitpoints[3]     |hitroll|dam[3]           |mana[3]          |ac[4]                  
    { 1,    4,    2,    3,    1,      1,    4,    0,    1,    1,    99,   80,   80,   80,   80}, 
    { 9999, 99999,99999,99999,99999,  99999,99999,99999,99999,99999,99999,99999,99999,99999,99999},
    { 0 }
};

void autostat (CHAR_DATA * ch, MOB_INDEX_DATA * mob, MOB_STATS_DATA stat_table[]);
int calc_stat (int min, int max);

//--------------------------------------------------------------------------------
OLC_FUN(mobed_autostat)
{
	MOB_INDEX_DATA *pMob;

	EDIT_MOB(ch, pMob);
    if (!(str_prefix(argument, "normal")))
    {
        char_printf (ch, "Autosetting NORMAL stats for level %d.\n", pMob->level);
        autostat (ch, pMob, normal_mob_stats);
        return TRUE;
    }
    else if (!(str_prefix(argument, "strong")))
    {
        char_printf (ch, "Autosetting STRONG stats for level %d.\n", pMob->level);
        autostat (ch, pMob, strong_mob_stats);
        return TRUE;
    }
    else if (!(str_prefix(argument, "weak")))
    {
        char_printf (ch, "Autosetting WEAK stats for level %d.\n", pMob->level);
        autostat (ch, pMob, weak_mob_stats);
        return TRUE;
    }
    else
    {
        char_act ("Syntax: autostat [<strong/normal/weak>]", ch);
        return FALSE;
    }
}

void autostat (CHAR_DATA * ch, MOB_INDEX_DATA * mob, MOB_STATS_DATA stat_table[])
{
    MOB_STATS_DATA     * mob_stat, * prev_mob_stat;
    int level; 

    level = mob->level;
    prev_mob_stat = NULL;
    for (mob_stat = stat_table; mob_stat; mob_stat++)
    {
        if (level <= mob_stat->level) // position found
            break;
        prev_mob_stat = mob_stat;
    }

    if ((!prev_mob_stat) || (level == mob_stat->level))
        prev_mob_stat = mob_stat;

    char_printf(ch, "Levels found in the table: %d - %d\n", prev_mob_stat->level, mob_stat->level);

    mob->hit[DICE_NUMBER] = calc_stat(mob_stat->hit_number,prev_mob_stat->hit_number);
    mob->hit[DICE_TYPE]   = calc_stat(mob_stat->hit_type,  prev_mob_stat->hit_type);
    mob->hit[DICE_BONUS]  = calc_stat(mob_stat->hit_bonus, prev_mob_stat->hit_bonus);
    char_printf(ch, "Hitpoint  : %dd%d+%d\n", mob->hit[DICE_NUMBER], mob->hit[DICE_TYPE], mob->hit[DICE_BONUS]);

    mob->mana[DICE_NUMBER] = calc_stat(mob_stat->mana_number,prev_mob_stat->mana_number);
    mob->mana[DICE_TYPE]   = calc_stat(mob_stat->mana_type,  prev_mob_stat->mana_type);
    mob->mana[DICE_BONUS]  = calc_stat(mob_stat->mana_bonus, prev_mob_stat->mana_bonus);
    char_printf(ch, "Mana      : %dd%d+%d\n", mob->mana[DICE_NUMBER], mob->mana[DICE_TYPE], mob->mana[DICE_BONUS]);

    mob->damage[DICE_NUMBER] = calc_stat(mob_stat->dam_number,prev_mob_stat->dam_number);
    mob->damage[DICE_TYPE]   = calc_stat(mob_stat->dam_type,  prev_mob_stat->dam_type);
    mob->damage[DICE_BONUS]  = calc_stat(mob_stat->dam_bonus, prev_mob_stat->dam_bonus);
    char_printf(ch, "Damage    : %dd%d+%d\n", mob->damage[DICE_NUMBER], mob->damage[DICE_TYPE], mob->damage[DICE_BONUS]);

    mob->hitroll             = calc_stat(mob_stat->hitroll,prev_mob_stat->hitroll);
    char_printf(ch, "Hitroll   : %d\n", mob->hitroll);

    mob->ac[AC_PIERCE]       = calc_stat(mob_stat->ac_pierce,prev_mob_stat->ac_pierce);
    mob->ac[AC_BASH]         = calc_stat(mob_stat->ac_bash,prev_mob_stat->ac_bash);
    mob->ac[AC_SLASH]        = calc_stat(mob_stat->ac_slash,prev_mob_stat->ac_slash);
    mob->ac[AC_EXOTIC]       = calc_stat(mob_stat->ac_exotic,prev_mob_stat->ac_exotic);
    char_printf(ch, "AC        : -%d -%d -%d -%d\n", mob->ac[AC_PIERCE], mob->ac[AC_BASH], mob->ac[AC_SLASH], mob->ac[AC_EXOTIC]);
}

int calc_stat (int min, int max)
{
    //return number_fuzzy(number_range((max+min)/2,max));
    return number_range((max+min)/2,max);
}
// end-added