#include "define.h" #include "struct.h" const char* seperate ( const char*, bool ); void append_liquid ( char*, obj_data* ); char static_storage [ 10*THREE_LINES ]; int store_pntr = 0; bool include_liquid = TRUE; bool include_empty = TRUE; bool include_closed = TRUE; /* * SUPPORT ROUTINES */ const char* color_word [] = { "grey", "red", "orange", "yellow", "green", "cyan", "blue", "indigo", "violet", "purple", "white" }; const char* gem_quality [] = { "uncut", "flawless", "blemished", "fractured" }; void get_obj_adj( char* tmp, char_data* ch, obj_data* obj ) { int metal; *tmp = '\0'; for( metal = MAT_BRONZE; metal <= MAT_ADAMANTINE; metal++ ) if( is_set( &obj->materials, metal ) ) break; /* if( is_set( obj->pIndexData->size_flags, SFLAG_RANDOM ) ) { for( i = SFLAG_TINY; i < SFLAG_GIANT; i++ ) if( is_set( &obj_clss->size_flags, i ) ) break; */ if( ch != NULL ) { if( is_set( obj->extra_flags, OFLAG_EVIL ) && IS_AFFECTED( ch, AFF_DETECT_EVIL ) ) sprintf( tmp+strlen( tmp ), "%s+evil+", tmp[0] == '\0' ? "" : ", " ); if( is_set( obj->extra_flags, OFLAG_GOOD ) && IS_AFFECTED( ch, AFF_DETECT_GOOD ) ) sprintf( tmp+strlen( tmp ), "%s+good+", tmp[0] == '\0' ? "" : ", " ); } if( obj->rust != 0 && metal <= MAT_ADAMANTINE ) strcpy( tmp, material_table[ metal ].rust[ obj->rust-1 ] ); if( is_set( obj->extra_flags, OFLAG_IS_INVIS ) ) sprintf( tmp+strlen( tmp ), "%sinvisible", tmp[0] == '\0' ? "" : ", " ); if( ch != NULL && IS_AFFECTED( ch, AFF_DETECT_MAGIC ) && is_set( obj->extra_flags, OFLAG_MAGIC ) ) sprintf( tmp+strlen( tmp ), "%senchanted", tmp[0] == '\0' ? "" : ", " ); if( is_set( obj->extra_flags, OFLAG_BURNING ) ) sprintf( tmp+strlen( tmp ), "%sburning", tmp[0] == '\0' ? "" : ", " ); if( is_set( obj->extra_flags, OFLAG_FLAMING ) ) sprintf( tmp+strlen( tmp ), "%sflaming", tmp[0] == '\0' ? "" : ", " ); if( is_set( obj->extra_flags, OFLAG_POISON_COATED ) ) sprintf( tmp+strlen( tmp ), "%spoison coated", tmp[0] == '\0' ? "" : ", " ); switch( obj->pIndexData->item_type ) { case ITEM_DRINK_CON : if( obj->value[1] == 0 && include_empty ) sprintf( tmp+strlen( tmp ), "%sempty", *tmp == '\0' ? "" : ", " ); break; case ITEM_FOOD : if( obj->value[1] >= 0 && obj->value[1] < 3 ) sprintf( tmp+strlen( tmp ), "%s%s", *tmp == '\0' ? "" : ", ", cook_word[ obj->value[1] ] ); break; case ITEM_CONTAINER : if( include_closed ) { if( is_set( &obj->value[1], CONT_CLOSED ) ) sprintf( tmp+strlen( tmp ), "%sclosed", *tmp == '\0' ? "" : ", " ); else if( obj->contents == NULL ) sprintf( tmp+strlen( tmp ), "%sempty", *tmp == '\0' ? "" : ", " ); } /* case ITEM_GEM : sprintf( tmp+strlen( tmp ), "%s%s", *tmp == '\0' ? "" : ", ", gem_quality[ obj->value[1] ] ); break; */ } if( obj->pIndexData->vnum == 21 ) sprintf( tmp+strlen( tmp ), "%s%s", *tmp == '\0' ? "" : ", ", color_word[ range( 0, obj->value[2]/3, 10 ) ] ); if( is_set( obj->pIndexData->extra_flags, OFLAG_RANDOM_METAL ) && metal <= MAT_ADAMANTINE ) sprintf( tmp+strlen( tmp ), "%s%s", tmp[0] == '\0' ? "" : ", ", material_name[metal] ); return; } void append_liquid( char* tmp, obj_data* obj ) { if( !include_liquid ) return; if( obj->pIndexData->item_type != ITEM_DRINK_CON || ( obj->value[1] != -1 && obj->value[1] <= 0 ) || obj->value[2] < 0 || obj->value[2] >= MAX_ENTRY_LIQUID ) return; if( is_set( obj->extra_flags, OFLAG_KNOWN_LIQUID ) ) sprintf( tmp+strlen( tmp ), " of %s", liquid_table[obj->value[2]].name ); else { sprintf( tmp+strlen( tmp ), " containing %s", liquid_table[obj->value[2]].color ); } return; } /* * LOOK_SAME? */ bool char_data :: look_same( obj_data* obj1, obj_data* obj2 ) { bool id1; bool id2; if( obj1->pIndexData->fakes != obj2->pIndexData->fakes || ( obj1->contents == NULL ) != ( obj2->contents == NULL ) || obj1->rust != obj2->rust ) return FALSE; id1 = is_set( obj1->extra_flags, OFLAG_IDENTIFIED ); id2 = is_set( obj2->extra_flags, OFLAG_IDENTIFIED ); if( id2 ) { swap( obj1, obj2 ); swap( id1, id2 ); } if( id1 ) { if( !id2 ) { if( *obj1->singular == '{' || strcasecmp( obj1->after, obj2->before ) ) return FALSE; if( ( obj1->pIndexData->item_type == ITEM_WEAPON || obj1->pIndexData->item_type == ITEM_ARMOR ) && obj1->value[0] != 0 ) return FALSE; } if( obj1->pIndexData != obj2->pIndexData ) return FALSE; if( ( obj1->pIndexData->item_type == ITEM_WEAPON || obj1->pIndexData->item_type == ITEM_ARMOR ) && obj1->value[0] != obj2->value[0] ) return FALSE; } if( obj1->pIndexData->vnum == 21 && range( 0, obj1->value[2]/3, 10 ) != range( 0, obj2->value[2]/3, 10 ) ) return FALSE; if( obj1->pIndexData->item_type == ITEM_CORPSE && strcasecmp( obj1->singular, obj2->singular ) ) return FALSE; if( is_set( obj1->extra_flags, OFLAG_IS_INVIS ) != is_set( obj2->extra_flags, OFLAG_IS_INVIS ) ) return FALSE; if( is_set( obj1->extra_flags, OFLAG_BURNING ) != is_set( obj2->extra_flags, OFLAG_BURNING ) ) return FALSE; if( IS_AFFECTED( this, AFF_DETECT_MAGIC ) && is_set( obj1->extra_flags, OFLAG_MAGIC ) != is_set( obj2->extra_flags, OFLAG_MAGIC ) ) return FALSE; if( is_set( obj1->extra_flags, OFLAG_FLAMING ) != is_set( obj2->extra_flags, OFLAG_FLAMING ) ) return FALSE; if( is_set( obj1->pIndexData->extra_flags, OFLAG_RANDOM_METAL ) && obj1->materials != obj2->materials ) return FALSE; if( obj1->pIndexData->item_type == ITEM_DRINK_CON ) { if( obj1->value[1] == 0 ) { if( obj2->value[1] != 0 ) return FALSE; } else { if( obj2->value[1] == 0 || obj2->value[2] != obj1->value[2] ) return FALSE; } } else if( obj1->pIndexData->item_type == ITEM_FOOD ) { if( obj1->value[1] != obj2->value[1] ) return FALSE; } if( strcmp( obj1->label, obj2->label ) ) return FALSE; return TRUE; } /* * OBJECT CLASS NAME ROUTINES */ const char* obj_clss_data :: Keywords( ) { return Name( ); } const char* obj_clss_data :: Name( ) { char* tmp; const char* singular; tmp = static_string( ); strcpy( tmp, is_set( extra_flags, OFLAG_THE ) ? "the " : "an " ); if( prefix_singular != empty_string ) sprintf( tmp+strlen( tmp ), "%s ", prefix_singular ); singular = seperate( this->singular, TRUE ); switch( *after ) { case '\0' : strcat( tmp, singular ); break; case '+' : sprintf( tmp+strlen( tmp ), "%s %s", singular, &after[1] ); break; default : sprintf( tmp+strlen( tmp ), "%s%s%s", after, *after == '\0' ? "" : " ", singular ); break; } if( *tmp == 't' || isvowel( tmp[3] ) ) return tmp; tmp[1] = 'a'; return &tmp[1]; } const char* obj_clss_data :: Name( int number ) { char* tmp; const char* plural; if( number == 1 ) return Name( ); tmp = static_string( ); strcpy( tmp, number_word( number ) ); if( prefix_plural != empty_string ) sprintf( tmp+strlen( tmp ), " %s ", prefix_plural ); plural = seperate( this->plural, TRUE ); switch( *after ) { case '\0' : sprintf( tmp+strlen( tmp ), " %s", plural ); break; case '+' : sprintf( tmp+strlen( tmp ), " %s %s", plural, &after[1] ); break; default : sprintf( tmp+strlen( tmp ), " %s %s", after, plural ); break; } return tmp; } char* name_before( obj_clss_data* obj ) { char* tmp; const char* singular; if( obj == NULL ) return "## Null Pointer?? ##"; tmp = static_string( ); strcpy( tmp, is_set( obj->extra_flags, OFLAG_THE ) ? "the " : "an " ); if( obj->prefix_singular != empty_string ) sprintf( tmp+strlen( tmp ), "%s ", obj->prefix_singular ); singular = seperate( obj->singular, FALSE ); switch( *obj->before ) { case '\0' : strcat( tmp, singular ); break; case '+' : sprintf( tmp+strlen( tmp ), "%s %s", singular, &obj->before[1] ); break; default : sprintf( tmp+strlen( tmp ), "%s%s%s", obj->before, *obj->before == '\0' ? "" : " ", singular ); break; } if( *tmp == 't' || isvowel( tmp[3] ) ) return tmp; tmp[1] = 'a'; return &tmp[1]; } char* name_brief( obj_clss_data* obj, int number ) { char* tmp; const char* singular; if( obj == NULL ) return "## Null Pointer?? ##"; if( number != 1 ) return (char *) obj->Name( number ); store_pntr = ( store_pntr+1 )%5; tmp = &static_storage[store_pntr*THREE_LINES]; singular = seperate( obj->singular, TRUE ); switch( *obj->after ) { case '\0' : strcpy( tmp, singular ); break; case '+' : sprintf( tmp, "%s %s", singular, &obj->after[1] ); break; default : sprintf( tmp, "%s%s%s", obj->after, *obj->after == '\0' ? "" : " ", singular ); break; } return tmp; } /* * OBJECT NAME ROUTINES */ const char* obj_data :: Name( char_data* ch, int number, bool brief ) { if( ch != NULL && is_set( extra_flags, OFLAG_IS_INVIS ) && !ch->Sees_Invis( ) ) return( number == 1 ? "something invisible" : "several invisible items" ); return Seen_Name( ch, number, brief ); } const char* obj_data :: Seen_Name( char_data* ch, int num, bool brief ) { char adj [ TWO_LINES ]; char plus [ 6 ]; char* string; char* tmp; const char* noun; bool identified = is_set( extra_flags, OFLAG_IDENTIFIED ); tmp = static_string( ); *tmp = '\0'; get_obj_adj( adj, ch, this ); if( num == 1 || brief ) { noun = seperate( singular, identified ); } else { strcpy( tmp, number_word( num, ch ) ); noun = seperate( plural, identified ); } *plus = '\0'; if( identified ) { string = after; if( ( pIndexData->item_type == ITEM_WEAPON || pIndexData->item_type == ITEM_ARMOR ) && value[0] != 0 ) sprintf( plus, " %+d", value[0] ); } else string = before; if( num == 1 || brief ) { if( !brief ) { strcpy( tmp, is_set( pIndexData->extra_flags, OFLAG_THE ) ? "the " : "an " ); if( pIndexData->prefix_singular != empty_string ) sprintf( tmp+strlen( tmp ), "%s ", pIndexData->prefix_singular ); } if( *string != '+' ) sprintf( tmp+strlen( tmp ), "%s%s%s%s%s%s", adj, adj[0] == '\0' ? "" : " ", string, ( *noun == '\0' || string[0] == '\0' ) ? "" : " ", noun, plus ); else sprintf( tmp+strlen( tmp ), "%s%s%s %s%s", adj,( *noun == '\0' || *adj == '\0' ) ? "" : " ", noun, &string[1], plus ); if( num != 1 ) sprintf( tmp+strlen( tmp ), " (x%d)", num ); } else { if( pIndexData->prefix_plural != empty_string ) sprintf( tmp+strlen( tmp ), " %s ", pIndexData->prefix_plural ); else strcat( tmp, " " ); if( *string != '+' ) sprintf( tmp+strlen( tmp ), "%s%s%s%s%s%s", adj, adj[0] == '\0' ? "" : " ", string, ( noun[0] == '\0' || string[0] == '\0' ) ? "" : " ", noun, plus ); else sprintf( tmp+strlen( tmp ), "%s%s%s %s%s", adj, ( *noun == '\0' || adj[0] == '\0' ) ? "" : " ", noun, &string[1], plus ); } append_liquid( tmp, this ); if( label != empty_string ) sprintf( tmp+strlen( tmp ), " labeled %s", label ); if( num == 1 && !brief && *tmp == 'a' && !isvowel( tmp[3] ) && ( tmp[3] != '+' || !isvowel( tmp[4] ) ) ) { tmp[1] = 'a'; return &tmp[1]; } return tmp; } const char* obj_data :: Keywords( char_data* ch ) { if( pIndexData->item_type != ITEM_WEAPON && pIndexData->item_type != ITEM_ARMOR && pIndexData->item_type != ITEM_FOOD && pIndexData->item_type != ITEM_REAGENT ) return Seen_Name( ch ); char* tmp = static_string( ); sprintf( tmp, "%s %s %s", Seen_Name( ch ), condition_name( ch ), item_type_name[ pIndexData->item_type ] ); return tmp; } const char* obj_data :: Show( char_data* ch, int num ) { char* tmp = static_string( ); sprintf( tmp, "%s %s", Seen_Name( ch, num ), num == 1 ? ( *pIndexData->long_s == '\0' ? "lies here." : pIndexData->long_s ) : ( *pIndexData->long_p == '\0' ? "lie here." : pIndexData->long_p ) ); return tmp; } /* * LABEL ROUTINE */ bool valid_label( char_data* ch, const char* label ) { int i; for( i = 0; label[i] != '\0'; i++ ) if( !isalpha( label[i] ) && label[i] != ' ' ) { send( ch, "Labels may only contain letters and spaces.\r\n" ); return FALSE; } if( i >= 15 ) { send( ch, "Labels must be less than 15 characters.\r\n" ); return FALSE; } return TRUE; } void do_label( char_data* ch, char* argument ) { char arg [ MAX_INPUT_LENGTH ]; obj_data* obj; char* label; bool remove; remove = !contains_word( argument, "as", arg ); if( *argument == '\0' || ( !remove && *arg == '\0' ) ) { send( ch, "Label what item and as what?\r\n" ); return; } if( ( obj = one_object( ch, remove ? argument : arg, "label", &ch->contents ) ) == NULL ) return; if( remove ) { if( obj->label == empty_string ) { send( ch, "%s isn't labeled.\r\n", obj ); return; } free_string( obj->label, MEM_OBJECT ); obj->label = empty_string; send( ch, "You remove the label from %s.\r\n", obj ); return; } if( obj->pIndexData->item_type != ITEM_CONTAINER ) { send( ch, "You may only label containers.\r\n" ); return; } if( ( label = obj->label ) != empty_string ) { obj->label = empty_string; send( ch, "%s is already labeled as '%s'.\r\n", obj, label ); obj->label = label; return; } if( !valid_label( ch, argument ) ) return; if( obj->number > 1 ) { obj->number--; obj = duplicate( obj ); } if( obj->label == empty_string ) { send( ch, "You label %s '%s'.\r\n", obj, argument ); } else { free_string( obj->label, MEM_OBJECT ); obj->label = empty_string; fsend( ch, "You remove the old label from %s and replace it with '%s'.\r\n", obj, argument ); } obj->label = alloc_string( argument, MEM_OBJECT ); if( obj->array == NULL ) obj->To( ch ); consolidate( obj ); }