/*************************************************************************** * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. * * * * Merc Diku Mud improvements copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * * * Envy Diku Mud improvements copyright (C) 1994 by Michael Quan, David * * Love, Guilherme 'Willie' Arnold, and Mitchell Tse. * * * * In order to use any part of this Envy Diku Mud, you must comply with * * the original Diku license in 'license.doc', the Merc license in * * 'license.txt', as well as the Envy license in 'license.nvy'. * * 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. * ***************************************************************************/ /* $Id: language.c,v 1.15 2004/11/04 14:48:10 ahsile Exp $ */ #if defined( macintosh ) #include <types.h> #else #include <sys/types.h> #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "merc.h" /* * Lookup a language by name. */ int lang_lookup( const char *name ) { int ln; for ( ln = 0; ln < MAX_LANGUAGE; ln++ ) { if ( !lang_table[ln].name ) break; if ( LOWER( name[0] ) == LOWER( lang_table[ln].name[0] ) && !str_prefix( name, lang_table[ln].name ) ) return ln; } return -1; } void do_speak( CHAR_DATA *ch, char *argument ) { char arg [ MAX_INPUT_LENGTH ]; char buf [ MAX_STRING_LENGTH]; int speaking; int canspeak; argument = one_argument(argument, arg); buf[0] = '\0'; if( ch->position == POS_GHOST ) { send_to_char( AT_LBLUE, "You can not speak anything but spiritspeak while dead.\n\r", ch ); ch->speaking = SPIRITSPEAK; return; } if (arg[0] == '\0') { sprintf (buf, "You currently speak %s.\n\r", lang_table[ch->speaking].name); send_to_char (AT_LBLUE, buf, ch); } else { if ((speaking = lang_lookup(arg)) != -1) { if ((canspeak = ch->language[speaking]) == 0 && !IS_NPC( ch ) && ch->position != POS_DEAD && !IS_IMMORTAL( ch ) ) { sprintf (buf, "But you don't know how to speak %s.\n\r", lang_table[speaking].name); send_to_char(AT_LBLUE, buf, ch); } else { ch->speaking = speaking; sprintf (buf, "You will speak %s from now on.\n\r", lang_table[ch->speaking].name); send_to_char(AT_LBLUE, buf, ch); } } else { sprintf (buf, "%s is not a valid language!\n\r", arg); send_to_char(AT_LBLUE, buf, ch); } } } void do_lset( CHAR_DATA *ch, char *argument ) { CHAR_DATA *rch; CHAR_DATA *victim; char arg1 [ MAX_INPUT_LENGTH ]; char arg2 [ MAX_INPUT_LENGTH ]; char arg3 [ MAX_INPUT_LENGTH ]; int value; int ln; bool fAll; rch = get_char( ch ); if ( !authorized( rch, "lset" ) ) return; argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); one_argument( argument, arg3 ); if ( arg1[0] == '\0' || arg2[0] == '\0' || arg3[0] == '\0' ) { send_to_char(AT_WHITE, "Syntax: lset <victim> <lang> <value>\n\r", ch ); send_to_char(AT_WHITE, "or: lset <victim> all <value>\n\r", ch ); send_to_char(AT_WHITE, "or: lset <victim> learn <value>\n\r", ch ); send_to_char(AT_WHITE, "Lang being any language.\n\r", ch ); return; } if ( !( victim = get_char_world( ch, arg1 ) ) ) { send_to_char(AT_WHITE, "They aren't here.\n\r", ch ); return; } if ( IS_NPC( victim ) ) { send_to_char(AT_WHITE, "Not on NPC's.\n\r", ch ); return; } if (!str_prefix(arg2, "learn") ) { if (!is_number(arg3)) { send_to_char (AT_WHITE, "Value must be numeric.\n\r", ch); return; } value = atoi(arg3); if (value < 0) value = 0; if (value > 100) value = 100; victim->pcdata->learn = value; send_to_char(AT_WHITE, "Ok.\n\r", ch); return; } fAll = !str_cmp( arg2, "all" ); ln = 0; if ( !fAll && ( ln = lang_lookup( arg2 ) ) < 0 ) { send_to_char(AT_WHITE, "No such language.\n\r", ch ); return; } /* * Snarf the value. */ if ( !is_number( arg3 ) ) { send_to_char(AT_WHITE, "Value must be numeric.\n\r", ch ); return; } value = atoi( arg3 ); if ( value < 0 || value > 100 ) { send_to_char(AT_WHITE, "Value range is 0 to 100.\n\r", ch ); return; } if ( fAll ) { if ( get_trust( ch ) < L_SEN ) { send_to_char(AT_WHITE, "Only Seniors may lset all.\n\r", ch ); return; } for ( ln = 0; ln < MAX_LANGUAGE; ln++ ) if ( lang_table[ln].name ) victim->language[ln] = value; } else { victim->language[ln] = value; } return; } void do_lstat( CHAR_DATA *ch, char *argument ) /* lstat by Maniac && Canth */ { CHAR_DATA *victim; char arg[MAX_INPUT_LENGTH]; char buf1[MAX_STRING_LENGTH]; char buf2[MAX_STRING_LENGTH]; int ln; int col; one_argument( argument, arg ); col = 0; if ( arg[0] == '\0' ) { send_to_char(AT_WHITE, "Lstat whom\n\r?", ch); return; } if ( ( victim = get_char_world( ch, arg ) ) == NULL ) { send_to_char(AT_WHITE, "That person isn't logged on.\n\r", ch); return; } if ( IS_NPC( victim ) ) { send_to_char(AT_WHITE, "Not on NPC's.\n\r", ch); return; } buf2[0] = '\0'; for ( ln = 0; ln < MAX_LANGUAGE ; ln++ ) { if ( lang_table[ln].name == NULL ) break; sprintf( buf1, "%18s %3d %% ", lang_table[ln].name, victim->language[ln] ); strcat( buf2, buf1 ); if ( ++col %3 == 0 ) strcat( buf2, "\n\r" ); } if ( col % 3 != 0 ) strcat( buf2, "\n\r" ); sprintf( buf1, "%s has %d learning sessions left.\n\r", victim->name, victim->pcdata->learn ); strcat( buf2, buf1 ); send_to_char(AT_WHITE, buf2, ch ); return; } void do_learn( CHAR_DATA *ch, char *argument ) { char buf [ MAX_STRING_LENGTH ]; char buf1 [ MAX_STRING_LENGTH*2 ]; int ln; int money; if( ch->level > 5 ) { money = ch->level * 20; } else { money = ch->level * 5; } if ( IS_NPC( ch ) ) return; buf1[0] = '\0'; if ( argument[0] == '\0' ) { CHAR_DATA *mob; int col; for ( mob = ch->in_room->people; mob; mob = mob->next_in_room ) { if ( mob->deleted ) continue; if ( IS_NPC( mob ) && IS_SET( mob->act, ACT_TEACHER ) ) break; } col = 0; for ( ln = 0; ln < MAX_LANGUAGE; ln++ ) { if ( !lang_table[ln].name ) break; if ( ( mob ) || ( ch->language[ln] > 0 ) ) { sprintf( buf, "%18s %3d%% ", lang_table[ln].name, ch->language[ln] ); strcat( buf1, buf ); if ( ++col % 3 == 0 ) strcat( buf1, "\n\r" ); } } if ( col % 3 != 0 ) strcat( buf1, "\n\r" ); sprintf( buf, "You have %d learning sessions left.\n\r", ch->pcdata->learn); strcat( buf1, buf ); sprintf( buf, "Cost of lessons is %d gold coins.\n\r", money ); strcat( buf1, buf ); send_to_char(AT_WHITE, buf1, ch ); } else { CHAR_DATA *mob; int adept; if ( !IS_AWAKE( ch ) ) { send_to_char(AT_WHITE, "In your dreams, or what?\n\r", ch ); return; } for ( mob = ch->in_room->people; mob; mob = mob->next_in_room ) { if ( mob->deleted ) continue; if ( IS_NPC( mob ) && IS_SET( mob->act, ACT_TEACHER ) ) break; } if ( !mob ) { send_to_char(AT_WHITE, "You can't do that here.\n\r", ch ); return; } if ( ch->pcdata->learn <= 0 ) { send_to_char(AT_WHITE, "You have no lessons left.\n\r", ch ); return; } else if ( money > ch->gold ) { send_to_char(AT_WHITE, "You don't have enough money to take lessons.\n\r", ch ); return; } if (( ln = lang_lookup( argument ) ) < 0) { send_to_char(AT_WHITE, "That's not a language.\n\r", ch ); return; } adept = (int) (get_curr_int(ch) * 0.5); /* Max learned = int/2 */ if ( ch->level < LEVEL_HERO ) /* Max is 95% */ { adept = 95; } if ( ch->level >= LEVEL_HERO ) /* Max is 100% for champion + */ adept = 100; if ( ch->language[ln] >= adept ) { sprintf( buf, "You are already fluent in %s.\n\r", lang_table[ln].name ); ch->language[ln] = adept; send_to_char(AT_WHITE, buf, ch ); } else { ch->pcdata->learn--; ch->gold -= money; ch->language[ln] += int_app[get_curr_int( ch )].learn; if ( ch->language[ln] < adept ) { act(AT_WHITE, "You take lessons in $T.", ch, NULL, lang_table[ln].name, TO_CHAR ); act(AT_WHITE, "$n practices $T.", ch, NULL, lang_table[ln].name, TO_ROOM ); } else { ch->language[ln] = adept; act(AT_WHITE, "You are now fluent in $T.", ch, NULL, lang_table[ln].name, TO_CHAR ); act(AT_WHITE, "$n is now fluent in $T.", ch, NULL, lang_table[ln].name, TO_ROOM ); } } } return; } void do_common( CHAR_DATA *ch, char *argument) { do_language(ch, argument, COMMON); } void do_feline( CHAR_DATA *ch, char *argument) { do_language(ch, argument, FELINE); } void do_canine( CHAR_DATA *ch, char *argument) { do_language(ch, argument, CANINE); } void do_human( CHAR_DATA *ch, char *argument) { do_language(ch,argument, HUMAN); } void do_dwarvish( CHAR_DATA *ch, char *argument) { do_language(ch,argument, DWARVISH); } void do_elvish( CHAR_DATA *ch, char *argument) { do_language(ch,argument, ELVISH); } void do_gnomish( CHAR_DATA *ch, char *argument) { do_language(ch,argument, GNOMISH); } void do_dragon( CHAR_DATA *ch, char *argument) { do_language(ch,argument, DRAGON); } void do_demon( CHAR_DATA *ch, char *argument) { do_language(ch,argument, DEMON); } void do_angel( CHAR_DATA *ch, char *argument) { do_language(ch,argument, ANGEL); } void do_shadow_speak( CHAR_DATA *ch, char *argument) { do_language(ch,argument, SHADOW_SPEAK); } void do_magick( CHAR_DATA *ch, char *argument) { do_language(ch,argument, MAGICK); } void do_spiritspeak( CHAR_DATA *ch, char *argument ) { do_language(ch,argument, SPIRITSPEAK ); } void do_satanic( CHAR_DATA *ch, char *argument ) { do_language(ch,argument, SATANIC ); } void do_enlightened( CHAR_DATA *ch, char *argument ) { do_language(ch,argument, ENLIGHTENED ); } void do_animalspeak( CHAR_DATA *ch, char *argument ) { do_language(ch,argument, ANIMALSPEAK ); } void do_bretonnian( CHAR_DATA *ch, char *argument ) { do_language(ch,argument, BRETONNIAN ); } void do_orcish( CHAR_DATA *ch, char *argument) { do_language(ch,argument, ORCISH); } void do_ogre( CHAR_DATA *ch, char *argument) { do_language(ch,argument, OGRE); } void do_drow( CHAR_DATA *ch, char *argument) { do_language(ch,argument, DROW); } void do_elder( CHAR_DATA *ch, char *argument) { do_language(ch,argument, ELDER); } void do_pixie( CHAR_DATA *ch, char *argument) { do_language(ch,argument, PIXIE); } void do_hobbit( CHAR_DATA *ch, char *argument) { do_language(ch,argument, HOBBIT); } void do_minotaur( CHAR_DATA *ch, char *argument) { do_language(ch,argument, MINOTAUR); } void do_lizard( CHAR_DATA *ch, char *argument) { do_language(ch,argument, LIZARD); } void do_halfling( CHAR_DATA *ch, char *argument) { do_language(ch,argument, HALFLING); } void do_gargoyle( CHAR_DATA *ch, char *argument) { do_language(ch,argument, GARGISH); } /* ========== Language ======================== */ void do_language( CHAR_DATA *ch, char *argument, int language) { CHAR_DATA *och; int chance = 0; int chance2 = 0; int receiver_chance; int speaker_chance; char *lan_str; char charname [ MAX_STRING_LENGTH]; char buf [ MAX_STRING_LENGTH ]; char buf2 [ MAX_STRING_LENGTH ]; char buf3 [ MAX_STRING_LENGTH ]; char buf4 [ MAX_STRING_LENGTH ]; char buf5 [ MAX_STRING_LENGTH ]; char buf6 [ MAX_STRING_LENGTH ]; char buf7 [ MAX_STRING_LENGTH ]; int bufcolour = AT_DGREY; if( IS_NPC( ch ) ) { ch->language[language] = 100; } chance = ch->language[language]; speaker_chance = number_percent(); if( ch->position == POS_GHOST ) { language = SPIRITSPEAK; speaker_chance = 100; chance = 100; ch->speaking = SPIRITSPEAK; bufcolour = AT_LBLUE; } lan_str = lang_table[language].name; buf[0] = '\0'; if( chance == 0 && !IS_NPC( ch ) && ch->position != POS_GHOST ) { sprintf(buf, "You don't know how to speak %s.\n\r", lan_str); send_to_char(C_DEFAULT, buf ,ch); return; } if( ch->speaking == COMMON && !IS_IMMORTAL( ch ) && !IS_NPC( ch ) ) { sprintf(buf, "Mortals can not speak %s.\n\r", lan_str ); send_to_char(C_DEFAULT, buf, ch ); return; } if(argument[0] == '\0') { buf[0] = '\0'; sprintf(buf, "Say WHAT in %s ??\n\r", lan_str); send_to_char(C_DEFAULT, buf ,ch); return; } if (!IS_NPC(ch)) argument = makedrunk(argument,ch); sprintf( buf, "In %s, You say &W'%s'\n\r", lan_str, argument ); sprintf( buf3, "In %s you try to say &W'%s'", lan_str, argument ); sprintf( buf7, ", but it doesn't sound correct.\n\r" ); for(och = ch->in_room->people; och != NULL; och = och->next_in_room ) { if( och == ch ) continue; sprintf( charname, ch->name ); if( ( !can_see( och, ch ) ) && och != ch ) { sprintf( charname, "Someone" ); } if( IS_NPC( ch ) ) { sprintf( charname, ch->short_descr ); } if( IS_NPC( och ) ) { och->language[language] = 100; } chance2 = och->language[language]; receiver_chance = number_percent( ); if(ch->position != POS_GHOST ) { sprintf( buf2, "In %s, %s says &W'%s'\n\r", lan_str, charname, argument ); sprintf( buf4, "In a wierd form of %s, %s says something incomprehensible.\n\r", lan_str, charname ); sprintf( buf5, "In %s, %s says something you can't understand.\n\r", lan_str, charname ); sprintf( buf6, "%s says something in a strange tongue.\n\r", charname ); } else { sprintf( buf2, "In %s, The Ghost of %s says &W'%s'\n\r", lan_str, charname, argument ); sprintf( buf4, "In a wierd form of %s, The Ghost of %s says something incomprehensible.\n\r", lan_str, charname ); sprintf( buf5, "In %s, The Ghost of %s says something you can't understand.\n\r", lan_str, charname ); sprintf( buf6, "The Ghost of %s says something in a strange tongue.\n\r", charname ); } if( speaker_chance <= chance ) { if( chance2 == 0 ) { send_to_char( bufcolour, buf6, och ); if( IS_AFFECTED4( och, AFF_TONGUES ) ) { send_to_char( bufcolour, "Your tongues spell translates the speech, and you understand the following:\n\r", och ); send_to_char( bufcolour, buf2, och ); } } else { if( receiver_chance <= chance2 ) { send_to_char( bufcolour, buf2, och ); } else { send_to_char( bufcolour, buf5, och ); if( IS_AFFECTED4( och, AFF_TONGUES ) ) { send_to_char( bufcolour, "Your tongues spell translates the speech, and you understand the following:\n\r", och ); send_to_char( bufcolour, buf2, och ); } } } } else { if( chance2 == 0) { send_to_char( bufcolour, buf6, och ); if( IS_AFFECTED4( och, AFF_TONGUES ) ) { send_to_char( bufcolour, "Your tongues spell translates the speech, and you understand the following:\n\r", och ); send_to_char( bufcolour, buf2, och ); } } else { if( receiver_chance <= chance2 ) { send_to_char(bufcolour, buf4, och ); if( IS_AFFECTED4( och, AFF_TONGUES ) ) { send_to_char( bufcolour, "Your tongues spell translates the speech, and you understand the following:\n\r", och ); send_to_char( bufcolour, buf2, och ); } } else { send_to_char(bufcolour, buf5, och ); if( IS_AFFECTED4( och, AFF_TONGUES ) ) { send_to_char( bufcolour, "Your tongues spell translates the speech, and you understand the following:\n\r", och ); send_to_char( bufcolour, buf2, och ); } } } } } if( speaker_chance <= chance ) { send_to_char( bufcolour, buf, ch ); } else { send_to_char( bufcolour, buf3, ch ); send_to_char( bufcolour, buf7, ch ); } return; }