/* $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