/**************************************************************************** * [S]imulated [M]edieval [A]dventure multi[U]ser [G]ame | \\._.// * * -----------------------------------------------------------| (0...0) * * SMAUG 1.4 (C) 1994, 1995, 1996, 1998 by Derek Snider | ).:.( * * -----------------------------------------------------------| {o o} * * SMAUG code team: Thoric, Altrag, Blodkai, Narn, Haus, | / ' ' \ * * Scryn, Rennard, Swordbearer, Gorog, Grishnakh, Nivek, |~'~.VxvxV.~'~* * Tricops and Fireblade | * *------------------------------------------------------------------------ * * Shaddai's Polymorph * ****************************************************************************/ #include <string.h> #include <ctype.h> #include <stdio.h> #include "mud.h" #if defined(KEY) #undef KEY #endif #define KEY( literal, field, value ) \ if ( !str_cmp( word, literal ) ) \ { \ field = value; \ fMatch = TRUE; \ break; \ } MORPH_DATA *morph_start = NULL; MORPH_DATA *morph_end = NULL; int morph_vnum = 0; /* * Local functions */ void copy_morph args((MORPH_DATA * morph, MORPH_DATA * temp)); /* * Extern prototypes */ int get_risflag args((char *flag)); int get_npc_race args((char *type)); /* * Command used to set all the morphing information. * Must use the morphset save command, to write the commands to file. * Blood/Hp/Mana/Move/Hitroll/Damroll can be set using variables such * as 1d2+10. No boundry checks are in place yet on those, so care must * be taken when using these. --Shaddai */ void do_morphset(CHAR_DATA * ch, char *argument) { char arg1[MIL]; char arg2[MIL]; char arg3[MIL]; char buf[MSL]; char *origarg = argument; int value; MORPH_DATA *morph = NULL; set_char_color(AT_PLAIN, ch); if (IS_NPC(ch)) { send_to_char("Mob's can't morphset\n\r", ch); return; } if (!ch->desc) { send_to_char("You have no descriptor\n\r", ch); return; } switch (ch->substate) { default: break; case SUB_MORPH_DESC: if (!ch->dest_buf) { send_to_char("Fatal error: report to Shaddai.\n\r", ch); bug("do_morphset: sub_morph_desc: NULL ch->dest_buf", 0); ch->substate = SUB_NONE; return; } morph = ch->dest_buf; STRFREE(morph->description); morph->description = copy_buffer(ch); stop_editing(ch); ch->substate = ch->tempnum; if (ch->substate == SUB_REPEATCMD) ch->dest_buf = morph; return; case SUB_MORPH_HELP: if (!ch->dest_buf) { send_to_char("Fatal error: report to Shaddai.\n\r", ch); bug("do_morphset: sub_morph_help: NULL ch->dest_buf", 0); ch->substate = SUB_NONE; return; } morph = ch->dest_buf; STRFREE(morph->help); morph->help = copy_buffer(ch); stop_editing(ch); ch->substate = ch->tempnum; if (ch->substate == SUB_REPEATCMD) ch->dest_buf = morph; return; } morph = NULL; smash_tilde(argument); if (ch->substate == SUB_REPEATCMD) { morph = ch->dest_buf; if (!morph) { send_to_char("Someone deleted your morph!\n\r", ch); argument = "done"; } if (argument[0] == '\0' || !str_cmp(argument, " ")) { do_morphstat(ch, morph->name); return; } if (!str_cmp(argument, "stat")) { strcpy(buf, morph->name); strcat(buf, " help"); do_morphstat(ch, buf); return; } if (!str_cmp(argument, "done") || !str_cmp(argument, "off")) { send_to_char("Morphset mode off.\n\r", ch); ch->substate = SUB_NONE; ch->dest_buf = NULL; if (ch->pcdata && ch->pcdata->subprompt) { STRFREE(ch->pcdata->subprompt); ch->pcdata->subprompt = NULL; } return; } } if (morph) { strcpy(arg1, morph->name); argument = one_argument(argument, arg2); strcpy(arg3, argument); } else { argument = one_argument(argument, arg1); argument = one_argument(argument, arg2); strcpy(arg3, argument); } if (!str_cmp(arg1, "on")) { send_to_char("Syntax: morphset <morph> on.\n\r", ch); return; } value = is_number(arg3) ? atoi(arg3) : -1; if (atoi(arg3) < -1 && value == -1) value = atoi(arg3); if (ch->substate != SUB_REPEATCMD && arg1[0] != '\0' && !str_cmp(arg1, "save")) { save_morphs(); send_to_char("Morph data saved.\n\r", ch); return; } if (arg1[0] == '\0' || (arg2[0] == '\0' && ch->substate != SUB_REPEATCMD) || !str_cmp(arg1, "?")) { if (ch->substate == SUB_REPEATCMD) { if (morph) send_to_char("Syntax: <field> <value>\n\r", ch); else send_to_char("Syntax: <morph> <field> <value>\n\r", ch); } else send_to_char("Syntax: morphset <morph> <field> <value>\n\r", ch); send_to_char("Syntax: morphset save\n\r", ch); send_to_char("\n\r", ch); send_to_char_color("&cField being one of:\n\r", ch); send_to_char_color("&c-------------------------------------------------\n\r", ch); send_to_char(" ac, affected, blood, bloodused, cha, con, damroll, dayto,\n\r", ch); send_to_char(" dayfrom, deity, description, defpos, dex, dodge,\n\r", ch); send_to_char(" favourused, gloryused, help, hitroll, hp, hpused, immune,\n\r", ch); send_to_char(" int, str, keyword, lck, level, long, mana, manaused,\n\r", ch); send_to_char(" morphother, morphself, move, moveused, name, noaffected,\n\r", ch); send_to_char(" nocast, noimmune, noresistant, noskill, nosusceptible,\n\r", ch); send_to_char(" obj1, obj2, obj3, objuse1, objuse2, objuse3, parry,\n\r", ch); send_to_char(" pkill, race, resistant, sav1, sav2, sav3, sav4, sav5,\n\r", ch); send_to_char(" sex, short, skills, susceptible, timefrom, timer, timeto,\n\r", ch); send_to_char(" tumble, unmorphother, unmorphself, wis.\n\r", ch); send_to_char_color("&c-------------------------------------------------\n\r", ch); return; } if (!morph) { if (!is_number(arg1)) morph = get_morph(arg1); else morph = get_morph_vnum(atoi(arg1)); if (morph == NULL) { send_to_char("That morph does not exist.\n\r", ch); return; } } if (!str_cmp(arg2, "on")) { CHECK_SUBRESTRICTED(ch); ch_printf(ch, "Morphset mode on. (Editing %s).\n\r", morph->name); ch->substate = SUB_REPEATCMD; ch->dest_buf = morph; if (ch->pcdata) { if (ch->pcdata->subprompt) { STRFREE(ch->pcdata->subprompt); ch->pcdata->subprompt = NULL; } sprintf(buf, "<&CMorphset &W%s&w> %%i", morph->name); ch->pcdata->subprompt = STRALLOC(buf); } return; } if (!str_cmp(arg2, "str")) { if (value < -10 || value > 10) { send_to_char("Strength must be a value from -10 to 10.\n\r", ch); return; } morph->str = value; } else if (!str_cmp(arg2, "int")) { if (value < -10 || value > 10) { send_to_char("Intelligence must be a value from -10 to 10.\n\r", ch); return; } morph->inte = value; } else if (!str_cmp(arg2, "wis")) { if (value < -10 || value > 10) { send_to_char("Wisdom must be a value from -10 to 10.\n\r", ch); return; } morph->wis = value; } else if (!str_cmp(arg2, "defpos")) { if (value < 0 || value > POS_STANDING) { ch_printf(ch, "Position range is 0 to %d.\n\r", POS_STANDING); return; } morph->defpos = value; } else if (!str_cmp(arg2, "dex")) { if (value < -10 || value > 10) { send_to_char("Dexterity must be a value from -10 to 10.\n\r", ch); return; } morph->dex = value; } else if (!str_cmp(arg2, "con")) { if (value < -10 || value > 10) { send_to_char("Constitution must be a value from -10 to 10.\n\r", ch); return; } morph->con = value; } else if (!str_cmp(arg2, "cha")) { if (value < -10 || value > 10) { send_to_char("Charisma must be a value from -10 to 10.\n\r", ch); return; } morph->cha = value; } else if (!str_cmp(arg2, "lck")) { if (value < -10 || value > 10) { send_to_char("Luck must be a value from -10 to 10.\n\r", ch); return; } morph->lck = value; } else if (!str_cmp(arg2, "sex")) { if (value < 0 || value > 2) { send_to_char("Sex must be a value from 0 to 2.\n\r", ch); return; } morph->sex = value; } else if (!str_cmp(arg2, "pkill")) { if (!str_cmp(arg3, "pkill")) morph->pkill = ONLY_PKILL; else if (!str_cmp(arg3, "peace")) morph->pkill = ONLY_PEACEFULL; else if (!str_cmp(arg3, "none")) morph->pkill = 0; else { send_to_char("Usuage: morphset <morph> pkill [pkill|peace|none]\n\r", ch); return; } } else if (!str_cmp(arg2, "bloodused")) { if (value < 0 || value > 60) { send_to_char("Blood used is a value from 0 to 60.\n\r", ch); return; } morph->bloodused = value; } else if (!str_cmp(arg2, "manaused")) { if (value < 0 || value > 2000) { send_to_char("Mana used is a value from 0 to 2000.\n\r", ch); return; } morph->manaused = value; } else if (!str_cmp(arg2, "moveused")) { if (value < 0 || value > 2000) { send_to_char("Move used is a value from 0 to 2000.\n\r", ch); return; } morph->moveused = value; } else if (!str_cmp(arg2, "hpused")) { if (value < 0 || value > 2000) { send_to_char("Hp used is a value from 0 to 2000.\n\r", ch); return; } morph->hpused = value; } else if (!str_cmp(arg2, "favourused")) { if (value < 0 || value > 2000) { send_to_char("Favour used is a value from 0 to 2000.\n\r", ch); return; } morph->favourused = value; } else if (!str_cmp(arg2, "gloryused")) { if (value < 0 || value > 2000) { send_to_char("Glory used is a value from 0 to 2000.\n\r", ch); return; } morph->gloryused = value; } else if (!str_cmp(arg2, "timeto")) { if (value < 0 || value > 23) { send_to_char("Timeto is a value from 0 to 23.\n\r", ch); return; } morph->timeto = value; } else if (!str_cmp(arg2, "timefrom")) { if (value < 0 || value > 23) { send_to_char("Timefrom is a value from 0 to 23.\n\r", ch); return; } morph->timefrom = value; } else if (!str_cmp(arg2, "dayto")) { if (value < 0 || value > 31) { send_to_char("Dayto is a value from 0 to 31.\n\r", ch); return; } morph->dayto = value; } else if (!str_cmp(arg2, "dayfrom")) { if (value < 0 || value > 31) { send_to_char("Dayfrom is a value from 0 to 31.\n\r", ch); return; } morph->dayfrom = value; } else if (!str_cmp(arg2, "sav1") || !str_cmp(arg2, "savepoison")) { if (value < -30 || value > 30) { send_to_char("Saving throw range is -30 to 30.\n\r", ch); return; } morph->saving_poison_death = value; } else if (!str_cmp(arg2, "sav2") || !str_cmp(arg2, "savewand")) { if (value < -30 || value > 30) { send_to_char("Saving throw range is -30 to 30.\n\r", ch); return; } morph->saving_wand = value; } else if (!str_cmp(arg2, "sav3") || !str_cmp(arg2, "savepara")) { if (value < -30 || value > 30) { send_to_char("Saving throw range is -30 to 30.\n\r", ch); return; } morph->saving_para_petri = value; } else if (!str_cmp(arg2, "sav4") || !str_cmp(arg2, "savebreath")) { if (value < -30 || value > 30) { send_to_char("Saving throw range is -30 to 30.\n\r", ch); return; } morph->saving_breath = value; } else if (!str_cmp(arg2, "sav5") || !str_cmp(arg2, "savestaff")) { if (value < -30 || value > 30) { send_to_char("Saving throw range is -30 to 30.\n\r", ch); return; } morph->saving_spell_staff = value; } else if (!str_cmp(arg2, "timer")) { if (value < -1 || value == 0) { send_to_char("Timer must be -1 (None) or greater than 0.\n\r", ch); return; } morph->timer = value; } else if (!str_cmp(arg2, "hp")) { argument = one_argument(argument, arg3); if (!str_cmp(arg3, "0")) arg3[0] = '\0'; morph->hit = str_dup(arg3); } else if (!str_cmp(arg2, "mana")) { argument = one_argument(argument, arg3); if (!str_cmp(arg3, "0")) arg3[0] = '\0'; morph->mana = str_dup(arg3); } else if (!str_cmp(arg2, "move")) { argument = one_argument(argument, arg3); if (!str_cmp(arg3, "0")) arg3[0] = '\0'; morph->move = str_dup(arg3); } else if (!str_cmp(arg2, "blood")) { argument = one_argument(argument, arg3); if (!str_cmp(arg3, "0")) arg3[0] = '\0'; morph->blood = str_dup(arg3); } else if (!str_cmp(arg2, "ac")) { if (value > 500 || value < -500) { send_to_char("Ac range is -500 to 500.\n\r", ch); return; } morph->ac = value; } else if (!str_cmp(arg2, "hitroll")) { argument = one_argument(argument, arg3); if (!str_cmp(arg3, "0")) arg3[0] = '\0'; morph->hitroll = str_dup(arg3); } else if (!str_cmp(arg2, "damroll")) { argument = one_argument(argument, arg3); if (!str_cmp(arg3, "0")) arg3[0] = '\0'; morph->damroll = str_dup(arg3); } else if (!str_cmp(arg2, "dodge")) { if (value > 100 || value < -100) { send_to_char("Dodge range is -100 to 100.\n\r", ch); return; } morph->dodge = value; } else if (!str_prefix("obj", arg2)) { int index; char temp[MSL]; if (arg2[3] == '\0') { send_to_char("Obj 1, 2, or 3.\n\r", ch); return; } temp[0] = arg2[3]; temp[1] = '\0'; index = atoi(temp); if (index > 3 || index < 1) { send_to_char("Obj 1, 2, or 3.\n\r", ch); return; } if ((get_obj_index(value)) == NULL) { send_to_char("No such vnum.\n\r", ch); return; } morph->obj[index - 1] = value; } else if (!str_cmp(arg2, "parry")) { if (value > 100 || value < -100) { send_to_char("Dodge range is -100 to 100.\n\r", ch); return; } morph->parry = value; } else if (!str_cmp(arg2, "tumble")) { if (value > 100 || value < -100) { send_to_char("Dodge range is -100 to 100.\n\r", ch); return; } morph->tumble = value; } else if (!str_cmp(arg2, "level")) { if (value < 0 || value > 2) { send_to_char("Level range is 0 to 1.\n\r", ch); return; } morph->level = value; } else if (!str_prefix(arg2, "objuse")) { int index; char temp[MIL]; if (arg2[6] == '\0') { send_to_char("Objuse 1, 2 or 3?\n\r", ch); return; } temp[0] = arg2[6]; temp[1] = '\0'; index = atoi(temp); if (index > 3 || index < 1) { send_to_char("Objuse 1, 2, or 3?\n\r", ch); return; } if (value) morph->objuse[index - 1] = TRUE; else morph->objuse[index - 1] = FALSE; } else if (!str_cmp(arg2, "nocast")) { if (value) morph->no_cast = TRUE; else morph->no_cast = FALSE; } else if (!str_cmp(arg2, "resistant") || !str_cmp(arg2, "r")) { if (!argument || argument[0] == '\0') { send_to_char("Usage: morphset <morph> resistant <flag> [flag]...\n\r", ch); return; } while (argument[0] != '\0') { argument = one_argument(argument, arg3); value = get_risflag(arg3); if (value < 0 || value > 31) ch_printf(ch, "Unknown flag: %s\n\r", arg3); else TOGGLE_BIT(morph->resistant, 1 << value); } } else if (!str_cmp(arg2, "susceptible") || !str_cmp(arg2, "s")) { if (!argument || argument[0] == '\0') { send_to_char("Usage: morphset <morph> susceptible <flag> [flag]...\n\r", ch); return; } while (argument[0] != '\0') { argument = one_argument(argument, arg3); value = get_risflag(arg3); if (value < 0 || value > 31) ch_printf(ch, "Unknown flag: %s\n\r", arg3); else TOGGLE_BIT(morph->suscept, 1 << value); } } else if (!str_cmp(arg2, "immune") || !str_cmp(arg2, "i")) { if (!argument || argument[0] == '\0') { send_to_char("Usage: morphset <morph> immune <flag> [flag]...\n\r", ch); return; } while (argument[0] != '\0') { argument = one_argument(argument, arg3); value = get_risflag(arg3); if (value < 0 || value > 31) ch_printf(ch, "Unknown flag: %s\n\r", arg3); else TOGGLE_BIT(morph->immune, 1 << value); } } else if (!str_cmp(arg2, "noresistant") || !str_cmp(arg2, "nr")) { if (!argument || argument[0] == '\0') { send_to_char("Usage: morphset <morph> noresistant <flag> [flag]...\n\r", ch); return; } while (argument[0] != '\0') { argument = one_argument(argument, arg3); value = get_risflag(arg3); if (value < 0 || value > 31) ch_printf(ch, "Unknown flag: %s\n\r", arg3); else TOGGLE_BIT(morph->no_resistant, 1 << value); } } else if (!str_cmp(arg2, "nosusceptible") || !str_cmp(arg2, "ns")) { if (!argument || argument[0] == '\0') { send_to_char("Usage: morphset <morph> nosusceptible <flag> [flag]...\n\r", ch); return; } while (argument[0] != '\0') { argument = one_argument(argument, arg3); value = get_risflag(arg3); if (value < 0 || value > 31) ch_printf(ch, "Unknown flag: %s\n\r", arg3); else TOGGLE_BIT(morph->no_suscept, 1 << value); } } else if (!str_cmp(arg2, "noimmune") || !str_cmp(arg2, "ni")) { if (!argument || argument[0] == '\0') { send_to_char("Usage: morphset <morph> noimmune <flag> [flag]...\n\r", ch); return; } while (argument[0] != '\0') { argument = one_argument(argument, arg3); value = get_risflag(arg3); if (value < 0 || value > 31) ch_printf(ch, "Unknown flag: %s\n\r", arg3); else TOGGLE_BIT(morph->no_immune, 1 << value); } } else if (!str_cmp(arg2, "affected") || !str_cmp(arg2, "aff")) { if (!argument || argument[0] == '\0') { send_to_char("Usage: morphset <morph> affected <flag> [flag]...\n\r", ch); return; } while (argument[0] != '\0') { argument = one_argument(argument, arg3); value = get_aflag(arg3); if (value < 0 || value > MAX_BITS) ch_printf(ch, "Unknown flag: %s\n\r", arg3); else xTOGGLE_BIT(morph->affected_by, value); } } else if (!str_cmp(arg2, "noaffected") || !str_cmp(arg2, "naff")) { if (!argument || argument[0] == '\0') { send_to_char("Usage: morphset <morph> noaffected <flag> [flag]...\n\r", ch); return; } while (argument[0] != '\0') { argument = one_argument(argument, arg3); value = get_aflag(arg3); if (value < 0 || value > MAX_BITS) ch_printf(ch, "Unknown flag: %s\n\r", arg3); else xTOGGLE_BIT(morph->no_affected_by, value); } } else if (!str_cmp(arg2, "short")) { STRFREE(morph->short_desc); morph->short_desc = STRALLOC(arg3); } else if (!str_cmp(arg2, "morphother")) { STRFREE(morph->morph_other); morph->morph_other = STRALLOC(arg3); } else if (!str_cmp(arg2, "morphself")) { STRFREE(morph->morph_self); morph->morph_self = STRALLOC(arg3); } else if (!str_cmp(arg2, "unmorphother")) { STRFREE(morph->unmorph_other); morph->unmorph_other = STRALLOC(arg3); } else if (!str_cmp(arg2, "unmorphself")) { STRFREE(morph->unmorph_self); morph->unmorph_self = STRALLOC(arg3); } else if (!str_cmp(arg2, "keyword")) { STRFREE(morph->key_words); morph->key_words = STRALLOC(arg3); } else if (!str_cmp(arg2, "long")) { STRFREE(morph->long_desc); strcpy(buf, arg3); strcat(buf, "\n\r"); morph->long_desc = STRALLOC(buf); } else if (!str_cmp(arg2, "description") || !str_cmp(arg2, "desc")) { if (arg3[0]) { STRFREE(morph->description); morph->description = STRALLOC(arg3); } CHECK_SUBRESTRICTED(ch); if (ch->substate == SUB_REPEATCMD) ch->tempnum = SUB_REPEATCMD; else ch->tempnum = SUB_NONE; ch->substate = SUB_MORPH_DESC; ch->dest_buf = morph; start_editing(ch, morph->description); set_editor_desc(ch, "A morph description."); return; } else if (!str_cmp(arg2, "name")) { STRFREE(morph->name); morph->name = STRALLOC(arg3); } else if (!str_cmp(arg2, "help")) { if (arg3[0]) { STRFREE(morph->help); morph->help = STRALLOC(arg3); } CHECK_SUBRESTRICTED(ch); if (ch->substate == SUB_REPEATCMD) ch->tempnum = SUB_REPEATCMD; else ch->tempnum = SUB_NONE; ch->substate = SUB_MORPH_HELP; ch->dest_buf = morph; start_editing(ch, morph->help); set_editor_desc(ch, "A morph help file."); return; } else if (!str_cmp(arg2, "skills")) { if (!morph->skills) morph->skills = str_dup(""); if (arg3[0] == '\0' || !str_cmp(arg3, "none")) { DISPOSE(morph->skills); morph->skills = str_dup(""); return; } sprintf(buf, "%s %s", morph->skills, arg3); DISPOSE(morph->skills); morph->skills = str_dup(buf); } else if (!str_cmp(arg2, "noskills")) { if (!morph->no_skills) morph->no_skills = str_dup(""); if (arg3[0] == '\0' || !str_cmp(arg3, "none")) { DISPOSE(morph->no_skills); morph->no_skills = str_dup(""); return; } sprintf(buf, "%s %s", morph->no_skills, arg3); DISPOSE(morph->no_skills); morph->no_skills = str_dup(buf); } else if (!str_cmp(arg2, "race")) { if (is_number(arg3)) value = atoi(arg3); else value = get_npc_race(arg3); if (value < 0 && !is_number(arg3)) { ch_printf(ch, "Unknown race: %s", arg3); return; } else if (value < 0 || value >= MAX_RACE) { ch_printf(ch, "Race range is 0 to %d.\n", MAX_RACE - 1); return; } TOGGLE_BIT(morph->race, (1 << value)); } else if (ch->substate == SUB_REPEATCMD) { ch->substate = SUB_RESTRICTED; interpret(ch, origarg); ch->substate = SUB_REPEATCMD; ch->last_cmd = do_morphset; } else { do_morphset(ch, ""); return; } send_to_char("Done.\n\r", ch); return; } /* * Shows morph info on a given morph. * To see the description and help file, must use morphstat <morph> help * Shaddai */ void do_morphstat(CHAR_DATA * ch, char *argument) { MORPH_DATA *morph; char arg[MIL]; int count = 1; set_pager_color(AT_CYAN, ch); argument = one_argument(argument, arg); if (arg[0] == '\0') { send_to_pager("Morphstat what?\n\r", ch); return; } if (IS_NPC(ch)) { send_to_char("Mob's can't morphstat\n\r", ch); return; } if (!str_cmp(arg, "list")) { if (!morph_start) { send_to_pager("No morph's currently exist.\n\r", ch); return; } for (morph = morph_start; morph; morph = morph->next) { pager_printf_color(ch, "&c[&C%2d&c] Name: &C%-13s &cVnum: &C%4d &cUsed: &C%3d\n\r", count, morph->name, morph->vnum, morph->used); count++; } return; } if (!is_number(arg)) morph = get_morph(arg); else morph = get_morph_vnum(atoi(arg)); if (morph == NULL) { send_to_pager("No such morph exists.\n\r", ch); return; } if (argument[0] == '\0') { pager_printf_color(ch, " &cMorph Name: &C%-20s Vnum: %4d\n\r", morph->name, morph->vnum); send_to_pager_color("&B[----------------------------------------------------------------------------]\n\r", ch); send_to_pager_color(" &BMorph Restrictions\n\r", ch); send_to_pager_color("&B[----------------------------------------------------------------------------]\n\r", ch);; pager_printf_color(ch, " &cRaces Not Allowed: &w%s\n\r", race_string(morph->race)); pager_printf_color(ch, " &cSex: &C%s &cPkill: &C%s &cTime From: &C%d &cTime To: &C%d\n\r", morph->sex == SEX_MALE ? "male" : morph->sex == SEX_FEMALE ? "female" : "neutral", morph->pkill == ONLY_PKILL ? "YES" : morph->pkill == ONLY_PEACEFULL ? "NO" : "n/a", morph->timefrom, morph->timeto); pager_printf_color(ch, " &cDay From: &C%d &cDay To: &C%d\n\r", morph->dayfrom, morph->dayto); pager_printf_color(ch, " &cLevel: &C%d &cCasting Allowed : &C%s\n\r", morph->level, (morph->no_cast) ? "NO" : "yes"); pager_printf_color(ch, " &cUSAGES: Mana: &C%d &cMove: &C%d &cHp: &C%d &cFavour: &C%d &cGlory: &C%d\n\r", morph->manaused, morph->moveused, morph->hpused, morph->favourused, morph->gloryused); pager_printf_color(ch, " &cBlood: &C%d\n\r", morph->bloodused); pager_printf_color(ch, " &cObj1: &C%d &cObjuse1: &C%s &cObj2: &C%d &cObjuse2: &C%s &cObj3: &C%d &cObjuse3: &c%s\n\r", morph->obj[0], (morph->objuse[0] ? "YES" : "no"), morph->obj[1], (morph->objuse[1] ? "YES" : "no"), morph->obj[2], (morph->objuse[2] ? "YES" : "no")); pager_printf_color(ch, " &cTimer: &w%d\n\r", morph->timer); send_to_pager_color("&B[----------------------------------------------------------------------------]\n\r", ch); send_to_pager_color(" &BEnhancements to the Player\n\r", ch); send_to_pager_color("&B[----------------------------------------------------------------------------]\n\r", ch); pager_printf_color(ch, " &cStr: &C%2d&c )( Int: &C%2d&c )( Wis: &C%2d&c )( Dex: &C%2d&c )( Con: &C%2d&c )( Cha: &C%2d&c )( Lck: &C%2d&c )\n\r", morph->str, morph->inte, morph->wis, morph->dex, morph->con, morph->cha, morph->lck); pager_printf_color(ch, " &cSave versus: &w%d %d %d %d %d &cDodge: &w%d &cParry: &w%d &cTumble: &w%d\n\r", morph->saving_poison_death, morph->saving_wand, morph->saving_para_petri, morph->saving_breath, morph->saving_spell_staff, morph->dodge, morph->parry, morph->tumble); pager_printf_color(ch, " &cHps : &w%s &cBlood : &w%s &cMana : &w%s &cMove : &w%s\n\r", morph->hit, morph->blood, morph->mana, morph->mana); pager_printf_color(ch, " &cDamroll : &w%s &cHitroll: &w%s &cAC : &w%d\n\r", morph->damroll, morph->hitroll, morph->ac); send_to_pager_color("&B[----------------------------------------------------------------------------]\n\r", ch); send_to_pager_color(" &BAffects to the Player\n\r", ch); send_to_pager_color("&B[----------------------------------------------------------------------------]\n\r", ch); pager_printf_color(ch, " &cAffected by: &C%s\n\r", affect_bit_name(&morph->affected_by)); pager_printf_color(ch, " &cImmune : &w%s\n\r", flag_string(morph->immune, ris_flags)); pager_printf_color(ch, " &cSusceptible: &w%s\n\r", flag_string(morph->suscept, ris_flags)); pager_printf_color(ch, " &cResistant : &w%s\n\r", flag_string(morph->resistant, ris_flags)); pager_printf_color(ch, " &cSkills : &w%s\n\r", morph->skills); send_to_pager_color("&B[----------------------------------------------------------------------------]\n\r", ch); send_to_pager_color(" &BPrevented affects to the Player\n\r", ch); send_to_pager_color("&B[----------------------------------------------------------------------------]\n\r", ch); pager_printf_color(ch, " &cNot affected by: &C%s\n\r", affect_bit_name(&morph->no_affected_by)); pager_printf_color(ch, " &cNot Immune : &w%s\n\r", flag_string(morph->no_immune, ris_flags)); pager_printf_color(ch, " &cNot Susceptible: &w%s\n\r", flag_string(morph->no_suscept, ris_flags)); pager_printf_color(ch, " &cNot Resistant : &w%s\n\r", flag_string(morph->no_resistant, ris_flags)); pager_printf_color(ch, " &cNot Skills : &w%s\n\r", morph->no_skills); send_to_pager_color("&B[----------------------------------------------------------------------------]\n\r", ch); send_to_char("\n\r", ch); } else if (!str_cmp(argument, "help") || !str_cmp(argument, "desc")) { pager_printf_color(ch, " &cMorph Name : &C%-20s\n\r", morph->name); pager_printf_color(ch, " &cDefault Pos : &w%d\n\r", morph->defpos); pager_printf_color(ch, " &cKeywords : &w%s\n\r", morph->key_words); pager_printf_color(ch, " &cShortdesc : &w%s\n\r", (morph->short_desc[0] == '\0') ? "(none set)" : morph->short_desc); pager_printf_color(ch, " &cLongdesc : &w%s", (morph->long_desc[0] == '\0') ? "(none set)\n\r" : morph->long_desc); pager_printf_color(ch, " &cMorphself : &w%s\n\r", morph->morph_self); pager_printf_color(ch, " &cMorphother : &w%s\n\r", morph->morph_other); pager_printf_color(ch, " &cUnMorphself : &w%s\n\r", morph->unmorph_self); pager_printf_color(ch, " &cUnMorphother: &w%s\n\r", morph->unmorph_other); send_to_pager_color("&B[----------------------------------------------------------------------------]\n\r", ch); pager_printf_color(ch, " &cHelp:\n\r&w%s\n\r", morph->help); send_to_pager_color("&B[----------------------------------------------------------------------------]\n\r", ch); pager_printf_color(ch, " &cDescription:\n\r&w%s\n\r", morph->description); send_to_pager_color("&B[----------------------------------------------------------------------------]\n\r", ch); } else { send_to_char("Syntax: morphstat <morph>\n\r", ch); send_to_char("Syntax: morphstat <morph> <help/desc>\n\r", ch); } return; } char *race_string(int bitvector) { static char buf[MSL]; int x; buf[0] = '\0'; for (x = 0; x < MAX_RACE; x++) if (IS_SET(bitvector, 1 << x)) { strcat(buf, race_table[x]->race_name); strcat(buf, " "); } if ((x = strlen(buf)) > 0) buf[--x] = '\0'; return buf; } /* * Given the Morph's name, returns the pointer to the morph structure. * --Shaddai */ MORPH_DATA *get_morph(char *arg) { MORPH_DATA *morph; if (arg[0] == '\0') return NULL; for (morph = morph_start; morph; morph = morph->next) if (!str_cmp(morph->name, arg)) break; return morph; } /* * Find a morph you can use -- Shaddai */ MORPH_DATA *find_morph(CHAR_DATA * ch, char *target, bool is_cast) { MORPH_DATA *morph; if (target[0] == '\0') return NULL; for (morph = morph_start; morph; morph = morph->next) { if (str_cmp(morph->name, target)) continue; if (can_morph(ch, morph, is_cast)) break; } return morph; } /* * Given the Morph's vnum, returns the pointer to the morph structure. * --Shaddai */ MORPH_DATA *get_morph_vnum(int vnum) { MORPH_DATA *morph; if (vnum < 1) return NULL; for (morph = morph_start; morph; morph = morph->next) if (morph->vnum == vnum) break; return morph; } /* * These functions wrap the sending of morph stuff, with morphing the code. * In most cases this is what should be called in the code when using spells, * obj morphing, etc... --Shaddai */ int do_morph_char(CHAR_DATA * ch, MORPH_DATA * morph) { bool canmorph = TRUE; OBJ_DATA *obj; OBJ_DATA *tmpobj; if (ch->morph) canmorph = FALSE; if (morph->obj[0]) { if ((obj = get_obj_vnum(ch, morph->obj[0])) == NULL) canmorph = FALSE; else if (morph->objuse[0]) { act(AT_OBJECT, "$p disappears in a whisp of smoke!", obj->carried_by, obj, NULL, TO_CHAR); if (obj == get_eq_char(obj->carried_by, WEAR_WIELD) && (tmpobj = get_eq_char(obj->carried_by, WEAR_DUAL_WIELD)) != NULL) tmpobj->wear_loc = WEAR_WIELD; separate_obj(obj); extract_obj(obj); } } if (morph->obj[1]) { if ((obj = get_obj_vnum(ch, morph->obj[1])) == NULL) canmorph = FALSE; else if (morph->objuse[1]) { act(AT_OBJECT, "$p disappears in a whisp of smoke!", obj->carried_by, obj, NULL, TO_CHAR); if (obj == get_eq_char(obj->carried_by, WEAR_WIELD) && (tmpobj = get_eq_char(obj->carried_by, WEAR_DUAL_WIELD)) != NULL) tmpobj->wear_loc = WEAR_WIELD; separate_obj(obj); extract_obj(obj); } } if (morph->obj[2]) { if ((obj = get_obj_vnum(ch, morph->obj[2])) == NULL) canmorph = FALSE; else if (morph->objuse[2]) { act(AT_OBJECT, "$p disappears in a whisp of smoke!", obj->carried_by, obj, NULL, TO_CHAR); if (obj == get_eq_char(obj->carried_by, WEAR_WIELD) && (tmpobj = get_eq_char(obj->carried_by, WEAR_DUAL_WIELD)) != NULL) tmpobj->wear_loc = WEAR_WIELD; separate_obj(obj); extract_obj(obj); } } if (morph->hpused) { if (ch->hit < morph->hpused) canmorph = FALSE; else ch->hit -= morph->hpused; } if (morph->moveused) { if (ch->move < morph->moveused) canmorph = FALSE; else ch->move -= morph->moveused; } if (morph->manaused && !IS_VAMPIRE(ch)) { if (ch->mana < morph->manaused) canmorph = FALSE; else ch->mana -= morph->manaused; } if (morph->bloodused && IS_VAMPIRE(ch)) { if (ch->pcdata->condition[COND_BLOODTHIRST] < morph->bloodused) canmorph = FALSE; else ch->pcdata->condition[COND_BLOODTHIRST] -= morph->bloodused; } if (morph->favourused) { if (IS_NPC(ch) || !ch->pcdata->deity || ch->pcdata->favor < morph->favourused) canmorph = FALSE; else { ch->pcdata->favor -= morph->favourused; if (ch->pcdata->favor < ch->pcdata->deity->susceptnum) SET_BIT(ch->susceptible, ch->pcdata->deity->suscept); } } if (morph->gloryused) { if (!IS_NPC(ch) && ch->pcdata->quest_curr < morph->gloryused) canmorph = FALSE; else ch->pcdata->quest_curr -= morph->gloryused; } if (!canmorph) { send_to_char("You begin to transform, but something goes wrong.\n\r", ch); return FALSE; } send_morph_message(ch, morph, TRUE); do_morph(ch, morph); return TRUE; } void do_unmorph_char(CHAR_DATA * ch) { MORPH_DATA *temp; if (!ch->morph) return; temp = ch->morph->morph; do_unmorph(ch); send_morph_message(ch, temp, FALSE); return; } /* * This function sends the morph/unmorph message to the people in the room. * -- Shaddai */ void send_morph_message(CHAR_DATA * ch, MORPH_DATA * morph, bool is_morph) { if (morph == NULL) return; if (is_morph) { act(AT_MORPH, morph->morph_other, ch, NULL, NULL, TO_ROOM); act(AT_MORPH, morph->morph_self, ch, NULL, NULL, TO_CHAR); } else { act(AT_MORPH, morph->unmorph_other, ch, NULL, NULL, TO_ROOM); act(AT_MORPH, morph->unmorph_self, ch, NULL, NULL, TO_CHAR); } return; } /* * Checks to see if the char meets all the requirements to morph into * the provided morph. Doesn't Look at NPC's class or race as they * are different from pc's, but still checks level and if they can * cast it or not. --Shaddai */ bool can_morph(CHAR_DATA * ch, MORPH_DATA * morph, bool is_cast) { if (morph == NULL) return FALSE; if (IS_IMMORTAL(ch) || IS_NPC(ch)) /* Let immortals morph to anything Also NPC can do any morph */ return TRUE; if (morph->no_cast && is_cast) return FALSE; if (ch->level < morph->level) return FALSE; if (morph->sex != -1 && morph->sex != ch->sex) return FALSE; if (morph->race != 0 && IS_SET(morph->race, (1 << ch->race))) return FALSE; if (morph->deity && (!ch->pcdata->deity || !get_deity(morph->deity))) return FALSE; if (morph->timeto != -1 && morph->timefrom != -1 && (morph->timeto < gethour() || morph->timefrom > gethour())) return FALSE; if (morph->dayfrom != -1 && morph->dayto != -1 && (morph->dayto < (getday() + 1) || morph->dayfrom > (getday() + 1))) return FALSE; return TRUE; } /* * Workhorse of the polymorph code, this turns the player into the proper * morph. Doesn't check if you can morph or not so must use can_morph before * this is called. That is so we can let people morph into things without * checking. Also, if anything is changed here, make sure it gets changed * in do_unmorph otherwise you will be giving your player stats for free. * This also does not send the message to people when you morph good to * use in save functions. * --Shaddai */ void do_morph(CHAR_DATA * ch, MORPH_DATA * morph) { CHAR_MORPH *ch_morph; if (!morph) return; if (ch->morph) do_unmorph_char(ch); ch_morph = make_char_morph(morph); ch->armor += morph->ac; ch->mod_str += morph->str; ch->mod_int += morph->inte; ch->mod_wis += morph->wis; ch->mod_dex += morph->dex; ch->mod_cha += morph->cha; ch->mod_lck += morph->lck; ch->saving_breath += morph->saving_breath; ch->saving_para_petri += morph->saving_para_petri; ch->saving_poison_death += morph->saving_poison_death; ch->saving_spell_staff += morph->saving_spell_staff; ch->saving_wand += morph->saving_wand; ch_morph->hitroll = dice_parse(ch, morph->level, morph->hitroll, 1); ch->hitroll += ch_morph->hitroll; ch_morph->damroll = dice_parse(ch, morph->level, morph->damroll, 1); ch->damroll += ch_morph->damroll; ch_morph->hit = dice_parse(ch, morph->level, morph->hit, 1); if ((ch->hit + ch_morph->hit) > MAX_HPMANA) ch_morph->hit = (MAX_HPMANA - ch->hit); ch->hit += ch_morph->hit; ch_morph->move = dice_parse(ch, morph->level, morph->move, 1); if ((ch->move + ch_morph->move) > 32700) ch_morph->move = (32700 - ch->move); ch->move += ch_morph->move; if (!IS_NPC(ch) && IS_VAMPIRE(ch)) { ch_morph->blood = dice_parse(ch, morph->level, morph->blood, 1); ch->pcdata->condition[COND_BLOODTHIRST] += ch_morph->blood; } else { ch_morph->mana = dice_parse(ch, morph->level, morph->mana, 1); if ((ch->mana + ch_morph->mana) > MAX_HPMANA) ch_morph->mana = (MAX_HPMANA - ch->mana); ch->mana += ch_morph->mana; } xSET_BITS(ch->affected_by, morph->affected_by); SET_BIT(ch->immune, morph->immune); SET_BIT(ch->resistant, morph->resistant); SET_BIT(ch->susceptible, morph->suscept); xREMOVE_BITS(ch->affected_by, morph->no_affected_by); REMOVE_BIT(ch->immune, morph->no_immune); REMOVE_BIT(ch->resistant, morph->no_resistant); REMOVE_BIT(ch->susceptible, morph->no_suscept); ch->morph = ch_morph; morph->used++; return; } /* * This makes sure to take all the affects given to the player by the morph * away. Several things to keep in mind. If you add something here make * sure you add it to do_morph as well (Unless you want to charge your players * for morphing ;) ). Also make sure that their pfile saves with the morph * affects off, as the morph may not exist when they log back in. This * function also does not send the message to people when you morph so it is * good to use in save functions and other places you don't want people to * see the stuff. * --Shaddai */ void do_unmorph(CHAR_DATA * ch) { CHAR_MORPH *morph; if ((morph = ch->morph) == NULL) return; ch->armor -= morph->ac; ch->mod_str -= morph->str; ch->mod_int -= morph->inte; ch->mod_wis -= morph->wis; ch->mod_dex -= morph->dex; ch->mod_cha -= morph->cha; ch->mod_lck -= morph->lck; ch->saving_breath -= morph->saving_breath; ch->saving_para_petri -= morph->saving_para_petri; ch->saving_poison_death -= morph->saving_poison_death; ch->saving_spell_staff -= morph->saving_spell_staff; ch->saving_wand -= morph->saving_wand; ch->hitroll -= morph->hitroll; ch->damroll -= morph->damroll; ch->hit -= morph->hit; ch->move -= morph->move; if (!IS_NPC(ch) && IS_VAMPIRE(ch)) ch->pcdata->condition[COND_BLOODTHIRST] -= morph->blood; else ch->mana -= morph->mana; xREMOVE_BITS(ch->affected_by, morph->affected_by); REMOVE_BIT(ch->immune, morph->immune); REMOVE_BIT(ch->resistant, morph->resistant); REMOVE_BIT(ch->susceptible, morph->suscept); free_char_morph(ch->morph); ch->morph = NULL; update_aris(ch); return; } /* * This function saves the morph data. Should be put in on reboot or shutdown * to make use of the sort algorithim. --Shaddai */ void save_morphs() { MORPH_DATA *morph; FILE *fp; fclose(fpReserve); if ((fp = fopen(SYSTEM_DIR MORPH_FILE, "w")) == NULL) { bug("Save_morph: fopen", 0); perror(SYSTEM_DIR MORPH_FILE); fpReserve = fopen(NULL_FILE, "r"); return; } for (morph = morph_start; morph; morph = morph->next) fwrite_morph(fp, morph); fprintf(fp, "#END\n"); fclose(fp); fpReserve = fopen(NULL_FILE, "r"); return; } /* * Write one morph structure to a file. It doesn't print the variable to file * if it hasn't been set why waste disk-space :) --Shaddai */ void fwrite_morph(FILE * fp, MORPH_DATA * morph) { if (!morph) return; fprintf(fp, "Morph %s\n", morph->name); if (morph->obj[0] != 0 || morph->obj[1] != 0 || morph->obj[2] != 0) fprintf(fp, "Objs %d %d %d\n", morph->obj[0], morph->obj[1], morph->obj[2]); if (morph->objuse[0] != 0 || morph->objuse[1] != 0 || morph->objuse[2] != 0) fprintf(fp, "Objuse %d %d %d\n", morph->objuse[0], morph->objuse[1], morph->objuse[2]); if (morph->vnum != 0) fprintf(fp, "Vnum %d\n", morph->vnum); if (morph->blood[0] != '\0') fprintf(fp, "Blood %s~\n", morph->blood); if (morph->damroll[0] != '\0') fprintf(fp, "Damroll %s~\n", morph->damroll); if (morph->defpos != POS_STANDING) fprintf(fp, "Defpos %d\n", morph->defpos); if (morph->description[0] != '\0') fprintf(fp, "Description %s~\n", morph->description); if (morph->help[0] != '\0') fprintf(fp, "Help %s~\n", morph->help); if (morph->hit[0] != '\0') fprintf(fp, "Hit %s~\n", morph->hit); if (morph->hitroll[0] != '\0') fprintf(fp, "Hitroll %s~\n", morph->hitroll); if (morph->key_words[0] != '\0') fprintf(fp, "Keywords %s~\n", morph->key_words); if (morph->long_desc[0] != '\0') fprintf(fp, "Longdesc %s~\n", morph->long_desc); if (morph->mana[0] != '\0') fprintf(fp, "Mana %s~\n", morph->mana); if (morph->morph_other[0] != '\0') fprintf(fp, "MorphOther %s~\n", morph->morph_other); if (morph->morph_self[0] != '\0') fprintf(fp, "MorphSelf %s~\n", morph->morph_self); if (morph->move[0] != '\0') fprintf(fp, "Move %s~\n", morph->move); if (morph->no_skills[0] != '\0') fprintf(fp, "NoSkills %s~\n", morph->no_skills); if (morph->short_desc[0] != '\0') fprintf(fp, "ShortDesc %s~\n", morph->short_desc); if (morph->skills[0] != '\0') fprintf(fp, "Skills %s~\n", morph->skills); if (morph->unmorph_other[0] != '\0') fprintf(fp, "UnmorphOther %s~\n", morph->unmorph_other); if (morph->unmorph_self[0] != '\0') fprintf(fp, "UnmorphSelf %s~\n", morph->unmorph_self); if (!xIS_EMPTY(morph->affected_by)) fprintf(fp, "Affected %s\n", print_bitvector(&morph->affected_by)); if (morph->immune != 0) fprintf(fp, "Immune %d\n", morph->immune); if (!xIS_EMPTY(morph->no_affected_by)) fprintf(fp, "NoAffected %s\n", print_bitvector(&morph->no_affected_by)); if (morph->no_immune != 0) fprintf(fp, "NoImmune %d\n", morph->no_immune); if (morph->no_resistant != 0) fprintf(fp, "NoResistant %d\n", morph->no_resistant); if (morph->no_suscept != 0) fprintf(fp, "NoSuscept %d\n", morph->no_suscept); if (morph->race != 0) fprintf(fp, "Race %s~\n", race_string(morph->race)); if (morph->resistant != 0) fprintf(fp, "Resistant %d\n", morph->resistant); if (morph->suscept != 0) fprintf(fp, "Suscept %d\n", morph->suscept); if (morph->used != 0) fprintf(fp, "Used %d\n", morph->used); if (morph->sex != -1) fprintf(fp, "Sex %d\n", morph->sex); if (morph->pkill != 0) fprintf(fp, "Pkill %d\n", morph->pkill); if (morph->timefrom != -1) fprintf(fp, "TimeFrom %d\n", morph->timefrom); if (morph->timeto != -1) fprintf(fp, "TimeTo %d\n", morph->timeto); if (morph->dayfrom != -1) fprintf(fp, "DayFrom %d\n", morph->dayfrom); if (morph->dayto != -1) fprintf(fp, "DayTo %d\n", morph->dayto); if (morph->bloodused != 0) fprintf(fp, "BloodUsed %d\n", morph->bloodused); if (morph->manaused != 0) fprintf(fp, "ManaUsed %d\n", morph->manaused); if (morph->moveused != 0) fprintf(fp, "MoveUsed %d\n", morph->moveused); if (morph->hpused != 0) fprintf(fp, "HpUsed %d\n", morph->hpused); if (morph->favourused != 0) fprintf(fp, "FavourUsed %d\n", morph->favourused); if (morph->gloryused != 0) fprintf(fp, "GloryUsed %d\n", morph->gloryused); if (morph->ac != 0) fprintf(fp, "Armor %d\n", morph->ac); if (morph->cha != 0) fprintf(fp, "Charisma %d\n", morph->cha); if (morph->con != 0) fprintf(fp, "Constitution %d\n", morph->con); if (morph->dex != 0) fprintf(fp, "Dexterity %d\n", morph->dex); if (morph->dodge != 0) fprintf(fp, "Dodge %d\n", morph->dodge); if (morph->inte != 0) fprintf(fp, "Intelligence %d\n", morph->inte); if (morph->lck != 0) fprintf(fp, "Luck %d\n", morph->lck); if (morph->level != 0) fprintf(fp, "Level %d\n", morph->level); if (morph->parry != 0) fprintf(fp, "Parry %d\n", morph->parry); if (morph->saving_breath != 0) fprintf(fp, "SaveBreath %d\n", morph->saving_breath); if (morph->saving_para_petri != 0) fprintf(fp, "SavePara %d\n", morph->saving_para_petri); if (morph->saving_poison_death != 0) fprintf(fp, "SavePoison %d\n", morph->saving_poison_death); if (morph->saving_spell_staff != 0) fprintf(fp, "SaveSpell %d\n", morph->saving_spell_staff); if (morph->saving_wand != 0) fprintf(fp, "SaveWand %d\n", morph->saving_wand); if (morph->str != 0) fprintf(fp, "Strength %d\n", morph->str); if (morph->tumble != 0) fprintf(fp, "Tumble %d\n", morph->tumble); if (morph->wis != 0) fprintf(fp, "Wisdom %d\n", morph->wis); if (morph->no_cast) fprintf(fp, "NoCast %d\n", morph->no_cast); fprintf(fp, "End\n\n"); return; } /* * This function loads in the morph data. Note that this function MUST be * used AFTER the race and class tables have been read in and setup. * --Shaddai */ void load_morphs() { MORPH_DATA *morph; char buf[MIL]; char *word; FILE *fp; bool my_continue = TRUE; bool fMatch = FALSE; if ((fp = fopen(SYSTEM_DIR MORPH_FILE, "r")) == NULL) { bug("Load_morph: fopen", 0); perror(SYSTEM_DIR MORPH_FILE); return; } while (my_continue) { morph = NULL; word = feof(fp) ? "#END" : fread_word(fp); fMatch = FALSE; switch (UPPER(word[0])) { case '#': if (!str_cmp(word, "#END")) { fclose(fp); fMatch = TRUE; my_continue = FALSE; break; } break; case 'M': if (!str_cmp(word, "Morph")) { morph = fread_morph(fp); fMatch = TRUE; } break; } if (!fMatch) { sprintf(buf, "Fread_morph: no match: %s", word); bug(buf, 0); } if (morph) LINK(morph, morph_start, morph_end, next, prev); } if (sysdata.morph_opt) { log_string("Optimizing Morphs."); sort_morphs(); } setup_morph_vnum(); log_string("Done."); return; } /* * Read in one morph structure */ MORPH_DATA *fread_morph(FILE * fp) { MORPH_DATA *morph; char buf[MIL]; char *arg; char temp[MSL]; char *word; int i; bool fMatch; word = feof(fp) ? "End" : fread_word(fp); if (!str_cmp(word, "End")) return NULL; CREATE(morph, MORPH_DATA, 1); morph_defaults(morph); morph->name = str_dup(word); for (;;) { word = feof(fp) ? "End" : fread_word(fp); fMatch = FALSE; switch (UPPER(word[0])) { case 'A': KEY("Armor", morph->ac, fread_number(fp)); KEY("Affected", morph->affected_by, fread_bitvector(fp)); break; case 'B': KEY("Blood", morph->blood, fread_string_nohash(fp)); KEY("BloodUsed", morph->bloodused, fread_number(fp)); break; case 'C': KEY("Charisma", morph->cha, fread_number(fp)); KEY("Constitution", morph->con, fread_number(fp)); break; case 'D': KEY("Damroll", morph->damroll, fread_string_nohash(fp)); KEY("DayFrom", morph->dayfrom, fread_number(fp)); KEY("DayTo", morph->dayto, fread_number(fp)); KEY("Defpos", morph->defpos, fread_number(fp)); KEY("Description", morph->description, fread_string_nohash(fp)); KEY("Dexterity", morph->dex, fread_number(fp)); KEY("Dodge", morph->dodge, fread_number(fp)); break; case 'E': if (!str_cmp(word, "End")) return morph; break; case 'F': KEY("FavourUsed", morph->favourused, fread_number(fp)); break; case 'G': KEY("GloryUsed", morph->gloryused, fread_number(fp)); break; case 'H': KEY("Help", morph->help, fread_string_nohash(fp)); KEY("Hit", morph->hit, fread_string_nohash(fp)); KEY("Hitroll", morph->hitroll, fread_string_nohash(fp)); KEY("HpUsed", morph->hpused, fread_number(fp)); break; case 'I': KEY("Intelligence", morph->inte, fread_number(fp)); KEY("Immune", morph->immune, fread_number(fp)); break; case 'K': KEY("Keywords", morph->key_words, fread_string_nohash(fp)); break; case 'L': KEY("Level", morph->level, fread_number(fp)); KEY("Longdesc", morph->long_desc, fread_string_nohash(fp)); KEY("Luck", morph->lck, fread_number(fp)); break; case 'M': KEY("Mana", morph->mana, fread_string_nohash(fp)); KEY("ManaUsed", morph->manaused, fread_number(fp)); KEY("MorphOther", morph->morph_other, fread_string_nohash(fp)); KEY("MorphSelf", morph->morph_self, fread_string_nohash(fp)); KEY("Move", morph->morph_self, fread_string_nohash(fp)); KEY("MoveUsed", morph->moveused, fread_number(fp)); break; case 'N': KEY("NoAffected", morph->no_affected_by, fread_bitvector(fp)); KEY("NoImmune", morph->no_immune, fread_number(fp)); KEY("NoResistant", morph->no_resistant, fread_number(fp)); KEY("NoSkills", morph->no_skills, fread_string_nohash(fp)); KEY("NoSuscept", morph->no_suscept, fread_number(fp)); if (!str_cmp(word, "NoCast")) { fMatch = TRUE; morph->no_cast = fread_number(fp); } break; case 'O': if (!str_cmp(word, "Objs")) { fMatch = TRUE; morph->obj[0] = fread_number(fp); morph->obj[1] = fread_number(fp); morph->obj[2] = fread_number(fp); } if (!str_cmp(word, "Objuse")) { fMatch = TRUE; morph->objuse[0] = fread_number(fp); morph->objuse[1] = fread_number(fp); morph->objuse[2] = fread_number(fp); } break; case 'P': KEY("Parry", morph->parry, fread_number(fp)); KEY("Pkill", morph->pkill, fread_number(fp)); break; case 'R': if (!str_cmp(word, "Race")) { fMatch = TRUE; arg = fread_string_nohash(fp); arg = one_argument(arg, temp); while (temp[0] != '\0') { for (i = 0; i < MAX_RACE; i++) if (!str_cmp(temp, race_table[i]->race_name)) { SET_BIT(morph->race, (1 << i)); break; } arg = one_argument(arg, temp); } } KEY("Resistant", morph->resistant, fread_number(fp)); break; case 'S': KEY("SaveBreath", morph->saving_breath, fread_number(fp)); KEY("SavePara", morph->saving_para_petri, fread_number(fp)); KEY("SavePoison", morph->saving_poison_death, fread_number(fp)); KEY("SaveSpell", morph->saving_spell_staff, fread_number(fp)); KEY("SaveWand", morph->saving_wand, fread_number(fp)); KEY("Sex", morph->sex, fread_number(fp)); KEY("ShortDesc", morph->short_desc, fread_string_nohash(fp)); KEY("Skills", morph->skills, fread_string_nohash(fp)); KEY("Strength", morph->str, fread_number(fp)); KEY("Suscept", morph->suscept, fread_number(fp)); break; case 'T': KEY("TimeFrom", morph->timefrom, fread_number(fp)); KEY("TimeTo", morph->timeto, fread_number(fp)); KEY("Tumble", morph->tumble, fread_number(fp)); break; case 'U': KEY("UnmorphOther", morph->unmorph_other, fread_string_nohash(fp)); KEY("UnmorphSelf", morph->unmorph_self, fread_string_nohash(fp)); KEY("Used", morph->used, fread_number(fp)); break; case 'V': KEY("Vnum", morph->vnum, fread_number(fp)); break; case 'W': KEY("Wisdom", morph->wis, fread_number(fp)); break; } if (!fMatch) { sprintf(buf, "Fread_morph: no match: %s", word); bug(buf, 0); /* Bailing out on this morph as something may be messed up * this is going to have lots of bugs from the load_morphs this * way, but it is better than possibly having the memory messed * up! --Shaddai */ free_morph(morph); return NULL; } } } /* * Function that releases all the memory for a morph struct. Carefull not * to use the memory afterwards as it doesn't exist. * --Shaddai */ void free_morph(MORPH_DATA * morph) { if (!morph) return; if (morph->blood) DISPOSE(morph->blood); if (morph->damroll) DISPOSE(morph->damroll); if (morph->description) DISPOSE(morph->description); if (morph->help) DISPOSE(morph->help); if (morph->hit) DISPOSE(morph->hit); if (morph->hitroll) DISPOSE(morph->hitroll); if (morph->key_words) DISPOSE(morph->key_words); if (morph->long_desc) DISPOSE(morph->long_desc); if (morph->mana) DISPOSE(morph->mana); if (morph->morph_other) DISPOSE(morph->morph_other); if (morph->morph_self) DISPOSE(morph->morph_self); if (morph->move) DISPOSE(morph->move); if (morph->name) DISPOSE(morph->name); if (morph->short_desc) DISPOSE(morph->short_desc); if (morph->skills) DISPOSE(morph->skills); if (morph->no_skills) DISPOSE(morph->no_skills); if (morph->unmorph_other) DISPOSE(morph->unmorph_other); if (morph->unmorph_self) DISPOSE(morph->unmorph_self); DISPOSE(morph); return; } /* * This function set's up all the default values for a morph */ void morph_defaults(MORPH_DATA * morph) { morph->blood = str_dup(""); morph->damroll = str_dup(""); morph->description = str_dup(""); morph->help = str_dup(""); morph->hit = str_dup(""); morph->hitroll = str_dup(""); morph->key_words = str_dup(""); morph->long_desc = str_dup(""); morph->mana = str_dup(""); morph->morph_other = str_dup(""); morph->morph_self = str_dup(""); morph->move = str_dup(""); morph->name = str_dup(""); morph->short_desc = str_dup(""); morph->skills = str_dup(""); morph->no_skills = str_dup(""); morph->unmorph_other = str_dup(""); morph->unmorph_self = str_dup(""); xCLEAR_BITS(morph->affected_by); morph->sex = -1; morph->timefrom = -1; morph->timeto = -1; morph->dayfrom = -1; morph->dayto = -1; morph->pkill = 0; morph->bloodused = 0; morph->manaused = 0; morph->moveused = 0; morph->hpused = 0; morph->favourused = 0; morph->gloryused = 0; morph->immune = 0; xCLEAR_BITS(morph->no_affected_by); morph->no_immune = 0; morph->no_resistant = 0; morph->no_suscept = 0; morph->obj[0] = 0; morph->obj[1] = 0; morph->obj[2] = 0; morph->objuse[0] = FALSE; morph->objuse[1] = FALSE; morph->objuse[2] = FALSE; morph->race = 0; morph->resistant = 0; morph->suscept = 0; morph->used = 0; morph->ac = 0; morph->defpos = POS_STANDING; morph->dex = 0; morph->dodge = 0; morph->cha = 0; morph->con = 0; morph->inte = 0; morph->lck = 0; morph->level = 0; morph->parry = 0; morph->saving_breath = 0; morph->saving_para_petri = 0; morph->saving_poison_death = 0; morph->saving_spell_staff = 0; morph->saving_wand = 0; morph->str = 0; morph->tumble = 0; morph->wis = 0; morph->no_cast = FALSE; morph->timer = -1; morph->vnum = 0; return; } /* * This function copys one morph structure to another */ void copy_morph(MORPH_DATA * morph, MORPH_DATA * temp) { morph->blood = str_dup(temp->blood); morph->damroll = str_dup(temp->damroll); morph->description = str_dup(temp->description); morph->help = str_dup(temp->help); morph->hit = str_dup(temp->hit); morph->hitroll = str_dup(temp->hitroll); morph->key_words = str_dup(temp->key_words); morph->long_desc = str_dup(temp->long_desc); morph->mana = str_dup(temp->mana); morph->morph_other = str_dup(temp->morph_other); morph->morph_self = str_dup(temp->morph_self); morph->move = str_dup(temp->move); morph->name = str_dup(temp->name); morph->short_desc = str_dup(temp->short_desc); morph->skills = str_dup(temp->skills); morph->no_skills = str_dup(temp->no_skills); morph->unmorph_other = str_dup(temp->unmorph_other); morph->unmorph_self = str_dup(temp->unmorph_self); morph->affected_by = temp->affected_by; morph->sex = temp->sex; morph->timefrom = temp->timefrom; morph->timeto = temp->timeto; morph->timefrom = temp->timefrom; morph->dayfrom = temp->dayfrom; morph->dayto = temp->dayto; morph->pkill = temp->pkill; morph->manaused = temp->manaused; morph->bloodused = temp->bloodused; morph->moveused = temp->moveused; morph->hpused = temp->hpused; morph->favourused = temp->favourused; morph->gloryused = temp->gloryused; morph->immune = temp->immune; morph->no_affected_by = temp->no_affected_by; morph->no_immune = temp->no_immune; morph->no_resistant = temp->no_resistant; morph->no_suscept = temp->no_suscept; morph->obj[0] = temp->obj[0]; morph->obj[1] = temp->obj[1]; morph->obj[2] = temp->obj[2]; morph->objuse[0] = temp->objuse[0]; morph->objuse[1] = temp->objuse[1]; morph->objuse[2] = temp->objuse[2]; morph->race = temp->race; morph->resistant = temp->resistant; morph->suscept = temp->suscept; morph->ac = temp->ac; morph->defpos = temp->defpos; morph->dex = temp->dex; morph->dodge = temp->dodge; morph->cha = temp->cha; morph->con = temp->con; morph->inte = temp->inte; morph->lck = temp->lck; morph->level = temp->level; morph->parry = temp->parry; morph->saving_breath = temp->saving_breath; morph->saving_para_petri = temp->saving_para_petri; morph->saving_poison_death = temp->saving_poison_death; morph->saving_spell_staff = temp->saving_spell_staff; morph->saving_wand = temp->saving_wand; morph->str = temp->str; morph->tumble = temp->tumble; morph->wis = temp->wis; morph->no_cast = temp->no_cast; morph->timer = temp->timer; return; } /* * This is to move the more used morphs to the beginning hopefully saving * that .000000001 second ;) --Shaddai */ void sort_morphs() { MORPH_DATA *morph, *temp; int fMatch; /* This is slow and the wrong way to code it but I am tired and have more * Important things to-do :) Also it is only done at boot-up so who cares * if it is slow or not. --Shaddai */ do { fMatch = FALSE; if (morph_start == NULL) return; for (morph = morph_start, temp = morph->next; morph && temp; morph = morph->next, temp = temp->next) { if (morph->used < temp->used) { if (morph == morph_start) morph_start = temp; if (temp == morph_end) morph_end = morph; if (morph->prev) morph->prev->next = temp; if (temp->next) temp->next->prev = morph; temp->prev = morph->prev; morph->next = temp->next; temp->next = morph; morph->prev = temp; fMatch = TRUE; break; } } } while (fMatch); return; } /* * Create new player morph, a scailed down version of original morph * so if morph gets changed stats don't get messed up. */ CHAR_MORPH *make_char_morph(MORPH_DATA * morph) { CHAR_MORPH *ch_morph; if (morph == NULL) return NULL; CREATE(ch_morph, CHAR_MORPH, 1); ch_morph->morph = morph; ch_morph->ac = morph->ac; ch_morph->str = morph->str; ch_morph->inte = morph->inte; ch_morph->wis = morph->wis; ch_morph->dex = morph->dex; ch_morph->cha = morph->cha; ch_morph->lck = morph->lck; ch_morph->saving_breath = morph->saving_breath; ch_morph->saving_para_petri = morph->saving_para_petri; ch_morph->saving_poison_death = morph->saving_poison_death; ch_morph->saving_spell_staff = morph->saving_spell_staff; ch_morph->saving_wand = morph->saving_wand; ch_morph->timer = morph->timer; ch_morph->hitroll = 0; ch_morph->damroll = 0; ch_morph->hit = 0; ch_morph->mana = 0; ch_morph->move = 0; ch_morph->blood = 0; ch_morph->affected_by = morph->affected_by; ch_morph->immune = morph->immune; ch_morph->resistant = morph->resistant; ch_morph->suscept = morph->suscept; ch_morph->no_affected_by = morph->no_affected_by; ch_morph->no_immune = morph->no_immune; ch_morph->no_resistant = morph->no_resistant; ch_morph->no_suscept = morph->no_suscept; return ch_morph; } /* * Player command to create a new morph */ void do_morphcreate(CHAR_DATA * ch, char *argument) { MORPH_DATA *morph; MORPH_DATA *temp = NULL; char arg1[MIL]; char arg2[MIL]; argument = one_argument(argument, arg1); argument = one_argument(argument, arg2); if (arg1[0] == '\0') { send_to_char("Usage: morphcreate <name>\n\r", ch); send_to_char("Usage: morphcreate <name/vnum> copy\n\r", ch); return; } if (arg2[0] != '\0' && !str_cmp(arg2, "copy")) { if (is_number(arg1)) { if ((temp = get_morph_vnum(atoi(arg1))) == NULL) { ch_printf(ch, "No such morph vnum %d exists.\n\r", atoi(arg1)); return; } } else if ((temp = get_morph(arg1)) == NULL) { ch_printf(ch, "No such morph %s exists.\n\r", arg1); return; } } smash_tilde(arg1); CREATE(morph, MORPH_DATA, 1); morph_defaults(morph); if (morph->name) DISPOSE(morph->name); if (arg2[0] != '\0' && !str_cmp(arg2, "copy") && temp) copy_morph(morph, temp); else morph->name = str_dup(arg1); morph->vnum = morph_vnum; morph_vnum++; LINK(morph, morph_start, morph_end, next, prev); ch_printf(ch, "Morph %s created with vnum %d.\n\r", morph->name, morph->vnum); return; } /* * Player function to delete a morph. --Shaddai * NOTE Need to check all players and force them to unmorph first */ void do_morphdestroy(CHAR_DATA * ch, char *argument) { MORPH_DATA *morph; char arg[MIL]; one_argument(argument, arg); if (is_number(arg)) morph = get_morph_vnum(atoi(arg)); else morph = get_morph(arg); if (!morph) { ch_printf(ch, "Unkown morph %s.\n\r", arg); return; } unmorph_all(morph); UNLINK(morph, morph_start, morph_end, next, prev); free_morph(morph); send_to_char("Morph deleted.\n\r", ch); return; } void free_char_morph(CHAR_MORPH * morph) { /* Boy this is easy but better to keep it a seperate function for later * possible complications. --Shaddai */ DISPOSE(morph); return; } void fwrite_morph_data(CHAR_DATA * ch, FILE * fp) { CHAR_MORPH *morph; if (ch->morph == NULL) return; morph = ch->morph; fprintf(fp, "#MorphData\n"); /* Only Print Out what is necessary */ if (morph->morph != NULL) { fprintf(fp, "Vnum %d\n", morph->morph->vnum); fprintf(fp, "Name %s~\n", morph->morph->name); } if (!xIS_EMPTY(morph->affected_by)) fprintf(fp, "Affect %s\n", print_bitvector(&morph->affected_by)); if (morph->immune != 0) fprintf(fp, "Immune %d\n", morph->immune); if (morph->resistant != 0) fprintf(fp, "Resistant %d\n", morph->resistant); if (morph->suscept != 0) fprintf(fp, "Suscept %d\n", morph->suscept); if (!xIS_EMPTY(morph->no_affected_by)) fprintf(fp, "NoAffect %s\n", print_bitvector(&morph->no_affected_by)); if (morph->no_immune != 0) fprintf(fp, "NoImmune %d\n", morph->no_immune); if (morph->no_resistant != 0) fprintf(fp, "NoResistant %d\n", morph->no_resistant); if (morph->no_suscept != 0) fprintf(fp, "NoSuscept %d\n", morph->no_suscept); if (morph->ac != 0) fprintf(fp, "Armor %d\n", morph->ac); if (morph->blood != 0) fprintf(fp, "Blood %d\n", morph->blood); if (morph->cha != 0) fprintf(fp, "Charisma %d\n", morph->cha); if (morph->con != 0) fprintf(fp, "Constitution %d\n", morph->con); if (morph->damroll != 0) fprintf(fp, "Damroll %d\n", morph->damroll); if (morph->dex != 0) fprintf(fp, "Dexterity %d\n", morph->dex); if (morph->dodge != 0) fprintf(fp, "Dodge %d\n", morph->dodge); if (morph->hit != 0) fprintf(fp, "Hit %d\n", morph->hit); if (morph->hitroll != 0) fprintf(fp, "Hitroll %d\n", morph->hitroll); if (morph->inte != 0) fprintf(fp, "Intelligence %d\n", morph->inte); if (morph->lck != 0) fprintf(fp, "Luck %d\n", morph->lck); if (morph->mana != 0) fprintf(fp, "Mana %d\n", morph->mana); if (morph->move != 0) fprintf(fp, "Move %d\n", morph->move); if (morph->parry != 0) fprintf(fp, "Parry %d\n", morph->parry); if (morph->saving_breath != 0) fprintf(fp, "Save1 %d\n", morph->saving_breath); if (morph->saving_para_petri != 0) fprintf(fp, "Save2 %d\n", morph->saving_para_petri); if (morph->saving_poison_death != 0) fprintf(fp, "Save3 %d\n", morph->saving_poison_death); if (morph->saving_spell_staff != 0) fprintf(fp, "Save4 %d\n", morph->saving_spell_staff); if (morph->saving_wand != 0) fprintf(fp, "Save5 %d\n", morph->saving_wand); if (morph->str != 0) fprintf(fp, "Strength %d\n", morph->str); if (morph->timer != -1) fprintf(fp, "Timer %d\n", morph->timer); if (morph->tumble != 0) fprintf(fp, "Tumble %d\n", morph->tumble); if (morph->wis != 0) fprintf(fp, "Wisdom %d\n", morph->wis); fprintf(fp, "End\n"); return; } void fread_morph_data(CHAR_DATA * ch, FILE * fp) { CHAR_MORPH *morph; bool fMatch; char *word; char buf[MSL]; CREATE(morph, CHAR_MORPH, 1); clear_char_morph(morph); ch->morph = morph; for (;;) { word = feof(fp) ? "End" : fread_word(fp); fMatch = FALSE; switch (UPPER(word[0])) { case 'A': KEY("Affect", morph->affected_by, fread_bitvector(fp)); KEY("Armor", morph->ac, fread_number(fp)); break; case 'B': KEY("Blood", morph->blood, fread_number(fp)); break; case 'C': KEY("Charisma", morph->cha, fread_number(fp)); KEY("Constitution", morph->con, fread_number(fp)); break; case 'D': KEY("Damroll", morph->damroll, fread_number(fp)); KEY("Dexterity", morph->dex, fread_number(fp)); KEY("Dodge", morph->dodge, fread_number(fp)); break; case 'E': if (!str_cmp("End", word)) return; break; case 'H': KEY("Hit", morph->hit, fread_number(fp)); KEY("Hitroll", morph->hitroll, fread_number(fp)); break; case 'I': KEY("Immune", morph->immune, fread_number(fp)); KEY("Intelligence", morph->inte, fread_number(fp)); break; case 'L': KEY("Luck", morph->lck, fread_number(fp)); break; case 'M': KEY("Mana", morph->mana, fread_number(fp)); KEY("Move", morph->move, fread_number(fp)); break; case 'N': if (!str_cmp("Name", word)) { fMatch = TRUE; if (morph->morph) if (str_cmp(morph->morph->name, fread_string(fp))) bug("Morph Name doesn't match vnum %d.", morph->morph->vnum); } KEY("NoAffect", morph->no_affected_by, fread_bitvector(fp)); KEY("NoImmune", morph->no_immune, fread_number(fp)); KEY("NoResistant", morph->no_resistant, fread_number(fp)); KEY("NoSuscept", morph->no_suscept, fread_number(fp)); break; case 'P': KEY("Parry", morph->parry, fread_number(fp)); break; case 'R': KEY("Resistant", morph->resistant, fread_number(fp)); break; case 'S': KEY("Save1", morph->saving_breath, fread_number(fp)); KEY("Save2", morph->saving_para_petri, fread_number(fp)); KEY("Save3", morph->saving_poison_death, fread_number(fp)); KEY("Save4", morph->saving_spell_staff, fread_number(fp)); KEY("Save5", morph->saving_wand, fread_number(fp)); KEY("Strength", morph->str, fread_number(fp)); KEY("Suscept", morph->suscept, fread_number(fp)); break; case 'T': KEY("Timer", morph->timer, fread_number(fp)); KEY("Tumble", morph->tumble, fread_number(fp)); break; case 'V': if (!str_cmp("Vnum", word)) { fMatch = TRUE; morph->morph = get_morph_vnum(fread_number(fp)); } break; case 'W': KEY("Wisdom", morph->wis, fread_number(fp)); break; } if (!fMatch) { sprintf(buf, "Fread_morph_data: no match: %s", word); bug(buf, 0); } } return; } void clear_char_morph(CHAR_MORPH * morph) { morph->timer = -1; xCLEAR_BITS(morph->affected_by); xCLEAR_BITS(morph->no_affected_by); morph->immune = 0; morph->no_immune = 0; morph->no_resistant = 0; morph->no_suscept = 0; morph->resistant = 0; morph->suscept = 0; morph->ac = 0; morph->blood = 0; morph->cha = 0; morph->con = 0; morph->damroll = 0; morph->dex = 0; morph->dodge = 0; morph->hit = 0; morph->hitroll = 0; morph->inte = 0; morph->lck = 0; morph->mana = 0; morph->parry = 0; morph->saving_breath = 0; morph->saving_para_petri = 0; morph->saving_poison_death = 0; morph->saving_spell_staff = 0; morph->saving_wand = 0; morph->str = 0; morph->tumble = 0; morph->wis = 0; morph->morph = NULL; return; } void setup_morph_vnum(void) { MORPH_DATA *morph; int vnum; vnum = morph_vnum; for (morph = morph_start; morph; morph = morph->next) if (morph->vnum > vnum) vnum = morph->vnum; if (vnum < 1000) vnum = 1000; else vnum++; for (morph = morph_start; morph; morph = morph->next) if (morph->vnum == 0) { morph->vnum = vnum; vnum++; } morph_vnum = vnum; return; } void unmorph_all(MORPH_DATA * morph) { CHAR_DATA *vch; for (vch = first_char; vch; vch = vch->next) { if (IS_NPC(vch)) continue; if (vch->morph == NULL || vch->morph->morph == NULL || vch->morph->morph != morph) continue; do_unmorph_char(vch); } return; } /* * Following functions are for immortal testing purposes. */ void do_imm_morph(CHAR_DATA * ch, char *argument) { MORPH_DATA *morph; CHAR_DATA *victim = NULL; char arg[MIL]; char arg2[MIL]; int vnum; if (IS_NPC(ch)) { send_to_char("Only player characters can use this command.\n\r", ch); return; } argument = one_argument(argument, arg); one_argument(argument, arg2); if (!is_number(arg)) { send_to_char("Syntax: morph <vnum>\n\r", ch); return; } vnum = atoi(arg); morph = get_morph_vnum(vnum); if (morph == NULL) { ch_printf(ch, "No such morph %d exists.\n\r", vnum); return; } if (arg2[0] == '\0') do_morph_char(ch, morph); else if ((victim = get_char_world(ch, arg2)) == NULL) { send_to_char("No one like that in all the realms.\n\r", ch); return; } if (victim != NULL && get_trust(ch) < get_trust(victim) && !IS_NPC(victim)) { send_to_char("You can't do that!\n\r", ch); return; } else if (victim != NULL) do_morph_char(victim, morph); send_to_char("Done.\n\r", ch); return; } /* * This is just a wrapper. --Shaddai */ void do_imm_unmorph(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim = NULL; char arg[MIL]; one_argument(argument, arg); if (arg[0] == '\0') do_unmorph_char(ch); else if ((victim = get_char_world(ch, arg)) == NULL) { send_to_char("No one like that in all the realms.\n\r", ch); return; } if (victim != NULL && get_trust(ch) < get_trust(victim) && !IS_NPC(victim)) { send_to_char("You can't do that!\n\r", ch); return; } else if (victim != NULL) do_unmorph_char(victim); send_to_char("Done.\n\r", ch); return; }