/*~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- ~ 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. ~ ~ ~ ~ Ack 2.2 improvements copyright (C) 1994 by Stephen Dooley ~ ~ ACK!MUD is modified Merc2.0/2.1/2.2 code (c)Stephen Zepp 1998 Ver: 4.3 ~ ~ ~ ~ In order to use any part of this PA Diku Mud, you must comply with ~ ~ both the original Diku license in 'license.doc' as well the Merc ~ ~ license in 'license.txt', and the Ack!Mud license in 'ack_license.txt'.~ ~ In particular, you may not remove any of these copyright notices. ~ ~ ~ ~ _______ _____ ~ ~ / __ /\ / ___ \ 222222 PA_MUD by Amnon Kruvi ~ ~ /______/ / / /___\ \ 2 PA_MUD is modified ~ ~ / _______/ / _______ \ 2 Ack!Mud, v4.3 ~ ~ /_/ /_/ \_\ 2 ~ ~ 2 ~ ~ 2222222 ~ ~ ~ ~ ~ ~ Years of work have been invested to create DIKU, Merc, Ack and PA. ~ ~ Please show your respect by following the licenses, and issuing ~ ~ credits where due. ~ ~ ~ ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-*/ #if defined(macintosh) #include <types.h> #else #include <sys/types.h> #endif #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <stdarg.h> #include <string.h> #include <time.h> #include "ack.h" int const prof_times [] = { 0,2,5,10,15,50,100,150,200,250,300,350,400,450,500,550,-1 }; /* * Retrieve a character's trusted level for permission checking. */ int get_trust( CHAR_DATA *ch ) { return ch->trust; } /* * Replacement for retrieving a character's age * Each tick = 1 mud hr. (spaced at 1 minute rl) * 24 mud hrs = 1 mud day * 20 mud days = 1 mud month * 8 mud months = 1 mud year * Therefore, 24*20*8 = 3840 ticks/mins. * Returns a string with age info in for use by score, mst, etc */ void my_get_age( CHAR_DATA *ch, char *buf ) { int days, years, months; int base, ticks; /* Base = time in seconds ch has been playing... */ base = ch->played + (int) (current_time - ch->logon ); ticks = base/60; /* 1 tick = 60 seconds */ days = ( ticks / HOURS_PER_DAY ) % DAYS_PER_MONTH; months = ( ticks / (HOURS_PER_DAY * DAYS_PER_MONTH)) % MONTHS_PER_YEAR; years = 17 + ( ticks / (HOURS_PER_DAY * DAYS_PER_MONTH * MONTHS_PER_YEAR )); sprintf( buf+strlen(buf), "%d years, %d months and %d days", years, months, days ); return; } /* Simple function to return number of hours a character has played */ int my_get_hours(CHAR_DATA *ch, bool total ) { int secs; int hrs; if ( total == FALSE ) secs = ch->played + (int) (current_time - ch->logon ); else secs = ch->played_tot + (int) (current_time - ch->logon ); hrs = ( secs / 3600 ); return hrs; } int my_get_minutes(CHAR_DATA *ch, bool total ) { int mins; if ( total == FALSE ) mins = ( ch->played + (int) (current_time - ch->logon ) ) / 60; else mins = ( ch->played_tot + (int) (current_time - ch->logon ) ) / 60; return mins; } /* * Retrieve a character's age. */ int get_age( CHAR_DATA *ch ) { return 17 + ( ch->played + (int) (current_time - ch->logon) ) / 14400; /* 12240 assumes 30 second hours, 24 hours a day, 20 day - Kahn */ } /* * Retrieve a character's carry capacity. */ int can_carry_n( CHAR_DATA *ch ) { int n = 50; if ( ch->level >= LEVEL_IMMORTAL ) return 500; return n; } /* * Retrieve a character's carry capacity. */ int can_carry_w( CHAR_DATA *ch ) { int weight; if ( ch->level >= LEVEL_IMMORTAL ) return 9999999; weight = 350; return weight; } /* * Move a char out of a room. */ void char_from_room( CHAR_DATA *ch ) { CHAR_DATA *wch; int i = 0; if ( map_ch[ch->x][ch->y][ch->z] == ch ) map_ch[ch->x][ch->y][ch->z] = ch->next_in_room; for ( wch = map_ch[ch->x][ch->y][ch->z]; wch != NULL; wch = wch->next_in_room ) { if ( i > 50 ) break; if ( wch->next_in_room == ch ) wch->next_in_room = ch->next_in_room; i++; } ch->in_room = NULL; return; } /* * Move a char into a room. */ void char_to_room( CHAR_DATA *ch, ROOM_INDEX_DATA *pRoomIndex ) { ch->in_room = pRoomIndex; return; } /* * Give an obj to a char. */ void obj_to_char( OBJ_DATA *obj, CHAR_DATA *ch ) { obj->next_in_carry_list = NULL; obj->prev_in_carry_list = NULL; LINK(obj, ch->first_carry, ch->last_carry, next_in_carry_list, prev_in_carry_list); obj->carried_by = ch; obj->in_room = NULL; obj->in_building = NULL; ch->carry_number += get_obj_number( obj ); ch->carry_weight += get_obj_weight( obj ); obj->x = ch->x; obj->y = ch->y; obj->z = ch->z; if ( obj->item_type != ITEM_BOMB || obj->value[1] <= 0 ) { free_string(obj->owner); obj->owner = str_dup(ch->name); } if ( obj->wear_loc != WEAR_NONE && ch ) ch->heat += obj->heat; } /* * Take an obj from its character. */ void obj_from_char( OBJ_DATA *obj ) { CHAR_DATA *ch; if ( ( ch = obj->carried_by ) == NULL ) { char buf[MAX_STRING_LENGTH]; sprintf( buf, "obj_from_char: NULL ch to remove %s from.", obj->short_descr ); monitor_chan( NULL, buf, MONITOR_OBJ ); bug( "Obj_from_char: null ch.", 0 ); return; } if ( obj->wear_loc != WEAR_NONE ) unequip_char( ch, obj ); UNLINK(obj, ch->first_carry, ch->last_carry, next_in_carry_list, prev_in_carry_list); free_string(obj->owner); obj->owner = str_dup(obj->carried_by->name); obj->carried_by = NULL; obj->next_in_carry_list = NULL; obj->prev_in_carry_list = NULL; obj->in_room = NULL; obj->x = ch->x; obj->y = ch->y; obj->z = ch->z; obj->in_building = ch->in_building; ch->carry_number -= get_obj_number( obj ); ch->carry_weight -= get_obj_weight( obj ); return; } /* * Find the ac value of an obj, including position effect. */ int apply_ac( OBJ_DATA *obj, int iWear ) { if ( obj->item_type != ITEM_ARMOR ) return 0; switch ( iWear ) { case WEAR_BODY: return 3 * obj->value[0]; case WEAR_HEAD: return 2 * obj->value[0]; case WEAR_LEGS: return 2 * obj->value[0]; case WEAR_FEET: return obj->value[0]; case WEAR_ARMS: return obj->value[0]; case WEAR_HOLD_HAND_R: return obj->value[0]; case WEAR_WAIST: return obj->value[0]; case WEAR_HOLD_HAND_L: return obj->value[0]; } return 0; } /* * Find a piece of eq on a character. */ OBJ_DATA *get_eq_char( CHAR_DATA *ch, int iWear ) { OBJ_DATA *obj; for ( obj = ch->first_carry; obj != NULL; obj = obj->next_in_carry_list ) { if ( obj->wear_loc == iWear ) return obj; } return NULL; } /* * Equip a char with an obj. */ void equip_char( CHAR_DATA *ch, OBJ_DATA *obj, int iWear ) { char log[MAX_STRING_LENGTH]; if ( paintball(ch) ) { send_to_char( "You cannot wear items in paintball mode!\n\r", ch ); return; } if ( ( ch->desc && ch->desc->connected != CON_SETTING_STATS ) && ( get_eq_char( ch, iWear ) != NULL ) ) { sprintf( log, "equip_char: %s (room %d) cannot be equiped with %s, as wear slot (%d) not empty.", NAME(ch), ch->in_room->vnum, obj->short_descr, iWear ); monitor_chan( ch, log, MONITOR_OBJ ); bug( log, 0 ); return; } obj->wear_loc = iWear; ch->heat += obj->heat; return; } /* * Unequip a char with an obj. */ void unequip_char( CHAR_DATA *ch, OBJ_DATA *obj ) { if ( paintball(ch) ) { send_to_char( "You cannot remove items in paintball mode.\n\r", ch ); return; } if ( obj->wear_loc == WEAR_NONE ) { char buf[MAX_STRING_LENGTH]; sprintf( buf, "unequip_char: %s is not wearing %s.", NAME(ch), obj->short_descr ); monitor_chan( ch, buf, MONITOR_OBJ ); bug( "Unequip_char: already unequipped.", 0 ); return; } if ( obj->item_type == ITEM_WEAPON && ch->victim != ch ) { send_to_char( "You have lost your target.\n\r", ch ); ch->victim = ch; } obj->wear_loc = -1; ch->heat -= obj->heat; if ( ch->hit > ch->max_hit ) ch->hit = ch->max_hit; 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_in_carry_list ) { if ( obj->pIndexData == pObjIndex ) nMatch++; } return nMatch; } /* * 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 ) { char buf[MAX_STRING_LENGTH]; sprintf( buf, "obj_from_room: %s in NULL room.", obj->short_descr ); monitor_chan( NULL, buf, MONITOR_OBJ ); bug( "obj_from_room: NULL.", 0 ); /* attempt to recover by moving obj to another room */ if ( obj->carried_by != NULL ) obj_from_char( obj ); obj_to_room( obj, get_room_index( ROOM_VNUM_LIMBO ) ); if ( ( in_room = obj->in_room ) == NULL ) { sprintf( buf, "obj_from_room, %s really screwed up, failed attempts to move to Limbo.", obj->short_descr ); monitor_chan( NULL, buf, MONITOR_OBJ ); return; } /* code to save everyone here Zen */ } obj->in_room = NULL; obj->next_in_carry_list = NULL; obj->prev_in_carry_list = NULL; obj->carried_by = NULL; { extern OBJ_DATA *map_obj[MAX_MAPS][MAX_MAPS]; OBJ_DATA *obj2; if ( obj == map_obj[obj->x][obj->y] ) map_obj[obj->x][obj->y] = obj->next_in_room; else for ( obj2 = map_obj[obj->x][obj->y];obj2;obj2 = obj2->next_in_room ) if ( obj2->next_in_room && obj2->next_in_room == obj ) obj2->next_in_room = obj->next_in_room; } return; } /* * Move an obj into a room. */ void obj_to_room( OBJ_DATA *obj, ROOM_INDEX_DATA *pRoomIndex ) { obj->in_room = pRoomIndex; obj->carried_by = NULL; obj->next_in_carry_list = NULL; obj->prev_in_carry_list = NULL; move_obj(obj,obj->x,obj->y,obj->z); return; } /* * Extract an obj from the world. */ void extract_obj( OBJ_DATA *obj ) { if ( obj == NULL || !obj ) return; if (( obj->is_free == FALSE && ( ( obj->next && obj->next->prev != obj ) || ( obj->prev && obj->prev->next != obj ) )) ) { /* char buf[MSL]; sprintf(buf,"%s - Bad extract: %d/%d/%d, carried by %s.", obj->short_descr,obj->x,obj->y,obj->z,(obj->carried_by)?obj->carried_by->name:"nobody"); log_f(buf);*/ // if ( obj->x != 0 || obj->y != 0 ) move_obj(obj,0,0,Z_GROUND); return; } { if ( obj->carried_by ) { obj_from_char(obj); obj_to_room(obj,get_room_index(ROOM_VNUM_WMAP)); } if ( obj->item_type == ITEM_BOMB && obj->value[1] != 0 ) obj->value[1] = 0; } if ( obj->carried_by != NULL ) obj_from_char( obj ); else if ( obj->in_room != NULL ) obj_from_room( obj ); { extern OBJ_DATA *map_obj[MAX_MAPS][MAX_MAPS]; OBJ_DATA *obj2; if ( obj == map_obj[obj->x][obj->y] ) map_obj[obj->x][obj->y] = obj->next_in_room; else for ( obj2 = map_obj[obj->x][obj->y];obj2;obj2 = obj2->next_in_room ) if ( obj2->next_in_room && obj2->next_in_room == obj ) { obj2->next_in_room = obj->next_in_room; break; } } if ( obj->item_type == ITEM_BOMB ) UNLINK(obj,first_bomb,last_bomb,next_bomb,prev_bomb); if ( obj->is_free == FALSE && ( !obj->next || obj->next->prev == obj ) && ( !obj->prev || obj->prev->next == obj ) ) { UNLINK(obj, first_obj, last_obj, next, prev); PUT_FREE(obj, obj_free); } return; } /* * Extract a char from the world. */ void extract_char( CHAR_DATA *ch, bool fPull ) { CHAR_DATA *wch; OBJ_DATA * this_object; BUILDING_DATA *bld; BUILDING_DATA *bld_next; int i; if ( ch == NULL || ch->is_free ) { char buf[MAX_STRING_LENGTH]; sprintf( buf, "extract_char: %s in NULL room., Moved to room 2", NAME(ch) ); monitor_chan( NULL, buf, MONITOR_BAD ); bug( "Extract_char: NULL.", 0 ); return; } if ( ch->bvictim && ch->bvictim->value[8] != 0 ) ch->bvictim->value[8] = 0; { QUEUE_DATA * q; QUEUE_DATA * q_next; for ( q = ch->pcdata->queue;q;q = q_next ) { q_next = q->next; extract_queue(q); } } // ch->is_free = FALSE; if ( fPull ) die_follower( ch ); for ( bld = ch->first_building;bld;bld = bld_next ) { bld_next = bld->next_owned; if ( bld->timer > 0 ) continue; activate_building(bld,FALSE); } if ( ch->in_vehicle != NULL ) { VEHICLE_DATA *vhc = ch->in_vehicle; ch->in_vehicle->driving = NULL; ch->in_vehicle = NULL; extract_vehicle(vhc,FALSE); } ch->is_quitting = TRUE; while ( ( this_object = ch->last_carry ) != NULL ) extract_obj( this_object ); char_from_room( ch ); if ( ch->desc != NULL && ch->desc->original != NULL ) do_return( ch, "" ); if ( map_ch[ch->x][ch->y][ch->z] == ch ) { if ( ch->next_in_room == ch ) map_ch[ch->x][ch->y][ch->z] = NULL; else map_ch[ch->x][ch->y][ch->z] = ch->next_in_room; } for ( wch = first_char; wch != NULL; wch = wch->next ) { if ( wch->next_in_room == ch ) wch->next_in_room = ch->next_in_room; if ( wch->reply == ch ) wch->reply = NULL; if ( wch->victim == ch ) wch->victim = wch; if ( wch->bvictim && !str_cmp(wch->bvictim->owned,ch->name) ) { send_to_char( "Mainframe shut down. Connection Terminated...\n\r", ch ); wch->bvictim->value[8] = 0; wch->position =POS_STANDING; wch->bvictim = NULL; wch->c_sn = -1; } } for ( i=0;i<MAX_QUESTS;i++ ) if ( quest_table[i].target == ch ) { quest_table[i].target = NULL; quest_table[i].bld = NULL; quest_table[i].type = 0; } UNLINK(ch, first_char, last_char, next, prev); if ( ch->desc ) ch->desc->character = NULL; 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; char names[MSL]; number = number_argument( argument, arg ); count = 0; if ( arg[0] == '\0' ) return NULL; if ( !str_cmp( arg, "self" ) ) return ch; for ( rch = map_ch[ch->x][ch->y][ch->z]; rch != NULL; rch = rch->next_in_room ) { sprintf( names, "%s", rch->name ); if ( NOT_IN_ROOM( ch, rch ) ) continue; if ( !( is_name( arg, names ) ) ) continue; if ( !can_see( ch, rch ) ) 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 ( argument[0] == '\0' ) return NULL; if ( !str_cmp(argument,"self") ) return ch; number = number_argument( argument, arg ); count = 0; for ( wch = first_char; wch != NULL ; wch = wch->next ) { if ( !is_name( arg, wch->name ) || !can_see(ch,wch)) continue; if ( ++count == number ) return wch; } return NULL; } CHAR_DATA *get_char( CHAR_DATA *ch ) { if ( !ch->pcdata ) return ch->desc->original; else return ch; } /* * 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 = first_obj; obj != NULL; obj = obj->next ) { if ( obj->pIndexData == pObjIndex ) return obj; } return NULL; } /* * Find an obj in a room. */ OBJ_DATA *get_obj_room( CHAR_DATA *ch, char *argument, OBJ_DATA *list ) { char arg[MAX_INPUT_LENGTH]; OBJ_DATA *obj; int number; int count; if ( argument[0] == '\0' ) return NULL; number = number_argument( argument, arg ); count = 0; for ( obj = list; obj != NULL; obj = obj->next_in_room ) { if ( is_name( arg, obj->name ) && !NOT_IN_ROOM(obj,ch) && obj->carried_by == NULL && can_see_obj(ch,obj) ) { if ( ++count == number ) return obj; } } return NULL; } /* * Find an obj in a room. */ 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_in_carry_list ) { if ( can_see_obj( ch, obj ) && is_name( arg, obj->name ) && can_see_obj(ch,obj) ) { 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; if ( argument[0] == '\0' ) return NULL; number = number_argument( argument, arg ); count = 0; for ( obj = ch->first_carry; obj != NULL; obj = obj->next_in_carry_list ) { if ( obj->wear_loc == WEAR_NONE && is_name( arg, obj->name ) && can_see_obj(ch,obj) ) { 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->first_carry; obj != NULL; obj = obj->next_in_carry_list ) { if ( obj->wear_loc != WEAR_NONE && is_name( arg, obj->name ) && can_see_obj(ch,obj) ) { 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; extern OBJ_DATA *map_obj[MAX_MAPS][MAX_MAPS]; obj = get_obj_room( ch, argument, map_obj[ch->x][ch->y] ); 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; for ( obj = first_obj; 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; /* OBJ_DATA *vobj; */ number = 1; /*set to one since bag will count as 1 item*/ /* if ( obj->item_type == ITEM_CONTAINER ) { for ( vobj = obj->first_in_carry_list; vobj != NULL; vobj = vobj->next_in_carry_list ) { number = number - 1; } } */ /* containers should count as one item! if ( obj->item_type == ITEM_CONTAINER ) for ( obj = obj->contains; obj != NULL; obj = obj->next_content ) number += get_obj_number( obj ); else number = 1; Zen */ return number; } /* * Return weight of an object, including weight of contents. */ int get_obj_weight( OBJ_DATA *obj ) { int weight; weight = obj->weight; return weight; } /* * True if char can see victim. */ bool can_see( CHAR_DATA *ch, CHAR_DATA *victim ) { if ( ch == victim ) return TRUE; if ( IS_SET(ch->pcdata->pflags,PLR_ASS) ) return FALSE; if ( IS_SET(victim->act, PLR_WIZINVIS) && get_trust( ch ) < victim->invis ) return FALSE; if ( IS_SET(victim->act, PLR_INCOG) && get_trust( ch ) < victim->incog && NOT_IN_ROOM(ch,victim) ) return FALSE; if ( IS_SET(ch->act, PLR_HOLYLIGHT) ) return TRUE; if ( IS_SET(victim->pcdata->pflags,PLR_ASS) ) return FALSE; if ( IS_SET(ch->effect,EFFECT_BLIND) ) if ( !blind_combat_check(ch) ) return FALSE; if ( victim->in_building && victim->in_building->type == BUILDING_CLUB && complete(victim->in_building) && NOT_IN_ROOM(ch,victim) ) return FALSE; return TRUE; } /* * True if char can see obj. */ bool can_see_obj( CHAR_DATA *ch, OBJ_DATA *obj ) { if ( IS_SET(ch->act, PLR_HOLYLIGHT) ) return TRUE; if ( IS_SET(ch->effect,EFFECT_BLIND) ) if ( !blind_combat_check(ch) ) { send_to_char( "You feel around your inventory, but can't find it.\n\r", ch ); 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; } bool can_use( CHAR_DATA *ch, OBJ_DATA *obj ) { return( TRUE ); } /* * Return names of classes which can use an object * -- Stephen */ char *who_can_use( OBJ_DATA *obj ) { return( " all classes." ); } void info( char * message, int lv ) { /* This function sends <message> * to all players of level (lv) and above * Used mainly to send level gain, death info, etc to mortals. * - Stephen */ DESCRIPTOR_DATA *d; char buf[MAX_STRING_LENGTH]; if ( lv == 1 ) lv = 0; for ( d = first_desc; d; d = d->next ) if ( ( d->connected == CON_PLAYING ) && d->character->level >= lv && !IS_SET( d->character->deaf, CHANNEL_INFO ) ) { sprintf( buf, "%s: %s%s%s\n\r", (IS_SET(d->character->config,CONFIG_BLIND))?"INFO":"@@i@@B@@7[INFO]@@N@@b", color_string( d->character, "info" ), message, color_string( d->character, "normal" ) ); send_to_char( buf, d->character ); } return; } void log_chan( const char *message, int lv ) { /* Used to send messages to Immortals. * Level is used to determine WHO gets the message... */ DESCRIPTOR_DATA *d; char buf[MAX_STRING_LENGTH]; sprintf( buf, "[LOG]: %s\n\r", message ); for ( d = first_desc; d; d = d->next ) if ( ( d->connected == CON_PLAYING ) && ( get_trust( d->character ) == MAX_LEVEL ) && ( !IS_NPC( d->character ) ) && ( d->character->level >= lv ) && ( !IS_SET( d->character->deaf, CHANNEL_LOG ) ) ) send_to_char( buf, d->character ); return; } /* * Extended bitvector utility functions. */ bool xbv_is_empty( XBV *bits ) { register int i; for ( i = 0; i < XBI; i++ ) if ( bits->bits[i] != 0 ) return FALSE; return TRUE; } bool xbv_same_bits( XBV *dest, const XBV *src ) { register int i; for ( i = 0; i < XBI; i++ ) if ( dest->bits[i] != src->bits[i] ) return FALSE; return TRUE; } void xbv_clear_bits( XBV *bits ) { register int i; for ( i = 0; i < XBI; i++ ) bits->bits[i] = 0; } void xbv_set_bits( XBV *dest, const XBV *src ) { register int i; for ( i = 0; i < XBI; i++ ) SET_BIT( dest->bits[i], src->bits[i] ); } void xbv_remove_bits( XBV *dest, const XBV *src ) { register int i; for ( i = 0; i < XBI; i++ ) REMOVE_BIT( dest->bits[i], src->bits[i] ); } XBV new_xbv (int bit, ...) { static XBV bits; va_list param; int b; xCLEAR_BITS (bits); xSET_BIT (bits, bit); va_start (param, bit); while ((b=va_arg (param, int)) != -1) xSET_BIT( bits, b); va_end (param); return bits; } void extract_building( BUILDING_DATA *bld, bool msg ) { OBJ_DATA *obj; OBJ_DATA *obj_next; CHAR_DATA *ch; int i; extern OBJ_DATA *map_obj[MAX_MAPS][MAX_MAPS]; if ( bld->is_free ) { char buf[MSL]; sprintf(buf,"Bad extract: %s (Owned by %s), at %d/%d/%x is already free.", bld->name,bld->owned,bld->x,bld->y,bld->z ); log_f(buf); return; } if ( bld->owner && bld->owner->first_building == bld ) bld->owner->first_building = bld->next_owned; if ( bld->next_owned ) bld->next_owned->prev_owned = bld->prev_owned; if ( bld->prev_owned ) bld->prev_owned->next_owned = bld->next_owned; activate_building(bld,FALSE); if ( msg && !is_evil(bld) ) { for ( obj = map_obj[bld->x][bld->y];obj;obj = obj_next ) { obj_next = obj->next_in_room; if ( obj->z != bld->z ) continue; obj->in_building = NULL; if ( (obj->item_type == ITEM_BOMB && obj->value[1] != 0) || obj->item_type == ITEM_BLUEPRINT || obj->carried_by != NULL || obj->item_type == ITEM_TOKEN ) continue; if ( obj->x == bld->x && obj->y == bld->y && obj->z == bld->z ) extract_obj(obj); } } else { for ( obj = map_obj[bld->x][bld->y];obj;obj = obj_next ) { obj_next = obj->next_in_room; if ( obj->z != bld->z ) continue; obj->in_building = NULL; } } for ( i=0;i<MAX_QUESTS;i++ ) if ( quest_table[i].bld == bld ) { quest_table[i].time = 0; quest_table[i].target = NULL; quest_table[i].bld = NULL; } for ( ch = first_char;ch;ch = ch->next ) { if ( ch->x == bld->x && ch->y == bld->y && ch->z == bld->z && msg ) { send_to_char( "The building you are in has collapsed!\n\r", ch ); ch->in_building = NULL; } if ( ch->bvictim == bld ) ch->bvictim = NULL; } map_bld[bld->x][bld->y][bld->z] = NULL; // bld->is_free = FALSE; building_count--; UNLINK(bld, first_building, last_building, next, prev); PUT_FREE(bld, building_free); return; } BUILDING_DATA *get_char_building( CHAR_DATA *ch ) { ch->in_building = map_bld[ch->x][ch->y][ch->z]; return ch->in_building; } BUILDING_DATA *get_obj_building( OBJ_DATA *obj ) { if ( obj->carried_by != NULL ) return obj->carried_by->in_building; obj->in_building = map_bld[obj->x][obj->y][obj->z]; return obj->in_building; } CHAR_DATA *get_ch( char *argument ) { CHAR_DATA *rch; if ( !str_cmp(argument,"nobody") ) return NULL; for ( rch = first_char;rch;rch = rch->next ) if ( !str_cmp(rch->name, argument) ) return rch; return NULL; } BUILDING_DATA *get_building( int x, int y, int z ) { if ( z < 0 || z >= Z_MAX ) return NULL; if ( x < 0 || x >= MAX_MAPS || y < 0 || y >= MAX_MAPS ) return NULL; return map_bld[x][y][z]; } BUILDING_DATA *get_building_range( int x, int y, int x2, int y2, int z ) { int xx,yy,d,d_next; bool xaxis = FALSE; d = -999; if ( x != x2 ) { xaxis = TRUE; d_next = x; } else d_next = y; xx = x; yy = y; for ( ;; ) { if ( ( xaxis && d == x2 ) || ( !xaxis && d == y2 ) ) break; d = d_next; if ( xaxis ) { if ( d < x2 ) d_next = d + 1; else d_next = d - 1; xx = d; } else { if ( d < y2 ) d_next = d + 1; else d_next = d - 1; yy = d; } real_coords(&xx,&yy); if ( map_bld[xx][yy][z] ) return map_bld[xx][yy][z]; } return NULL; } CHAR_DATA *get_char_loc( int x, int y, int z ) { CHAR_DATA *ch; for ( ch = first_char;ch;ch = ch->next ) if ( ch->x == x && ch->y == y && ch->z == z && ch->in_room->vnum == ROOM_VNUM_WMAP ) return ch; return NULL; } void extract_vehicle( VEHICLE_DATA *vhc, bool msg ) { char buf[MSL]; if ( vhc == NULL ) return; if ( vhc->vehicle_in ) extract_vehicle(vhc->vehicle_in,FALSE); { if ( vhc->driving ) { CHAR_DATA *ch = vhc->driving; act( "You eject!!", ch, NULL, NULL, TO_CHAR ); act( "$n ejects!!", ch, NULL, NULL, TO_ROOM ); if ( vhc->z == Z_AIR ) { ch->c_sn = gsn_paradrop; ch->c_level = 20; ch->c_time = 0; } do_look(ch,""); vhc->driving->in_vehicle = NULL; vhc->driving = NULL; } if ( msg ) { sprintf( buf, "%s has exploded!\n\r", vhc->desc ); send_to_loc( buf, vhc->x, vhc->y, vhc->z ); } { VEHICLE_DATA *vhc2; if ( vhc == map_vhc[vhc->x][vhc->y][vhc->z] ) { // free(map_vhc[vhc->x][vhc->y][vhc->z]); //amnon map_vhc[vhc->x][vhc->y][vhc->z] = vhc->next_in_room; } else { for ( vhc2 = map_vhc[vhc->x][vhc->y][vhc->z];vhc2;vhc2 = vhc2->next_in_room ) if ( vhc2->next_in_room && vhc2->next_in_room == vhc ) vhc2->next_in_room = vhc->next_in_room; } } // move_vehicle(vhc,0,0,vhc->z); } // else { UNLINK(vhc, first_vehicle, last_vehicle, next, prev); PUT_FREE(vhc, vehicle_free); } return; } VEHICLE_DATA *get_vehicle_char( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; VEHICLE_DATA *vhc; int number; int count; number = number_argument( argument, arg ); count = 0; for ( vhc = map_vhc[ch->x][ch->y][ch->z]; vhc; vhc = vhc->next_in_room ) { if ( vhc->driving == ch ) continue; if ( is_name( arg, vhc->name ) && vhc->in_vehicle == NULL ) { if ( ++count == number ) return vhc; } } return NULL; } VEHICLE_DATA *get_vehicle( char *argument, int x, int y, int z ) { char arg[MAX_INPUT_LENGTH]; VEHICLE_DATA *vhc; int number; int count; number = number_argument( argument, arg ); count = 0; for ( vhc = map_vhc[x][y][z]; vhc; vhc = vhc->next_in_room ) { if ( is_name( arg, vhc->name ) && vhc->in_vehicle == NULL ) { if ( ++count == number ) return vhc; } } return NULL; } VEHICLE_DATA *get_vehicle_world( char *argument ) { char arg[MAX_INPUT_LENGTH]; VEHICLE_DATA *vhc; int number; int count; number = number_argument( argument, arg ); count = 0; for ( vhc = first_vehicle; vhc; vhc = vhc->next ) { if ( is_name( arg, vhc->name ) && vhc->in_vehicle == NULL ) { if ( ++count == number ) return vhc; } } return NULL; } void char_to_building( CHAR_DATA *ch, BUILDING_DATA *bld ) { OBJ_DATA *obj; VEHICLE_DATA *vhc; ch->in_building = bld; if ( ch->in_vehicle ) { ch->in_vehicle->in_building = bld; if ( TRANSPORT_VEHICLE(ch->in_vehicle->type) ) { vhc = get_vehicle_from_vehicle(ch->in_vehicle); if ( vhc != NULL ) vhc->in_building = ch->in_building; } } for ( obj = ch->first_carry;obj;obj = obj->next_in_carry_list ) obj->in_building = ch->in_building; } CHAR_DATA *get_rand_char( int x, int y, int z ) { CHAR_DATA *ch; CHAR_DATA *wch = NULL; ch = map_ch[x][y][z]; if ( ch == NULL ) return NULL; if ( ch->x != x || ch->y != y ) map_ch[x][y][z] = ch->next_in_room; for ( ;ch; ch = ch->next_in_room ) { if ( ch->dead || (ch->c_sn == gsn_paradrop && ch->c_level < 20 ) ) continue; if ( IN_PIT(ch) ) continue; if ( number_percent() < 50 || wch == NULL ) wch = ch; } return wch; } int get_random_planet() { return Z_GROUND; } void extract_queue(QUEUE_DATA *q) { if ( !q->is_free ) PUT_FREE(q,queue_free); return; } void check_prof(CHAR_DATA *ch) { int time,ttl,x=0,i; char buf[MSL]; if ( !ch ) return; time = my_get_hours(ch,TRUE); ttl = ch->pcdata->prof_ttl; for ( i=0;prof_times[i] > -1;i++ ) { if ( prof_times[i] >= time || prof_times[i+1] == -1 ) { x = i - ttl; break; } } if ( x == 0 ) return; ch->pcdata->prof_ttl = ch->pcdata->prof_ttl + x; ch->pcdata->prof_points = ch->pcdata->prof_points + x; sprintf( buf, "\n\r@@WYou have earned @@a%d@@W Proficiency Point(s) in your last login session!\n\rType '@@eprof@@W' to use them.@@N\n\r", x ); send_to_char(buf,ch); return; } void activate_building(BUILDING_DATA *bld, bool on) { if ( !bld ) return; if ( bld->active == on ) return; bld->active = on; if ( on ) LINK(bld,first_active_building,last_active_building,next_active,prev_active); else { bld->owner = NULL; UNLINK(bld,first_active_building,last_active_building,next_active,prev_active); } return; }