/***************************************************************************
* 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. *
* *
* Ground ZERO improvements copyright pending 1994, 1995 by James Hilke *
* *
* 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. *
***************************************************************************/
#if defined(macintosh)
#include <types.h>
#else
#include <sys/types.h>
#endif
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "ground0.h"
AFFECT_DATA * affect_free;
/*
* Local functions.
*/
void affect_modify args( ( CHAR_DATA *ch, AFFECT_DATA *paf, bool fAdd ) );
void scatter_obj args( ( OBJ_DATA *obj) );
bool can_see_linear_char args( ( CHAR_DATA *ch, CHAR_DATA *victim) );
bool can_see_linear_room args( ( CHAR_DATA *ch, ROOM_DATA *a_room) );
bool rooms_linear_with_no_walls args( ( ROOM_DATA *room1,
ROOM_DATA *room2) );
CHAR_DATA *char_file_active args ((char *argument ) );
/*
* Retrieve a character's trusted level for permission checking.
*/
int get_trust( CHAR_DATA *ch )
{
return ch->trust;
}
/*
* Retrieve a character's age.
*/
int get_age( CHAR_DATA *ch )
{
return 17 + ( ch->played + (int) (current_time - ch->logon) ) / 72000;
}
/*
* Retrieve a character's carry capacity.
*/
int can_carry_n( CHAR_DATA *ch )
{
if ( !IS_NPC(ch) && ch->trust )
return 1000;
return 150;
}
/*
* Retrieve a character's carry capacity.
*/
int can_carry_w( CHAR_DATA *ch )
{
if ( !IS_NPC(ch) && ch->trust )
return 1000000;
return 500;
}
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_prefix(part,name))
break;
}
}
}
bool is_name_exact ( 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;
}
}
}
/*
* Move a char out of a room.
*/
void char_from_room( CHAR_DATA *ch )
{
OBJ_DATA *obj;
if ( ch->in_room == NULL )
{
bug( "Char_from_room: NULL.", 0 );
return;
}
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 )
bug( "Char_from_room: ch not found.", 0 );
}
ch->in_room = NULL;
ch->next_in_room = NULL;
return;
}
/*
* Move a char into a room.
*/
void char_to_room( CHAR_DATA *ch, ROOM_DATA *pRoomIndex )
{
OBJ_DATA *obj;
if ( pRoomIndex == NULL )
{
bug( "Char_to_room: NULL.", 0 );
return;
}
ch->in_room = pRoomIndex;
ch->next_in_room = pRoomIndex->people;
pRoomIndex->people = ch;
return;
}
void bug_object_state (OBJ_DATA *obj)
{
if (obj->in_room)
{
sprintf (log_buf, "in room %d, %d, %d.", obj->in_room->x,
obj->in_room->y, obj->in_room->level);
sbug (log_buf);
}
if (obj->destination)
{
sprintf (log_buf, "has destination %d, %d, %d.", obj->destination->x,
obj->destination->y, obj->destination->level);
sbug (log_buf);
}
if (obj->in_obj)
{
sprintf (log_buf, "inside object %s.", obj->in_obj->name);
sbug (log_buf);
}
if (obj->carried_by)
{
sprintf (log_buf, "carried by %s.", obj->carried_by->names);
sbug (log_buf);
}
}
/*
* Give an obj to a char.
*/
void obj_to_char( OBJ_DATA *obj, CHAR_DATA *ch )
{
if (obj->in_room || obj->destination || obj->in_obj || obj->carried_by)
{
sprintf (log_buf, "obj_to_char: %s could not go to %s because it is "
"somewhere.", obj->name, ch->names);
sbug (log_buf);
bug_object_state (obj);
return;
}
obj->next_content = ch->carrying;
ch->carrying = obj;
obj->carried_by = ch;
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 )
{
bug( "Obj_from_char: null ch.", 0 );
bug_object_state (obj);
return;
}
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 )
bug( "Obj_from_char: obj not in list.", 0 );
}
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->carried_by != ch)
{
char buf[MAX_STRING_LENGTH];
if (obj->carried_by)
sprintf (buf, "get_eq_char: Carried by %s; in list of %s",
obj->carried_by->names, ch->names);
else
sprintf (buf, "get_eq_char: Carried by null; in list of %s",
ch->names);
sbug (buf);
}
if ( obj->wear_loc == iWear )
return obj;
}
return NULL;
}
/*
* Find a piece of eq on a character.
*/
OBJ_DATA *find_eq_char (CHAR_DATA *ch, int search_type,
unsigned int search_value)
{
OBJ_DATA *obj;
char buf[MAX_INPUT_LENGTH];
if (ch == NULL)
return NULL;
for ( obj = ch->carrying; obj != NULL; obj = obj->next_content )
{
if (obj->carried_by != ch)
sbug ("find_eq_char: carried_by not ch");
switch (search_type)
{
case SEARCH_ITEM_TYPE:
if ( obj->item_type == search_value )
return obj;
break;
case SEARCH_GEN_FLAG:
if (IS_SET (obj->general_flags, search_value))
return obj;
break;
case SEARCH_AMMO_TYPE:
if ((obj->item_type == ITEM_AMMO) &&
(obj->ammo_type == search_value))
return obj;
break;
}
}
return NULL;
}
/*
* Equip a char with an obj.
*/
void equip_char( CHAR_DATA *ch, OBJ_DATA *obj, int iWear )
{
AFFECT_DATA *paf;
int i;
if ( get_eq_char( ch, iWear ) != NULL )
{
bug( "Equip_char: already equipped (%d).", iWear );
return;
}
ch->armor += obj->armor;
obj->wear_loc = iWear;
ch->carry_number -= get_obj_number( obj );
return;
}
/*
* Unequip a char with an obj.
*/
void unequip_char( CHAR_DATA *ch, OBJ_DATA *obj )
{
AFFECT_DATA *paf;
int i;
if ( obj->wear_loc == WEAR_NONE )
{
bug( "Unequip_char: already unequipped.", 0 );
return;
}
obj->wear_loc = -1;
ch->armor -= obj->armor;
ch->carry_number += get_obj_number( obj );
return;
}
/*
* Count occurrences of an obj in a list.
*/
int count_obj_list( OBJ_INDEX_DATA *pObjIndex, OBJ_DATA *list )
{
OBJ_DATA *obj;
int nMatch;
nMatch = 0;
for ( obj = list; obj != NULL; obj = obj->next_content )
{
if ( obj->pIndexData == pObjIndex )
nMatch++;
}
return nMatch;
}
/*
* Move an obj out of a room.
*/
void obj_from_room( OBJ_DATA *obj )
{
ROOM_DATA *in_room;
if ( ( in_room = obj->in_room ) == NULL )
{
bug( "obj_from_room: NULL room.", 0 );
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 )
{
bug( "Obj_from_room: obj not found.", 0 );
return;
}
}
if ((obj->in_room == explosive_area) && obj->in_room->people)
{
act ("$p flashes out of existence to be destroyed somewhere.",
obj->in_room->people, obj, NULL, TO_ROOM);
act ("$p flashes out of existence to be destroyed somewhere.",
obj->in_room->people, obj, NULL, TO_CHAR);
}
if (IS_SET (obj->general_flags, GEN_DARKS_ROOM))
REMOVE_BIT (obj->in_room->room_flags, ROOM_DARK);
obj->in_room = NULL;
obj->next_content = NULL;
return;
}
/*
* Move an obj into a room.
*/
void obj_to_room( OBJ_DATA *obj, ROOM_DATA *pRoomIndex )
{
if (obj->in_room ||
(obj->destination && (pRoomIndex != explosive_area)) ||
obj->in_obj || obj->carried_by)
{
sprintf (log_buf, "obj_to_room: %s could not go to %d,%d,%d because "
"it is somewhere.", obj->name, pRoomIndex->x,
pRoomIndex->y, pRoomIndex->level);
sbug (log_buf);
bug_object_state (obj);
return;
}
if ((pRoomIndex == explosive_area) && (explosive_area->people))
{
act ("$p flashes into existance.", explosive_area->people, obj, NULL,
TO_ROOM);
act ("$p flashes into existance.", explosive_area->people, obj, NULL,
TO_CHAR);
}
if (IS_SET (obj->general_flags, GEN_DARKS_ROOM))
SET_BIT (pRoomIndex->room_flags, ROOM_DARK);
obj->next_content = pRoomIndex->contents;
pRoomIndex->contents = obj;
obj->in_room = pRoomIndex;
obj->carried_by = NULL;
return;
}
/*
* Move an object into an object.
*/
void obj_to_obj( OBJ_DATA *obj, OBJ_DATA *obj_to )
{
if (obj->in_room || obj->destination || obj->in_obj || obj->carried_by)
{
sprintf (log_buf, "obj_to_obj: %s could not go to %s because it is "
"somewhere.", obj->name, obj->name);
sbug (log_buf);
bug_object_state (obj);
return;
}
obj->next_content = NULL;
obj_to->contains = obj;
obj->in_obj = obj_to;
return;
}
void obj_from_obj (OBJ_DATA *obj)
{
obj->in_obj->contains = NULL;
obj->in_obj = NULL;
}
void scatter_obj (OBJ_DATA *obj)
{
sh_int x, y;
int count;
LEVEL_DATA *a_level;
/* char buf[MAX_STRING_LENGTH]; */
ROOM_DATA *temp_room = NULL;
if (obj->in_room || obj->destination || obj->in_obj || obj->carried_by)
{
sprintf (log_buf, "%s could not be recycled because it still is "
"somewhere.", obj->name);
sbug (log_buf);
bug_object_state (obj);
return;
}
if ((obj->item_type == ITEM_AMMO) && !expand_event && !fBootDb)
temp_room = ammo_repop[number_range(0, 2)];
else
{
x = number_range (0, the_city->x_size - 1);
y = number_range (0, the_city->y_size - 1);
a_level = the_city;
}
if (!temp_room)
temp_room = index_room (a_level->rooms_on_level, x, y);
obj_to_room (obj, temp_room);
if (temp_room->people)
{
act ("$p glides down to earth on a small parachute to land at "
"your feet.", temp_room->people, obj, NULL, TO_ROOM);
act ("$p glides down to earth on a small parachute to land at "
"your feet.", temp_room->people, obj, NULL, TO_CHAR);
}
}
/*
* Extract an obj from the world.
*/
void extract_obj( OBJ_DATA *obj, int perm_extract )
{
OBJ_DATA *obj_content;
OBJ_DATA *obj_next;
OBJ_DATA *new_obj;
if (obj->valid != VALID_VALUE)
{
sprintf (log_buf, "Extract object: the object was not set to valid "
"(%s).", obj->name);
sbug (log_buf);
return;
}
if ( obj->in_room != NULL )
obj_from_room( obj );
else if ( obj->carried_by != NULL )
obj_from_char( obj );
if (!perm_extract)
{
int count;
new_obj = create_object (obj->pIndexData, 0);
scatter_obj (new_obj);
}
if (obj->interior)
{
CHAR_DATA *the_dead, *dead_next;
OBJ_DATA *extra_obj, *extra_next;
log_string ("Taking out the interior.\n\r");
for (the_dead = obj->interior->people; the_dead; the_dead = dead_next)
{
dead_next = the_dead->next_in_room;
the_dead->last_hit_by = obj->owner;
char_death (the_dead);
}
for (extra_obj = obj->interior->contents; extra_obj;
extra_obj = extra_next)
{
extra_next = extra_obj->next_content;
extract_obj (extra_obj, extra_obj->extract_me);
}
free_mem (obj->interior, sizeof (ROOM_DATA));
obj->interior = NULL;
}
if (obj->contains)
extract_obj(obj->contains, obj->contains->extract_me);
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 )
{
bug( "Extract_obj: obj %d not found.", obj->pIndexData->vnum );
return;
}
}
obj->valid = 0;
free_string( obj->name );
free_string( obj->description );
free_string( obj->short_descr );
if (obj->explode_desc)
free_string( obj->explode_desc);
--obj->pIndexData->count;
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 )
{
bug( "Extract_char: NULL room.", 0 );
*((char*)NULL) = 'b';
return;
}
stop_manning (ch);
REMOVE_BIT (ch->temp_flags, IN_TANK);
ch->fighting = NULL;
char_from_room( ch );
for ( wch = char_list; wch != NULL; wch = wch->next )
{
if (wch->last_hit_by == ch )
wch->last_hit_by = NULL;
if (wch->fighting == ch )
wch->fighting = NULL;
if (wch->chasing == ch )
{
wch->chasing = NULL;
wch->ld_behavior = BEHAVIOR_PILLBOX;
}
if (wch->owner == ch)
wch->owner = NULL;
}
if (!fPull)
{
char_to_room (ch, safe_area);
if (!IS_NPC(ch))
{
do_look (ch, "auto");
act ("A mangled and bloody corpse arrives in a box carried by several "
"orderlies, \n\rwho dump the unsightly remains into a large "
"machine with the words\n\rREGENERATION UNIT inscribed on the "
"side. Several seconds later\n\ra door on the side opens and "
"$n steps out grinning from ear to ear.", ch, NULL, NULL,
TO_ROOM);
}
return;
}
for ( wch = char_list; wch != NULL; wch = wch->next )
{
if ( wch->reply == ch )
wch->reply = 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;
if (ch == next_violence)
next_violence = prev->next;
break;
}
}
if ( prev == NULL )
{
bug( "Extract_char: char not found.", 0 );
return;
}
}
if ( ch->desc )
ch->desc->character = NULL;
ch->valid = 0;
free_char( ch );
return;
}
/*
* Find a char in the room.
*/
CHAR_DATA *get_char_room( CHAR_DATA *ch, 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;
for ( rch = ch->in_room->people; rch != NULL; rch = rch->next_in_room )
{
if ( !can_see( ch, rch ) || !is_name( arg, rch->names ) )
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;
if (ch && (( wch = get_char_room (ch, 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->names ) )
continue;
if ( ++count == number )
return wch;
}
return NULL;
}
CHAR_DATA *char_file_active (char *argument )
{
CHAR_DATA *wch;
char name_cap1[MAX_INPUT_LENGTH], *name_cap2;
sh_int count;
for ( wch = char_list; wch != NULL ; wch = wch->next )
{
name_cap2 = capitalize(argument);
for (count = 0; name_cap2[count]; count++)
name_cap1[count] = name_cap2[count];
name_cap1[count] = 0;
if (!strcmp (name_cap1, capitalize (wch->names)))
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 (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 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->carried_by != ch)
sbug ("get_obj_carry: carried_by not ch");
if ( obj->wear_loc == WEAR_NONE
&& is_name( 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 )
{
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->carried_by != ch)
sbug ("get_obj_carry: get_obj_wear not ch");
if ( obj->wear_loc != WEAR_NONE
&& is_name( 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, char *argument )
{
OBJ_DATA *obj;
obj = get_obj_list( ch, argument, ch->in_room->contents );
if ( obj != NULL )
return obj;
if ( ( obj = get_obj_carry( ch, argument ) ) != NULL )
return obj;
if ( ( obj = get_obj_wear( ch, argument ) ) != NULL )
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 ( ( obj = get_obj_here( ch, argument ) ) != NULL )
return obj;
number = number_argument( argument, arg );
count = 0;
if (number == 1)
{
for ( obj = object_list; obj != NULL; obj = obj->next )
{
if ( is_name_exact( arg, obj->name ))
{
if ( ++count == number )
return obj;
}
}
count = 0;
}
for ( obj = object_list; obj != NULL; obj = obj->next )
{
if ( is_name( arg, obj->name ))
{
if ( ++count == number )
return obj;
}
}
return NULL;
}
/*
* 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)
number = 0;
else
number = 1;
for ( obj = obj->contains; obj != NULL; obj = obj->next_content )
number += get_obj_number( obj );
return number; */
return 1;
}
/*
* Return weight of an object, including weight of contents.
*/
int get_obj_weight( OBJ_DATA *obj )
{
int weight;
weight = obj->weight;
for ( obj = obj->contains; obj != NULL; obj = obj->next_content )
weight += get_obj_weight( obj );
return weight;
}
/*
* True if room is private.
*/
bool room_is_private( ROOM_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_DATA *pRoomIndex )
{
if (IS_SET(pRoomIndex->room_flags, ROOM_GODS_ONLY)
&& !IS_IMMORTAL(ch))
return FALSE;
return TRUE;
}
/*
* True if char can see victim.
*/
bool can_see( CHAR_DATA *ch, CHAR_DATA *victim )
{
OBJ_DATA *prot_obj;
/* RT changed so that WIZ_INVIS has levels */
if ((ch == victim) ||
(IS_NPC(ch) && ((ch->in_room->level) ||
(ch->ld_behavior == BEHAVIOR_GUARD))))
return TRUE;
if ( !IS_NPC(victim)
&& IS_SET(victim->act, PLR_WIZINVIS)
&& get_trust( ch ) < victim->invis_level )
return FALSE;
if ( (!IS_NPC(ch) && IS_SET(ch->act, PLR_HOLYLIGHT))
|| (IS_NPC(ch) && IS_IMMORTAL(ch)))
return TRUE;
if ( IS_SET(ch->affected_by, AFF_BLIND))
return FALSE;
if ((ch->in_room && IS_SET (ch->in_room->room_flags, ROOM_DARK)) ||
(victim->in_room && IS_SET (victim->in_room->room_flags, ROOM_DARK)))
if (((prot_obj = get_eq_char (ch, WEAR_HEAD)) == NULL) ||
!IS_SET (prot_obj->general_flags, GEN_SEE_IN_DARK))
return FALSE;
return TRUE;
}
int max_sight (CHAR_DATA *ch)
{
return 4;
}
bool can_see_linear_char ( CHAR_DATA *ch, CHAR_DATA *victim )
{
sh_int diff_x, diff_y, direction, count, pos_neg;
char report_buf[MAX_INPUT_LENGTH];
ROOM_DATA *temp_room;
if (can_see (ch, victim))
{
if (ch->in_room->level != victim->in_room->level)
return FALSE;
if (ch->in_room == victim->in_room)
return TRUE;
if ((ch->in_room->level < 0) || (ch->in_room->x < 0) ||
(ch->in_room->y < 0))
return FALSE;
if (ch->in_room->x == victim->in_room->x)
{
diff_x = 0;
diff_y = ch->in_room->y - victim->in_room->y;
if ((diff_y > max_sight (ch)) || (diff_y < -max_sight (ch)))
return FALSE;
else
if (diff_y > 0)
direction = 2;
else
direction = 0;
}
else
if (ch->in_room->y == victim->in_room->y)
{
diff_x = ch->in_room->x - victim->in_room->x;
diff_y = 0;
if ((diff_x > max_sight (ch)) || (diff_x < -max_sight (ch)))
return FALSE;
else
if (diff_x > 0)
direction = 3;
else
direction = 1;
}
else
return FALSE;
pos_neg = (diff_x > 0) ? -1 : ((diff_x < 0) ? 1 : 0);
if (!pos_neg)
pos_neg = (diff_y > 0) ? -1 : ((diff_y < 0) ? 1 : 0);
for (count = 0; count != (diff_x ? -diff_x : -diff_y); count += pos_neg)
{
temp_room = index_room (ch->in_room, (diff_x ? count : 0),
(diff_y ? count : 0));
if (temp_room->exit[direction])
return FALSE;
}
return TRUE;
}
return FALSE;
}
bool can_see_linear_room( CHAR_DATA *ch, ROOM_DATA *a_room )
{
sh_int diff_x, diff_y, direction, count, pos_neg;
char report_buf[MAX_INPUT_LENGTH];
ROOM_DATA *temp_room;
if (ch->in_room->level != a_room->level)
return FALSE;
if (ch->in_room == a_room)
return TRUE;
if (ch->in_room->x == a_room->x)
{
diff_x = 0;
diff_y = ch->in_room->y - a_room->y;
if ((diff_y > max_sight (ch)) || (diff_y < -max_sight (ch)))
return FALSE;
else
if (diff_y > 0)
direction = 2;
else
direction = 0;
}
else
if (ch->in_room->y == a_room->y)
{
diff_x = ch->in_room->x - a_room->x;
diff_y = 0;
if ((diff_x > max_sight (ch)) || (diff_x < -max_sight (ch)))
return FALSE;
else
if (diff_x > 0)
direction = 3;
else
direction = 1;
}
else
return FALSE;
pos_neg = (diff_x > 0) ? -1 : ((diff_x < 0) ? 1 : 0);
if (!pos_neg)
pos_neg = (diff_y > 0) ? -1 : ((diff_y < 0) ? 1 : 0);
for (count = 0; count != (diff_x ? -diff_x : -diff_y); count += pos_neg)
{
temp_room = index_room (ch->in_room, (diff_x ? count : 0),
(diff_y ? count : 0));
if (temp_room->exit[direction])
return FALSE;
}
return TRUE;
}
bool rooms_linear_with_no_walls( ROOM_DATA *room1, ROOM_DATA *room2 )
{
sh_int diff_x, diff_y, direction, count, pos_neg;
char report_buf[MAX_INPUT_LENGTH];
ROOM_DATA *temp_room;
if (room1->level != room2->level)
return FALSE;
if (room1 == room2)
return TRUE;
if (room1->x == room2->x)
{
diff_x = 0;
diff_y = room1->y - room2->y;
if (diff_y > 0)
direction = 2;
else
direction = 0;
}
else
if (room1->y == room2->y)
{
diff_x = room1->x - room2->x;
diff_y = 0;
if (diff_x > 0)
direction = 3;
else
direction = 1;
}
else
return FALSE;
pos_neg = (diff_x > 0) ? -1 : ((diff_x < 0) ? 1 : 0);
if (!pos_neg)
pos_neg = (diff_y > 0) ? -1 : ((diff_y < 0) ? 1 : 0);
for (count = 0; count != (diff_x ? -diff_x : -diff_y); count += pos_neg)
{
temp_room = index_room (room1, (diff_x ? count : 0),
(diff_y ? count : 0));
if (temp_room->exit[direction])
return FALSE;
}
return TRUE;
}
/*
* Return ascii name of an item type.
*/
char *item_type_name( OBJ_DATA *obj )
{
sprintf (log_buf, "item type is %d.", obj->item_type);
log_string (log_buf);
switch ( obj->item_type )
{
case ITEM_MISC : return "misc";
case ITEM_WEAPON : return "weapon";
case ITEM_ARMOR : return "armor";
case ITEM_EXPLOSIVE : return "explosive";
case ITEM_AMMO : return "ammo";
case ITEM_TEAM_VEHICLE : return "team vehicle";
case ITEM_TEAM_ENTRANCE : return "team entrance";
}
bug( "Item_type_name: unknown type %d.", obj->item_type );
return "(unknown)";
}
/* return ascii name of an act vector */
char *act_bit_name( int act_flags )
{
static char buf[512];
buf[0] = '\0';
if (act_flags & PLR_AGGRO_ALL ) strcat(buf, " agg_all");
if (act_flags & PLR_HOLYLIGHT ) strcat(buf, " holy_light");
if (act_flags & PLR_WIZINVIS ) strcat(buf, " wizinvis");
if (act_flags & PLR_FREEZE ) strcat(buf, " frozen");
if (act_flags & PLR_FREEZE ) strcat(buf, " noleader");
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 ) strcat(buf, " quiet");
if (comm_flags & COMM_NOWIZ ) strcat(buf, " no_wiz");
if (comm_flags & COMM_COMPACT ) strcat(buf, " compact");
if (comm_flags & COMM_BRIEF ) strcat(buf, " brief");
if (comm_flags & COMM_PROMPT ) strcat(buf, " prompt");
if (comm_flags & COMM_COMBINE ) strcat(buf, " combine");
if (comm_flags & COMM_NOEMOTE ) strcat(buf, " no_emote");
if (comm_flags & COMM_NOSHOUT ) strcat(buf, " no_shout");
if (comm_flags & COMM_NOTELL ) strcat(buf, " no_tell");
if (comm_flags & COMM_NOCHANNELS ) strcat(buf, " no_channels");
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 ) strcat(buf, " take");
if (wear_flags & ITEM_WEAR_FINGER ) strcat(buf, " finger");
if (wear_flags & ITEM_WEAR_NECK ) strcat(buf, " neck");
if (wear_flags & ITEM_WEAR_BODY ) strcat(buf, " torso");
if (wear_flags & ITEM_WEAR_HEAD ) strcat(buf, " head");
if (wear_flags & ITEM_WEAR_LEGS ) strcat(buf, " legs");
if (wear_flags & ITEM_WEAR_FEET ) strcat(buf, " feet");
if (wear_flags & ITEM_WEAR_HANDS ) strcat(buf, " hands");
if (wear_flags & ITEM_WEAR_ARMS ) strcat(buf, " arms");
if (wear_flags & ITEM_WEAR_SHIELD ) strcat(buf, " shield");
if (wear_flags & ITEM_WEAR_ABOUT ) strcat(buf, " body");
if (wear_flags & ITEM_WEAR_WAIST ) strcat(buf, " waist");
if (wear_flags & ITEM_WEAR_WRIST ) strcat(buf, " wrist");
if (wear_flags & ITEM_WIELD ) strcat(buf, " wield");
if (wear_flags & ITEM_HOLD ) strcat(buf, " hold");
return ( buf[0] != '\0' ) ? buf+1 : "none";
}
int rem_from_top (TOP_DATA *top_array, CHAR_DATA *ch)
{
int count;
int count2;
int ret_val = 0;
for (count = 0; count < NUM_TOP; count++)
if (!str_cmp (top_array[count].name, ch->names))
{
ret_val = 1;
free_string(top_array[count].name);
for (count2 = count+1; (count2 < NUM_TOP) &&
(top_array[count2].name[0] != '<'); count2++)
top_array[count2-1] = top_array[count2];
top_array[count2-1].name = str_dup ("<empty>");
top_array[count2-1].kills = 0;
count--;
}
return ret_val;
}
int better_than (CHAR_DATA *ch, TOP_DATA *top_array, int num)
{
if (top_array == top_players_kills)
return (ch->kills > top_array[num].kills);
else
return 0;
}
void add_to_top (TOP_DATA *top_array, CHAR_DATA *ch, int num)
{
int count;
TOP_DATA temp, temp2;
temp = top_array[num];
top_array[num].name = str_dup (ch->names);
top_array[num].kills = ch->kills;
for (count = num+1; count < NUM_TOP; count++)
{
temp2 = top_array[count];
top_array[count] = temp;
temp = temp2;
}
}
void show_top_list (CHAR_DATA *ch, TOP_DATA *top_array)
{
int count;
char buf[MAX_STRING_LENGTH];
send_to_char ("`!TOP`` `1Ground`@ZERO`` `!PLAYERS``\n\r", ch);
for (count = 0; count < NUM_TOP; count++)
{
sprintf (buf, "[K:`!%d``] `1%s``\n\r",
top_array[count].kills, top_array[count].name);
send_to_char (buf, ch);
}
}
void insert_top (CHAR_DATA *ch, TOP_DATA *top_array)
{
int old_member, count;
FILE *fp;
old_member = rem_from_top (top_array, ch);
for (count = NUM_TOP - 2; count >= 0; count--)
{
if (!better_than (ch, top_array, count))
break;
}
add_to_top (top_array, ch, count + 1);
if (!old_member)
send_to_char ("Your name has been added to the top player list!!\n\r", ch);
if ((fp = fopen (TOP_FILE, "w")) == NULL)
return;
fprintf (fp, "#TOP\n");
fprintf (fp, "%d %s~\n",
top_players_kills[count].kills,
top_players_kills[count].name);
fprintf (fp, "\n#$\n");
fclose(fp);
}
void top_stuff (CHAR_DATA *ch)
{
if (!IS_IMMORTAL (ch) && !IS_NPC (ch))
if (ch->pcdata->account && ch->pcdata->account[0])
if (better_than (ch, top_players_kills, NUM_TOP-1))
insert_top (ch, top_players_kills);
}