/*~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- ~ 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 <string.h> #include <time.h> #include "ack.h" #include "tables.h" #include <math.h> sh_int get_psuedo_level( CHAR_DATA *ch ) { return 80; } bool ok_to_use( CHAR_DATA *ch, int value ) { if ( value == NO_USE && get_trust(ch) < 85 ) { send_to_char( "Only Creators may use this value.\n\r", ch ); return FALSE; } return TRUE; } bool check_level_use( CHAR_DATA *ch, int level ) { char buf[MAX_STRING_LENGTH]; char out[MAX_STRING_LENGTH]; if ( get_trust(ch) >= level ) return TRUE; sprintf( out, "This option limited to " ); switch ( level ) { case 85: safe_strcat( MSL, out, "Creators only.\n\r" ); break; case 84: safe_strcat( MSL, out, "Supremes or higher.\n\r" ); break; case 83: safe_strcat( MSL, out, "Dieties or higher.\n\r" ); break; case 82: safe_strcat( MSL, out, "Immortals or higher.\n\r" ); break; case 81: safe_strcat( MSL, out, "Heroes or higher.\n\r" ); break; default: sprintf( buf, "level %d players and higher.\n\r", level ); safe_strcat( MSL, out, buf ); } send_to_char( out, ch ); return FALSE; } OBJ_DATA * create_teleporter( BUILDING_DATA *bld, int range ) { OBJ_DATA *obj; char buf[MSL]; obj = create_object( get_obj_index( OBJ_VNUM_TELEPORTER ), 0 ); obj->level = range; obj->value[0] = range; obj->value[1] = bld->type; sprintf( buf, "A Series %d, %s-Teleporter", range, capitalize(bld->name) ); free_string( obj->short_descr ); free_string( obj->description ); free_string( obj->name ); obj->short_descr = str_dup(buf); obj->description = str_dup(buf); sprintf( buf, "Teleporter %s", bld->name ); obj->name = str_dup(buf); obj->x = bld->x; obj->y = bld->y; obj_to_room(obj,get_room_index(ROOM_VNUM_WMAP)); return obj; } OBJ_DATA * create_locator( int range ) { OBJ_DATA *obj; char buf[MSL]; obj = create_object( get_obj_index( OBJ_VNUM_LOCATOR ), 0 ); obj->level = range; obj->value[0] = range; sprintf( buf, "A Series %d item locator", range ); free_string( obj->short_descr ); free_string( obj->description ); obj->short_descr = str_dup(buf); obj->description = str_dup(buf); obj->x = 1; obj->y = 1; obj_to_room(obj,get_room_index(ROOM_VNUM_WMAP)); return obj; } bool complete( BUILDING_DATA *bld ) { return (!bld->cost); } VEHICLE_DATA *get_vehicle_from_vehicle( VEHICLE_DATA *vhc ) { if ( !vhc || vhc == NULL || !TRANSPORT_VEHICLE(vhc->type) ) return NULL; return vhc->vehicle_in; } bool is_upgrade( int type ) { int i; for ( i = 0;i<8;i++ ) if ( build_table[type].cost != 0 ) return FALSE; return TRUE; } bool is_evil( BUILDING_DATA *bld ) { if ( bld->timer > 0 || IS_SET(bld->value[1],INST_ONLINE)) return TRUE; return FALSE; } int get_char_cost( CHAR_DATA *ch ) { BUILDING_DATA *bld; int cost = 0; for ( bld = ch->first_building;bld;bld = bld->next_owned ) { cost += bld->level; } return cost; } bool IS_BETWEEN(int x,int x1, int x2) { if ( x1 > x2 ) if ( x >= x2 && x <= x1 ) return TRUE; if ( x1 < x2 ) if ( x <= x2 && x >= x1 ) return TRUE; if ( x1 == x2 ) if ( x == x1 ) return TRUE; return FALSE; } bool building_can_shoot( BUILDING_DATA *bld, CHAR_DATA *ch, int range ) { BUILDING_DATA *bld2; if ( ch == NULL ) return FALSE; if ( bld->owner == ch ) return FALSE; if ( IS_IMMORTAL(ch) ) return FALSE; if ( (bld->level < 5 && sneak(ch) ) || sneak(ch) ) return FALSE; if ( ( bld2 = ch->in_building ) != NULL && complete(bld2) && !open_bld(bld2) ) return FALSE; if ( bld2 && bld2 == bld ) return FALSE; return TRUE; } bool open_bld( BUILDING_DATA *bld ) { if ( !complete(bld) ) return TRUE; if ( build_table[bld->type].act == BUILDING_WALLS || build_table[bld->type].act == BUILDING_UNATTACHED || bld->type == BUILDING_WAR_CANNON || bld->type == BUILDING_SNIPER_TOWER || bld->type == BUILDING_SPACEYARD || bld->type == BUILDING_AIRFIELD ) return TRUE; return FALSE; } int get_rank( CHAR_DATA *ch ) { int rank; if ( IS_IMMORTAL(ch) ) return 9999; /* rank = ((ch->pcdata->tbkills/4) + (ch->pcdata->tpkills/3)) - ( ch->pcdata->deaths/3); rank += 1; */ rank = (ch->rank / 100)+1; if ( rank < 1 ) rank = 1; else if ( rank > 9998 ) rank = 9998; return rank; } int get_bit_value( int bit ) { switch (bit) { case 1: return BIT_1; case 2: return BIT_2; case 3: return BIT_3; case 4: return BIT_4; case 5: return BIT_5; case 6: return BIT_6; case 7: return BIT_7; case 8: return BIT_8; case 9: return BIT_9; case 10: return BIT_10; case 11: return BIT_11; case 12: return BIT_12; case 13: return BIT_13; case 14: return BIT_14; case 15: return BIT_15; case 16: return BIT_16; case 17: return BIT_17; case 18: return BIT_18; case 19: return BIT_19; case 20: return BIT_20; case 21: return BIT_21; case 22: return BIT_22; case 23: return BIT_23; case 24: return BIT_24; case 25: return BIT_25; case 26: return BIT_26; case 27: return BIT_27; case 28: return BIT_28; case 29: return BIT_29; case 30: return BIT_30; case 31: return BIT_31; case 32: return BIT_32; default: return 0; } return 0; } bool sneak( CHAR_DATA *ch ) { int chance,sect; OBJ_DATA *obj; if ( !ch ) return TRUE; if ( ch->z == Z_PAINTBALL ) return FALSE; if ( ch->class == CLASS_DARKOP && ch->in_vehicle == NULL && number_percent() < 22 ) return TRUE; if ( ( obj = get_eq_char(ch,WEAR_BODY) ) != NULL && obj->item_type == ITEM_SUIT && obj->value[0] == 0 && number_percent() < obj->value[1] ) return TRUE; if ( ch->position != POS_SNEAKING ) return FALSE; sect = map_table.type[ch->x][ch->y][ch->z]; chance = ch->pcdata->skill[gsn_sneak]; chance += ch->pcdata->skill[gsn_combat] * 1.5; if ( sect == SECT_ROCK ) chance -= 7; else if ( sect == SECT_FIELD ) chance -= 5; else if ( sect == SECT_FOREST ) chance += 10; if ( chance > 90 ) chance = 90; if ( number_percent() < chance ) return TRUE; return FALSE; } void check_building_destroyed( BUILDING_DATA *bld ) { CHAR_DATA *bch; if ( bld == NULL ) return; bch = get_ch(bld->owned); if ( bch == NULL ) return; if ( bld->type == BUILDING_BANK && bld->value[5] > 1 ) { if ( has_ability(bch,6) ) //money safe { send_to_char("You manage to keep 50% of the bank's deposited money.\n\r", bch ); gain_money(bch,bld->value[5]/2); } } else if ( bld->type == BUILDING_PSYCHIC_LAB ) { BUILDING_DATA *bld2; int x=0, labcount = 0; char buf[MSL]; for ( bld2=bch->first_building;bld2;bld2 = bld2->next_owned ) if ( bld2->type == BUILDING_PSYCHIC_LAB ) labcount++; for ( bld2=bch->first_building;bld2 && labcount <= 1;bld2 = bld2->next_owned ) { if ( build_table[bld2->type].act == BUILDING_DEFENSE && bld2->value[10] == DAMAGE_PSYCHIC ) { bld2->value[10] = DAMAGE_BULLETS; x++; } } if ( x > 0 ) { sprintf(buf,"%d of your turrets have been reverted back to bullet damage.\n\r", x ); send_to_char(buf,bch); } if ( labcount > 1) send_to_char("None of your defenses have been reverted. Alternate Psychic Lab found.\r\n", bch); } return; } int get_item_limit( BUILDING_DATA *bld ) { if ( bld == NULL ) return 0; if ( bld->type == BUILDING_WAREHOUSE ) return bld->level * 20; return 20; } void send_warning( CHAR_DATA *ch, BUILDING_DATA *bld, CHAR_DATA *victim ) { char buf[MSL]; if ( ch == victim ) return; if ( victim->in_vehicle && victim->in_vehicle->type == VEHICLE_BOMBER ) return; sprintf( buf, "@@yYour %s, at %d/%d, is firing at %s!\n\r", bld->name, bld->x, bld->y, victim->name ); send_to_char( buf, ch ); return; } void update_ranks( CHAR_DATA *ch ) { int i,min,rank,max=0; bool stop = FALSE; if ( !ch ) return; min = 0; rank = get_rank(ch); for ( i = 0;i<30;i++ ) { if ( !stop && (rank_table[i].name == NULL || !str_cmp(rank_table[i].name,ch->name) ) ) { min = i; stop = TRUE; // break; } if ( !stop && rank_table[i].rank < rank_table[min].rank ) min = i; if ( rank_table[i].rank > max ) max = rank_table[i].rank; } if ( rank_table[min].name != NULL ) free_string(rank_table[min].name); rank_table[min].name = str_dup(ch->name); rank_table[min].rank = rank; save_ranks(); if ( rank > max ) { web_data.highest_rank = rank; update_web_data(WEB_DATA_HIGHEST_RANK,ch->name); } return; } bool defense_building( BUILDING_DATA *bld ) { if ( build_table[bld->type].act == BUILDING_DEFENSE ) return TRUE; return FALSE; } void sendsound( CHAR_DATA *ch, char *file, int V, int I, int P, char *T, char *filename ) { char buf[MSL]; if ( !IS_SET(ch->config,CONFIG_SOUND) ) return; sprintf( buf, "\n\r!!SOUND(%s V=%d L=%d P=%d T=%s U=%s/sounds/%s)", file, V,I,P,T,WEBSITE,filename ); send_to_char(buf,ch); return; } int check_dodge( CHAR_DATA *ch, int chance ) { int newchance; newchance = chance - ( (chance / 100) * (ch->pcdata->skill[gsn_dodge] /2) ); if ( ch->pcdata->skill[gsn_dodge] < 100 && number_percent() < 2 ) { send_to_char( "You have become better at dodge!\n\r", ch ); ch->pcdata->skill[gsn_dodge]++; save_char_obj(ch); } return newchance; } bool in_range( CHAR_DATA *ch, CHAR_DATA *victim, int range ) { if ( !ch || !victim ) return FALSE; if ( (IS_BETWEEN(victim->x,ch->x-range,ch->x+range)) && (IS_BETWEEN(victim->y,ch->y-range,ch->y+range))) return TRUE; else return FALSE; } void create_obj_atch( CHAR_DATA *ch, int index ) { OBJ_DATA *obj; obj = create_object(get_obj_index(index),0); obj->x = ch->x; obj->y = ch->y; obj->z = ch->z; obj_to_room(obj,ch->in_room); return; } bool blind_spot( CHAR_DATA *ch, int x, int y ) { int range = 5; if ( !ch->in_vehicle ) return FALSE; if ( IS_SET(ch->in_vehicle->flags,VEHICLE_SWIM) ) range = 8; else if ( AIR_VEHICLE(ch->in_vehicle->type) ) range = 6; else if ( ch->in_vehicle->type == VEHICLE_CREEPER ) range = 2; if ( (x < ch->x - range || x > ch->x + range || y < ch->y - range || y > ch->y + range)) return TRUE; return FALSE; } void reset_building(BUILDING_DATA *bld,int type) { activate_building(bld,TRUE); bld->type = type; bld->maxhp = build_table[type].hp; bld->maxshield = build_table[type].shield; bld->hp = bld->maxhp; bld->shield = bld->maxshield; bld->level = 1; if ( bld->owned != NULL ) free_string(bld->owned); if ( bld->name != NULL ) free_string(bld->name); bld->owned = str_dup("Nobody"); bld->owner = NULL; bld->name = str_dup(build_table[type].name); bld->cost = 0; } OBJ_DATA * make_quest_base( int type, int size, int z ) { bool bad = TRUE; bool skip = FALSE; BUILDING_DATA *bld; OBJ_DATA *obj = NULL; int i,x,y,xx,yy; int ox,oy; i=0; ox = 0; oy = 0; size /= 1.5; while ( bad ) { i++; if ( i > 5 ) return NULL; bad = FALSE; x = number_range(size+4,MAX_MAPS-size-5); y = number_range(size+4,MAX_MAPS-size-5); if ( map_table.type[x][y][z] == SECT_NULL ) { bad = TRUE; continue; } for ( xx = x-size-4;xx<x+size+4;xx++ ) for ( yy = y-size-4;yy<y+size+4;yy++ ) if ( map_bld[xx][yy][z] ) bad = TRUE; } for ( xx = x-size;xx<x+size;xx++ ) { for ( yy = y-size;yy<y+size;yy++ ) { skip = !skip; if ( number_percent() < 15 ) skip = !skip; if ( skip ) continue; if ( ox == 0 || number_percent() < 5 ) { ox = xx; oy = yy; } bld = create_building(type); bld->x = xx; bld->y = yy; bld->z = z; map_bld[bld->x][bld->y][bld->z] = bld; reset_building(bld,type); bld->timer = 60; for ( i=0;i<4;i++ ) bld->exit[i] = TRUE; } } if ( ox > 0 && oy > 0 ) { char buf[MSL]; obj = create_object(get_obj_index(OBJ_VNUM_SCAFFOLD),0); obj->level = 1; obj->value[0] = type; sprintf(buf,"@@cA@@a %s @@cScaffold@@N",build_table[type].name); free_string(obj->short_descr); free_string(obj->description); obj->short_descr = str_dup(buf); obj->description = str_dup(buf); sprintf(buf,"%s Scaffold",build_table[type].name); free_string(obj->name); obj->name = str_dup(buf); obj_to_room(obj,get_room_index(ROOM_VNUM_WMAP)); move_obj(obj,ox,oy,z); } return obj; } bool open_scaffold(CHAR_DATA *ch, OBJ_DATA *obj) { BUILDING_DATA *bld; int i,buildings=0,same=0; char buf[MSL]; if ( !obj || obj->item_type != ITEM_SCAFFOLD || get_building(obj->x,obj->y,obj->z)) return FALSE; if ( !sysdata.killfest ) { for ( bld = first_building;bld;bld = bld->next ) { if ( str_cmp(ch->name, bld->owned) ) continue; if ( bld->type == obj->value[0] ) same++; buildings++; } } if ( buildings >= BUILDING_LIMIT ) return FALSE; if ( same >= obj->value[1] ) return FALSE; bld = create_building(obj->value[0]); if ( bld == NULL ) return FALSE; reset_building(bld,obj->value[0]); bld->x = obj->x; bld->y = obj->y; bld->z = obj->z; map_bld[bld->x][bld->y][bld->z] = bld; free_string(bld->owned); bld->owned = str_dup(ch->name); bld->owner = ch; sprintf(buf,"%s @@copens up into the @@a%s@@c!@@N\n\r",obj->short_descr,bld->name); send_to_loc(buf,obj->x,obj->y,obj->z); bld->cost = 0; for ( i=0;i<4;i++ ) bld->exit[i] = TRUE; bld->hp = 1; bld->shield = 1; extract_obj(obj); reset_special_building(bld); return TRUE; } bool has_ability(CHAR_DATA *ch,int abil) { if ( ch->pcdata->skill[gsn_economics] >= ability_table[abil].economics ) if ( ch->pcdata->skill[gsn_building] >= ability_table[abil].building ) if ( ch->pcdata->skill[gsn_combat] >= ability_table[abil].combat ) return TRUE; return FALSE; } void reset_special_building(BUILDING_DATA *bld) { return; } int get_armor_value(int dt) { if ( dt == DAMAGE_GENERAL ) return 2; else if ( dt == DAMAGE_BULLETS ) return 3; else if ( dt == DAMAGE_BLAST ) return 4; else if ( dt == DAMAGE_ACID ) return 5; else if ( dt == DAMAGE_FLAME ) return 6; else if ( dt == DAMAGE_LASER ) return 7; else if ( dt == DAMAGE_SOUND ) return 8; else return -1; } bool hidden(CHAR_DATA *victim) { if ( IS_SET(victim->act, PLR_WIZINVIS) || IS_SET(victim->act, PLR_INCOG) ) return TRUE; if ( victim->in_building && victim->in_building->type == BUILDING_CLUB && complete(victim->in_building) ) return TRUE; return FALSE; } int count_buildings(CHAR_DATA *victim) { int i=0; BUILDING_DATA *bld; if ( !victim || victim == NULL ) return 999; for ( bld = victim->first_building;bld;bld = bld->next_owned ) i++; return i; } void clear_basic(CHAR_DATA *ch) { ch->pcdata->pkills = 0; ch->pcdata->tpkills = 0; ch->pcdata->bkills = 0; ch->pcdata->tbkills = 0; ch->quest_points = 0; ch->pcdata->deaths = 0; return; } void real_coords(int *x,int *y) { if ( *x < 0 ) *x = MAX_MAPS + *x; if ( *y < 0 ) *y = MAX_MAPS + *y; if ( *x >= MAX_MAPS ) *x = *x - MAX_MAPS; if ( *y >= MAX_MAPS ) *y = *y - MAX_MAPS; } bool check_hq_connection(BUILDING_DATA *bldc) { CHAR_DATA *ch = bldc->owner; BUILDING_DATA *bld; BUILDING_DATA *bld_next; int b; if ( !ch || ch == NULL ) return FALSE; if ( sysdata.killfest ) { for (bld=ch->first_building;bld;bld = bld->next_owned) bld->tag = TRUE; return TRUE; } for (bld=ch->first_building;bld;bld = bld->next_owned){ if (bld->type==BUILDING_HQ) tag(bld); } for (bld=ch->first_building;bld;bld = bld_next) { bld_next = bld->next_owned; if ( bld->tag == FALSE ) b++; bld->visible = TRUE; } return TRUE; } void tag(BUILDING_DATA *bld) { int range, xx, yy, x, y; if (!bld || bld==NULL) return; range = (bld->value[6] +(bld->level / 2)); for (xx=bld->x - range;xx <= bld->x + range;xx++) for (yy=bld->y - range;yy <= bld->y + range;yy++) { x = xx; y = yy; real_coords(&x,&y); if (map_bld[x][y][bld->z]) { if (map_bld[x][y][bld->z]->owner == bld->owner && bld->tag != TRUE && build_table[bld->type].act != BUILDING_POWERPLANT) map_bld[x][y][bld->z]->tag = TRUE; }} tag(find_building(bld,DIR_NORTH)); tag(find_building(bld,DIR_WEST)); tag(find_building(bld,DIR_SOUTH)); tag(find_building(bld,DIR_EAST)); return; } BUILDING_DATA *find_building(BUILDING_DATA *bld,int dir) { int x,y; x = bld->x; y = bld->y; if ( dir == DIR_NORTH ) y++; else if ( dir == DIR_SOUTH ) y--; else if ( dir == DIR_WEST ) x--; else x++; real_coords(&x,&y); return map_bld[x][y][bld->z]; } void gain_money(CHAR_DATA *ch,long r) { if ( ch->money + r > MAX_CASH ) ch->money = MAX_CASH; else ch->money += r; } void check_power(CHAR_DATA *vict) { int range = 0 ; int xx, yy, x, y; BUILDING_DATA *bld; if(vict == NULL) return; if(vict->first_building == NULL) return; for ( bld = vict->first_building;bld != NULL;bld = bld->next_owned ) { bld->tag = FALSE; } for ( bld = vict->first_building;bld != NULL;bld = bld->next_owned ) { if (build_table[bld->type].act == BUILDING_POWERPLANT || bld->type == BUILDING_HQ || build_table[bld->type].act == BUILDING_UNATTACHED ) { bld->tag = TRUE; range = (bld->value[6] + (bld->level / 2)); if(build_table[bld->type].act != BUILDING_UNATTACHED) { for (xx=bld->x - range;xx <= bld->x + range;xx++) for (yy=bld->y - range;yy <= bld->y + range;yy++) { x = xx; y = yy; real_coords(&x,&y); if (map_bld[x][y][bld->z]) if (map_bld[x][y][bld->z]->owner == vict ) map_bld[x][y][bld->z]->tag = TRUE; } } } } //check_hq_connection(bld); return; } OBJ_DATA *get_best_laptop(CHAR_DATA *ch) { OBJ_DATA *obj; OBJ_DATA *obj2=NULL; for ( obj = ch->first_carry;obj;obj = obj->next_in_carry_list ) { if ( obj->item_type != ITEM_COMPUTER ) continue; if ( obj->value[1] <= 0 ) continue; if ( obj->value[8] == 0 ) continue; if ( obj2 == NULL || obj->value[0] > obj2->value[0] ) obj2 = obj; } return obj2; }