/**************************************************************************** * [S]imulated [M]edieval [A]dventure multi[U]ser [G]ame | \\._.// * * -----------------------------------------------------------| (0...0) * * SMAUG 1.0 (C) 1994, 1995, 1996, 1998 by Derek Snider | ).:.( * * -----------------------------------------------------------| {o o} * * SMAUG code team: Thoric, Altrag, Blodkai, Narn, Haus, | / ' ' \ * * Scryn, Rennard, Swordbearer, Gorog, Grishnakh, Nivek, |~'~.VxvxV.~'~* * Tricops and Fireblade | * * ------------------------------------------------------------------------ * * Merc 2.1 Diku Mud improvments copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. * * ------------------------------------------------------------------------ * * Online Building and Editing Module * ****************************************************************************/ #include <stdio.h> #include <string.h> #include <unistd.h> #include "mud.h" extern ROOM_INDEX_DATA *room_index_hash[MAX_KEY_HASH]; /* * Exit Pull/push types * (water, air, earth, fire) */ const char *const ex_pmisc[] = { "undefined", "vortex", "vacuum", "slip", "ice", "mysterious" }; const char *const ex_pwater[] = { "current", "wave", "whirlpool", "geyser" }; const char *const ex_pair[] = { "wind", "storm", "coldwind", "breeze" }; const char *const ex_pearth[] = { "landslide", "sinkhole", "quicksand", "earthquake" }; const char *const ex_pfire[] = { "lava", "hotair" }; const char *const ex_flags[] = { "isdoor", "closed", "locked", "secret", "swim", "pickproof", "fly", "climb", "dig", "eatkey", "nopassdoor", "hidden", "passage", "portal", "r1", "r2", "can_climb", "can_enter", "can_leave", "auto", "noflee", "searchable", "bashed", "bashproof", "nomob", "window", "can_look", "isbolt", "bolted" }; const char *const sec_flags[] = { "inside", "city", "field", "forest", "hills", "mountain", "water_swim", "water_noswim", "underwater", "air", "desert", "dunno", "oceanfloor", "underground", "lava", "swamp", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16" }; const char *const r_flags[] = { "dark", "death", "nomob", "indoors", "lawful", "neutral", "chaotic", "nomagic", "tunnel", "private", "safe", "solitary", "petshop", "norecall", "donation", "nodropall", "silence", "logspeech", "nodrop", "clanstoreroom", "nosummon", "noastral", "teleport", "teleshowdesc", "nofloor", "nosupplicate", "arena", "nomissile", "r4", "r5", "prototype", "dnd", "bfs_mark" }; const char *const o_flags[] = { "glow", "hum", "dark", "loyal", "evil", "invis", "magic", "nodrop", "bless", "antigood", "antievil", "antineutral", "noremove", "inventory", "antimage", "antithief", "antiwarrior", "anticleric", "organic", "metal", "donation", "clanobject", "clancorpse", "antivampire", "antidruid", "hidden", "poisoned", "covering", "deathrot", "buried", "prototype", "nolocate", "groundrot", "lootable", "personal", "multi_invoke", "enchanted" }; const char *const w_flags[] = { "take", "finger", "neck", "body", "head", "legs", "feet", "hands", "arms", "shield", "about", "waist", "wrist", "wield", "hold", "_dual_", "ears", "eyes", "missile", "back", "face", "ankle", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13" }; const char *const area_flags[] = { "nopkill", "freekill", "noteleport", "spelllimit", "prototype", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31" }; const char *const o_types[] = { "none", "light", "scroll", "wand", "staff", "weapon", "_fireweapon", "_missile", "treasure", "armor", "potion", "_worn", "furniture", "trash", "_oldtrap", "container", "_note", "drinkcon", "key", "food", "money", "pen", "boat", "corpse", "corpse_pc", "fountain", "pill", "blood", "bloodstain", "scraps", "pipe", "herbcon", "herb", "incense", "fire", "book", "switch", "lever", "pullchain", "button", "dial", "rune", "runepouch", "match", "trap", "map", "portal", "paper", "tinder", "lockpick", "spike", "disease", "oil", "fuel", "_empty1", "_empty2", "missileweapon", "projectile", "quiver", "shovel", "salve", "cook", "keyring", "odor", "chance", "mix" }; const char *const a_types[] = { "none", "strength", "dexterity", "intelligence", "wisdom", "constitution", "sex", "class", "level", "age", "height", "weight", "mana", "hit", "move", "gold", "experience", "armor", "hitroll", "damroll", "save_poison", "save_rod", "save_para", "save_breath", "save_spell", "charisma", "affected", "resistant", "immune", "susceptible", "weaponspell", "luck", "backstab", "pick", "track", "steal", "sneak", "hide", "palm", "detrap", "dodge", "peek", "scan", "gouge", "search", "mount", "disarm", "kick", "parry", "bash", "stun", "punch", "climb", "grip", "scribe", "brew", "wearspell", "removespell", "emotion", "mentalstate", "stripsn", "remove", "dig", "full", "thirst", "drunk", "blood", "cook", "recurringspell", "contagious", "xaffected", "odor", "roomflag", "sectortype", "roomlight", "televnum", "teledelay" }; const char *const a_flags[] = { "blind", "invisible", "detect_evil", "detect_invis", "detect_magic", "detect_hidden", "hold", "sanctuary", "faerie_fire", "infrared", "curse", "_flaming", "poison", "protect", "_paralysis", "sneak", "hide", "sleep", "charm", "flying", "pass_door", "floating", "truesight", "detect_traps", "scrying", "fireshield", "shockshield", "r1", "iceshield", "possess", "berserk", "aqua_breath", "recurringspell", "contagious", "acidmist", "venomshield" }; const char *const act_flags[] = { "npc", "sentinel", "scavenger", "r1", "r2", "aggressive", "stayarea", "wimpy", "pet", "train", "practice", "immortal", "deadly", "polyself", "meta_aggr", "guardian", "running", "nowander", "mountable", "mounted", "scholar", "secretive", "hardhat", "mobinvis", "noassist", "autonomous", "pacifist", "noattack", "annoying", "statshield", "prototype" }; const char *const ris_flags[] = { "fire", "cold", "electricity", "energy", "blunt", "pierce", "slash", "acid", "poison", "drain", "sleep", "charm", "hold", "nonmagic", "plus1", "plus2", "plus3", "plus4", "plus5", "plus6", "magic", "paralysis", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" }; const char *const part_flags[] = { "head", "arms", "legs", "heart", "brains", "guts", "hands", "feet", "fingers", "ear", "eye", "long_tongue", "eyestalks", "tentacles", "fins", "wings", "tail", "scales", "claws", "fangs", "horns", "tusks", "tailattack", "sharpscales", "beak", "haunches", "hooves", "paws", "forelegs", "feathers", "r1", "r2" }; const char *const attack_flags[] = { "bite", "claws", "tail", "sting", "punch", "kick", "trip", "bash", "stun", "gouge", "backstab", "feed", "drain", "firebreath", "frostbreath", "acidbreath", "lightnbreath", "gasbreath", "poison", "nastypoison", "gaze", "blindness", "causeserious", "earthquake", "causecritical", "curse", "flamestrike", "harm", "fireball", "colorspray", "weaken", "spiralblast" }; const char *const defense_flags[] = { "parry", "dodge", "heal", "curelight", "cureserious", "curecritical", "dispelmagic", "dispelevil", "sanctuary", "fireshield", "shockshield", "shield", "bless", "stoneskin", "teleport", "monsum1", "monsum2", "monsum3", "monsum4", "disarm", "iceshield", "grip", "truesight", "acidmist", "venomshield" }; const char *const npc_position[] = { "dead", "mortal", "incapacitated", "stunned", "sleeping", "resting", "sitting", "berserk", "aggressive", "fighting", "defensive", "evasive", "standing", "mounted", "shove", "drag" }; const char *const npc_sex[] = { "neuter", "male", "female" }; const char *flag_string( int bitvector, const char *const flagarray[] ) { static char buf[MAX_STRING_LENGTH]; int x; buf[0] = '\0'; for( x = 0; x < 32; ++x ) if( IS_SET( bitvector, 1 << x ) ) { mudstrlcat( buf, flagarray[x], MAX_STRING_LENGTH ); /* * don't catenate a blank if the last char is blank --Gorog */ if( buf[0] != '\0' && ' ' != buf[strlen( buf ) - 1] ) mudstrlcat( buf, " ", MAX_STRING_LENGTH ); } if( ( x = strlen( buf ) ) > 0 ) buf[--x] = '\0'; return buf; } const char *ext_flag_string( EXT_BV * bitvector, const char *const flagarray[] ) { static char buf[MAX_STRING_LENGTH]; int x; buf[0] = '\0'; for( x = 0; x < MAX_BITS; ++x ) if( xIS_SET( *bitvector, x ) ) { mudstrlcat( buf, flagarray[x], MAX_STRING_LENGTH ); mudstrlcat( buf, " ", MAX_STRING_LENGTH ); } if( ( x = strlen( buf ) ) > 0 ) buf[--x] = '\0'; return buf; } int get_otype( const char *type ) { unsigned int x; for( x = 0; x < ( sizeof( o_types ) / sizeof( o_types[0] ) ); x++ ) if( !str_cmp( type, o_types[x] ) ) return x; return -1; } int get_aflag( const char *flag ) { unsigned int x; for( x = 0; x < ( sizeof( a_flags ) / sizeof( a_flags[0] ) ); x++ ) if( !str_cmp( flag, a_flags[x] ) ) return x; return -1; } int get_secflag( const char *flag ) { unsigned int x; for( x = 0; x < ( sizeof( sec_flags ) / sizeof( sec_flags[0] ) ); x++ ) if( !str_cmp( flag, sec_flags[x] ) ) return x; return -1; } int get_exflag( const char *flag ) { unsigned int x; for( x = 0; x < ( sizeof( ex_flags ) / sizeof( ex_flags[0] ) ); x++ ) if( !str_cmp( flag, ex_flags[x] ) ) return x; return -1; } int get_pulltype( const char *type ) { unsigned int x; if( !str_cmp( type, "none" ) || !str_cmp( type, "clear" ) ) return 0; for( x = 0; x < ( sizeof( ex_pmisc ) / sizeof( ex_pmisc[0] ) ); x++ ) if( !str_cmp( type, ex_pmisc[x] ) ) return x; for( x = 0; x < ( sizeof( ex_pwater ) / sizeof( ex_pwater[0] ) ); x++ ) if( !str_cmp( type, ex_pwater[x] ) ) return x + PT_WATER; for( x = 0; x < ( sizeof( ex_pair ) / sizeof( ex_pair[0] ) ); x++ ) if( !str_cmp( type, ex_pair[x] ) ) return x + PT_AIR; for( x = 0; x < ( sizeof( ex_pearth ) / sizeof( ex_pearth[0] ) ); x++ ) if( !str_cmp( type, ex_pearth[x] ) ) return x + PT_EARTH; for( x = 0; x < ( sizeof( ex_pfire ) / sizeof( ex_pfire[0] ) ); x++ ) if( !str_cmp( type, ex_pfire[x] ) ) return x + PT_FIRE; return -1; } int get_rflag( const char *flag ) { unsigned int x; for( x = 0; x < ( sizeof( r_flags ) / sizeof( r_flags[0] ) ); x++ ) if( !str_cmp( flag, r_flags[x] ) ) return x; return -1; } int get_oflag( const char *flag ) { unsigned int x; for( x = 0; x < ( sizeof( o_flags ) / sizeof( o_flags[0] ) ); x++ ) if( !str_cmp( flag, o_flags[x] ) ) return x; return -1; } int get_areaflag( const char *flag ) { unsigned int x; for( x = 0; x < ( sizeof( area_flags ) / sizeof( area_flags[0] ) ); x++ ) if( !str_cmp( flag, area_flags[x] ) ) return x; return -1; } int get_wflag( const char *flag ) { unsigned int x; for( x = 0; x < ( sizeof( w_flags ) / sizeof( w_flags[0] ) ); x++ ) if( !str_cmp( flag, w_flags[x] ) ) return x; return -1; } int get_actflag( const char *flag ) { unsigned int x; for( x = 0; x < ( sizeof( act_flags ) / sizeof( act_flags[0] ) ); x++ ) if( !str_cmp( flag, act_flags[x] ) ) return x; return -1; } int get_risflag( const char *flag ) { unsigned int x; for( x = 0; x < ( sizeof( ris_flags ) / sizeof( ris_flags[0] ) ); x++ ) if( !str_cmp( flag, ris_flags[x] ) ) return x; return -1; } int get_partflag( const char *flag ) { unsigned int x; for( x = 0; x < ( sizeof( part_flags ) / sizeof( part_flags[0] ) ); x++ ) if( !str_cmp( flag, part_flags[x] ) ) return x; return -1; } int get_attackflag( const char *flag ) { unsigned int x; for( x = 0; x < ( sizeof( attack_flags ) / sizeof( attack_flags[0] ) ); x++ ) if( !str_cmp( flag, attack_flags[x] ) ) return x; return -1; } int get_defenseflag( const char *flag ) { unsigned int x; for( x = 0; x < ( sizeof( defense_flags ) / sizeof( defense_flags[0] ) ); x++ ) if( !str_cmp( flag, defense_flags[x] ) ) return x; return -1; } int get_npc_position( const char *position ) { size_t x; for( x = 0; x <= POS_DRAG; x++ ) if( !str_cmp( position, npc_position[x] ) ) return x; return -1; } int get_npc_sex( const char *sex ) { size_t x; for( x = 0; x <= SEX_FEMALE; x++ ) if( !str_cmp( sex, npc_sex[x] ) ) return x; return -1; } /* * Remove carriage returns from a line */ char *strip_cr( const char *str ) { static char newstr[MAX_STRING_LENGTH]; int i, j; if( !str || str[0] == '\0' ) { newstr[0] = '\0'; return newstr; } for( i = j = 0; str[i] != '\0'; i++ ) if( str[i] != '\r' ) { newstr[j++] = str[i]; } newstr[j] = '\0'; return newstr; } /* * Returns value 0 - 9 based on directional text. */ int get_dir( const char *txt ) { int edir; char c1, c2; if( !str_cmp( txt, "northeast" ) ) return DIR_NORTHEAST; if( !str_cmp( txt, "northwest" ) ) return DIR_NORTHWEST; if( !str_cmp( txt, "southeast" ) ) return DIR_SOUTHEAST; if( !str_cmp( txt, "southwest" ) ) return DIR_SOUTHWEST; if( !str_cmp( txt, "somewhere" ) ) return 10; c1 = txt[0]; if( c1 == '\0' ) return 0; c2 = txt[1]; edir = 0; switch ( c1 ) { case 'n': switch ( c2 ) { default: edir = 0; break; /* north */ case 'e': edir = 6; break; /* ne */ case 'w': edir = 7; break; /* nw */ } break; case '0': edir = 0; break; /* north */ case 'e': case '1': edir = 1; break; /* east */ case 's': switch ( c2 ) { default: edir = 2; break; /* south */ case 'e': edir = 8; break; /* se */ case 'w': edir = 9; break; /* sw */ } break; case '2': edir = 2; break; /* south */ case 'w': case '3': edir = 3; break; /* west */ case 'u': case '4': edir = 4; break; /* up */ case 'd': case '5': edir = 5; break; /* down */ case '6': edir = 6; break; /* ne */ case '7': edir = 7; break; /* nw */ case '8': edir = 8; break; /* se */ case '9': edir = 9; break; /* sw */ case '?': edir = 10; break; /* somewhere */ } return edir; }