/**************************************************************************r
* 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. *
***************************************************************************/
/**********************************************************
*************** S U N D E R M U D *** 2 . 0 **************
**********************************************************
* The unique portions of the SunderMud code as well as *
* the integration efforts for code from other sources is *
* based primarily on the efforts of: *
* *
* Lotherius <aelfwyne@operamail.com> (Alvin W. Brinson) *
* and many others, see "help sundermud" in the mud. *
**********************************************************/
/* Have removed several unused functions from this file */
#include "everything.h"
/* command procedures needed */
DECLARE_DO_FUN ( do_return );
AFFECT_DATA *affect_free;
/*
* Local functions.
*/
void affect_modify args ( ( CHAR_DATA * ch, AFFECT_DATA * paf, bool fAdd ) );
/* Counts Users on an Object. */
int count_users ( OBJ_DATA * obj )
{
CHAR_DATA *fch;
int count = 0;
if ( obj->in_room == NULL )
return 0;
for ( fch = obj->in_room->people; fch != NULL;
fch = fch->next_in_room )
if ( fch->on == obj )
count++;
return count;
}
/* returns material number */
int material_lookup ( const char *name )
{
int counter;
for ( counter = 0; counter <= MAX_MATERIAL; counter++ )
{
if ( !str_cmp ( material_table[counter].name, name ) )
return material_table[counter].type;
}
return 0;
}
/* returns material name -- ROM OLC temp patch -- doesn't look very temp to me */
char *material_name ( sh_int num )
{
int counter;
for ( counter = 0; counter <= MAX_MATERIAL; counter++ )
{
if ( material_table[counter].type == num )
return material_table[counter].name;
}
return "unknown";
}
/* returns material vulnerability flag */
long material_vuln ( sh_int num )
{
int counter;
for ( counter = 0; counter <= MAX_MATERIAL; counter++ )
{
if ( material_table[counter].type == num )
return material_table[counter].vuln_flag;
}
return 0;
}
/* returns material durability flag */
long material_dura ( sh_int num )
{
int counter;
for ( counter = 0; counter <= MAX_MATERIAL; counter++ )
{
if ( material_table[counter].type == num )
return material_table[counter].durable;
}
return 0;
}
/* returns material repair difficulty */
long material_repa ( sh_int num )
{
int counter;
for ( counter = 0; counter <= MAX_MATERIAL; counter++ )
{
if ( material_table[counter].type == num )
return material_table[counter].difficult;
}
return 0;
}
/* Checks a flag from material flags. */
bool is_material ( sh_int num, long material_flag )
{
int counter;
for ( counter = 0; counter <= MAX_MATERIAL; counter++ )
{
if ( material_table[counter].type == num )
{
if IS_SET ( material_table[counter].flags, material_flag )
return TRUE;
else
return FALSE;
}
}
return FALSE;
}
/* returns race number */
int race_lookup ( const char *name )
{
int race;
for ( race = 0; race_table[race].name != NULL; race++ )
{
if ( LOWER ( name[0] ) == LOWER ( race_table[race].name[0] ) &&
!str_prefix ( name, race_table[race].name ) )
return race;
}
return 0;
}
/* returns race number for race's PCDATA */
int pcrace_lookup ( const char *name )
{
int pcrace;
for ( pcrace = 0; pcrace < MAX_PCRACE; pcrace++ )
{
if ( LOWER ( name[0] ) == LOWER ( pc_race_table[pcrace].name[0] ) && !str_prefix ( name, pc_race_table[pcrace].name ) )
return pcrace;
}
return 0;
}
/* returns class number */
int class_lookup ( const char *name )
{
int class;
for ( class = 0; class < MAX_CLASS; class++ )
{
if ( LOWER ( name[0] ) ==
LOWER ( class_table[class].name[0] ) &&
!str_prefix ( name, class_table[class].name ) )
return class;
}
return -1;
}
/* for immunity, vulnerabiltiy, and resistant
the 'globals' (magic and weapons) may be overriden
three other cases -- wood, silver, and iron -- are checked in fight.c */
int check_immune ( CHAR_DATA * ch, int dam_type )
{
int immune;
int bit;
immune = IS_NORMAL;
if ( dam_type == DAM_NONE )
return immune;
if ( dam_type <= 3 )
{
if ( IS_SET ( ch->imm_flags, IMM_WEAPON ) )
immune = IS_IMMUNE;
else if ( IS_SET ( ch->res_flags, RES_WEAPON ) )
immune = IS_RESISTANT;
else if ( IS_SET ( ch->vuln_flags, VULN_WEAPON ) )
immune = IS_VULNERABLE;
}
else /* magical attack */
{
if ( IS_SET ( ch->imm_flags, IMM_MAGIC ) )
immune = IS_IMMUNE;
else if ( IS_SET ( ch->res_flags, RES_MAGIC ) )
immune = IS_RESISTANT;
else if ( IS_SET ( ch->vuln_flags, VULN_MAGIC ) )
immune = IS_VULNERABLE;
}
/* set bits to check -- VULN etc. must ALL be the same or this will fail */
switch ( dam_type )
{
case ( DAM_BASH ):
bit = IMM_BASH;
break;
case ( DAM_PIERCE ):
bit = IMM_PIERCE;
break;
case ( DAM_SLASH ):
bit = IMM_SLASH;
break;
case ( DAM_FIRE ):
bit = IMM_FIRE;
break;
case ( DAM_COLD ):
bit = IMM_COLD;
break;
case ( DAM_LIGHTNING ):
bit = IMM_LIGHTNING;
break;
case ( DAM_ACID ):
bit = IMM_ACID;
break;
case ( DAM_POISON ):
bit = IMM_POISON;
break;
case ( DAM_NEGATIVE ):
bit = IMM_NEGATIVE;
break;
case ( DAM_HOLY ):
bit = IMM_HOLY;
break;
case ( DAM_ENERGY ):
bit = IMM_ENERGY;
break;
case ( DAM_MENTAL ):
bit = IMM_MENTAL;
break;
case ( DAM_DISEASE ):
bit = IMM_DISEASE;
break;
case ( DAM_DROWNING ):
bit = IMM_DROWNING;
break;
case ( DAM_LIGHT ):
bit = IMM_LIGHT;
break;
default:
return immune;
}
if ( IS_SET ( ch->imm_flags, bit ) )
immune = IS_IMMUNE;
else if ( IS_SET ( ch->res_flags, bit ) )
immune = IS_RESISTANT;
else if ( IS_SET ( ch->vuln_flags, bit ) )
immune = IS_VULNERABLE;
return immune;
}
/*
* See if a string is one of the names of an object.
*/
bool is_full_name ( const char *str, char *namelist )
{
char name[MAX_INPUT_LENGTH];
for ( ;; )
{
namelist = one_argument ( namelist, name );
if ( name[0] == '\0' )
return FALSE;
if ( !str_cmp ( str, name ) )
return TRUE;
}
}
/* for returning skill information */
int get_skill ( CHAR_DATA * ch, int sn )
{
int skill;
if ( sn == -1 ) /* shorthand for level based skills */
{
skill = ch->level * 5 / 2;
}
else if ( sn < -1 || sn > MAX_SKILL )
{
bugf ( "Bad sn %d in get_skill.", sn );
skill = 0;
}
else if ( !IS_NPC ( ch ) )
{
if ( ch->level < skill_table[sn].skill_level[ch->pcdata->pclass] )
skill = 0;
else
skill = ch->pcdata->learned[sn];
}
else /* mobiles */
{
int pclass, sclass, slev;
if (IS_SET(ch->act, ACT_CLERIC) )
{
pclass = CLASS_AVENGER;
sclass = CLASS_DEFILER;
}
else if (IS_SET(ch->act, ACT_MAGE) )
{
pclass = CLASS_MAGE;
sclass = CLASS_CHAOSMAGE;
}
else if (IS_SET(ch->act, ACT_THIEF) )
{
pclass = CLASS_THIEF;
sclass = CLASS_THIEF;
}
else
{
pclass = CLASS_WARRIOR;
sclass = CLASS_MONK;
}
/* Take the average of the 2 classes */
slev = (skill_table[sn].skill_level[pclass] + skill_table[sn].skill_level[sclass]) /2;
if (ch->level < slev )
skill = 0;
else
skill = 35 + ch->level - slev;
}
if ( IS_AFFECTED ( ch, AFF_BERSERK ) )
skill -= ch->level / 2;
return URANGE ( 0, skill, 100 );
}
/* for returning weapon information */
int get_weapon_sn ( CHAR_DATA * ch, bool dual )
{
OBJ_DATA *wield;
int sn;
if ( !dual )
wield = get_eq_char ( ch, WEAR_WIELD );
else
wield = get_eq_char ( ch, WEAR_WIELD2 );
if ( wield == NULL || wield->item_type != ITEM_WEAPON )
sn = gsn_hand_to_hand;
else
switch ( wield->value[0] )
{
default:
sn = -1;
break;
case ( WEAPON_SWORD ):
sn = gsn_sword;
break;
case ( WEAPON_DAGGER ):
sn = gsn_dagger;
break;
case ( WEAPON_SPEAR ):
sn = gsn_spear;
break;
case ( WEAPON_MACE ):
sn = gsn_mace;
break;
case ( WEAPON_AXE ):
sn = gsn_axe;
break;
case ( WEAPON_FLAIL ):
sn = gsn_flail;
break;
case ( WEAPON_WHIP ):
sn = gsn_whip;
break;
case ( WEAPON_POLEARM ):
sn = gsn_polearm;
break;
}
return sn;
}
int get_weapon_skill ( CHAR_DATA * ch, int sn )
{
int skill;
/* -1 is exotic */
if ( IS_NPC ( ch ) )
{
if ( sn == -1 )
skill = 3 * ch->level;
else if ( sn == gsn_hand_to_hand )
skill = 40 + 2 * ch->level;
else
{
int pclass, sclass, slev;
if (IS_SET(ch->act, ACT_CLERIC) )
{
pclass = CLASS_AVENGER;
sclass = CLASS_DEFILER;
}
else if (IS_SET(ch->act, ACT_MAGE) )
{
pclass = CLASS_MAGE;
sclass = CLASS_CHAOSMAGE;
}
else if (IS_SET(ch->act, ACT_THIEF) )
{
pclass = CLASS_THIEF;
sclass = CLASS_THIEF;
}
else
{
pclass = CLASS_WARRIOR;
sclass = CLASS_MONK;
}
/* Take the average of the 2 classes */
slev = (skill_table[sn].skill_level[pclass] + skill_table[sn].skill_level[sclass]) /2;
/* Hack to avoid bad area design. All mobs given 40% in their weapon skills */
/* This is due to mobs that have weapons they shouldn't, so they don't miss continuously */
if (ch->level >= slev )
skill = 40 + ch->level - slev;
else
skill = 40;
}
}
else
{
if ( sn == -1 )
skill = 3 * ch->level;
else
skill = ch->pcdata->learned[sn];
}
return URANGE ( 0, skill, 100 );
}
/* used to de-screw characters */
/* Nice way of putting it. */
void reset_char ( CHAR_DATA * ch )
{
int loc, mod, stat;
OBJ_DATA *obj;
AFFECT_DATA *af;
if ( IS_NPC ( ch ) )
return;
if ( ch->pcdata->perm_hit == 0
|| ch->pcdata->perm_mana == 0
|| ch->pcdata->perm_move == 0
|| ch->pcdata->last_level == 0 )
{
/* do a FULL reset */
for ( loc = 0; loc < MAX_WEAR; loc++ )
{
obj = get_eq_char ( ch, loc );
if ( obj == NULL )
continue;
if ( !obj->enchanted )
for ( af = obj->pIndexData->affected; af != NULL;
af = af->next )
{
mod = af->modifier;
switch ( af->location )
{
case APPLY_SEX:
ch->sex -= mod;
if ( ch->sex < 0 || ch->sex > 2 )
ch->sex = IS_NPC ( ch ) ?
0 : ch->pcdata->true_sex;
break;
case APPLY_MANA:
ch->max_mana -= mod;
break;
case APPLY_HIT:
ch->max_hit -= mod;
break;
case APPLY_MOVE:
ch->max_move -= mod;
break;
}
}
for ( af = obj->affected; af != NULL; af = af->next )
{
mod = af->modifier;
switch ( af->location )
{
case APPLY_SEX:
ch->sex -= mod;
break;
case APPLY_MANA:
ch->max_mana -= mod;
break;
case APPLY_HIT:
ch->max_hit -= mod;
break;
case APPLY_MOVE:
ch->max_move -= mod;
break;
}
}
}
/* now reset the permanent stats */
ch->pcdata->perm_hit = ch->max_hit;
ch->pcdata->perm_mana = ch->max_mana;
ch->pcdata->perm_move = ch->max_move;
ch->pcdata->last_level = ch->played / 3600;
if ( ch->pcdata->true_sex < 0 || ch->pcdata->true_sex > 2 )
{
if ( ch->sex > 0 && ch->sex < 3 )
ch->pcdata->true_sex = ch->sex;
else
ch->pcdata->true_sex = 0;
}
}
/* now restore the character to his/her true condition */
for ( stat = 0; stat < MAX_STATS; stat++ )
ch->mod_stat[stat] = 0;
if ( ch->pcdata->true_sex < 0 || ch->pcdata->true_sex > 2 )
ch->pcdata->true_sex = 0;
ch->sex = ch->pcdata->true_sex;
ch->max_hit = ch->pcdata->perm_hit;
ch->max_mana = ch->pcdata->perm_mana;
ch->max_move = ch->pcdata->perm_move;
// for ( i = 0; i < 4; i++ )
ch->armor = 0;
ch->hitroll = 0;
ch->damroll = 0;
ch->saving_throw = 0;
/* now start adding back the effects */
for ( loc = 0; loc < MAX_WEAR; loc++ )
{
obj = get_eq_char ( ch, loc );
if ( obj == NULL )
continue;
if ( !obj->enchanted )
for ( af = obj->pIndexData->affected; af != NULL;
af = af->next )
{
mod = af->modifier;
switch ( af->location )
{
case APPLY_STR:
ch->mod_stat[STAT_STR] += mod;
break;
case APPLY_DEX:
ch->mod_stat[STAT_DEX] += mod;
break;
case APPLY_INT:
ch->mod_stat[STAT_INT] += mod;
break;
case APPLY_WIS:
ch->mod_stat[STAT_WIS] += mod;
break;
case APPLY_CON:
ch->mod_stat[STAT_CON] += mod;
break;
case APPLY_SEX:
ch->sex += mod;
break;
case APPLY_MANA:
ch->max_mana += mod;
break;
case APPLY_HIT:
ch->max_hit += mod;
break;
case APPLY_MOVE:
ch->max_move += mod;
break;
case APPLY_AC: // Magical AC
ch->armor += mod;
break;
case APPLY_HITROLL:
ch->hitroll += mod;
break;
case APPLY_DAMROLL:
ch->damroll += mod;
break;
case APPLY_SAVING_PARA:
ch->saving_throw += mod;
break;
case APPLY_SAVING_ROD:
ch->saving_throw += mod;
break;
case APPLY_SAVING_PETRI:
ch->saving_throw += mod;
break;
case APPLY_SAVING_BREATH:
ch->saving_throw += mod;
break;
case APPLY_SAVING_SPELL:
ch->saving_throw += mod;
break;
case APPLY_ENCUMBRANCE:
ch->encumbrance += mod;
break;
}
}
for ( af = obj->affected; af != NULL; af = af->next )
{
mod = af->modifier;
switch ( af->location )
{
case APPLY_STR:
ch->mod_stat[STAT_STR] += mod;
break;
case APPLY_DEX:
ch->mod_stat[STAT_DEX] += mod;
break;
case APPLY_INT:
ch->mod_stat[STAT_INT] += mod;
break;
case APPLY_WIS:
ch->mod_stat[STAT_WIS] += mod;
break;
case APPLY_CON:
ch->mod_stat[STAT_CON] += mod;
break;
case APPLY_SEX:
ch->sex += mod;
break;
case APPLY_MANA:
ch->max_mana += mod;
break;
case APPLY_HIT:
ch->max_hit += mod;
break;
case APPLY_MOVE:
ch->max_move += mod;
break;
case APPLY_AC: // Magical AC
ch->armor += mod;
break;
case APPLY_HITROLL:
ch->hitroll += mod;
break;
case APPLY_DAMROLL:
ch->damroll += mod;
break;
case APPLY_SAVING_PARA:
ch->saving_throw += mod;
break;
case APPLY_SAVING_ROD:
ch->saving_throw += mod;
break;
case APPLY_SAVING_PETRI:
ch->saving_throw += mod;
break;
case APPLY_SAVING_BREATH:
ch->saving_throw += mod;
break;
case APPLY_SAVING_SPELL:
ch->saving_throw += mod;
break;
case APPLY_ENCUMBRANCE:
ch->saving_throw += mod;
break;
}
}
}
/* now add back spell effects */
for ( af = ch->affected; af != NULL; af = af->next )
{
mod = af->modifier;
switch ( af->location )
{
case APPLY_STR:
ch->mod_stat[STAT_STR] += mod;
break;
case APPLY_DEX:
ch->mod_stat[STAT_DEX] += mod;
break;
case APPLY_INT:
ch->mod_stat[STAT_INT] += mod;
break;
case APPLY_WIS:
ch->mod_stat[STAT_WIS] += mod;
break;
case APPLY_CON:
ch->mod_stat[STAT_CON] += mod;
break;
case APPLY_SEX:
ch->sex += mod;
break;
case APPLY_MANA:
ch->max_mana += mod;
break;
case APPLY_HIT:
ch->max_hit += mod;
break;
case APPLY_MOVE:
ch->max_move += mod;
break;
case APPLY_AC: // Magical AC
ch->armor += mod;
break;
case APPLY_HITROLL:
ch->hitroll += mod;
break;
case APPLY_DAMROLL:
ch->damroll += mod;
break;
case APPLY_SAVING_PARA:
ch->saving_throw += mod;
break;
case APPLY_SAVING_ROD:
ch->saving_throw += mod;
break;
case APPLY_SAVING_PETRI:
ch->saving_throw += mod;
break;
case APPLY_SAVING_BREATH:
ch->saving_throw += mod;
break;
case APPLY_SAVING_SPELL:
ch->saving_throw += mod;
break;
case APPLY_ENCUMBRANCE:
ch->saving_throw += mod;
break;
}
}
/* make sure sex is RIGHT!!!! */
if ( ch->sex < 0 || ch->sex > 2 )
ch->sex = ch->pcdata->true_sex;
}
/*
* Retrieve a character's trusted level for permission checking.
*/
int get_trust ( CHAR_DATA * ch )
{
if ( ch->desc != NULL && ch->desc->original != NULL )
ch = ch->desc->original;
if ( ch->trust != 0 )
return ch->trust;
/* Okay good, the following prevents an NPC from being able to
* be ordered to do IMM commands...
*/
if ( IS_NPC ( ch ) && ch->level >= LEVEL_HERO )
return LEVEL_HERO - 1;
else
return ch->level;
}
/*
* Retrieve a character's age.
*/
int get_age ( CHAR_DATA * ch )
{
int age;
if ( IS_NPC ( ch ) )
{
return 20; /* Well yeah, we'll assume they're all young punks */
}
/* Start with 1 under base, then will add 1 if have had bday */
/* First year will automatically be base, since will have had bday */
age = ( pc_race_table[ch->pcdata->pcrace].startage - 1 ) + ( time_info.year - ch->pcdata->startyear );
/* check for a modifier */
age -= ch->pcdata->age_mod;
/* check for birthdate yet this year */
if ( ( time_info.month >= ch->pcdata->startmonth ) &&
( time_info.day >= ch->pcdata->startday ) )
{
age += 1;
}
return age;
}
/* command for retrieving stats */
int get_curr_stat ( CHAR_DATA * ch, int stat )
{
int max;
if ( IS_NPC ( ch ) || ch->level > LEVEL_IMMORTAL )
max = 25;
else
{
max = pc_race_table[ch->pcdata->pcrace].max_stats[stat] + 4;
if ( class_table[ch->pcdata->pclass].attr_prime == stat )
max += 2;
if ( ch->pcdata->pcrace == pcrace_lookup ( "human" ) )
max += 1;
max = UMIN ( max, 25 );
}
return URANGE ( 3, ch->perm_stat[stat] + ch->mod_stat[stat], max );
}
/*
* Retrieve a character's carry capacity.
*/
int can_carry_n ( CHAR_DATA * ch )
{
if ( !IS_NPC ( ch ) && ch->level >= LEVEL_IMMORTAL )
return 1000;
if ( IS_NPC ( ch ) && IS_SET ( ch->act, ACT_PET ) )
return 0;
/* followers can carry, pets can't */
return MAX_WEAR + 2 * get_curr_stat ( ch, STAT_DEX ) + ch->level;
}
/*
* Retrieve a character's carry capacity.
*/
int can_carry_w ( CHAR_DATA * ch )
{
if ( !IS_NPC ( ch ) && ch->level >= LEVEL_IMMORTAL )
return 1000000;
if ( IS_NPC ( ch ) && IS_SET ( ch->act, ACT_PET ) )
return 0;
return str_app[get_curr_stat ( ch, STAT_STR )].carry +
ch->level * 5 / 2;
}
/*
* See if a string is one of the names of an object.
*/
bool is_name ( char *str, char *namelist )
{
char name[MAX_INPUT_LENGTH], part[MAX_INPUT_LENGTH];
char *list, *string;
string = str;
/* we need ALL parts of string to match part of namelist */
for ( ;; ) /* start parsing string */
{
str = one_argument ( str, part );
if ( part[0] == '\0' )
return TRUE;
/* check to see if this is part of namelist */
list = namelist;
for ( ;; ) /* start parsing namelist */
{
list = one_argument ( list, name );
if ( name[0] == '\0' ) /* this name was not found */
return FALSE;
if ( !str_cmp ( string, name ) )
return TRUE; /* full pattern match */
if ( !str_cmp ( part, name ) )
break;
}
}
}
bool is_name_abbv ( char *str, char *namelist ) /*Zeran, abbrev is_name */
{
char name[MAX_INPUT_LENGTH];
char *list, *string;
if ( strstr ( namelist, str ) == namelist ) /* got partial match already */
return TRUE;
string = str;
/* check to see if this is part of namelist */
list = namelist;
for ( ;; ) /* start parsing namelist */
{
list = one_argument ( list, name );
if ( name[0] == '\0' ) /* this name was not found */
return FALSE;
if ( strstr ( name, string ) == name ) /*Zeran: hack for abbreviations */
return TRUE; /*abbreviated string, return a match */
}
}
/*
* Set some values on an affect
* NOTICE: This function does no error checking. Be careful calling it.
* All values must be specified, if you set NULL, then it will set NULL,
* overwriting what was there before.
*/
void set_affect ( AFFECT_DATA *paf, sh_int type, sh_int level, sh_int duration,
sh_int location, sh_int modifier, sh_int where,
int bitvector, char *caster )
{
paf->type = type;
paf->level = level;
paf->duration = duration;
paf->location = location;
paf->modifier = modifier;
paf->where = where;
paf->bitvector = bitvector;
}
/*
* Apply or remove an affect to a character.
*
*/
void affect_modify ( CHAR_DATA * ch, AFFECT_DATA * paf, bool fAdd )
{
OBJ_DATA *wield;
OBJ_DATA *objtmp;
int mod;
bool duplicate = FALSE;
AFFECT_DATA *tmp;
mod = paf->modifier;
if ( fAdd )
{
switch ( paf->where)
{
case TO_AFFECTS:
SET_BIT (ch->affected_by, paf->bitvector);
break;
case TO_DETECTIONS:
SET_BIT (ch->detections, paf->bitvector );
break;
case TO_PROTECTIONS:
SET_BIT (ch->protections, paf->bitvector );
break;
}
}
else if ( paf->bitvector ) /* Zeran - can skip if bitvector is 0 */
{
/* check spells that were cast */
for ( tmp = ch->affected; tmp != NULL; tmp = tmp->next )
{
if ( ( tmp != paf ) && ( tmp->bitvector == paf->bitvector ) && ( tmp->where == paf->where ) )
{
duplicate = TRUE;
break;
}
}
/* check against other worn objects if no duplicate found yet */
if ( !duplicate )
for ( objtmp = ch->carrying; objtmp != NULL; objtmp = objtmp->next_content )
{
if ( objtmp->wear_loc != WEAR_NONE ) /*worn, check affects */
{
for ( tmp = objtmp->affected; tmp != NULL; tmp = tmp->next )
{
if ( ( tmp != paf ) && ( tmp->bitvector == paf->bitvector ) && ( tmp->where == paf->where ) )
duplicate = TRUE;
break;
}
for ( tmp = objtmp->pIndexData->affected;
tmp != NULL; tmp = tmp->next )
{
if ( ( tmp != paf ) && ( tmp->bitvector == paf->bitvector ) && ( tmp->where == paf->where ) )
duplicate = TRUE;
break;
}
}
if ( duplicate )
break;
}
if ( !duplicate )
{
switch ( paf->where)
{
case TO_AFFECTS:
REMOVE_BIT (ch->affected_by, paf->bitvector);
ch->affected_by = ch->affected_by | race_table[ch->race].aff;
break;
case TO_DETECTIONS:
REMOVE_BIT (ch->detections, paf->bitvector );
ch->detections = ch->detections | race_table[ch->race].detect;
break;
case TO_PROTECTIONS:
REMOVE_BIT (ch->protections, paf->bitvector );
ch->detections = ch->detections | race_table[ch->race].protect;
break;
}
}
}
if ( !fAdd )
mod = 0 - mod;
switch ( paf->location )
{
default:
bugf ( "Affect_modify: unknown location %d.", paf->location );
return;
case APPLY_NONE: break;
case APPLY_STR: ch->mod_stat[STAT_STR] += mod; break;
case APPLY_DEX: ch->mod_stat[STAT_DEX] += mod; break;
case APPLY_INT: ch->mod_stat[STAT_INT] += mod; break;
case APPLY_WIS: ch->mod_stat[STAT_WIS] += mod; break;
case APPLY_CON: ch->mod_stat[STAT_CON] += mod; break;
case APPLY_SEX: ch->sex += mod; break;
case APPLY_CLASS: break;
case APPLY_LEVEL: break;
case APPLY_AGE: break;
case APPLY_HEIGHT: break;
case APPLY_WEIGHT: break;
case APPLY_MANA: ch->max_mana += mod; break;
case APPLY_HIT: ch->max_hit += mod; break;
case APPLY_MOVE: ch->max_move += mod; break;
case APPLY_GOLD: break;
case APPLY_EXP: break;
case APPLY_AC: ch->armor += mod; break;
case APPLY_HITROLL: ch->hitroll += mod; break;
case APPLY_DAMROLL: ch->damroll += mod; break;
case APPLY_SAVING_PARA: ch->saving_throw += mod; break;
case APPLY_SAVING_ROD: ch->saving_throw += mod; break;
case APPLY_SAVING_PETRI: ch->saving_throw += mod; break;
case APPLY_SAVING_BREATH: ch->saving_throw += mod; break;
case APPLY_SAVING_SPELL: ch->saving_throw += mod; break;
case APPLY_ENCUMBRANCE: ch->encumbrance += mod; break;
}
/*
* Check for weapon wielding.
* Guard against recursion (for weapons with affects).
*/
if ( !IS_NPC ( ch ) &&
( wield = get_eq_char ( ch, WEAR_WIELD ) ) != NULL &&
get_obj_weight ( wield ) >
str_app[get_curr_stat ( ch, STAT_STR )].wield )
{
static int depth;
if ( depth == 0 )
{
depth++;
act ( "You drop $p.", ch, wield, NULL, TO_CHAR );
act ( "$n drops $p.", ch, wield, NULL, TO_ROOM );
obj_from_char ( wield );
obj_to_room ( wield, ch->in_room );
depth--;
}
}
/* now check the dual wield weapon */
if ( !IS_NPC ( ch ) &&
( wield = get_eq_char ( ch, WEAR_WIELD2 ) ) != NULL &&
get_obj_weight ( wield ) >
str_app[get_curr_stat ( ch, STAT_STR )].wield )
{
static int depth2;
if ( depth2 == 0 )
{
depth2++;
act ( "You drop $p.", ch, wield, NULL, TO_CHAR );
act ( "$n drops $p.", ch, wield, NULL, TO_ROOM );
obj_from_char ( wield );
obj_to_room ( wield, ch->in_room );
depth2--;
}
}
return;
}
/*
* Give an affect to a char.
*/
void affect_to_char ( CHAR_DATA * ch, AFFECT_DATA * paf )
{
AFFECT_DATA *paf_new;
if ( affect_free == NULL )
{
paf_new = alloc_perm ( sizeof ( *paf_new ), "paf_new:aff_to_ch" );
}
else
{
paf_new = affect_free;
affect_free = affect_free->next;
}
*paf_new = *paf;
paf_new->next = ch->affected;
ch->affected = paf_new;
affect_modify ( ch, paf_new, TRUE );
return;
}
/* give an affect to an object */
void affect_to_obj ( OBJ_DATA * obj, AFFECT_DATA * paf )
{
AFFECT_DATA *paf_new;
if ( affect_free == NULL )
{
paf_new = alloc_perm ( sizeof ( *paf_new ), "paf_new:aff_to_obj" );
}
else
{
paf_new = affect_free;
affect_free = affect_free->next;
}
*paf_new = *paf;
paf_new->next = obj->affected;
obj->affected = paf_new;
return;
}
/*
* affect_to_room ??
* What were ya thinkin' Z?
* Neat idea though, so I'll leave it here, just commented since it is unused
* and there's no code to support it -- Lotherius
*/
//void affect_to_room ( ROOM_INDEX_DATA * room, AFFECT_DATA * paf )
//{
// AFFECT_DATA *paf_new;
//
// if ( affect_free == NULL )
// {
// paf_new = alloc_perm ( sizeof ( *paf_new ), "paf_new:aff_to_room" );
// } else
// {
// paf_new = affect_free;
// affect_free = affect_free->next;
// }
//
// *paf_new = *paf;
// paf_new->next = room->affected;
//
// room->affected = paf_new;
//
// return;
//}
//void affect_remove_room ( ROOM_INDEX_DATA * room, AFFECT_DATA * paf )
//{
// if ( room->affected == NULL )
// {
// bugf ( "Affect_remove_room: no affect." );
// return;
// }
//
// if ( paf == room->affected )
// {
// room->affected = paf->next;
// } else
// {
// AFFECT_DATA *prev;
//
// for ( prev = room->affected; prev != NULL;
// prev = prev->next )
// {
// if ( prev->next == paf )
// {
// prev->next = paf->next;
// break;
// }
// }
//
// if ( prev == NULL )
// {
// bugf ( "Affect_remove_room: cannot find paf." );
// return;
// }
// }
//
// paf->next = affect_free;
// affect_free = paf;
// return;
//}
/*
* Remove an affect from a char.
*/
void affect_remove ( CHAR_DATA * ch, AFFECT_DATA * paf )
{
if ( ch->affected == NULL )
{
bugf ( "Affect_remove: no affect." );
return;
}
affect_modify ( ch, paf, FALSE );
if ( paf == ch->affected )
{
ch->affected = paf->next;
}
else
{
AFFECT_DATA *prev;
for ( prev = ch->affected; prev != NULL;
prev = prev->next )
{
if ( prev->next == paf )
{
prev->next = paf->next;
break;
}
}
if ( prev == NULL )
{
bugf ( "Affect_remove: cannot find paf." );
return;
}
}
paf->next = affect_free;
affect_free = paf;
return;
}
void affect_remove_obj ( OBJ_DATA * obj, AFFECT_DATA * paf )
{
if ( obj->affected == NULL )
{
bugf ( "Affect_remove_object: no affect." );
return;
}
if ( obj->carried_by != NULL && obj->wear_loc != -1 )
affect_modify ( obj->carried_by, paf, FALSE );
if ( paf == obj->affected )
{
obj->affected = paf->next;
}
else
{
AFFECT_DATA *prev;
for ( prev = obj->affected; prev != NULL;
prev = prev->next )
{
if ( prev->next == paf )
{
prev->next = paf->next;
break;
}
}
if ( prev == NULL )
{
bugf ( "Affect_remove_object: cannot find paf." );
return;
}
}
paf->next = affect_free;
affect_free = paf;
return;
}
/*
* Strip all affects of a given sn.
*/
void affect_strip ( CHAR_DATA * ch, int sn )
{
AFFECT_DATA *paf;
AFFECT_DATA *paf_next;
for ( paf = ch->affected; paf != NULL; paf = paf_next )
{
paf_next = paf->next;
if ( paf->type == sn )
affect_remove ( ch, paf );
}
return;
}
/*
* Return true if a char is affected by a spell.
*/
bool is_affected ( CHAR_DATA * ch, int sn )
{
AFFECT_DATA *paf;
for ( paf = ch->affected; paf != NULL; paf = paf->next )
{
if ( paf->type == sn )
return TRUE;
}
return FALSE;
}
/*
* Add or enhance an affect.
*/
void affect_join ( CHAR_DATA * ch, AFFECT_DATA * paf )
{
AFFECT_DATA *paf_old;
bool found;
found = FALSE;
for ( paf_old = ch->affected; paf_old != NULL;
paf_old = paf_old->next )
{
if ( paf_old->type == paf->type )
{
paf->level = ( paf->level += paf_old->level ) / 2;
paf->duration += paf_old->duration;
paf->modifier += paf_old->modifier;
affect_remove ( ch, paf_old );
break;
}
}
affect_to_char ( ch, paf );
return;
}
/*
* Move a char out of a room.
*/
void char_from_room ( CHAR_DATA * ch )
{
OBJ_DATA *obj;
if ( ch->in_room == NULL )
{
bugf ( "Char_from_room: NULL." );
return;
}
if ( !IS_NPC ( ch ) )
--ch->in_room->area->nplayer;
if ( ( obj = get_eq_char ( ch, WEAR_LIGHT ) ) != NULL
&& obj->item_type == ITEM_LIGHT
&& obj->value[2] != 0 && ch->in_room->light > 0 )
--ch->in_room->light;
if ( ch == ch->in_room->people )
{
ch->in_room->people = ch->next_in_room;
}
else
{
CHAR_DATA *prev;
for ( prev = ch->in_room->people; prev;
prev = prev->next_in_room )
{
if ( prev->next_in_room == ch )
{
prev->next_in_room = ch->next_in_room;
break;
}
}
if ( prev == NULL )
bugf ( "Char_from_room: ch not found." );
}
ch->in_room = NULL;
ch->next_in_room = NULL;
return;
}
/*
* Move a char into a room.
*/
void char_to_room ( CHAR_DATA * ch, ROOM_INDEX_DATA * pRoomIndex )
{
OBJ_DATA *obj;
if ( pRoomIndex == NULL )
{
bugf ( "Char_to_room: NULL." );
return;
}
ch->in_room = pRoomIndex;
ch->next_in_room = pRoomIndex->people;
pRoomIndex->people = ch;
if ( !IS_NPC ( ch ) )
{
if ( ch->in_room->area->empty )
{
ch->in_room->area->empty = FALSE;
ch->in_room->area->age = 0;
}
++ch->in_room->area->nplayer;
}
if ( ( obj = get_eq_char ( ch, WEAR_LIGHT ) ) != NULL
&& obj->item_type == ITEM_LIGHT && obj->value[2] != 0 )
++ch->in_room->light;
/*
* startup some music
* music only sends data if the soundfile has changed
* Areas with no sound, set the sound to "None"
*/
if ( !IS_NPC(ch) )
{
if ( ch->in_room->area->soundfile[0] != '\0' )
{
music ( ch->in_room->area->soundfile, ch, TRUE );
}
else
{
free_string (ch->pcdata->mplaying);
ch->pcdata->mplaying = str_dup ( "None" );
stop_music ( ch->desc );
}
}
if ( IS_AFFECTED ( ch, AFF_PLAGUE ) )
{
AFFECT_DATA *af, plague;
CHAR_DATA *vch;
int save;
for ( af = ch->affected; af != NULL; af = af->next )
{
if ( af->type == gsn_plague )
break;
}
if ( af == NULL )
{
REMOVE_BIT ( ch->affected_by, AFF_PLAGUE );
return;
}
if ( af->level == 1 )
return;
plague.type = gsn_plague;
plague.level = af->level - 1;
plague.duration = number_range ( 1, 2 * plague.level );
plague.location = APPLY_STR;
plague.modifier = -5;
plague.bitvector = AFF_PLAGUE;
for ( vch = ch->in_room->people; vch != NULL;
vch = vch->next_in_room )
{
switch ( check_immune ( vch, DAM_DISEASE ) )
{
case ( IS_NORMAL ):
save = af->level - 4;
break;
case ( IS_IMMUNE ):
save = 0;
break;
case ( IS_RESISTANT ):
save = af->level - 8;
break;
case ( IS_VULNERABLE ):
save = af->level;
break;
default:
save = af->level - 4;
break;
}
if ( save != 0 && !saves_spell ( save, vch ) &&
!IS_IMMORTAL ( vch ) &&
!IS_AFFECTED ( vch, AFF_PLAGUE ) &&
number_bits ( 6 ) == 0 )
{
send_to_char ( "You feel hot and feverish.\n\r", vch );
act ( "$n shivers and looks very ill.", vch, NULL,
NULL, TO_ROOM );
affect_join ( vch, &plague );
}
}
}
return;
}
/*
* Give an obj to a char.
*/
void obj_to_char ( OBJ_DATA * obj, CHAR_DATA * ch )
{
obj->next_content = ch->carrying;
ch->carrying = obj;
obj->carried_by = ch;
obj->in_room = NULL;
obj->in_obj = NULL;
ch->carry_number += get_obj_number ( obj );
ch->carry_weight += get_obj_weight ( obj );
}
/*
* Take an obj from its character.
*/
void obj_from_char ( OBJ_DATA * obj )
{
CHAR_DATA *ch;
if ( ( ch = obj->carried_by ) == NULL )
{
bugf ( "Obj_from_char: null ch. Fatal, exiting to avoid possible infinite loop." );
/* This error must be fatal to avoid a horrendous loop */
/* If you're getting this error you MUST fix something. */
exit (1);
}
if ( obj->wear_loc != WEAR_NONE )
unequip_char ( ch, obj );
if ( ch->carrying == obj )
{
ch->carrying = obj->next_content;
}
else
{
OBJ_DATA *prev;
for ( prev = ch->carrying; prev != NULL;
prev = prev->next_content )
{
if ( prev->next_content == obj )
{
prev->next_content = obj->next_content;
break;
}
}
if ( prev == NULL )
bugf ( "Obj_from_char: obj not in list." );
}
obj->carried_by = NULL;
obj->next_content = NULL;
ch->carry_number -= get_obj_number ( obj );
ch->carry_weight -= get_obj_weight ( obj );
return;
}
/*
* Find a piece of eq on a character.
*/
OBJ_DATA *get_eq_char ( CHAR_DATA * ch, int iWear )
{
OBJ_DATA *obj;
if ( ch == NULL )
return NULL;
for ( obj = ch->carrying; obj != NULL;
obj = obj->next_content )
{
if ( obj->wear_loc == iWear )
return obj;
}
return NULL;
}
/*
* Equip a char with an obj.
* Changed to a boolean function so the caller can see if the item was able to be
* equipped.
*/
bool equip_char ( CHAR_DATA * ch, OBJ_DATA * obj, int iWear )
{
AFFECT_DATA *paf;
if ( get_eq_char ( ch, iWear ) != NULL )
{
if (!IS_NPC(ch))
bugf ( "Equip_char: already equipped (%d : %d : %s).", iWear,
ch->in_room->vnum, ch->name );
else
bugf ( "Equip_char: already equipped (%d : %d : %d).",
iWear, ch->in_room->vnum, ch->pIndexData->vnum );
return FALSE;
}
if ( ( IS_OBJ_STAT(obj, ITEM_ANTI_EVIL) && IS_EVIL(ch) )
|| ( IS_OBJ_STAT(obj, ITEM_ANTI_GOOD) && IS_GOOD(ch) )
|| ( IS_OBJ_STAT(obj, ITEM_ANTI_NEUTRAL) && IS_NEUTRAL(ch) ) )
{
/*
* Thanks to Morgenes for the bug fix here!
*/
act ( "You are zapped by $p and drop it.", ch, obj, NULL, TO_CHAR );
act ( "$n is zapped by $p and drops it.", ch, obj, NULL, TO_ROOM );
obj_from_char ( obj );
obj_to_room ( obj, ch->in_room );
return FALSE;
}
obj->wear_loc = iWear;
if ( !obj->enchanted )
{
for ( paf = obj->pIndexData->affected; paf != NULL; paf = paf->next )
{
affect_modify ( ch, paf, TRUE );
}
}
for ( paf = obj->affected; paf != NULL; paf = paf->next )
{
affect_modify ( ch, paf, TRUE );
}
if ( obj->item_type == ITEM_LIGHT
&& obj->value[2] != 0 && ch->in_room != NULL )
++ch->in_room->light;
return TRUE;
}
/*
* Unequip a char with an obj.
*/
bool unequip_char ( CHAR_DATA * ch, OBJ_DATA * obj )
{
AFFECT_DATA *paf;
if ( obj->wear_loc == WEAR_NONE )
{
bugf ( "Unequip_char: already unequipped." );
return FALSE;
}
obj->wear_loc = -1;
if ( !obj->enchanted )
for ( paf = obj->pIndexData->affected; paf != NULL;
paf = paf->next )
{
affect_modify ( ch, paf, FALSE );
}
for ( paf = obj->affected; paf != NULL; paf = paf->next )
{
affect_modify ( ch, paf, FALSE );
}
if ( obj->item_type == ITEM_LIGHT
&& obj->value[2] != 0
&& ch->in_room != NULL && ch->in_room->light > 0 )
--ch->in_room->light;
return TRUE;
}
/*
* Move an obj out of a room.
*/
void obj_from_room ( OBJ_DATA * obj )
{
ROOM_INDEX_DATA *in_room;
if ( ( in_room = obj->in_room ) == NULL )
{
bugf ( "obj_from_room: NULL." );
return;
}
if ( obj == in_room->contents )
{
in_room->contents = obj->next_content;
}
else
{
OBJ_DATA *prev;
for ( prev = in_room->contents; prev;
prev = prev->next_content )
{
if ( prev->next_content == obj )
{
prev->next_content = obj->next_content;
break;
}
}
if ( prev == NULL )
{
bugf ( "Obj_from_room: obj not found." );
return;
}
}
obj->in_room = NULL;
obj->next_content = NULL;
return;
}
/*
* Move an obj into a room.
*/
void obj_to_room ( OBJ_DATA * obj, ROOM_INDEX_DATA * pRoomIndex )
{
obj->next_content = pRoomIndex->contents;
pRoomIndex->contents = obj;
obj->in_room = pRoomIndex;
obj->carried_by = NULL;
obj->in_obj = NULL;
return;
}
/*
* Move an object into an object.
*/
void obj_to_obj ( OBJ_DATA * obj, OBJ_DATA * obj_to )
{
obj->next_content = obj_to->contains;
obj_to->contains = obj;
obj->in_obj = obj_to;
obj->in_room = NULL;
obj->carried_by = NULL;
if ( obj_to->pIndexData->vnum == OBJ_VNUM_PIT )
obj->cost = 1;
for ( ; obj_to != NULL; obj_to = obj_to->in_obj )
{
if ( obj_to->carried_by != NULL )
{
obj_to->carried_by->carry_number +=
get_obj_number ( obj );
obj_to->carried_by->carry_weight +=
get_obj_weight ( obj );
}
}
return;
}
/*
* Move an object out of an object.
*/
void obj_from_obj ( OBJ_DATA * obj )
{
OBJ_DATA *obj_from;
if ( ( obj_from = obj->in_obj ) == NULL )
{
bugf ( "Obj_from_obj: null obj_from." );
return;
}
if ( obj == obj_from->contains )
{
obj_from->contains = obj->next_content;
}
else
{
OBJ_DATA *prev;
for ( prev = obj_from->contains; prev;
prev = prev->next_content )
{
if ( prev->next_content == obj )
{
prev->next_content = obj->next_content;
break;
}
}
if ( prev == NULL )
{
bugf ( "Obj_from_obj: obj not found." );
return;
}
}
obj->next_content = NULL;
obj->in_obj = NULL;
for ( ; obj_from != NULL; obj_from = obj_from->in_obj )
{
if ( obj_from->carried_by != NULL )
{
obj_from->carried_by->carry_number -=
get_obj_number ( obj );
obj_from->carried_by->carry_weight -=
get_obj_weight ( obj );
}
}
return;
}
/*
* Extract an obj from the world.
*/
void extract_obj ( OBJ_DATA * obj )
{
CHAR_DATA *ch = obj->carried_by;
OBJ_DATA *obj_content;
OBJ_DATA *obj_next;
if ( obj->in_room != NULL )
obj_from_room ( obj );
else if ( obj->carried_by != NULL )
obj_from_char ( obj );
else if ( obj->in_obj != NULL )
obj_from_obj ( obj );
for ( obj_content = obj->contains; obj_content;
obj_content = obj_next )
{
obj_next = obj_content->next_content;
extract_obj ( obj->contains );
}
if ( object_list == obj )
{
object_list = obj->next;
}
else
{
OBJ_DATA *prev;
for ( prev = object_list; prev != NULL; prev = prev->next )
{
if ( prev->next == obj )
{
prev->next = obj->next;
break;
}
}
if ( prev == NULL && obj->pIndexData != NULL )
{
bugf ( "Extract_obj: obj %d not found.", obj->pIndexData->vnum );
return;
}
}
{
AFFECT_DATA *paf;
AFFECT_DATA *paf_next;
for ( paf = obj->affected; paf != NULL; paf = paf_next )
{
paf_next = paf->next;
paf->next = affect_free;
affect_free = paf;
}
}
{
EXTRA_DESCR_DATA *ed;
EXTRA_DESCR_DATA *ed_next;
for ( ed = obj->extra_descr; ed != NULL; ed = ed_next )
{
ed_next = ed->next;
free_string ( ed->description );
free_string ( ed->keyword );
ed->next = extra_descr_free;
extra_descr_free = ed;
}
}
free_string ( obj->name );
free_string ( obj->description );
free_string ( obj->short_descr );
free_string ( obj->owner );
if ( obj->pIndexData == NULL )
bugf ( "Bug: (extract_obj) NULL obj->pIndexData" );
else /*safe to decrement */
--obj->pIndexData->count;
/* Zeran - if obj was carried by a player who is quitting, then don't
* decrement */
if ( obj->reset != NULL )
{
if ( ch == NULL )
{
obj->reset->count--;
}
else if ( !ch->quitting )
{
obj->reset->count--;
}
}
obj->reset = NULL;
obj->next = obj_free;
obj_free = obj;
return;
}
/*
* Extract a char from the world.
*/
void extract_char ( CHAR_DATA * ch, bool fPull )
{
CHAR_DATA *wch;
OBJ_DATA *obj;
OBJ_DATA *obj_next;
if ( ch->in_room == NULL )
{
bugf ( "Extract_char: NULL." );
return;
}
nuke_pets ( ch );
ch->pet = NULL; /* just in case */
if ( fPull )
die_follower ( ch );
stop_fighting ( ch, TRUE );
for ( obj = ch->carrying; obj != NULL; obj = obj_next )
{
extract_obj ( obj );
obj_next = obj->next_content;
}
char_from_room ( ch );
if ( !fPull )
{
char_to_room ( ch, get_room_index ( pc_race_table[ch->pcdata->pcrace].healer ) );
return;
}
if ( IS_NPC ( ch ) )
{
--ch->pIndexData->count;
if ( ch->reset != NULL )
--ch->reset->count; /* Zeran - added */
}
if ( ch->desc != NULL && ch->desc->original != NULL )
do_return ( ch, "" );
for ( wch = char_list; wch != NULL; wch = wch->next )
{
if ( wch->reply == ch )
wch->reply = NULL;
if ( ch->mprog_target == wch )
wch->mprog_target = NULL;
}
if ( ch == char_list )
{
char_list = ch->next;
}
else
{
CHAR_DATA *prev;
for ( prev = char_list; prev != NULL; prev = prev->next )
{
if ( prev->next == ch )
{
prev->next = ch->next;
break;
}
}
if ( prev == NULL )
{
bugf ( "Extract_char: char not found." );
return;
}
}
if ( ch->desc )
ch->desc->character = NULL;
free_char ( ch );
return;
}
/*
* Find a char in the room.
* Sortof the one with obj/roomprogs, but I had to modify it to fit some of the
* modifications we'd already done here.
*/
CHAR_DATA *get_char_room( CHAR_DATA *ch, ROOM_INDEX_DATA *room, char *argument )
{
char arg[MAX_INPUT_LENGTH];
CHAR_DATA *rch;
int number;
int count;
number = number_argument ( argument, arg );
count = 0;
if ( !str_cmp ( arg, "self" ) )
return ch;
if ( ch && room )
{
bugf ( "get_char_room received multiple types (ch/room)" );
return NULL;
}
if ( ch )
rch = ch->in_room->people;
else
rch = room->people;
for ( ; rch != NULL; rch = rch->next_in_room )
{
if ( (ch && !can_see( ch, rch ))
|| ( !is_name( arg, rch->name )
&& !is_name_abbv ( arg, rch->name ) ) )
continue;
if ( ++count == number )
return rch;
}
return NULL;
}
/*
* Find a char in the world.
*/
CHAR_DATA *get_char_world( CHAR_DATA *ch, char *argument )
{
char arg[MAX_INPUT_LENGTH];
CHAR_DATA *wch;
int number;
int count;
/* Zeran - trying "self" alias for yourself */
if ( !str_cmp ( "self", argument ) )
return ch;
if ( ch && ( wch = get_char_room( ch, NULL, argument ) ) != NULL )
return wch;
number = number_argument( argument, arg );
count = 0;
for ( wch = char_list; wch != NULL ; wch = wch->next )
{
if ( wch->in_room == NULL || ( ch && !can_see( ch, wch ) )
|| ( !is_name( arg, wch->name )
&& !is_name_abbv ( arg, wch->name ) ) )
continue;
if ( ++count == number )
return wch;
}
return NULL;
}
/*
* Find some object with a given index data.
* Used by area-reset 'P' command.
*/
OBJ_DATA *get_obj_type ( OBJ_INDEX_DATA * pObjIndex )
{
OBJ_DATA *obj;
for ( obj = object_list; obj != NULL; obj = obj->next )
{
if ( obj->pIndexData == pObjIndex )
return obj;
}
return NULL;
}
/*
* Find an obj in a list.
*/
OBJ_DATA *get_obj_list ( CHAR_DATA * ch, char *argument, OBJ_DATA * list )
{
char arg[MAX_INPUT_LENGTH];
OBJ_DATA *obj;
int number;
int count;
number = number_argument ( argument, arg );
count = 0;
for ( obj = list; obj != NULL; obj = obj->next_content )
{
if ( can_see_obj ( ch, obj ) && ( is_name_abbv ( arg, obj->name ) || is_name ( arg, obj->name ) ) )
{
if ( ++count == number )
return obj;
}
}
return NULL;
}
/*
* Find an obj in player's inventory.
*/
OBJ_DATA *get_obj_carry( CHAR_DATA *ch, char *argument, CHAR_DATA *viewer )
{
char arg[MAX_INPUT_LENGTH];
OBJ_DATA *obj;
int number;
int count;
number = number_argument( argument, arg );
count = 0;
for ( obj = ch->carrying; obj != NULL; obj = obj->next_content )
{
if ( obj->wear_loc == WEAR_NONE
&& ( viewer ? can_see_obj( viewer, obj ) : TRUE )
&& ( is_name( arg, obj->name ) || is_name_abbv ( arg, obj->name ) ) )
{
if ( ++count == number )
return obj;
}
}
return NULL;
}
/*
* Find an obj in player's equipment.
*/
OBJ_DATA *get_obj_wear( CHAR_DATA *ch, char *argument, bool character )
{
char arg[MAX_INPUT_LENGTH];
OBJ_DATA *obj;
int number;
int count;
number = number_argument( argument, arg );
count = 0;
for ( obj = ch->carrying; obj != NULL; obj = obj->next_content )
{
if ( obj->wear_loc != WEAR_NONE
&& ( character ? can_see_obj( ch, obj ) : TRUE)
&& ( is_name( arg, obj->name ) || is_name_abbv ( arg, obj->name ) ) )
{
if ( ++count == number )
return obj;
}
}
return NULL;
}
/*
* Find an obj in the room or in inventory.
*/
OBJ_DATA *get_obj_here( CHAR_DATA *ch, ROOM_INDEX_DATA *room, char *argument )
{
OBJ_DATA *obj;
int number, count;
char arg[MAX_INPUT_LENGTH];
if ( ch && room )
{
bugf ( "get_obj_here received a ch and a room");
return NULL;
}
number = number_argument( argument, arg );
count = 0;
if ( ch )
{
obj = get_obj_list( ch, argument, ch->in_room->contents );
if ( obj != NULL )
return obj;
if ( ( obj = get_obj_carry( ch, argument, ch ) ) != NULL )
return obj;
if ( ( obj = get_obj_wear( ch, argument, TRUE ) ) != NULL )
return obj;
}
else
{
for ( obj = room->contents; obj; obj = obj->next_content )
{
if ( !is_name( arg, obj->name ) && !is_name_abbv( arg, obj->name ) )
continue;
if ( ++count == number )
return obj;
}
}
return NULL;
}
/*
* Find an obj in the world.
*/
OBJ_DATA *get_obj_world( CHAR_DATA *ch, char *argument )
{
char arg[MAX_INPUT_LENGTH];
OBJ_DATA *obj;
int number;
int count;
if ( ch && ( obj = get_obj_here( ch, NULL, argument ) ) != NULL )
return obj;
number = number_argument( argument, arg );
count = 0;
for ( obj = object_list; obj != NULL; obj = obj->next )
{
if ( ( ch && !can_see_obj( ch, obj ) )
|| ( !is_name( arg, obj->name ) && !is_name_abbv ( arg, obj->name ) ) )
continue;
if ( ++count == number )
return obj;
}
return NULL;
}
/*
* Create a 'money' obj.
*/
OBJ_DATA *create_money ( int amount )
{
char buf[MAX_STRING_LENGTH];
OBJ_DATA *obj;
if ( amount <= 0 )
{
bugf ( "Create_money: zero or negative money %d.", amount );
amount = 1;
}
if ( amount == 1 )
{
obj =
create_object ( get_obj_index ( OBJ_VNUM_MONEY_ONE ),
0 );
}
else
{
obj =
create_object ( get_obj_index ( OBJ_VNUM_MONEY_SOME ),
0 );
SNP ( buf, obj->short_descr, amount );
free_string ( obj->short_descr );
obj->short_descr = str_dup ( buf );
obj->value[0] = amount;
obj->cost = amount;
}
return obj;
}
/*
* Return # of objects which an object counts as.
* Thanks to Tony Chamberlain for the correct recursive code here.
*/
int get_obj_number ( OBJ_DATA * obj )
{
int number;
if ( obj->item_type == ITEM_CONTAINER ||
obj->item_type == ITEM_MONEY )
number = 0;
else
number = 1;
for ( obj = obj->contains; obj != NULL;
obj = obj->next_content )
number += get_obj_number ( obj );
return number;
}
/*
* Return weight of an object, including weight of contents.
*/
int get_obj_weight ( OBJ_DATA * obj )
{
int weight;
/* Zeran - if object is a floating object, weight is irrelevant */
if ( IS_SET ( obj->wear_flags, ITEM_WEAR_FLOAT ) )
weight = 0;
else
weight = obj->weight;
for ( obj = obj->contains; obj != NULL;
obj = obj->next_content )
weight += get_obj_weight ( obj );
return weight;
}
/*
* True if room is dark.
*/
bool room_is_dark ( ROOM_INDEX_DATA * pRoomIndex )
{
if ( pRoomIndex->light > 0 )
return FALSE;
if ( IS_SET ( pRoomIndex->room_flags, ROOM_DARK ) )
return TRUE;
if ( pRoomIndex->sector_type == SECT_INSIDE
|| pRoomIndex->sector_type == SECT_CITY )
return FALSE;
if ( weather_info.sunlight == SUN_SET
|| weather_info.sunlight == SUN_DARK )
return TRUE;
return FALSE;
}
/*
* True if room is private.
*/
bool room_is_private ( ROOM_INDEX_DATA * pRoomIndex )
{
CHAR_DATA *rch;
int count;
count = 0;
for ( rch = pRoomIndex->people; rch != NULL;
rch = rch->next_in_room )
count++;
if ( IS_SET ( pRoomIndex->room_flags, ROOM_PRIVATE ) &&
count >= 2 )
return TRUE;
if ( IS_SET ( pRoomIndex->room_flags, ROOM_SOLITARY ) &&
count >= 1 )
return TRUE;
return FALSE;
}
/* visibility on a room -- for entering and exits */
bool can_see_room ( CHAR_DATA * ch, ROOM_INDEX_DATA * pRoomIndex )
{
if ( !pRoomIndex )
return FALSE; /* If the roomindex is NULL, must return false */
if ( IS_RENTED ( pRoomIndex->lease ) )
{
if ( pRoomIndex->lease->owner_only )
{
if ( !str_cmp ( ch->name, pRoomIndex->lease->rented_by ) ) // Owners can always see their own room
return TRUE;
else
return FALSE;
}
}
if ( IS_NPC(ch) )
{
return TRUE;
}
if ( IS_SET ( pRoomIndex->room_flags, ROOM_IMP_ONLY ) && get_trust ( ch ) < MAX_LEVEL )
return FALSE;
if ( IS_SET ( pRoomIndex->room_flags, ROOM_GODS_ONLY ) && !IS_IMMORTAL ( ch ) )
return FALSE;
if ( IS_SET ( pRoomIndex->room_flags, ROOM_HEROES_ONLY ) && !IS_HERO ( ch ) )
return FALSE;
if ( IS_SET ( pRoomIndex->room_flags, ROOM_NEWBIES_ONLY ) && ch->level > 5 && !IS_IMMORTAL ( ch ) )
return FALSE;
return TRUE;
}
/*
* True if char can see victim.
*/
bool can_see ( CHAR_DATA * ch, CHAR_DATA * victim )
{
/* RT changed so that WIZ_INVIS has levels */
if ( ch == victim )
return TRUE;
if ( !IS_NPC ( victim )
&& IS_SET ( victim->act, PLR_WIZINVIS )
&& get_trust ( ch ) < victim->invis_level )
return FALSE;
if ( !IS_NPC ( victim )
&& IS_SET ( victim->act, PLR_CLOAK )
&& get_trust ( ch ) < victim->cloak_level
&& ch->in_room != victim->in_room )
return FALSE;
if ( ( !IS_NPC ( ch ) && IS_SET ( ch->act, PLR_HOLYLIGHT ) )
|| ( IS_NPC ( ch ) && IS_IMMORTAL ( ch ) ) )
return TRUE;
if ( IS_AFFECTED ( ch, AFF_BLIND ) )
return FALSE;
if ( room_is_dark ( ch->in_room ) &&
!CAN_DETECT ( ch, DET_INFRARED ) )
return FALSE;
if ( IS_AFFECTED ( victim, AFF_INVISIBLE )
&& !CAN_DETECT ( ch, DET_INVIS ) )
return FALSE;
if ( IS_AFFECTED ( victim, AFF_HIDE )
&& !CAN_DETECT ( ch, DET_HIDDEN ) )
return FALSE;
/* sneaking */
if ( IS_AFFECTED ( victim, AFF_SNEAK )
&& !CAN_DETECT ( ch, DET_HIDDEN )
&& victim->fighting == NULL
&& ( IS_NPC ( ch ) ? !IS_NPC ( victim ) :
IS_NPC ( victim ) ) )
{
int chance;
chance = get_skill ( victim, gsn_sneak );
chance += get_curr_stat ( ch, STAT_DEX ) * 3 / 2;
chance -= get_curr_stat ( ch, STAT_INT ) * 2;
chance += ch->level - victim->level * 3 / 2;
if ( number_percent ( ) < chance )
return FALSE;
}
if ( IS_AFFECTED ( victim, AFF_HIDE )
&& !CAN_DETECT ( ch, DET_HIDDEN )
&& victim->fighting == NULL
&& ( IS_NPC ( ch ) ? !IS_NPC ( victim ) :
IS_NPC ( victim ) ) )
return FALSE;
return TRUE;
}
/*
* True if char can see obj.
*/
bool can_see_obj ( CHAR_DATA * ch, OBJ_DATA * obj )
{
if ( !IS_NPC ( ch ) && IS_SET ( ch->act, PLR_HOLYLIGHT ) )
return TRUE;
if ( IS_SET ( obj->extra_flags, ITEM_VIS_DEATH ) )
return FALSE;
if ( IS_AFFECTED ( ch, AFF_BLIND ) &&
obj->item_type != ITEM_POTION )
return FALSE;
if ( IS_SET ( obj->extra_flags, ITEM_CONCEALED ) &&
!ch->searching )
return FALSE;
if ( obj->item_type == ITEM_LIGHT && obj->value[2] != 0 )
return TRUE;
if ( IS_SET ( obj->extra_flags, ITEM_INVIS )
&& !CAN_DETECT ( ch, DET_INVIS ) )
return FALSE;
if ( IS_OBJ_STAT ( obj, ITEM_GLOW ) )
return TRUE;
if ( room_is_dark ( ch->in_room ) &&
!CAN_DETECT ( ch, DET_INFRARED ) )
return FALSE;
return TRUE;
}
/*
* True if char can drop obj.
*/
bool can_drop_obj ( CHAR_DATA * ch, OBJ_DATA * obj )
{
if ( !IS_SET ( obj->extra_flags, ITEM_NODROP ) )
return TRUE;
if ( !IS_NPC ( ch ) && ch->level >= LEVEL_IMMORTAL )
return TRUE;
return FALSE;
}
/*
* Return ascii name of an item type.
*/
char *item_type_name ( OBJ_DATA * obj )
{
switch ( obj->item_type )
{
case ITEM_LIGHT: return "light";
case ITEM_SCROLL: return "scroll";
case ITEM_WAND: return "wand";
case ITEM_STAFF: return "staff";
case ITEM_WEAPON: return "weapon";
case ITEM_TREASURE: return "treasure";
case ITEM_ARMOR: return "armor";
case ITEM_POTION: return "potion";
case ITEM_FURNITURE: return "furniture";
case ITEM_TRASH: return "trash";
case ITEM_CONTAINER: return "container";
case ITEM_DRINK_CON: return "drink container";
case ITEM_KEY: return "key";
case ITEM_FOOD: return "food";
case ITEM_MONEY: return "money";
case ITEM_BOAT: return "boat";
case ITEM_CORPSE_NPC: return "npc corpse";
case ITEM_CORPSE_PC: return "pc corpse";
case ITEM_FOUNTAIN: return "fountain";
case ITEM_PILL: return "pill";
case ITEM_MAP: return "map";
case ITEM_PRIDE: return "pride";
case ITEM_COMPONENT: return "component";
case ITEM_PORTAL: return "portal";
}
bugf ( "Item_type_name: unknown type %d.", obj->item_type );
return "(unknown)";
}
/*
* Return ascii name of an affect location.
*/
char *affect_loc_name ( int location )
{
switch ( location )
{
case APPLY_NONE: return "none";
case APPLY_STR: return "strength";
case APPLY_DEX: return "dexterity";
case APPLY_INT: return "intelligence";
case APPLY_WIS: return "wisdom";
case APPLY_CON: return "constitution";
case APPLY_SEX: return "sex";
case APPLY_CLASS: return "class";
case APPLY_LEVEL: return "level";
case APPLY_AGE: return "age";
case APPLY_MANA: return "mana";
case APPLY_HIT: return "hp";
case APPLY_MOVE: return "moves";
case APPLY_GOLD: return "gold";
case APPLY_EXP: return "experience";
case APPLY_AC: return "armor class";
case APPLY_HITROLL: return "hit roll";
case APPLY_DAMROLL: return "damage roll";
case APPLY_SAVING_PARA: return "save vs paralysis";
case APPLY_SAVING_ROD: return "save vs rod";
case APPLY_SAVING_PETRI: return "save vs petrification";
case APPLY_SAVING_BREATH: return "save vs breath";
case APPLY_SAVING_SPELL: return "save vs spell";
case APPLY_ENCUMBRANCE: return "encumbrance";
}
bugf ( "Affect_location_name: unknown location %d.", location );
return "(unknown)";
}
/*
* Return ascii name of an affect bit vector
*/
char *affect_bit_name ( int vector )
{
static char buf[1024];
buf[0] = '\0';
if ( vector & AFF_BLIND ) SLCAT ( buf, " blind" );
if ( vector & AFF_INVISIBLE ) SLCAT ( buf, " invisible" );
if ( vector & AFF_MELD ) SLCAT ( buf, " mind meld" );
if ( vector & AFF_FAERIE_FIRE ) SLCAT ( buf, " faerie fire" );
if ( vector & AFF_CURSE ) SLCAT ( buf, " curse" );
if ( vector & AFF_POISON ) SLCAT ( buf, " poison" );
if ( vector & AFF_SLEEP ) SLCAT ( buf, " sleep" );
if ( vector & AFF_SNEAK ) SLCAT ( buf, " sneak" );
if ( vector & AFF_HIDE ) SLCAT ( buf, " hide" );
if ( vector & AFF_CHARM ) SLCAT ( buf, " charm" );
if ( vector & AFF_FLYING ) SLCAT ( buf, " flying" );
if ( vector & AFF_PASS_DOOR ) SLCAT ( buf, " pass door" );
if ( vector & AFF_BERSERK ) SLCAT ( buf, " berserk" );
if ( vector & AFF_CALM ) SLCAT ( buf, " calm" );
if ( vector & AFF_HASTE ) SLCAT ( buf, " haste" );
if ( vector & AFF_PLAGUE ) SLCAT ( buf, " plague" );
if ( vector & AFF_FEAR ) SLCAT ( buf, " fear" );
if ( vector & AFF_REGENERATION ) SLCAT ( buf, " regeneration" );
if ( vector & AFF_SWIM ) SLCAT ( buf, " swim" );
if ( vector & AFF_POLY ) SLCAT ( buf, " polymorph" );
return ( buf[0] != '\0' ) ? buf+1 : "none";
}
char *detect_bit_name ( int vector )
{
static char buf[1024];
buf[0] = '\0';
if ( vector & AFF_SHIELD ) SLCAT (buf, " shield" );
if ( vector & AFF_MUTE ) SLCAT (buf, " mute" );
if ( vector & AFF_SLOW ) SLCAT (buf, " slow" );
if ( vector & AFF_CONFUSION ) SLCAT (buf, " confusion" );
if ( vector & AFF_RALLY ) SLCAT (buf, " rally" );
if ( vector & DET_EVIL ) SLCAT( buf, " evil" );
if ( vector & DET_INVIS ) SLCAT( buf, " invis" );
if ( vector & DET_MAGIC ) SLCAT( buf, " magic" );
if ( vector & DET_HIDDEN ) SLCAT( buf, " hidden" );
if ( vector & DET_DARK_VISION ) SLCAT( buf, " dark vision" );
if ( vector & DET_INFRARED ) SLCAT( buf, " infrared" );
return ( buf[0] != '\0' ) ? buf+1 : "none";
}
char *protect_bit_name ( int vector )
{
static char buf[1024];
buf[0] = '\0';
if ( vector & PROT_EVIL ) SLCAT ( buf, " evil" );
if ( vector & PROT_GOOD ) SLCAT ( buf, " good" );
if ( vector & PROT_SANCTUARY ) SLCAT ( buf, " sanctuary" );
if ( vector & PROT_ABSORB ) SLCAT ( buf, " absorb" );
if ( vector & PROT_PHASED ) SLCAT ( buf, " phased" );
return ( buf[0] != '\0' ) ? buf+1 : "none";
}
/*
* Return ascii name of extra flags vector.
*/
char *extra_bit_name ( int extra_flags )
{
static char buf[512];
buf[0] = '\0';
if ( extra_flags & ITEM_GLOW ) SLCAT ( buf, " glow" );
if ( extra_flags & ITEM_HUM ) SLCAT ( buf, " hum" );
if ( extra_flags & ITEM_DARK ) SLCAT ( buf, " dark" );
if ( extra_flags & ITEM_LOCK ) SLCAT ( buf, " lock" );
if ( extra_flags & ITEM_EVIL ) SLCAT ( buf, " evil" );
if ( extra_flags & ITEM_INVIS ) SLCAT ( buf, " invis" );
if ( extra_flags & ITEM_MAGIC ) SLCAT ( buf, " magic" );
if ( extra_flags & ITEM_NODROP ) SLCAT ( buf, " nodrop" );
if ( extra_flags & ITEM_BLESS ) SLCAT ( buf, " bless" );
if ( extra_flags & ITEM_ANTI_GOOD ) SLCAT ( buf, " anti good" );
if ( extra_flags & ITEM_ANTI_EVIL ) SLCAT ( buf, " anti evil" );
if ( extra_flags & ITEM_ANTI_NEUTRAL ) SLCAT ( buf, " anti neutral" );
if ( extra_flags & ITEM_NOREMOVE ) SLCAT ( buf, " noremove" );
if ( extra_flags & ITEM_NO_SAC ) SLCAT ( buf, " no sacrifice" );
if ( extra_flags & ITEM_NO_COND ) SLCAT ( buf, " no condition" );
if ( extra_flags & ITEM_CONCEALED ) SLCAT ( buf, " concealed" );
if ( extra_flags & ITEM_INVENTORY ) SLCAT ( buf, " inventory" );
if ( extra_flags & ITEM_NOPURGE ) SLCAT ( buf, " nopurge" );
if ( extra_flags & ITEM_VIS_DEATH ) SLCAT ( buf, " visibile at death" );
if ( extra_flags & ITEM_ROT_DEATH ) SLCAT ( buf, " rot on death" );
if ( extra_flags & ITEM_NODISP ) SLCAT ( buf, " no display" );
return ( buf[0] != '\0' ) ? buf + 1 : "none";
}
/* return ascii name of an act vector */
char *act_bit_name ( int act_flags )
{
static char buf[512];
buf[0] = '\0';
if ( IS_SET ( act_flags, ACT_IS_NPC ) )
{
SLCAT ( buf, " npc" );
if ( act_flags & ACT_SENTINEL ) SLCAT ( buf, " sentinel" );
if ( act_flags & ACT_SCAVENGER ) SLCAT ( buf, " scavenger" );
if ( act_flags & ACT_AGGRESSIVE ) SLCAT ( buf, " aggressive" );
if ( act_flags & ACT_STAY_AREA ) SLCAT ( buf, " stay area" );
if ( act_flags & ACT_WIMPY ) SLCAT ( buf, " wimpy" );
if ( act_flags & ACT_PET ) SLCAT ( buf, " pet" );
if ( act_flags & ACT_FOLLOWER ) SLCAT ( buf, " follower" );
if ( act_flags & ACT_PRACTICE ) SLCAT ( buf, " practice" );
if ( act_flags & ACT_UNDEAD ) SLCAT ( buf, " undead" );
if ( act_flags & ACT_CLERIC ) SLCAT ( buf, " cleric" );
if ( act_flags & ACT_MAGE ) SLCAT ( buf, " mage" );
if ( act_flags & ACT_THIEF ) SLCAT ( buf, " thief" );
if ( act_flags & ACT_WARRIOR ) SLCAT ( buf, " warrior" );
if ( act_flags & ACT_NOALIGN ) SLCAT ( buf, " no align" );
if ( act_flags & ACT_NOPURGE ) SLCAT ( buf, " no purge" );
if ( act_flags & ACT_IS_HEALER ) SLCAT ( buf, " healer" );
if ( act_flags & ACT_TELEPOP ) SLCAT ( buf, " telepop" );
if ( act_flags & ACT_UPDATE_ALWAYS ) SLCAT ( buf, " update always" );
if ( act_flags & ACT_NORANDOM ) SLCAT ( buf, " no random items");
if ( act_flags & ACT_NOQUEST ) SLCAT ( buf, " no quest" );
if ( act_flags & ACT_FOLLOWER ) SLCAT ( buf, " follower" );
if ( act_flags & ACT_SOLDIER ) SLCAT ( buf, " soldier" );
if ( act_flags & ACT_SKILLMASTER ) SLCAT ( buf, " skillmaster" );
}
else
{
SLCAT ( buf, " player" );
if ( act_flags & PLR_BOUGHT_PET ) SLCAT ( buf, " owner" );
if ( act_flags & PLR_AUTOASSIST ) SLCAT ( buf, " autoassist" );
if ( act_flags & PLR_AUTOEXIT ) SLCAT ( buf, " autoexit" );
if ( act_flags & PLR_AUTOLOOT ) SLCAT ( buf, " autoloot" );
if ( act_flags & PLR_AUTOSAC ) SLCAT ( buf, " autosac" );
if ( act_flags & PLR_AUTOGOLD ) SLCAT ( buf, " autogold" );
if ( act_flags & PLR_AUTOSPLIT ) SLCAT ( buf, " autosplit" );
if ( act_flags & PLR_HOLYLIGHT ) SLCAT ( buf, " holy light" );
if ( act_flags & PLR_WIZINVIS ) SLCAT ( buf, " wizinvis" );
if ( act_flags & PLR_CANLOOT ) SLCAT ( buf, " can loot corpse" );
if ( act_flags & PLR_NOSUMMON ) SLCAT ( buf, " nosummon" );
if ( act_flags & PLR_NOFOLLOW ) SLCAT ( buf, " nofollow" );
if ( act_flags & PLR_FREEZE ) SLCAT ( buf, " frozen" );
if ( act_flags & PLR_THIEF ) SLCAT ( buf, " thief" );
if ( act_flags & PLR_KILLER ) SLCAT ( buf, " killer" );
if ( act_flags & PLR_QUESTOR ) SLCAT ( buf, " questing" );
if ( act_flags & PLR_XINFO ) SLCAT ( buf, " x-info" );
if ( act_flags & PLR_CURSOR ) SLCAT ( buf, " cursor" );
if ( act_flags & PLR_CLOAK ) SLCAT ( buf, " cloak" );
}
return ( buf[0] != '\0' ) ? buf + 1 : "none";
}
char *comm_bit_name ( int comm_flags )
{
static char buf[512];
buf[0] = '\0';
if ( comm_flags & COMM_QUIET ) SLCAT ( buf, " quiet" );
if ( comm_flags & COMM_DEAF ) SLCAT ( buf, " deaf" );
if ( comm_flags & COMM_NOWIZ ) SLCAT ( buf, " no_wiz" );
if ( comm_flags & COMM_NOAUCTION ) SLCAT ( buf, " no_auction" );
if ( comm_flags & COMM_NOGOSSIP ) SLCAT ( buf, " no_gossip" );
if ( comm_flags & COMM_NOQUESTION ) SLCAT ( buf, " no_question" );
if ( comm_flags & COMM_NOMUSIC ) SLCAT ( buf, " no_music" );
if ( comm_flags & COMM_COMPACT ) SLCAT ( buf, " compact" );
if ( comm_flags & COMM_FULLFIGHT ) SLCAT ( buf, " full battle" );
if ( comm_flags & COMM_BRIEF ) SLCAT ( buf, " brief" );
if ( comm_flags & COMM_PROMPT ) SLCAT ( buf, " prompt" );
if ( comm_flags & COMM_COMBINE ) SLCAT ( buf, " combine" );
if ( comm_flags & COMM_NOEMOTE ) SLCAT ( buf, " no_emote" );
if ( comm_flags & COMM_NOSHOUT ) SLCAT ( buf, " no_shout" );
if ( comm_flags & COMM_NOTELL ) SLCAT ( buf, " no_tell" );
if ( comm_flags & COMM_NOCHANNELS ) SLCAT ( buf, " no_channels" );
if ( comm_flags & COMM_NOCLANTELL ) SLCAT ( buf, " no_clantell" );
if ( comm_flags & COMM_TELNET_GA ) SLCAT ( buf, " telnet_ga" );
if ( comm_flags & COMM_DARKCOLOR ) SLCAT ( buf, " dark colors" );
if ( comm_flags & COMM_NOFLASHY ) SLCAT ( buf, " no flashy" );
if ( comm_flags & COMM_BEEP ) SLCAT ( buf, " beep" );
if ( comm_flags & COMM_NODARKGREY ) SLCAT ( buf, " no dark grey" );
if ( comm_flags & COMM_COLOUR ) SLCAT ( buf, " colour" );
return ( buf[0] != '\0' ) ? buf + 1 : "none";
}
char *imm_bit_name ( int imm_flags )
{
static char buf[512];
buf[0] = '\0';
if ( imm_flags & IMM_SUMMON ) SLCAT ( buf, " summon" );
if ( imm_flags & IMM_CHARM ) SLCAT ( buf, " charm" );
if ( imm_flags & IMM_MAGIC ) SLCAT ( buf, " magic" );
if ( imm_flags & IMM_WEAPON ) SLCAT ( buf, " weapon" );
if ( imm_flags & IMM_BASH ) SLCAT ( buf, " blunt" );
if ( imm_flags & IMM_PIERCE ) SLCAT ( buf, " piercing" );
if ( imm_flags & IMM_SLASH ) SLCAT ( buf, " slashing" );
if ( imm_flags & IMM_FIRE ) SLCAT ( buf, " fire" );
if ( imm_flags & IMM_COLD ) SLCAT ( buf, " cold" );
if ( imm_flags & IMM_LIGHTNING ) SLCAT ( buf, " lightning" );
if ( imm_flags & IMM_ACID ) SLCAT ( buf, " acid" );
if ( imm_flags & IMM_POISON ) SLCAT ( buf, " poison" );
if ( imm_flags & IMM_NEGATIVE ) SLCAT ( buf, " negative" );
if ( imm_flags & IMM_HOLY ) SLCAT ( buf, " holy" );
if ( imm_flags & IMM_ENERGY ) SLCAT ( buf, " energy" );
if ( imm_flags & IMM_MENTAL ) SLCAT ( buf, " mental" );
if ( imm_flags & IMM_DISEASE ) SLCAT ( buf, " disease" );
if ( imm_flags & IMM_DROWNING ) SLCAT ( buf, " drowning" );
if ( imm_flags & IMM_LIGHT ) SLCAT ( buf, " light" );
if ( imm_flags & VULN_IRON ) SLCAT ( buf, " iron" );
if ( imm_flags & VULN_WOOD ) SLCAT ( buf, " wood" );
if ( imm_flags & VULN_SILVER ) SLCAT ( buf, " silver" );
if ( imm_flags & VULN_STEEL ) SLCAT ( buf, " steel" );
if ( imm_flags & VULN_ADAMANTITE ) SLCAT ( buf, " adamantite" );
if ( imm_flags & VULN_MITHRIL ) SLCAT ( buf, " mithril" );
return ( buf[0] != '\0' ) ? buf + 1 : "none";
}
char *wear_bit_name ( int wear_flags )
{
static char buf[512];
buf[0] = '\0';
if ( wear_flags & ITEM_TAKE ) SLCAT ( buf, " take" );
if ( wear_flags & ITEM_WEAR_FINGER ) SLCAT ( buf, " finger" );
if ( wear_flags & ITEM_WEAR_NECK ) SLCAT ( buf, " neck" );
if ( wear_flags & ITEM_WEAR_BODY ) SLCAT ( buf, " torso" );
if ( wear_flags & ITEM_WEAR_HEAD ) SLCAT ( buf, " head" );
if ( wear_flags & ITEM_WEAR_LEGS ) SLCAT ( buf, " legs" );
if ( wear_flags & ITEM_WEAR_FEET ) SLCAT ( buf, " feet" );
if ( wear_flags & ITEM_WEAR_HANDS ) SLCAT ( buf, " hands" );
if ( wear_flags & ITEM_WEAR_ARMS ) SLCAT ( buf, " arms" );
if ( wear_flags & ITEM_WEAR_SHIELD ) SLCAT ( buf, " shield" );
if ( wear_flags & ITEM_WEAR_ABOUT ) SLCAT ( buf, " body" );
if ( wear_flags & ITEM_WEAR_WAIST ) SLCAT ( buf, " waist" );
if ( wear_flags & ITEM_WEAR_WRIST ) SLCAT ( buf, " wrist" );
if ( wear_flags & ITEM_WIELD ) SLCAT ( buf, " wield" );
if ( wear_flags & ITEM_HOLD ) SLCAT ( buf, " hold" );
if ( wear_flags & ITEM_WEAR_PRIDE ) SLCAT ( buf, " pride" );
if ( wear_flags & ITEM_WEAR_FACE ) SLCAT ( buf, " face" );
if ( wear_flags & ITEM_WEAR_EARS ) SLCAT ( buf, " ears" );
if ( wear_flags & ITEM_WEAR_FLOAT ) SLCAT ( buf, " float" );
return ( buf[0] != '\0' ) ? buf + 1 : "none";
}
char *form_bit_name ( int form_flags )
{
static char buf[512];
buf[0] = '\0';
if ( form_flags & FORM_POISON ) SLCAT ( buf, " poison" );
else if ( form_flags & FORM_EDIBLE ) SLCAT ( buf, " edible" );
if ( form_flags & FORM_MAGICAL ) SLCAT ( buf, " magical" );
if ( form_flags & FORM_INSTANT_DECAY ) SLCAT ( buf, " instant_rot" );
if ( form_flags & FORM_OTHER ) SLCAT ( buf, " other" );
if ( form_flags & FORM_ANIMAL ) SLCAT ( buf, " animal" );
if ( form_flags & FORM_SENTIENT ) SLCAT ( buf, " sentient" );
if ( form_flags & FORM_UNDEAD ) SLCAT ( buf, " undead" );
if ( form_flags & FORM_CONSTRUCT ) SLCAT ( buf, " construct" );
if ( form_flags & FORM_MIST ) SLCAT ( buf, " mist" );
if ( form_flags & FORM_INTANGIBLE ) SLCAT ( buf, " intangible" );
if ( form_flags & FORM_BIPED ) SLCAT ( buf, " biped" );
if ( form_flags & FORM_CENTAUR ) SLCAT ( buf, " centaur" );
if ( form_flags & FORM_INSECT ) SLCAT ( buf, " insect" );
if ( form_flags & FORM_SPIDER ) SLCAT ( buf, " spider" );
if ( form_flags & FORM_CRUSTACEAN ) SLCAT ( buf, " crustacean" );
if ( form_flags & FORM_WORM ) SLCAT ( buf, " worm" );
if ( form_flags & FORM_BLOB ) SLCAT ( buf, " blob" );
if ( form_flags & FORM_MAMMAL ) SLCAT ( buf, " mammal" );
if ( form_flags & FORM_BIRD ) SLCAT ( buf, " bird" );
if ( form_flags & FORM_REPTILE ) SLCAT ( buf, " reptile" );
if ( form_flags & FORM_SNAKE ) SLCAT ( buf, " snake" );
if ( form_flags & FORM_DRAGON ) SLCAT ( buf, " dragon" );
if ( form_flags & FORM_AMPHIBIAN ) SLCAT ( buf, " amphibian" );
if ( form_flags & FORM_FISH ) SLCAT ( buf, " fish" );
if ( form_flags & FORM_COLD_BLOOD ) SLCAT ( buf, " cold_blooded" );
return ( buf[0] != '\0' ) ? buf + 1 : "none";
}
char *part_bit_name ( int part_flags )
{
static char buf[512];
buf[0] = '\0';
if ( part_flags & PART_HEAD ) SLCAT ( buf, " head" );
if ( part_flags & PART_ARMS ) SLCAT ( buf, " arms" );
if ( part_flags & PART_LEGS ) SLCAT ( buf, " legs" );
if ( part_flags & PART_HEART ) SLCAT ( buf, " heart" );
if ( part_flags & PART_BRAINS ) SLCAT ( buf, " brains" );
if ( part_flags & PART_GUTS ) SLCAT ( buf, " guts" );
if ( part_flags & PART_HANDS ) SLCAT ( buf, " hands" );
if ( part_flags & PART_FEET ) SLCAT ( buf, " feet" );
if ( part_flags & PART_FINGERS ) SLCAT ( buf, " fingers" );
if ( part_flags & PART_EAR ) SLCAT ( buf, " ears" );
if ( part_flags & PART_EYE ) SLCAT ( buf, " eyes" );
if ( part_flags & PART_LONG_TONGUE ) SLCAT ( buf, " long_tongue" );
if ( part_flags & PART_EYESTALKS ) SLCAT ( buf, " eyestalks" );
if ( part_flags & PART_TENTACLES ) SLCAT ( buf, " tentacles" );
if ( part_flags & PART_FINS ) SLCAT ( buf, " fins" );
if ( part_flags & PART_WINGS ) SLCAT ( buf, " wings" );
if ( part_flags & PART_TAIL ) SLCAT ( buf, " tail" );
if ( part_flags & PART_CLAWS ) SLCAT ( buf, " claws" );
if ( part_flags & PART_FANGS ) SLCAT ( buf, " fangs" );
if ( part_flags & PART_HORNS ) SLCAT ( buf, " horns" );
if ( part_flags & PART_SCALES ) SLCAT ( buf, " scales" );
if ( part_flags & PART_HOOFS ) SLCAT ( buf, " hooves" );
if ( part_flags & PART_NECK ) SLCAT ( buf, " neck" );
if ( part_flags & PART_WAIST ) SLCAT ( buf, " waist" );
if ( part_flags & PART_WRIST ) SLCAT ( buf, " wrist" );
if ( part_flags & PART_FACE ) SLCAT ( buf, " face" );
return ( buf[0] != '\0' ) ? buf + 1 : "none";
}
char *weapon_bit_name ( int weapon_flags )
{
static char buf[512];
buf[0] = '\0';
if ( weapon_flags & WEAPON_FLAMING ) SLCAT ( buf, " {rflaming{x" );
if ( weapon_flags & WEAPON_ACID ) SLCAT ( buf, " {Gacidic{x" );
if ( weapon_flags & WEAPON_LIGHTNING ) SLCAT ( buf, " {Yelectric{x" );
if ( weapon_flags & WEAPON_FROST ) SLCAT ( buf, " {Bfrost{x" );
if ( weapon_flags & WEAPON_VAMPIRIC ) SLCAT ( buf, " {Mvampiric{x" );
if ( weapon_flags & WEAPON_SHARP ) SLCAT ( buf, " {Wsharp{x" );
if ( weapon_flags & WEAPON_VORPAL ) SLCAT ( buf, " {mvorpal{x" );
if ( weapon_flags & WEAPON_TWO_HANDS ) SLCAT ( buf, " two-handed" );
if ( weapon_flags & WEAPON_POISON ) SLCAT ( buf, " {gpoisoned{x" );
return ( buf[0] != '\0' ) ? buf + 1 : "none";
}
char *off_bit_name ( int off_flags )
{
static char buf[512];
buf[0] = '\0';
if ( off_flags & OFF_AREA_ATTACK ) SLCAT ( buf, " area attack" );
if ( off_flags & OFF_BACKSTAB ) SLCAT ( buf, " backstab" );
if ( off_flags & OFF_BASH ) SLCAT ( buf, " bash" );
if ( off_flags & OFF_BERSERK ) SLCAT ( buf, " berserk" );
if ( off_flags & OFF_DISARM ) SLCAT ( buf, " disarm" );
if ( off_flags & OFF_DODGE ) SLCAT ( buf, " dodge" );
if ( off_flags & OFF_FADE ) SLCAT ( buf, " fade" );
if ( off_flags & OFF_FAST ) SLCAT ( buf, " fast" );
if ( off_flags & OFF_KICK ) SLCAT ( buf, " kick" );
if ( off_flags & OFF_KICK_DIRT ) SLCAT ( buf, " kick_dirt" );
if ( off_flags & OFF_PARRY ) SLCAT ( buf, " parry" );
if ( off_flags & OFF_RESCUE ) SLCAT ( buf, " rescue" );
if ( off_flags & OFF_TAIL ) SLCAT ( buf, " tail" );
if ( off_flags & OFF_TRIP ) SLCAT ( buf, " trip" );
if ( off_flags & OFF_CRUSH ) SLCAT ( buf, " crush" );
if ( off_flags & ASSIST_ALL ) SLCAT ( buf, " assist_all" );
if ( off_flags & ASSIST_ALIGN ) SLCAT ( buf, " assist_align" );
if ( off_flags & ASSIST_RACE ) SLCAT ( buf, " assist_race" );
if ( off_flags & ASSIST_PLAYERS ) SLCAT ( buf, " assist_players" );
if ( off_flags & ASSIST_GUARD ) SLCAT ( buf, " assist_guard" );
if ( off_flags & ASSIST_VNUM ) SLCAT ( buf, " assist_vnum" );
if ( off_flags & OFF_RACIST ) SLCAT ( buf, " racist" );
return ( buf[0] != '\0' ) ? buf + 1 : "none";
}