diff -ur old/act_comm.c new/act_comm.c --- old/act_comm.c Mon Sep 14 17:46:16 1998 +++ new/act_comm.c Mon Sep 14 17:46:53 1998 @@ -753,6 +753,18 @@ act( "$n says '$T'", ch, NULL, argument, TO_ROOM ); act( "You say '$T'", ch, NULL, argument, TO_CHAR ); + + if ( !IS_NPC(ch) ) + { + CHAR_DATA *mob, *mob_next; + for ( mob = ch->in_room->people; mob != NULL; mob = mob_next ) + { + mob_next = mob->next_in_room; + if ( IS_NPC(mob) && HAS_TRIGGER( mob, TRIG_SPEECH ) + && mob->position == mob->pIndexData->default_pos ) + mp_act_trigger( argument, mob, ch, NULL, NULL, TRIG_SPEECH ); + } + } return; } @@ -893,6 +905,9 @@ act_new("$n tells you '$t'",ch,argument,victim,TO_VICT,POS_DEAD); victim->reply = ch; + if ( !IS_NPC(ch) && IS_NPC(victim) && HAS_TRIGGER(victim,TRIG_SPEECH) ) + mp_act_trigger( argument, victim, ch, NULL, NULL, TRIG_SPEECH ); + return; } @@ -1018,8 +1033,10 @@ return; } + MOBtrigger = FALSE; act( "$n $T", ch, NULL, argument, TO_ROOM ); act( "$n $T", ch, NULL, argument, TO_CHAR ); + MOBtrigger = TRUE; return; } @@ -1052,7 +1069,9 @@ if ( ( letter = strstr( argument, vch->name ) ) == NULL ) { + MOBtrigger = FALSE; act( "$N $t", vch, argument, ch, TO_CHAR ); + MOBtrigger = TRUE; continue; } @@ -1102,7 +1121,9 @@ name = vch->name; } + MOBtrigger = FALSE; act( "$N $t", vch, temp, ch, TO_CHAR ); + MOBtrigger = TRUE; } return; @@ -1619,7 +1640,7 @@ argument = one_argument( argument, arg ); one_argument( argument, arg2 ); - if ( !str_cmp( arg2, "afk" ) ) + if ( !str_cmp(arg2,"delete") || !str_cmp(arg2,"mob") ) { ch_printf( ch, "That is a stupid thing to do.\r\n" ); return; diff -ur old/act_move.c new/act_move.c --- old/act_move.c Mon Sep 14 17:46:16 1998 +++ new/act_move.c Mon Sep 14 17:46:53 1998 @@ -2026,6 +2026,16 @@ } extract_obj( portal ); } + + /* + * If someone is following the char, these triggers get activated + * for the followers before the char, but it's safer this way... + */ + if ( IS_NPC( ch ) && HAS_TRIGGER( ch, TRIG_ENTRY ) ) + mp_percent_trigger( ch, NULL, NULL, NULL, TRIG_ENTRY ); + if ( !IS_NPC( ch ) ) + mp_greet_trigger( ch ); + return; } diff -ur old/act_info.c new/act_info.c --- old/act_info.c Mon Sep 14 17:46:16 1998 +++ new/act_info.c Mon Sep 14 17:46:53 1998 @@ -1027,7 +1027,8 @@ */ ch_printf( ch, "%s", ch->in_room->name ); - if ( IS_IMMORTAL( ch ) && ( IS_NPC( ch ) || IS_SET( ch->act, PLR_HOLYLIGHT ) ) ) + if ( (IS_IMMORTAL(ch) && (IS_NPC(ch) || IS_SET(ch->act,PLR_HOLYLIGHT))) + || IS_BUILDER(ch, ch->in_room->area) ) { ch_printf( ch, " [Room %d]", ch->in_room->vnum ); } diff -ur old/act_move.c new/act_move.c --- old/act_move.c Mon Sep 14 17:46:16 1998 +++ new/act_move.c Mon Sep 14 17:46:53 1998 @@ -76,6 +76,12 @@ return; } + /* + * Exit trigger, if activated, bail out. Only PCs are triggered. + */ + if ( !IS_NPC(ch) && mp_exit_trigger( ch, door ) ) + return; + in_room = ch->in_room; if ( ( pexit = in_room->exit[door] ) == NULL || ( to_room = pexit->u1.to_room ) == NULL @@ -230,6 +236,15 @@ move_char( fch, door, TRUE ); } } + + /* + * If someone is following the char, these triggers get activated + * for the followers before the char, but it's safer this way... + */ + if ( IS_NPC( ch ) && HAS_TRIGGER( ch, TRIG_ENTRY ) ) + mp_percent_trigger( ch, NULL, NULL, NULL, TRIG_ENTRY ); + if ( !IS_NPC( ch ) ) + mp_greet_trigger( ch ); return; } diff -ur old/act_obj.c new/act_obj.c --- old/act_obj.c Mon Sep 14 17:46:16 1998 +++ new/act_obj.c Mon Sep 14 17:46:53 1998 @@ -720,6 +720,12 @@ act_printf( "You give $N %d %s.", ch, NULL, victim, TO_CHAR, POS_RESTING, false, amount, silver ? "silver" : "gold" ); + /* + * Bribe trigger + */ + if ( IS_NPC(victim) && HAS_TRIGGER( victim, TRIG_BRIBE ) ) + mp_bribe_trigger( victim, ch, silver ? amount : amount * 100 ); + if ( IS_NPC( victim ) && IS_SET( victim->act, ACT_IS_CHANGER ) ) { int change = 0; @@ -815,9 +821,18 @@ obj_from_char( obj ); obj_to_char( obj, victim ); + MOBtrigger = FALSE; act( "$n gives $p to $N.", ch, obj, victim, TO_NOTVICT ); act( "$n gives you $p.", ch, obj, victim, TO_VICT ); act( "You give $p to $N.", ch, obj, victim, TO_CHAR ); + MOBtrigger = TRUE; + + /* + * Give trigger + */ + if ( IS_NPC(victim) && HAS_TRIGGER( victim, TRIG_GIVE ) ) + mp_give_trigger( victim, ch, obj ); + return; } diff -ur old/act_wiz.c new/act_wiz.c --- old/act_wiz.c Mon Sep 14 17:46:16 1998 +++ new/act_wiz.c Mon Sep 14 17:46:53 1998 @@ -1692,6 +1692,11 @@ victim->leader ? victim->leader->name : "(none)", victim->pet ? victim->pet->name : "(none)" ); + if (!IS_NPC(victim)) + { + ch_printf( ch, "Security: %d.\n\r", victim->pcdata->security ); /* OLC */ + } + ch_printf( ch, "Short description: %s\r\nLong description: %s", victim->short_descr, victim->long_descr[0] != '\0' ? victim->long_descr : "(none)\r\n" ); @@ -3343,6 +3349,7 @@ ch_printf( ch, " str int wis dex con sex class level\r\n" ); ch_printf( ch, " race group gold silver hp mana move prac\r\n" ); ch_printf( ch, " align train thirst hunger drunk full\r\n" ); + ch_printf( ch, " security\n\r" ); return; } @@ -3378,6 +3385,37 @@ return; } + if ( !str_cmp( arg2, "security" ) ) /* OLC */ + { + if ( IS_NPC(ch) ) + { + ch_printf( ch, "Yeah, sure.\n\r" ); + return; + } + + if ( IS_NPC( victim ) ) + { + ch_printf( ch, "Not on NPC's.\n\r" ); + return; + } + + if ( value > ch->pcdata->security || value < 0 ) + { + if ( ch->pcdata->security != 0 ) + { + ch_printf( ch, "Valid security is 0-%d.\n\r", + ch->pcdata->security ); + } + else + { + ch_printf( ch, "Valid security is 0 only.\n\r" ); + } + return; + } + victim->pcdata->security = value; + return; + } + if ( !str_cmp( arg2, "int" ) ) { if ( value < 3 || value > get_max_train(victim,STAT_INT) ) @@ -4103,7 +4142,7 @@ one_argument( argument, arg2 ); - if ( !str_cmp( arg2, "delete" ) ) + if ( !str_cmp(arg2,"delete") || !str_prefix(arg2,"mob") ) { ch_printf( ch, "That will NOT be done.\r\n" ); return; Only in new: bit.c diff -ur old/comm.c new/comm.c --- old/comm.c Mon Sep 14 17:46:16 1998 +++ new/comm.c Mon Sep 14 17:46:53 1998 @@ -305,6 +307,7 @@ bool newlock = false; /* Game is newlocked */ char str_boot_time[MAX_INPUT_LENGTH] = "\0\0\0\0\0\0\0"; time_t current_time = 0; /* time of this pulse */ +bool MOBtrigger = TRUE; /* act() switch */ DESCRIPTOR_DATA *new_descriptor( void ) { @@ -433,12 +438,21 @@ d->fcommand = TRUE; stop_idling( d->character ); - if ( d->showstr_point ) - show_string( d, d->incomm ); - else if ( d->connected == CON_PLAYING ) - substitute_alias( d, d->incomm ); - else - nanny( d, d->incomm ); + /* OLC */ + if ( d->showstr_point ) + show_string( d, d->incomm ); + else if ( d->pString ) + string_add( d->character, d->incomm ); + else + { + if( d->connected == CON_PLAYING ) + { + if ( !run_olc_editor( d ) ) + substitute_alias( d, d->incomm ); + } + else + nanny( d, d->incomm ); + } d->incomm[0] = '\0'; } @@ -892,6 +921,9 @@ dnew->showstr_head = NULL; dnew->showstr_point = NULL; dnew->outsize = 2000; + dnew->pEdit = NULL; /* OLC */ + dnew->pString = NULL; /* OLC */ + dnew->editor = 0; /* OLC */ dnew->outbuf = ( char * ) alloc_mem( dnew->outsize ); size = sizeof( sock_in ); @@ -1221,11 +1253,13 @@ /* * Bust a prompt. */ - if ( !merc_down && d->showstr_point ) - desc_printf( d, "[Hit Return to continue]\r\n" ); - else if ( fPrompt && !merc_down && d->connected == CON_PLAYING ) - { - CHAR_DATA *ch = NULL; + if ( !merc_down && d->showstr_point ) + write_to_buffer( d, "[Hit Return to continue]\n\r", 0 ); + else if ( fPrompt && !merc_down && d->pString && d->connected == CON_PLAYING ) + write_to_buffer( d, "> ", 2 ); + else if ( fPrompt && !merc_down && d->connected == CON_PLAYING ) + { + CHAR_DATA *ch; CHAR_DATA *victim = NULL; ch = d->character; @@ -1550,6 +1585,7 @@ ch->exp = exp_per_level( ch, ch->pcdata->points ) * UMAX( 1, ch->level ); ch->trust = ch->level; + ch->pcdata->security = 9; save_char_obj( ch ); log_auth( ch, "%s@%s is now an IMPLEMENTOR!", NAME( ch ), d->host ); need_god = false; @@ -1940,6 +1975,14 @@ sprintf( buf2, "%%" ); i = buf2; break; + case 'o' : + sprintf( buf2, "%s", olc_ed_name(ch) ); + i = buf2; + break; + case 'O' : + sprintf( buf2, "%s", olc_ed_vnum(ch) ); + i = buf2; + break; } ++str; while ( ( *point = *i ) != '\0' ) @@ -2272,9 +2313,11 @@ for ( ; to != NULL; to = to->next_in_room ) { /* - * If anyone can't here us, skip them + * If anyone can't hear us, skip them */ - if ( to->desc == NULL || to->position < min_pos ) + if ( (!IS_NPC(to) && to->desc == NULL ) + || ( IS_NPC(to) && !HAS_TRIGGER(to, TRIG_ACT) ) + || to->position < min_pos ) continue; if ( !IS_AWAKE( to ) ) continue; @@ -2551,7 +2594,10 @@ *( ++point ) = '\0'; buf[0] = UPPER( buf[0] ); + if ( to->desc != NULL ) write_to_buffer( to->desc, buf, point - buf ); + else if ( MOBtrigger ) + mp_act_trigger( buf, to, ch, arg1, arg2, TRIG_ACT ); if ( ( type == TO_VICT ) || ( type == TO_CHAR ) ) return; diff -ur old/db.c new/db.c --- old/db.c Mon Sep 14 17:46:16 1998 +++ new/db.c Mon Sep 14 19:20:47 1998 @@ -42,18 +42,24 @@ #include "interp.h" #include "magic.h" #include "special.h" +#include "olc.h" /* * Globals. */ HELP_DATA *help_first = NULL; HELP_DATA *help_last = NULL; +HELP_AREA *had_list = NULL; + SHOP_DATA *shop_first = NULL; SHOP_DATA *shop_last = NULL; +MPROG_CODE *mprog_list = NULL; + AREA_DATA *area_first = NULL; AREA_DATA *area_last = NULL; +AREA_DATA *current_area = NULL; char bug_buf[2 * MAX_INPUT_LENGTH] = "\0\0\0\0\0\0\0"; char log_buf[2 * MAX_INPUT_LENGTH] = "\0\0\0\0\0\0\0"; @@ -169,6 +175,10 @@ int top_reset = 0; int top_room = 0; int top_shop = 0; +int top_vnum_room = 0; /* OLC */ +int top_vnum_mob = 0; /* OLC */ +int top_vnum_obj = 0; /* OLC */ +int top_mprog_index = 0; /* OLC */ int mobile_count = 0; int newmobs = 0; int newobjs = 0; @@ -548,7 +565,9 @@ { log_boot( "Fixing exits" ); fix_exits( ); + fix_mobprogs( ); fBootDb = false; + convert_objects( ); /* ROM OLC */ area_update( ); load_notes( ); load_bans( ); @@ -612,6 +625,8 @@ */ void load_rom_area_file( FILE * fp ) { + current_area = NULL; + for ( ;; ) { char *word = NULL; @@ -626,11 +641,15 @@ else if ( !str_cmp( word, "AREA" ) ) load_area( fp ); else if ( !str_cmp( word, "HELPS" ) ) - load_helps( fp ); + load_helps(fp, strArea); + else if ( !str_cmp( word, "AREADATA" ) ) + new_load_area( fp ); else if ( !str_cmp( word, "MOBOLD" ) ) load_old_mob( fp ); else if ( !str_cmp( word, "MOBILES" ) ) load_mobiles( fp ); + else if ( !str_cmp( word, "MOBPROGS" ) ) + load_mobprogs( fp ); else if ( !str_cmp( word, "OBJOLD" ) ) load_old_obj( fp ); else if ( !str_cmp( word, "OBJECTS" ) ) @@ -658,9 +677,13 @@ AREA_DATA *pArea = NULL; pArea = ( AREA_DATA * ) alloc_perm( sizeof( *pArea ) ); - pArea->reset_first = NULL; - pArea->reset_last = NULL; pArea->file_name = fread_string( fp ); + + pArea->area_flags = AREA_LOADING; /* OLC */ + pArea->security = 9; /* OLC */ /* 9 -- Hugin */ + pArea->builders = str_dup( "None" ); /* OLC */ + pArea->vnum = top_area; /* OLC */ + pArea->name = fread_string( fp ); pArea->credits = fread_string( fp ); pArea->min_vnum = fread_number( fp ); @@ -669,31 +692,187 @@ pArea->nplayer = 0; pArea->empty = false; - if ( area_first == NULL ) + if ( !area_first ) area_first = pArea; - if ( area_last != NULL ) + if ( area_last ) + { area_last->next = pArea; - area_last = pArea; - pArea->next = NULL; + REMOVE_BIT(area_last->area_flags, AREA_LOADING); /* OLC */ + } + area_last = pArea; + pArea->next = NULL; + current_area = pArea; top_area++; return; } +/* + * OLC + * Use these macros to load any new area formats that you choose to + * support on your MUD. See the new_load_area format below for + * a short example. + */ +#if defined(KEY) +#undef KEY +#endif + +#define KEY( literal, field, value ) \ + if ( !str_cmp( word, literal ) ) \ + { \ + field = value; \ + fMatch = TRUE; \ + break; \ + } + +#define SKEY( string, field ) \ + if ( !str_cmp( word, string ) ) \ + { \ + free_string( field ); \ + field = fread_string( fp ); \ + fMatch = TRUE; \ + break; \ + } + + + +/* OLC + * Snarf an 'area' header line. Check this format. MUCH better. Add fields + * too. + * + * #AREAFILE + * Name { All } Locke Newbie School~ + * Repop A teacher pops in the room and says, 'Repop coming!'~ + * Recall 3001 + * End + */ +void new_load_area( FILE *fp ) +{ + AREA_DATA *pArea; + const char *word; + bool fMatch; + + pArea = (AREA_DATA * ) alloc_perm( sizeof(*pArea) ); + pArea->age = 15; + pArea->nplayer = 0; + pArea->file_name = str_dup( strArea ); + pArea->vnum = top_area; + pArea->name = str_dup( "New Area" ); + pArea->builders = str_dup( "" ); + pArea->security = 9; /* 9 -- Hugin */ + pArea->min_vnum = 0; + pArea->max_vnum = 0; + pArea->area_flags = 0; +/* pArea->recall = ROOM_VNUM_TEMPLE; ROM OLC */ + + for ( ; ; ) + { + word = feof( fp ) ? "End" : fread_word( fp ); + fMatch = FALSE; + + switch ( UPPER(word[0]) ) + { + case 'N': + SKEY( "Name", pArea->name ); + break; + case 'S': + KEY( "Security", pArea->security, fread_number( fp ) ); + break; + case 'V': + if ( !str_cmp( word, "VNUMs" ) ) + { + pArea->min_vnum = fread_number( fp ); + pArea->max_vnum = fread_number( fp ); + } + break; + case 'E': + if ( !str_cmp( word, "End" ) ) + { + fMatch = TRUE; + if ( area_first == NULL ) + area_first = pArea; + if ( area_last != NULL ) + area_last->next = pArea; + area_last = pArea; + pArea->next = NULL; + current_area = pArea; + top_area++; + + return; + } + break; + case 'B': + SKEY( "Builders", pArea->builders ); + break; + case 'C': + SKEY( "Credits", pArea->credits ); + break; + } + } +} + +/* + * Sets vnum range for area using OLC protection features. + */ +void assign_area_vnum( int vnum ) +{ + if ( area_last->min_vnum == 0 || area_last->max_vnum == 0 ) + area_last->min_vnum = area_last->max_vnum = vnum; + if ( vnum != URANGE( area_last->min_vnum, vnum, area_last->max_vnum ) ) + { + if ( vnum < area_last->min_vnum ) + area_last->min_vnum = vnum; + else + area_last->max_vnum = vnum; + } + return; +} + /* * Snarf a help section. */ -void load_helps( FILE * fp ) +void load_helps( FILE *fp, const char *fname ) { HELP_DATA *pHelp = NULL; + int level; + char *keyword = NULL; for ( ;; ) { - pHelp = ( HELP_DATA * ) alloc_perm( sizeof( *pHelp ) ); - pHelp->level = fread_number( fp ); - pHelp->keyword = fread_string( fp ); - if ( pHelp->keyword[0] == '$' ) - break; + HELP_AREA * had; + + level = fread_number( fp ); + keyword = fread_string( fp ); + + if ( keyword[0] == '$' ) + break; + + if ( !had_list ) + { + had = new_had (); + had->filename = str_dup( fname ); + had->area = current_area; + if ( current_area ) + current_area->helps = had; + had_list = had; + } + else + if ( str_cmp( fname, had_list->filename ) ) + { + had = new_had (); + had->filename = str_dup( fname ); + had->area = current_area; + if ( current_area ) + current_area->helps = had; + had->next = had_list; + had_list = had; + } + else + had = had_list; + + pHelp = new_help( ); + pHelp->level = level; + pHelp->keyword = keyword; pHelp->text = fread_string( fp ); if ( !str_cmp( pHelp->keyword, "greeting" ) ) @@ -446,8 +621,18 @@ if ( help_last != NULL ) help_last->next = pHelp; - help_last = pHelp; - pHelp->next = NULL; + help_last = pHelp; + pHelp->next = NULL; + + if ( !had->first ) + had->first = pHelp; + if ( !had->last ) + had->last = pHelp; + + had->last->next_area = pHelp; + had->last = pHelp; + pHelp->next_area = NULL; + top_help++; } @@ -466,6 +651,11 @@ int race = 0; char name[MAX_STRING_LENGTH] = "\0\0\0\0\0\0\0"; + if ( !area_last ) /* OLC */ + { + proper_exit( MUD_HALT, "Load_mobiles: no #AREA seen yet." ); + } + for ( ;; ) { int vnum = 0; @@ -493,6 +684,7 @@ pMobIndex = ( MOB_INDEX_DATA * ) alloc_perm( sizeof( *pMobIndex ) ); pMobIndex->vnum = vnum; + pMobIndex->area = area_last; /* OLC */ pMobIndex->new_format = false; pMobIndex->player_name = fread_string( fp ); pMobIndex->short_descr = fread_string( fp ); @@ -573,10 +765,14 @@ proper_exit( MUD_HALT, "Load_mobiles: vnum %d non-S.", vnum ); } + convert_mobile( pMobIndex ); /* ROM OLC */ + iHash = vnum % MAX_KEY_HASH; pMobIndex->next = mob_index_hash[iHash]; mob_index_hash[iHash] = pMobIndex; top_mob_index++; + top_vnum_mob = top_vnum_mob < vnum ? vnum : top_vnum_mob; /* OLC */ + assign_area_vnum( vnum ); /* OLC */ kill_table[URANGE( 0, pMobIndex->level, MAX_LEVEL - 1 )].number++; } @@ -590,6 +786,11 @@ { OBJ_INDEX_DATA *pObjIndex = NULL; + if ( !area_last ) /* OLC */ + { + proper_exit( MUD_HALT, "Load_mobiles: no #AREA seen yet." ); + } + for ( ;; ) { int vnum = 0; @@ -617,6 +819,7 @@ pObjIndex = ( OBJ_INDEX_DATA * ) alloc_perm( sizeof( *pObjIndex ) ); pObjIndex->vnum = vnum; + pObjIndex->area = area_last; /* OLC */ pObjIndex->new_format = false; pObjIndex->reset_num = 0; pObjIndex->name = fread_string( fp ); @@ -724,11 +927,39 @@ pObjIndex->next = obj_index_hash[iHash]; obj_index_hash[iHash] = pObjIndex; top_obj_index++; + top_vnum_obj = top_vnum_obj < vnum ? vnum : top_vnum_obj; /* OLC */ + assign_area_vnum( vnum ); /* OLC */ } return; } +/* + * Adds a reset to a room. OLC + * Similar to add_reset in olc.c + */ +void new_reset( ROOM_INDEX_DATA *pR, RESET_DATA *pReset ) +{ + RESET_DATA *pr; + + if ( !pR ) + return; + + pr = pR->reset_last; + if ( !pr ) + { + pR->reset_first = pReset; + pR->reset_last = pReset; + } + else + { + pR->reset_last->next = pReset; + pR->reset_last = pReset; + pR->reset_last->next = NULL; + } + return; +} + /* * Snarf a reset section. */ @@ -739,8 +970,11 @@ void load_resets( FILE * fp ) { RESET_DATA *pReset = NULL; + EXIT_DATA *pexit = NULL; + ROOM_INDEX_DATA *pRoomIndex = NULL; + int rVnum = -1; - if ( area_last == NULL ) + if ( !area_last ) { proper_exit( MUD_HALT, "Load_resets: no #AREA seen yet." ); } @@ -748,10 +982,7 @@ for ( ;; ) { - ROOM_INDEX_DATA *pRoomIndex = NULL; - EXIT_DATA *pexit = NULL; char letter = '\0'; - OBJ_INDEX_DATA *temp_index = NULL; if ( ( letter = fread_letter( fp ) ) == 'S' ) break; @@ -762,11 +993,9 @@ continue; } - pReset = ( RESET_DATA * ) alloc_perm( sizeof( *pReset ) ); + pReset = new_reset_data(); pReset->command = letter; - /* - * if_flag - */ fread_number( fp ); + fread_number( fp ); /* if_flag */ pReset->arg1 = fread_number( fp ); pReset->arg2 = fread_number( fp ); pReset->arg3 = ( letter == 'G' || letter == 'R' ) ? 0 : fread_number( fp ); @@ -773,79 +1004,64 @@ pReset->arg4 = ( letter == 'P' || letter == 'M' ) ? fread_number( fp ) : 0; fread_to_eol( fp ); - /* - * Validate parameters. - * We're calling the index functions for the side effect. - */ - switch ( letter ) + switch( pReset->command ) { - default: - proper_exit( MUD_HALT, "Load_resets: bad command '%c'.", letter ); - break; - - case 'M': - get_mob_index( pReset->arg1 ); - get_room_index( pReset->arg3 ); - break; - - case 'O': - temp_index = get_obj_index( pReset->arg1 ); - temp_index->reset_num++; - get_room_index( pReset->arg3 ); - break; - - case 'P': - temp_index = get_obj_index( pReset->arg1 ); - temp_index->reset_num++; - get_obj_index( pReset->arg3 ); - break; - - case 'G': - case 'E': - temp_index = get_obj_index( pReset->arg1 ); - temp_index->reset_num++; - break; - - case 'D': - pRoomIndex = get_room_index( pReset->arg1 ); - - if ( pReset->arg2 < 0 - || pReset->arg2 > 5 - || ( pexit = pRoomIndex->exit[pReset->arg2] ) == NULL - || !IS_SET( pexit->exit_info, EX_ISDOOR ) ) - { - proper_exit( MUD_HALT, "Load_resets: 'D': exit %d not door.", - pReset->arg2 ); - } - - if ( pReset->arg3 < 0 || pReset->arg3 > 2 ) - { - proper_exit( MUD_HALT, "Load_resets: 'D': bad 'locks': %d.", - pReset->arg3 ); - } + case 'M': + case 'O': + rVnum = pReset->arg3; + break; - break; + case 'P': + case 'G': + case 'E': + break; - case 'R': - pRoomIndex = get_room_index( pReset->arg1 ); + case 'D': + pRoomIndex = get_room_index( (rVnum = pReset->arg1) ); + if ( pReset->arg2 < 0 + || pReset->arg2 >= MAX_DIR + || !pRoomIndex + || !( pexit = pRoomIndex->exit[pReset->arg2] ) + || !IS_SET( pexit->rs_flags, EX_ISDOOR ) ) + { + proper_exit( MUD_HALT, + "Load_resets: 'D': exit %d, room %d not door.", + pReset->arg2, pReset->arg1 ); + } - if ( pReset->arg2 < 0 || pReset->arg2 > 6 ) - { - proper_exit( MUD_HALT, "Load_resets: 'R': bad exit %d.", - pReset->arg2 ); - } + switch ( pReset->arg3 ) + { + default: + log_error( "Load_resets: 'D': bad 'locks': %d.", + pReset->arg3); + break; + case 0: + break; + case 1: + SET_BIT( pexit->rs_flags, EX_CLOSED ); + SET_BIT( pexit->exit_info, EX_CLOSED ); + break; + case 2: + SET_BIT( pexit->rs_flags, EX_CLOSED | EX_LOCKED ); + SET_BIT( pexit->exit_info, EX_CLOSED | EX_LOCKED ); + break; + } + break; - break; + case 'R': + rVnum = pReset->arg1; + break; } - if ( area_last->reset_first == NULL ) - area_last->reset_first = pReset; - if ( area_last->reset_last != NULL ) - area_last->reset_last->next = pReset; - - area_last->reset_last = pReset; - pReset->next = NULL; - top_reset++; + if ( rVnum == -1 ) + { + proper_exit( MUD_HALT, "load_resets : rVnum == -1" ); + } + + if ( pReset->command != 'D' ) + new_reset( get_room_index(rVnum), pReset ); + else + free_reset_data( pReset ); } return; @@ -956,28 +1161,33 @@ pexit->description = fread_string( fp ); pexit->keyword = fread_string( fp ); pexit->exit_info = 0; + pexit->rs_flags = 0; /* OLC */ locks = fread_number( fp ); pexit->key = fread_number( fp ); pexit->u1.vnum = fread_number( fp ); + pexit->orig_door = door; /* OLC */ switch ( locks ) { case 1: pexit->exit_info = EX_ISDOOR; + pexit->rs_flags = EX_ISDOOR; break; case 2: pexit->exit_info = EX_ISDOOR | EX_PICKPROOF; + pexit->rs_flags = EX_ISDOOR | EX_PICKPROOF; break; case 3: pexit->exit_info = EX_ISDOOR | EX_NOPASS; + pexit->rs_flags = EX_ISDOOR | EX_NOPASS; break; case 4: pexit->exit_info = EX_ISDOOR | EX_NOPASS | EX_PICKPROOF; + pexit->rs_flags = EX_ISDOOR | EX_NOPASS | EX_PICKPROOF; break; } pRoomIndex->exit[door] = pexit; - pRoomIndex->old_exit[door] = pexit; top_exit++; } else if ( letter == 'E' ) @@ -1007,6 +1217,8 @@ pRoomIndex->next = room_index_hash[iHash]; room_index_hash[iHash] = pRoomIndex; top_room++; + top_vnum_room = top_vnum_room < vnum ? vnum : top_vnum_room; /* OLC */ + assign_area_vnum( vnum ); /* OLC */ } return; @@ -1105,6 +1317,9 @@ ROOM_INDEX_DATA *to_room = NULL; EXIT_DATA *pexit = NULL; EXIT_DATA *pexit_rev = NULL; + RESET_DATA *pReset = NULL; + ROOM_INDEX_DATA *iLastRoom = NULL; + ROOM_INDEX_DATA *iLastObj = NULL; int iHash = 0; int door = -1; @@ -1116,6 +1330,67 @@ { bool fexit = false; + iLastRoom = iLastObj = NULL; + + /* OLC : new check of resets */ + for ( pReset = pRoomIndex->reset_first; pReset; pReset = pReset->next ) + { + switch( pReset->command ) + { + default: + proper_exit( MUD_HALT, + "fix_exits : room %d with reset cmd %c", + pRoomIndex->vnum, pReset->command ); + break; + + case 'M': + get_mob_index( pReset->arg1 ); + iLastRoom = get_room_index( pReset->arg3 ); + break; + + case 'O': + get_obj_index( pReset->arg1 ); + iLastObj = get_room_index( pReset->arg3 ); + break; + + case 'P': + get_obj_index( pReset->arg1 ); + if (iLastObj == NULL) + { + proper_exit( MUD_HALT, + "fix_exits : reset in room %d with iLastObj NULL", + pRoomIndex->vnum ); + } + break; + + case 'G': + case 'E': + get_obj_index( pReset->arg1 ); + if (iLastRoom == NULL) + { + proper_exit( MUD_HALT, + "fix_exits : reset in room %d with iLastRoom NULL", + pRoomIndex->vnum ); + } + iLastObj = iLastRoom; + break; + + case 'D': + log_error( "???" ); + break; + + case 'R': + get_room_index( pReset->arg1 ); + if ( pReset->arg2 < 0 || pReset->arg2 > MAX_DIR ) + { + proper_exit( MUD_HALT, + "fix_exits : reset in room %d with arg2 %d >= MAX_DIR", + pRoomIndex->vnum, pReset->arg2 ); + } + break; + } /* switch */ + } /* for */ + for ( door = 0; door < MAX_EXIT; door++ ) { if ( ( pexit = pRoomIndex->exit[door] ) != NULL ) @@ -1164,6 +1436,86 @@ return; } +/* + * Load mobprogs section + */ +void load_mobprogs( FILE *fp ) +{ + MPROG_CODE *pMprog; + + if ( area_last == NULL ) + { + proper_exit( MUD_HALT, "Load_mobprogs: no #AREA seen yet." ); + } + + for ( ;; ) + { + sh_int vnum; + char letter; + + letter = fread_letter( fp ); + if ( letter != '#' ) + { + proper_exit( MUD_HALT, "Load_mobprogs: # not found." ); + } + + vnum = fread_number( fp ); + if ( vnum == 0 ) + break; + + fBootDb = false; + if ( get_mprog_index( vnum ) != NULL ) + { + proper_exit( MUD_HALT, "Load_mobprogs: vnum %d duplicated.", vnum ); + } + fBootDb = true; + + pMprog = (MPROG_CODE * ) alloc_perm( sizeof(*pMprog) ); + pMprog->vnum = vnum; + pMprog->code = fread_string( fp ); + if ( mprog_list == NULL ) + mprog_list = pMprog; + else + { + pMprog->next = mprog_list; + mprog_list = pMprog; + } + top_mprog_index++; + } + return; +} + +/* + * Translate mobprog vnums pointers to real code + */ +void fix_mobprogs( void ) +{ + MOB_INDEX_DATA *pMobIndex; + MPROG_LIST *list; + MPROG_CODE *prog; + int iHash; + + for ( iHash = 0; iHash < MAX_KEY_HASH; iHash++ ) + { + for ( pMobIndex = mob_index_hash[iHash]; + pMobIndex != NULL; + pMobIndex = pMobIndex->next ) + { + for( list = pMobIndex->mprogs; list != NULL; list = list->next ) + { + if ( ( prog = get_mprog_index( list->vnum ) ) != NULL ) + list->code = prog->code; + else + { + proper_exit( MUD_HALT, + "Fix_mobprogs: code vnum %d not found.", + list->vnum ); + } + } + } + } +} + /* * Repopulate areas periodically. */ @@ -1205,53 +1558,73 @@ return; } -/* - * Reset one area. +/* OLC + * Reset one room. Called by reset_area and olc. */ -void reset_area( AREA_DATA *pArea ) +void reset_room( ROOM_INDEX_DATA *pRoom ) { - RESET_DATA *pReset = NULL; - CHAR_DATA *mob = NULL; + RESET_DATA *pReset = NULL; + CHAR_DATA *pMob = NULL; + CHAR_DATA *mob = NULL; + OBJ_DATA *pObj = NULL; + CHAR_DATA *LastMob = NULL; + OBJ_DATA *LastObj = NULL; + int iExit; + int level = 0; bool last = true; - int level = 0; - for ( pReset = pArea->reset_first; pReset != NULL; pReset = pReset->next ) + if ( !pRoom ) + return; + + last = false; + + for ( iExit = 0; iExit < MAX_DIR; iExit++ ) { - ROOM_INDEX_DATA *pRoomIndex = NULL; - MOB_INDEX_DATA *pMobIndex = NULL; - OBJ_INDEX_DATA *pObjIndex = NULL; - OBJ_INDEX_DATA *pObjToIndex = NULL; - EXIT_DATA *pexit = NULL; - OBJ_DATA *obj = NULL; - OBJ_DATA *obj_to = NULL; - int count = 0; - int limit = 0; + EXIT_DATA *pExit; + if ( ( pExit = pRoom->exit[iExit] ) + /* && !IS_SET( pExit->exit_info, EX_BASHED ) ROM OLC */ ) + { + pExit->exit_info = pExit->rs_flags; + if ( ( pExit->u1.to_room != NULL ) + && ( ( pExit = pExit->u1.to_room->exit[rev_dir[iExit]] ) ) ) + { + /* nail the other side */ + pExit->exit_info = pExit->rs_flags; + } + } + } - switch ( pReset->command ) - { - default: - log_error( "Bad reset command %c", pReset->command ); - break; + for ( pReset = pRoom->reset_first; pReset != NULL; pReset = pReset->next ) + { + MOB_INDEX_DATA *pMobIndex; + OBJ_INDEX_DATA *pObjIndex; + OBJ_INDEX_DATA *pObjToIndex; + ROOM_INDEX_DATA *pRoomIndex; + int count,limit=0; - case 'M': - if ( ( pMobIndex = get_mob_index( pReset->arg1 ) ) == NULL ) - { - log_error( "'M': bad vnum %d", pReset->arg1 ); - continue; - } + switch ( pReset->command ) + { + default: + log_error( "Reset_room: bad command %c.", pReset->command ); + break; + + case 'M': + if ( !( pMobIndex = get_mob_index( pReset->arg1 ) ) ) + { + log_error( "Reset_room: 'M': bad vnum %d.", pReset->arg1 ); + continue; + } if ( ( pRoomIndex = get_room_index( pReset->arg3 ) ) == NULL ) { log_error( "'R': bad vnum %d", pReset->arg3 ); continue; } - - if ( pMobIndex->count >= pReset->arg2 ) - { - last = false; - break; - } - + if ( pMobIndex->count >= pReset->arg2 ) + { + last = FALSE; + break; + } count = 0; for ( mob = pRoomIndex->people; mob != NULL; mob = mob->next_in_room ) if ( mob->pIndexData == pMobIndex ) @@ -1271,69 +1643,77 @@ if ( count >= pReset->arg4 ) break; - mob = create_mobile( pMobIndex ); - /* - * Check for pet shop. - */ - { - ROOM_INDEX_DATA *pRoomIndexPrev = NULL; - - pRoomIndexPrev = get_room_index( pRoomIndex->vnum - 1 ); - if ( pRoomIndexPrev != NULL - && IS_SET( pRoomIndexPrev->room_flags, ROOM_PET_SHOP ) ) - SET_BIT( mob->act, ACT_PET ); - } + pMob = create_mobile( pMobIndex ); - /* - * set area - */ - mob->zone = pRoomIndex->area; + /* + * Some more hard coding. + */ + if ( room_is_dark( pRoom ) ) + SET_BIT(pMob->affected_by, AFF_INFRARED); + + /* + * Pet shop mobiles get ACT_PET set. + */ + { + ROOM_INDEX_DATA *pRoomIndexPrev; - char_to_room( mob, pRoomIndex ); - level = URANGE( 0, mob->level - 2, LEVEL_HERO - 1 ); - last = true; - break; + pRoomIndexPrev = get_room_index( pRoom->vnum - 1 ); + if ( pRoomIndexPrev + && IS_SET( pRoomIndexPrev->room_flags, ROOM_PET_SHOP ) ) + SET_BIT( pMob->act, ACT_PET); + } - case 'O': - if ( ( pObjIndex = get_obj_index( pReset->arg1 ) ) == NULL ) - { - log_error( "'O': bad vnum %d", pReset->arg1 ); - continue; - } + char_to_room( pMob, pRoom ); - if ( ( pRoomIndex = get_room_index( pReset->arg3 ) ) == NULL ) - { - log_error( "'R': bad vnum %d", pReset->arg3 ); - continue; - } + LastMob = pMob; + level = URANGE( 0, pMob->level - 2, LEVEL_HERO - 1 ); /* -1 ROM */ + last = true; + break; + + case 'O': + if ( !( pObjIndex = get_obj_index( pReset->arg1 ) ) ) + { + log_error( "Reset_room: 'O' 1 : bad vnum %d", pReset->arg1 ); + log_error( "%d %d %d %d",pReset->arg1, pReset->arg2, + pReset->arg3, pReset->arg4 ); + continue; + } + + if ( !( pRoomIndex = get_room_index( pReset->arg3 ) ) ) + { + log_error( "Reset_room: 'O' 2 : bad vnum %d.", pReset->arg3 ); + log_error( "%d %d %d %d",pReset->arg1, pReset->arg2, + pReset->arg3, pReset->arg4 ); + continue; + } - if ( pArea->nplayer > 0 - || count_obj_list( pObjIndex, pRoomIndex->contents ) > 0 ) + if ( pRoom->area->nplayer > 0 + || count_obj_list( pObjIndex, pRoom->contents ) > 0 ) { last = false; break; } - obj = create_object( pObjIndex, UMIN( number_fuzzy( level ), - LEVEL_HERO - 1 ) ); - obj->cost = 0; - obj_to_room( obj, pRoomIndex ); + pObj = create_object( pObjIndex, /* UMIN - ROM OLC */ + UMIN(number_fuzzy( level ), LEVEL_HERO -1) ); + pObj->cost = 0; + obj_to_room( pObj, pRoom ); last = true; - break; + break; - case 'P': - if ( ( pObjIndex = get_obj_index( pReset->arg1 ) ) == NULL ) - { - log_error( "'P': bad vnum %d", pReset->arg1 ); - continue; - } + case 'P': + if ( !( pObjIndex = get_obj_index( pReset->arg1 ) ) ) + { + log_error( "Reset_room: 'P': bad vnum %d.", pReset->arg1 ); + continue; + } - if ( ( pObjToIndex = get_obj_index( pReset->arg3 ) ) == NULL ) - { - log_error( "'P': bad vnum %d", pReset->arg3 ); - continue; - } + if ( !( pObjToIndex = get_obj_index( pReset->arg3 ) ) ) + { + log_error( "Reset_room: 'P': bad vnum %d.", pReset->arg3 ); + continue; + } if ( pReset->arg2 > 50 ) /* old format */ limit = 6; @@ -1339,59 +1725,64 @@ else limit = pReset->arg2; - if ( pArea->nplayer > 0 - || ( obj_to = get_obj_type( pObjToIndex ) ) == NULL - || ( obj_to->in_room == NULL && !last ) - || ( pObjIndex->count >= limit && number_range( 0, 4 ) != 0 ) - || ( count = count_obj_list( pObjIndex, obj_to->contains ) ) - > pReset->arg4 ) + if ( pRoom->area->nplayer > 0 + || ( LastObj = get_obj_type( pObjToIndex ) ) == NULL + || ( LastObj->in_room == NULL && !last) + || ( pObjIndex->count >= limit /* && number_range( 0, 4 ) != 0 */ ) + || ( count = count_obj_list( pObjIndex, LastObj->contains ) ) + > pReset->arg4 ) { last = false; break; } while ( count < pReset->arg4 ) { - obj = create_object( pObjIndex, number_fuzzy( obj_to->level ) ); - obj_to_obj( obj, obj_to ); + pObj = create_object( pObjIndex, number_fuzzy( LastObj->level ) ); + obj_to_obj( pObj, LastObj ); count++; if ( pObjIndex->count >= limit ) break; } + /* * fix object lock state! */ - obj_to->value[1] = obj_to->pIndexData->value[1]; + LastObj->value[1] = LastObj->pIndexData->value[1]; last = true; break; - case 'G': - case 'E': - if ( ( pObjIndex = get_obj_index( pReset->arg1 ) ) == NULL ) - { - log_error( "'E' or 'G': bad vnum %d", pReset->arg1 ); - continue; - } + case 'G': + case 'E': + if ( !( pObjIndex = get_obj_index( pReset->arg1 ) ) ) + { + log_error( "Reset_room: 'E' or 'G': bad vnum %d.", pReset->arg1 ); + continue; + } if ( !last ) break; - if ( mob == NULL ) - { - log_error( "'E' or 'G': NULL mob for vnum %d", pReset->arg1 ); - last = false; - break; - } + if ( !LastMob ) + { + log_error( "Reset_room: 'E' or 'G': null mob for vnum %d.", + pReset->arg1 ); + last = false; + break; + } - if ( mob->pIndexData->pShop != NULL ) + if ( LastMob->pIndexData->pShop ) /* Shop-keeper? */ { int olevel = 0; int i = 0; int j = 0; if ( !pObjIndex->new_format ) switch ( pObjIndex->item_type ) { + default: + olevel = 0; + break; case ITEM_PILL: case ITEM_POTION: case ITEM_SCROLL: @@ -1408,103 +1796,92 @@ break; } - obj = create_object( pObjIndex, olevel ); + pObj = create_object( pObjIndex, olevel ); - SET_BIT( obj->extra_flags, ITEM_INVENTORY ); + SET_BIT( pObj->extra_flags, ITEM_INVENTORY ); /* ROM OLC */ - } - - else + } + else /* ROM OLC else version */ { - if ( pReset->arg2 > 50 ) /* old format */ + if (pReset->arg2 > 50 ) /* old format */ limit = 6; - else if ( pReset->arg2 == -1 ) /* no limit */ + else if ( pReset->arg2 == -1 || pReset->arg2 == 0 ) limit = 999; else limit = pReset->arg2; if ( pObjIndex->count < limit || number_range( 0, 4 ) == 0 ) { - obj = create_object( pObjIndex, UMIN( number_fuzzy( level ), - LEVEL_HERO - 1 ) ); + pObj = create_object( pObjIndex, + UMIN( number_fuzzy( level ), LEVEL_HERO - 1 ) ); /* * error message if it is too high */ - if ( obj->item_type != ITEM_WEAPON - && obj->level > mob->level + 3 ) - log_balance( mob, - "Level %d object \"%s\"(#%d), owned by level %d mob \"%s\"(#%d)", - obj->level, obj->short_descr, - obj->pIndexData->vnum, mob->level, - mob->short_descr, mob->pIndexData->vnum ); + if ( pObj->item_type != ITEM_WEAPON + && pObj->level > LastMob->level + 3 ) + log_balance( LastMob, + "Level %d object \"%s\"(#%d), owned by level %d mob \"%s\"(#%d)", + pObj->level, pObj->short_descr, + pObj->pIndexData->vnum, LastMob->level, + LastMob->short_descr, LastMob->pIndexData->vnum ); - if ( obj->item_type == ITEM_WEAPON && pReset->command == 'E' - && obj->level < mob->level - 5 && obj->level < 45 ) - log_balance( mob, - "Level %d weapon \"%s\"(#%d), wielded by level %d mob \"%s\"(#%d)", - obj->level, obj->short_descr, - obj->pIndexData->vnum, mob->level, - mob->short_descr, mob->pIndexData->vnum ); + if ( pObj->item_type == ITEM_WEAPON && pReset->command == 'E' + && pObj->level < LastMob->level - 5 && pObj->level < 45 ) + log_balance( LastMob, + "Level %d weapon \"%s\"(#%d), wielded by level %d mob \"%s\"(#%d)", + pObj->level, pObj->short_descr, + pObj->pIndexData->vnum, LastMob->level, + LastMob->short_descr, LastMob->pIndexData->vnum ); } else break; } - obj_to_char( obj, mob ); - if ( pReset->command == 'E' ) - equip_char( mob, obj, pReset->arg3 ); - last = true; - break; - - case 'D': - if ( ( pRoomIndex = get_room_index( pReset->arg1 ) ) == NULL ) - { - log_error( "'D': bad vnum %d", pReset->arg1 ); - continue; - } - - if ( ( pexit = pRoomIndex->exit[pReset->arg2] ) == NULL ) - break; - - switch ( pReset->arg3 ) - { - case 0: - REMOVE_BIT( pexit->exit_info, EX_CLOSED ); - REMOVE_BIT( pexit->exit_info, EX_LOCKED ); - break; + obj_to_char( pObj, LastMob ); + if ( pReset->command == 'E' ) + equip_char( LastMob, pObj, pReset->arg3 ); + last = true; + break; - case 1: - SET_BIT( pexit->exit_info, EX_CLOSED ); - REMOVE_BIT( pexit->exit_info, EX_LOCKED ); - break; + case 'D': + break; - case 2: - SET_BIT( pexit->exit_info, EX_CLOSED ); - SET_BIT( pexit->exit_info, EX_LOCKED ); - break; - } + case 'R': + if ( !( pRoomIndex = get_room_index( pReset->arg1 ) ) ) + { + log_error( "Reset_room: 'R': bad vnum %d.", pReset->arg1 ); + continue; + } - last = true; - break; + { + EXIT_DATA *pExit; + int d0; + int d1; + + for ( d0 = 0; d0 < pReset->arg2 - 1; d0++ ) + { + d1 = number_range( d0, pReset->arg2-1 ); + pExit = pRoomIndex->exit[d0]; + pRoomIndex->exit[d0] = pRoomIndex->exit[d1]; + pRoomIndex->exit[d1] = pExit; + } + } + break; + } + } - case 'R': - if ( ( pRoomIndex = get_room_index( pReset->arg1 ) ) == NULL ) - { - log_error( "'R': bad vnum %d", pReset->arg1 ); - continue; - } + return; +} - { - int d0 = 0; - int d1 = 0; +/* OLC + * Reset one area. + */ +void reset_area( AREA_DATA *pArea ) +{ + ROOM_INDEX_DATA *pRoom; + int vnum; - for ( d0 = 0; d0 < pReset->arg2 - 1; d0++ ) - { - d1 = number_range( d0, pReset->arg2 - 1 ); - pexit = pRoomIndex->exit[d0]; - pRoomIndex->exit[d0] = pRoomIndex->exit[d1]; - pRoomIndex->exit[d1] = pexit; - } - } - break; - } + for ( vnum = pArea->min_vnum; vnum <= pArea->max_vnum; vnum++ ) + { + if ( ( pRoom = get_room_index(vnum) ) ) + reset_room(pRoom); } return; @@ -1531,13 +1932,14 @@ mob->pIndexData = pMobIndex; - mob->name = pMobIndex->player_name; + mob->name = str_dup( pMobIndex->player_name ); /* OLC */ + mob->short_descr = str_dup( pMobIndex->short_descr ); /* OLC */ + mob->long_descr = str_dup( pMobIndex->long_descr ); /* OLC */ + mob->description = str_dup( pMobIndex->description ); /* OLC */ mob->id = get_mob_id( ); - mob->short_descr = pMobIndex->short_descr; - mob->long_descr = pMobIndex->long_descr; - mob->description = pMobIndex->description; mob->spec_fun = pMobIndex->spec_fun; mob->prompt = NULL; + mob->mprog_target = NULL; if ( pMobIndex->wealth == 0 ) { @@ -1845,9 +2247,9 @@ obj->level = UMAX( 0, level ); obj->wear_loc = -1; - obj->name = pObjIndex->name; - obj->short_descr = pObjIndex->short_descr; - obj->description = pObjIndex->description; + obj->name = str_dup( pObjIndex->name ); /* OLC */ + obj->short_descr = str_dup( pObjIndex->short_descr ); /* OLC */ + obj->description = str_dup( pObjIndex->description ); /* OLC */ obj->material = str_dup( pObjIndex->material ); obj->item_type = pObjIndex->item_type; obj->extra_flags = pObjIndex->extra_flags; @@ -2139,6 +2541,17 @@ { return; } + +MPROG_CODE *get_mprog_index( int vnum ) +{ + MPROG_CODE *prg; + for( prg = mprog_list; prg; prg = prg->next ) + { + if ( prg->vnum == vnum ) + return( prg ); + } + return NULL; +} /* snarf a socials file */ void load_socials( FILE * fp ) @@ -3188,6 +3190,11 @@ { MOB_INDEX_DATA *pMobIndex; + if ( !area_last ) /* OLC */ + { + proper_exit( MUD_HALT, "Load_mobiles: no #AREA seen yet."); + } + for ( ;; ) { int vnum = 0; @@ -3215,6 +3223,7 @@ pMobIndex = ( MOB_INDEX_DATA * ) alloc_perm( sizeof( *pMobIndex ) ); pMobIndex->vnum = vnum; + pMobIndex->area = area_last; /* OLC */ pMobIndex->new_format = true; newmobs++; pMobIndex->player_name = fread_string( fp ); @@ -3287,7 +3296,7 @@ /* * size */ - pMobIndex->size = size_lookup( fread_word( fp ) ); + CHECK_POS( pMobIndex->size, size_lookup( fread_word( fp ) ), "size" ); pMobIndex->material = str_dup( fread_word( fp ) ); for ( ;; ) @@ -3324,6 +3334,25 @@ proper_exit( MUD_HALT, "Flag remove: flag not found." ); } } + else if ( letter == 'M' ) + { + MPROG_LIST *pMprog; + char *word; + int trigger = 0; + + pMprog = ( MPROG_LIST * ) alloc_perm(sizeof(*pMprog)); + word = fread_word( fp ); + if ( (trigger = flag_lookup( word, mprog_flags )) == NO_FLAG ) + { + proper_exit( MUD_HALT, "MOBprogs: invalid trigger." ); + } + SET_BIT( pMobIndex->mprog_flags, trigger ); + pMprog->trig_type = trigger; + pMprog->vnum = fread_number( fp ); + pMprog->trig_phrase = fread_string( fp ); + pMprog->next = pMobIndex->mprogs; + pMobIndex->mprogs = pMprog; + } else { ungetc( letter, fp ); @@ -3335,6 +3365,8 @@ pMobIndex->next = mob_index_hash[iHash]; mob_index_hash[iHash] = pMobIndex; top_mob_index++; + top_vnum_mob = top_vnum_mob < vnum ? vnum : top_vnum_mob; /* OLC */ + assign_area_vnum( vnum ); /* OLC */ kill_table[URANGE( 0, pMobIndex->level, MAX_LEVEL - 1 )].number++; } @@ -3348,6 +3380,11 @@ { OBJ_INDEX_DATA *pObjIndex; + if ( !area_last ) /* OLC */ + { + proper_exit( MUD_HALT, "Load_objects: no #AREA seen yet." ); + } + for ( ;; ) { int vnum = 0; @@ -3375,6 +3413,7 @@ pObjIndex = ( OBJ_INDEX_DATA * ) alloc_perm( sizeof( *pObjIndex ) ); pObjIndex->vnum = vnum; + pObjIndex->area = area_last; /* OLC */ pObjIndex->new_format = true; pObjIndex->reset_num = 0; newobjs++; @@ -3382,8 +3421,8 @@ pObjIndex->short_descr = fread_string( fp ); pObjIndex->description = fread_string( fp ); pObjIndex->material = fread_string( fp ); - - pObjIndex->item_type = item_lookup( fread_word( fp ) ); + + CHECK_POS(pObjIndex->item_type, item_lookup(fread_word( fp )), "item_type" ); pObjIndex->extra_flags = fread_flag( fp ); pObjIndex->wear_flags = fread_flag( fp ); switch ( pObjIndex->item_type ) @@ -3406,7 +3445,8 @@ case ITEM_FOUNTAIN: pObjIndex->value[0] = fread_number( fp ); pObjIndex->value[1] = fread_number( fp ); - pObjIndex->value[2] = liq_lookup( fread_word( fp ) ); + CHECK_POS(pObjIndex->value[2], + liq_lookup(fread_word(fp)), "liq_lookup" ); pObjIndex->value[3] = fread_number( fp ); pObjIndex->value[4] = fread_number( fp ); break; @@ -3534,7 +3573,429 @@ pObjIndex->next = obj_index_hash[iHash]; obj_index_hash[iHash] = pObjIndex; top_obj_index++; + top_vnum_obj = top_vnum_obj < vnum ? vnum : top_vnum_obj; /* OLC */ + assign_area_vnum( vnum ); /* OLC */ } return; } + +/***************************************************************************** + Name: convert_objects + Purpose: Converts all old format objects to new format + Called by: boot_db (db.c). + Note: Loops over all resets to find the level of the mob + loaded before the object to determine the level of + the object. + It might be better to update the levels in load_resets(). + This function is not pretty.. Sorry about that :) + Author: Hugin + ****************************************************************************/ +void convert_objects( void ) +{ + int vnum; + AREA_DATA *pArea; + RESET_DATA *pReset; + MOB_INDEX_DATA *pMob = NULL; + OBJ_INDEX_DATA *pObj, *pObjTo; + ROOM_INDEX_DATA *pRoom; + + if ( newobjs == top_obj_index ) return; /* all objects in new format */ + + for ( pArea = area_first; pArea; pArea = pArea->next ) + { + for ( vnum = pArea->min_vnum; vnum <= pArea->max_vnum; vnum++ ) + { + if ( !( pRoom = get_room_index( vnum ) ) ) continue; + + for ( pReset = pRoom->reset_first; pReset; pReset = pReset->next ) + { + switch ( pReset->command ) + { + case 'M': + if ( !( pMob = get_mob_index( pReset->arg1 ) ) ) + log_error( "Convert_objects: 'M': bad vnum %d.", pReset->arg1 ); + break; + + case 'O': + if ( !( pObj = get_obj_index( pReset->arg1 ) ) ) + { + log_error( "Convert_objects: 'O': bad vnum %d.", pReset->arg1 ); + break; + } + + if ( pObj->new_format ) + continue; + + if ( !pMob ) + { + log_error( "Convert_objects: 'O': No mob reset yet." ); + break; + } + + pObj->level = pObj->level < 1 ? pMob->level - 2 + : UMIN(pObj->level, pMob->level - 2); + break; + + case 'P': + { + + if ( !( pObj = get_obj_index( pReset->arg1 ) ) ) + { + log_error( "Convert_objects: 'P': bad vnum %d.", pReset->arg1 ); + break; + } + + if ( pObj->new_format ) + continue; + + if ( !( pObjTo = get_obj_index( pReset->arg3 ) ) ) + { + log_error( "Convert_objects: 'P': bad vnum %d.", pReset->arg3 ); + break; + } + + pObj->level = pObj->level < 1 ? pObjTo->level + : UMIN(pObj->level, pObjTo->level); + } + break; + + case 'G': + case 'E': + if ( !( pObj = get_obj_index( pReset->arg1 ) ) ) + { + log_error( "Convert_objects: 'E' or 'G': bad vnum %d.", pReset->arg1 ); + break; + } + + if ( !pMob ) + { + log_error( "Convert_objects: 'E' or 'G': null mob for vnum %d.", + pReset->arg1 ); + break; + } + + if ( pObj->new_format ) + continue; + + if ( pMob->pShop ) + { + switch ( pObj->item_type ) + { + default: + pObj->level = UMAX(0, pObj->level); + break; + case ITEM_PILL: + case ITEM_POTION: + pObj->level = UMAX(5, pObj->level); + break; + case ITEM_SCROLL: + case ITEM_ARMOR: + case ITEM_WEAPON: + pObj->level = UMAX(10, pObj->level); + break; + case ITEM_WAND: + case ITEM_TREASURE: + pObj->level = UMAX(15, pObj->level); + break; + case ITEM_STAFF: + pObj->level = UMAX(20, pObj->level); + break; + } + } + else + pObj->level = pObj->level < 1 ? pMob->level + : UMIN( pObj->level, pMob->level ); + break; + } /* switch ( pReset->command ) */ + } + } + } + + /* do the conversion: */ + + for ( pArea = area_first; pArea ; pArea = pArea->next ) + for ( vnum = pArea->min_vnum; vnum <= pArea->max_vnum; vnum++ ) + if ( (pObj = get_obj_index( vnum )) ) + if ( !pObj->new_format ) + convert_object( pObj ); + + return; +} + + + +/***************************************************************************** + Name: convert_object + Purpose: Converts an old_format obj to new_format + Called by: convert_objects (db2.c). + Note: Dug out of create_obj (db.c) + Author: Hugin + ****************************************************************************/ +void convert_object( OBJ_INDEX_DATA *pObjIndex ) +{ + int level; + int number, type; /* for dice-conversion */ + + if ( !pObjIndex || pObjIndex->new_format ) return; + + level = pObjIndex->level; + + pObjIndex->level = UMAX( 0, pObjIndex->level ); /* just to be sure */ + pObjIndex->cost = 10*level; + + switch ( pObjIndex->item_type ) + { + default: + log_error( "Obj_convert: vnum %d bad type.", pObjIndex->item_type ); + break; + + case ITEM_LIGHT: + case ITEM_TREASURE: + case ITEM_FURNITURE: + case ITEM_TRASH: + case ITEM_CONTAINER: + case ITEM_DRINK_CON: + case ITEM_KEY: + case ITEM_FOOD: + case ITEM_BOAT: + case ITEM_CORPSE_NPC: + case ITEM_CORPSE_PC: + case ITEM_FOUNTAIN: + case ITEM_MAP: + case ITEM_CLOTHING: + case ITEM_SCROLL: + break; + + case ITEM_WAND: + case ITEM_STAFF: + pObjIndex->value[2] = pObjIndex->value[1]; + break; + + case ITEM_WEAPON: + + /* + * The conversion below is based on the values generated + * in one_hit() (fight.c). Since I don't want a lvl 50 + * weapon to do 15d3 damage, the min value will be below + * the one in one_hit, and to make up for it, I've made + * the max value higher. + * (I don't want 15d2 because this will hardly ever roll + * 15 or 30, it will only roll damage close to 23. + * I can't do 4d8+11, because one_hit there is no dice- + * bounus value to set...) + * + * The conversion below gives: + + level: dice min max mean + 1: 1d8 1( 2) 8( 7) 5( 5) + 2: 2d5 2( 3) 10( 8) 6( 6) + 3: 2d5 2( 3) 10( 8) 6( 6) + 5: 2d6 2( 3) 12(10) 7( 7) + 10: 4d5 4( 5) 20(14) 12(10) + 20: 5d5 5( 7) 25(21) 15(14) + 30: 5d7 5(10) 35(29) 20(20) + 50: 5d11 5(15) 55(44) 30(30) + + */ + + number = UMIN(level/4 + 1, 5); + type = (level + 7)/number; + + pObjIndex->value[1] = number; + pObjIndex->value[2] = type; + break; + + case ITEM_ARMOR: + pObjIndex->value[0] = level / 5 + 3; + pObjIndex->value[1] = pObjIndex->value[0]; + pObjIndex->value[2] = pObjIndex->value[0]; + break; + + case ITEM_POTION: + case ITEM_PILL: + break; + + case ITEM_MONEY: + pObjIndex->value[0] = pObjIndex->cost; + break; + } + + pObjIndex->new_format = TRUE; + ++newobjs; + + return; +} + + + + +/***************************************************************************** + Name: convert_mobile + Purpose: Converts an old_format mob into new_format + Called by: load_old_mob (db.c). + Note: Dug out of create_mobile (db.c) + Author: Hugin + ****************************************************************************/ +void convert_mobile( MOB_INDEX_DATA *pMobIndex ) +{ + int i; + int type, number, bonus; + int level; + + if ( !pMobIndex || pMobIndex->new_format ) return; + + level = pMobIndex->level; + + pMobIndex->act |= ACT_WARRIOR; + + /* + * Calculate hit dice. Gives close to the hitpoints + * of old format mobs created with create_mobile() (db.c) + * A high number of dice makes for less variance in mobiles + * hitpoints. + * (might be a good idea to reduce the max number of dice) + * + * The conversion below gives: + + level: dice min max diff mean + 1: 1d2+6 7( 7) 8( 8) 1( 1) 8( 8) + 2: 1d3+15 16( 15) 18( 18) 2( 3) 17( 17) + 3: 1d6+24 25( 24) 30( 30) 5( 6) 27( 27) + 5: 1d17+42 43( 42) 59( 59) 16( 17) 51( 51) + 10: 3d22+96 99( 95) 162( 162) 63( 67) 131( ) + 15: 5d30+161 166(159) 311( 311) 145( 150) 239( ) + 30: 10d61+416 426(419) 1026(1026) 600( 607) 726( ) + 50: 10d169+920 930(923) 2610(2610) 1680(1688) 1770( ) + + The values in parenthesis give the values generated in create_mobile. + Diff = max - min. Mean is the arithmetic mean. + (hmm.. must be some roundoff error in my calculations.. smurfette got + 1d6+23 hp at level 3 ? -- anyway.. the values above should be + approximately right..) + */ + type = level*level*27/40; + number = UMIN(type/40 + 1, 10); /* how do they get 11 ??? */ + type = UMAX(2, type/number); + bonus = UMAX(0, level*(8 + level)*.9 - number*type); + + pMobIndex->hit[DICE_NUMBER] = number; + pMobIndex->hit[DICE_TYPE] = type; + pMobIndex->hit[DICE_BONUS] = bonus; + + pMobIndex->mana[DICE_NUMBER] = level; + pMobIndex->mana[DICE_TYPE] = 10; + pMobIndex->mana[DICE_BONUS] = 100; + + /* + * Calculate dam dice. Gives close to the damage + * of old format mobs in damage() (fight.c) + */ + type = level*7/4; + number = UMIN(type/8 + 1, 5); + type = UMAX(2, type/number); + bonus = UMAX(0, level*9/4 - number*type); + + pMobIndex->damage[DICE_NUMBER] = number; + pMobIndex->damage[DICE_TYPE] = type; + pMobIndex->damage[DICE_BONUS] = bonus; + + switch ( number_range( 1, 3 ) ) + { + case (1): pMobIndex->dam_type = 3; break; /* slash */ + case (2): pMobIndex->dam_type = 7; break; /* pound */ + case (3): pMobIndex->dam_type = 11; break; /* pierce */ + } + + for (i = 0; i < 3; i++) + pMobIndex->ac[i] = interpolate( level, 100, -100); + pMobIndex->ac[3] = interpolate( level, 100, 0); /* exotic */ + + pMobIndex->wealth /= 100; + pMobIndex->size = SIZE_MEDIUM; + pMobIndex->material = str_dup("none"); + + pMobIndex->new_format = TRUE; + ++newmobs; + + return; +} + +/* stuff for recycling mobprograms */ +MPROG_LIST *mprog_free; + +MPROG_LIST *new_mprog(void) +{ + static MPROG_LIST mp_zero; + MPROG_LIST *mp; + + if (mprog_free == NULL) + mp = ( MPROG_LIST * )alloc_perm(sizeof(*mp)); + else + { + mp = mprog_free; + mprog_free=mprog_free->next; + } + + *mp = mp_zero; + mp->vnum = 0; + mp->trig_type = 0; + mp->code = str_dup(""); + VALIDATE(mp); + return mp; +} + +void free_mprog(MPROG_LIST *mp) +{ + if (!IS_VALID(mp)) + return; + + INVALIDATE(mp); + mp->next = mprog_free; + mprog_free = mp; +} + +HELP_AREA * had_free; + +HELP_AREA * new_had ( void ) +{ + HELP_AREA * had; +static HELP_AREA zHad; + + if ( had_free ) + { + had = had_free; + had_free = had_free->next; + } + else + had = ( HELP_AREA * ) alloc_perm( sizeof( *had ) ); + + *had = zHad; + + return had; +} + +HELP_DATA * help_free; + +HELP_DATA * new_help ( void ) +{ + HELP_DATA * help; + + if ( help_free ) + { + help = help_free; + help_free = help_free->next; + } + else + help = ( HELP_DATA * ) alloc_perm( sizeof( *help ) ); + + return help; +} + +void free_help(HELP_DATA *help) +{ + free_string(help->keyword); + free_string(help->text); + help->next = help_free; + help_free = help; +} diff -ur old/db.h new/db.h --- old/db.h Mon Sep 14 17:46:16 1998 +++ new/db.h Mon Sep 14 17:46:53 1998 @@ -57,6 +58,7 @@ extern OBJ_DATA *object_list; extern TIME_INFO_DATA time_info; extern WEATHER_DATA weather_info; +extern bool MOBtrigger; extern MOB_INDEX_DATA *mob_index_hash[MAX_KEY_HASH]; extern OBJ_INDEX_DATA *obj_index_hash[MAX_KEY_HASH]; @@ -90,8 +90,25 @@ void load_ram_area_file( FILE * fp, int version ); void load_rom_area_file( FILE * fp ); + +/* func from db.c */ +extern void assign_area_vnum( int vnum ); /* OLC */ void load_area( FILE * fp ); +void new_load_area args( ( FILE *fp ) ); /* OLC */ -void load_helps( FILE * fp ); +void load_helps( FILE *fp, const char *fname ); +void load_mobprogs( FILE *fp ); /* OLC */ +void fix_mobprogs( void ); /* OLC */ +/*void reset_area( AREA_DATA * pArea );*/ /* OLC */ +void reset_room( ROOM_INDEX_DATA *pRoom ); /* OLC */ +MPROG_CODE* get_mprog_index( int vnum ); + +HELP_AREA *new_had( void ); +HELP_DATA *new_help( void ); +void free_help( HELP_DATA * ); + +void convert_mobile( MOB_INDEX_DATA *pMobIndex ); /* OLC ROM */ +void convert_objects( void ); /* OLC ROM */ +void convert_object( OBJ_INDEX_DATA *pObjIndex ); /* OLC ROM */ void load_old_mob( FILE * fp ); void load_old_obj( FILE * fp ); void load_resets( FILE * fp ); diff -ur old/fight.c new/fight.c --- old/fight.c Mon Sep 14 17:46:16 1998 +++ new/fight.c Mon Sep 14 17:46:53 1998 @@ -70,7 +70,7 @@ CHAR_DATA *ch_next = NULL; CHAR_DATA *victim = NULL; - for ( ch = char_list; ch != NULL; ch = ch->next ) + for ( ch = char_list; ch != NULL; ch = ch_next ) { ch_next = ch->next; @@ -89,6 +89,14 @@ * Fun for the whole family! */ check_assist( ch, victim ); + + if ( IS_NPC( ch ) ) + { + if ( HAS_TRIGGER( ch, TRIG_FIGHT ) ) + mp_percent_trigger( ch, victim, NULL, NULL, TRIG_FIGHT ); + if ( HAS_TRIGGER( ch, TRIG_HPCNT ) ) + mp_hprct_trigger( ch, victim ); + } } return; @@ -722,7 +730,11 @@ if ( victim->position > POS_STUNNED ) { if ( victim->fighting == NULL ) + { set_fighting( victim, ch ); + if ( IS_NPC( victim ) && HAS_TRIGGER( victim, TRIG_KILL ) ) + mp_percent_trigger( victim, ch, NULL, NULL, TRIG_KILL ); + } if ( victim->timer <= 4 ) victim->position = POS_FIGHTING; } @@ -893,6 +905,15 @@ "%s killed by %s at %s [#%d]", NAME( victim ), NAME( ch ), ch->in_room->name, ch->in_room->vnum ); + /* + * Death trigger + */ + if ( IS_NPC( victim ) && HAS_TRIGGER( victim, TRIG_DEATH) ) + { + victim->position = POS_STANDING; + mp_percent_trigger( victim, ch, NULL, NULL, TRIG_DEATH ); + } + raw_kill( victim ); /* * dump the flags @@ -3047,6 +3068,28 @@ return; } +void do_surrender( CHAR_DATA *ch, const char *argument ) +{ + CHAR_DATA *mob; + if ( (mob = ch->fighting) == NULL ) + { + ch_printf( ch, "But you're not fighting!\n\r"); + return; + } + act( "You surrender to $N!", ch, NULL, mob, TO_CHAR ); + act( "$n surrenders to you!", ch, NULL, mob, TO_VICT ); + act( "$n tries to surrender to $N!", ch, NULL, mob, TO_NOTVICT ); + stop_fighting( ch, TRUE ); + + if ( !IS_NPC( ch ) && IS_NPC( mob ) + && ( !HAS_TRIGGER( mob, TRIG_SURR ) + || !mp_percent_trigger( mob, ch, NULL, NULL, TRIG_SURR ) ) ) + { + act( "$N seems to ignore your cowardly act!", ch, NULL, mob, TO_CHAR ); + multi_hit( mob, ch, TYPE_UNDEFINED ); + } +} + void do_sla( CHAR_DATA *ch, const char *argument ) { ch_printf( ch, "If you want to SLAY, spell it out.\r\n" ); diff -ur old/handler.c new/handler.c --- old/handler.c Mon Sep 14 17:46:16 1998 +++ new/handler.c Mon Sep 14 17:46:53 1998 @@ -112,35 +112,6 @@ return 0; } -/* returns race number */ -int race_lookup( const char *name ) -{ - int race = 0; - - for ( race = 0; race_table[race].name != NULL; race++ ) - { - if ( LOWER( name[0] ) == LOWER( race_table[race].name[0] ) - && !str_prefix( name, race_table[race].name ) ) - return race; - } - - return 0; -} - -int liq_lookup( const char *name ) -{ - int liq = 0; - - for ( liq = 0; liq_table[liq].liq_name != NULL; liq++ ) - { - if ( LOWER( name[0] ) == LOWER( liq_table[liq].liq_name[0] ) - && !str_prefix( name, liq_table[liq].liq_name ) ) - return liq; - } - - return -1; -} - int weapon_lookup( const char *name ) { int type = 0; @@ -169,20 +140,6 @@ return WEAPON_EXOTIC; } -int item_lookup( const char *name ) -{ - int type = 0; - - for ( type = 0; item_table[type].name != NULL; type++ ) - { - if ( LOWER( name[0] ) == LOWER( item_table[type].name[0] ) - && !str_prefix( name, item_table[type].name ) ) - return item_table[type].type; - } - - return -1; -} - const char *item_name( int target_type ) { int type = 0; @@ -1972,6 +1928,8 @@ { if ( wch->reply == ch ) wch->reply = NULL; + if ( ch->mprog_target == wch ) + wch->mprog_target = NULL; } if ( ch == char_list ) diff -ur old/interp.c new/interp.c --- old/interp.c Mon Sep 14 17:46:16 1998 +++ new/interp.c Mon Sep 14 17:46:53 1998 @@ -246,9 +246,15 @@ {"murde", do_murde, POS_FIGHTING, 0, LOG_NORMAL, 0}, {"murder", do_murder, POS_FIGHTING, 5, LOG_ALWAYS, 1}, {"rescue", do_rescue, POS_FIGHTING, 0, LOG_NORMAL, 0}, + {"surrender", do_surrender, POS_FIGHTING, 0, LOG_NORMAL, 1}, {"trip", do_trip, POS_FIGHTING, 0, LOG_NORMAL, 1}, /* + * Mob command interpreter (placed here for faster scan...) + */ + {"mob", do_mob, POS_DEAD, 0, LOG_NEVER, 0}, + + /* * Miscellaneous commands. */ {"enter", do_enter, POS_STANDING, 0, LOG_NORMAL, 1}, @@ -350,6 +356,22 @@ {"smote", do_smote, POS_DEAD, IM, LOG_NORMAL, 1}, {"prefi", do_prefi, POS_DEAD, IM, LOG_NORMAL, 0}, {"prefix", do_prefix, POS_DEAD, IM, LOG_NORMAL, 1}, + {"mpdump", do_mpdump, POS_DEAD, IM, LOG_NEVER, 1}, + {"mpstat", do_mpstat, POS_DEAD, IM, LOG_NEVER, 1}, + + /* + * OLC + */ + {"edit", do_olc, POS_DEAD, 0, LOG_NORMAL, 1}, + {"asave", do_asave, POS_DEAD, 0, LOG_NORMAL, 1}, + {"alist", do_alist, POS_DEAD, 0, LOG_NORMAL, 1}, + {"resets", do_resets, POS_DEAD, 0, LOG_NORMAL, 1}, + {"redit", do_redit, POS_DEAD, 0, LOG_NORMAL, 1}, + {"medit", do_medit, POS_DEAD, 0, LOG_NORMAL, 1}, + {"aedit", do_aedit, POS_DEAD, 0, LOG_NORMAL, 1}, + {"oedit", do_oedit, POS_DEAD, 0, LOG_NORMAL, 1}, + {"mpedit", do_mpedit, POS_DEAD, 0, LOG_NORMAL, 1}, + {"hedit", do_hedit, POS_DEAD, 0, LOG_NORMAL, 1}, /* * End of list. diff -ur old/interp.h new/interp.h --- old/interp.h Mon Sep 14 17:46:16 1998 +++ new/interp.h Mon Sep 14 17:46:53 1998 @@ -166,6 +166,9 @@ void do_ofind( CHAR_DATA *ch, const char *argument ); void do_owhere( CHAR_DATA *ch, const char *argument ); void do_mwhere( CHAR_DATA *ch, const char *argument ); +void do_mob( CHAR_DATA *ch, const char *argument ); /* OLC */ +void do_mpstat( CHAR_DATA *ch, const char *argument ); /* OLC */ +void do_mpdump( CHAR_DATA *ch, const char *argument ); /* OLC */ void do_reboo( CHAR_DATA *ch, const char *argument ); void do_reboot( CHAR_DATA *ch, const char *argument ); void do_shutdow( CHAR_DATA *ch, const char *argument ); @@ -263,6 +266,7 @@ void do_disarm( CHAR_DATA *ch, const char *argument ); void do_sla( CHAR_DATA *ch, const char *argument ); void do_slay( CHAR_DATA *ch, const char *argument ); +void do_surrender( CHAR_DATA *ch, const char *argument ); /* OLC */ /* healer.c */ void do_heal( CHAR_DATA *ch, const char *argument ); @@ -296,3 +300,15 @@ /* tables.c */ void do_flag( CHAR_DATA *ch, const char *argument ); + +/* OLC */ +void do_olc( CHAR_DATA *ch, const char *argument ); +void do_asave( CHAR_DATA *ch, const char *argument ); +void do_alist( CHAR_DATA *ch, const char *argument ); +void do_resets( CHAR_DATA *ch, const char *argument ); +void do_redit( CHAR_DATA *ch, const char *argument ); +void do_aedit( CHAR_DATA *ch, const char *argument ); +void do_medit( CHAR_DATA *ch, const char *argument ); +void do_oedit( CHAR_DATA *ch, const char *argument ); +void do_mpedit( CHAR_DATA *ch, const char *argument ); +void do_hedit( CHAR_DATA *ch, const char *argument ); Only in new: mem.c diff -ur old/merc.h new/merc.h --- old/merc.h Mon Sep 14 17:46:16 1998 +++ new/merc.h Mon Sep 14 19:23:08 1998 @@ -86,6 +88,7 @@ typedef struct exit_data EXIT_DATA; typedef struct extra_descr_data EXTRA_DESCR_DATA; typedef struct help_data HELP_DATA; +typedef struct help_area_data HELP_AREA; typedef struct kill_data KILL_DATA; typedef struct mem_data MEM_DATA; typedef struct mob_index_data MOB_INDEX_DATA; @@ -99,6 +102,8 @@ typedef struct shop_data SHOP_DATA; typedef struct time_info_data TIME_INFO_DATA; typedef struct weather_data WEATHER_DATA; +typedef struct mprog_list MPROG_LIST; +typedef struct mprog_code MPROG_CODE; /* * Function types. @@ -267,6 +271,9 @@ int outtop; char *showstr_head; char *showstr_point; + void *pEdit; /* OLC */ + char **pString; /* OLC */ + int editor; /* OLC */ }; /* @@ -322,11 +329,22 @@ struct help_data { HELP_DATA *next; + HELP_DATA *next_area; int level; char *keyword; char *text; }; +struct help_area_data +{ + HELP_AREA * next; + HELP_DATA * first; + HELP_DATA * last; + AREA_DATA * area; + char * filename; + bool changed; +}; + /* * Shop types. */ @@ -1300,6 +1317,8 @@ MOB_INDEX_DATA *next; SPEC_FUN *spec_fun; SHOP_DATA *pShop; + MPROG_LIST *mprogs; + AREA_DATA *area; /* OLC */ int vnum; int group; bool new_format; @@ -1332,6 +1351,7 @@ int parts; int size; char *material; + long mprog_flags; }; /* memory settings */ @@ -1365,6 +1385,7 @@ CHAR_DATA *fighting; CHAR_DATA *reply; CHAR_DATA *pet; + CHAR_DATA *mprog_target; MEM_DATA *memory; SPEC_FUN *spec_fun; MOB_INDEX_DATA *pIndexData; @@ -1443,6 +1464,8 @@ int dam_type; int start_pos; int default_pos; + + sh_int mprog_delay; }; /* @@ -1476,6 +1499,7 @@ bool confirm_delete; char *alias[MAX_ALIAS]; char *alias_sub[MAX_ALIAS]; + int security; /* OLC */ /* Builder security */ }; /* Data for generating characters -- only used during generation */ @@ -1525,6 +1549,7 @@ OBJ_INDEX_DATA *next; EXTRA_DESCR_DATA *extra_descr; AFFECT_DATA *affected; + AREA_DATA *area; /* OLC */ bool new_format; char *name; char *short_descr; @@ -1595,6 +1620,9 @@ int key; char *keyword; char *description; + EXIT_DATA *next; /* OLC */ + int rs_flags; /* OLC */ + int orig_door; /* OLC */ }; /* @@ -1633,8 +1661,7 @@ struct area_data { AREA_DATA *next; - RESET_DATA *reset_first; - RESET_DATA *reset_last; + HELP_AREA *helps; char *file_name; char *name; char *credits; @@ -1645,6 +1672,10 @@ int min_vnum; int max_vnum; bool empty; + char *builders; /* OLC */ /* Listing of */ + int vnum; /* OLC */ /* Area vnum */ + int area_flags;/* OLC */ + int security; /* OLC */ /* Value 1-9 */ }; @@ -1660,7 +1691,8 @@ EXTRA_DESCR_DATA *extra_descr; AREA_DATA *area; EXIT_DATA *exit[MAX_EXIT]; - EXIT_DATA *old_exit[MAX_EXIT]; + RESET_DATA *reset_first; /* OLC */ + RESET_DATA *reset_last; /* OLC */ char *name; char *description; char *owner; @@ -1730,6 +1762,43 @@ const char *spells[MAX_IN_GROUP]; }; +/* + * MOBprog definitions + */ +#define TRIG_ACT (A) +#define TRIG_BRIBE (B) +#define TRIG_DEATH (C) +#define TRIG_ENTRY (D) +#define TRIG_FIGHT (E) +#define TRIG_GIVE (F) +#define TRIG_GREET (G) +#define TRIG_GRALL (H) +#define TRIG_KILL (I) +#define TRIG_HPCNT (J) +#define TRIG_RANDOM (K) +#define TRIG_SPEECH (L) +#define TRIG_EXIT (M) +#define TRIG_EXALL (N) +#define TRIG_DELAY (O) +#define TRIG_SURR (P) + +struct mprog_list +{ + int trig_type; + char *trig_phrase; + sh_int vnum; + char *code; + MPROG_LIST *next; + bool valid; +}; + +struct mprog_code +{ + sh_int vnum; + char *code; + MPROG_CODE *next; +}; + /* * Utility macros. */ @@ -1806,6 +1873,13 @@ #define IS_SET(flag, bit) ((flag) & (bit)) #define SET_BIT(var, bit) ((var) |= (bit)) #define REMOVE_BIT(var, bit) ((var) &= ~(bit)) +#define IS_NULLSTR(str) ((str) == NULL || (str)[0] == '\0') +#define ENTRE(min,num,max) ( ((min) < (num)) && ((num) < (max)) ) +#define CHECK_POS(a, b, c) { \ + (a) = (b); \ + if ( (a) < 0 ) \ + log_error("CHECK_POS : " c " == %d < 0", a );\ + } \ /* * Character macros. @@ -1846,6 +1918,13 @@ #define act(format,ch,arg1,arg2,type) \ act_new((format),(ch),(arg1),(arg2),(type),POS_RESTING) +#define HAS_TRIGGER(ch,trig) (IS_SET((ch)->pIndexData->mprog_flags,(trig))) +#define IS_SWITCHED( ch ) ( ch->desc && ch->desc->original ) +#define IS_BUILDER(ch, Area) ( !IS_NPC(ch) && !IS_SWITCHED( ch ) && \ + ( ch->pcdata->security >= Area->security \ + || strstr( Area->builders, ch->name ) \ + || strstr( Area->builders, "All" ) ) ) + /* * Object macros. */ @@ -1919,6 +1998,8 @@ extern DESCRIPTOR_DATA *descriptor_list; extern DESCRIPTOR_DATA *descriptor_free; +extern MPROG_CODE *mprog_list; + extern bool need_god; extern bool merc_down; extern bool wizlock; @@ -2190,11 +2279,8 @@ bool is_friend( CHAR_DATA *ch, CHAR_DATA *victim ); int count_users( OBJ_DATA *obj ); int material_lookup( const char *name ); -int race_lookup( const char *name ); -int liq_lookup( const char *name ); int weapon_lookup( const char *name ); int weapon_type_lookup( const char *name ); -int item_lookup( const char *name ); const char *item_name( int target_type ); const char *weapon_name( int target_type ); int attack_lookup( const char *name ); @@ -2288,6 +2373,27 @@ const char *cont_bit_name( int vector ); const char *off_bit_name( int vector ); +/* mob_prog.c */ +void program_flow( sh_int vnum, char *source, + CHAR_DATA *mob, CHAR_DATA *ch, + const void *arg1, const void *arg2 ); +void mp_act_trigger( const char *argument, CHAR_DATA *mob, + CHAR_DATA *ch, const void *arg1, + const void *arg2, int type ); +bool mp_percent_trigger( CHAR_DATA *mob, CHAR_DATA *ch, + const void *arg1, + const void *arg2, int type ); +void mp_bribe_trigger( CHAR_DATA *mob, CHAR_DATA *ch, + int amount ); +bool mp_exit_trigger( CHAR_DATA *ch, int dir ); +void mp_give_trigger( CHAR_DATA *mob, CHAR_DATA *ch, + OBJ_DATA *obj ); +void mp_greet_trigger( CHAR_DATA *ch ); +void mp_hprct_trigger( CHAR_DATA *mob, CHAR_DATA *ch ); + +/* mob_cmds.c */ +void mob_interpret( CHAR_DATA *ch, const char *argument ); + /* note.c */ extern NOTE_DATA *note_list; extern NOTE_DATA *idea_list; @@ -2318,6 +2420,11 @@ void update_read( CHAR_DATA *ch, NOTE_DATA *pnote ); void parse_note( CHAR_DATA *ch, const char *argument, int type ); +/* olc.c */ +bool run_olc_editor args( ( DESCRIPTOR_DATA *d ) ); +char *olc_ed_name args( ( CHAR_DATA *ch ) ); +char *olc_ed_vnum args( ( CHAR_DATA *ch ) ); + /* playerlist.c */ extern struct player_list *all_players; extern int top_player; @@ -2318,6 +2420,18 @@ void group_add( CHAR_DATA *ch, const char *name, bool deduct ); void group_remove( CHAR_DATA *ch, const char *name ); +/* string.c */ +void string_edit( CHAR_DATA *ch, char **pString ); +void string_append( CHAR_DATA *ch, char **pString ); +char *string_replace( char *orig, + const char *pOld, const char *pNew ); +void string_add( CHAR_DATA *ch, const char *argument ); +char *format_string( char *oldstring /*, bool fSpace */ ); +const char *first_arg( const char *argument, + char *arg_first, bool fCase ); +char *string_unpad( char * argument ); +char *string_proper( char * argument ); + /* update.c */ extern int save_number; @@ -2325,3 +2447,59 @@ void obj_update( void ); void aggr_update( void ); void update_handler( void ); + +/***************************************************************************** + * OLC * + *****************************************************************************/ + +/* + * Object defined in limbo.are + * Used in save.c to load objects that don't exist. + */ +#define OBJ_VNUM_DUMMY 30 + +/* + * Area flags. + */ +#define AREA_NONE 0 +#define AREA_CHANGED 1 /* Area has been modified. */ +#define AREA_ADDED 2 /* Area has been added to. */ +#define AREA_LOADING 4 /* Used for counting in db.c */ + +#define MAX_DIR 6 +#define NO_FLAG -99 /* Must not be used in flags or stats. */ + +/* + * Global Constants + */ +/*extern char * const dir_name [];*/ +/*extern const sh_int rev_dir [];*/ /* sh_int - ROM OLC */ +/*extern const struct spec_type spec_table [];*/ + +/* + * Global variables + */ +extern AREA_DATA * area_first; +extern AREA_DATA * area_last; +extern SHOP_DATA * shop_last; + +extern int top_affect; +extern int top_area; +extern int top_ed; +extern int top_exit; +extern int top_help; +extern int top_mob_index; +extern int top_obj_index; +extern int top_reset; +extern int top_room; +extern int top_shop; + +extern int top_vnum_mob; +extern int top_vnum_obj; +extern int top_vnum_room; + +extern char str_empty [1]; + +extern MOB_INDEX_DATA * mob_index_hash [MAX_KEY_HASH]; +extern OBJ_INDEX_DATA * obj_index_hash [MAX_KEY_HASH]; +extern ROOM_INDEX_DATA * room_index_hash [MAX_KEY_HASH]; diff -ur old/save.c new/save.c --- old/save.c Mon Sep 14 17:46:16 1998 +++ new/save.c Mon Sep 14 17:47:06 1998 @@ -188,6 +188,7 @@ fprintf( fp, "Levl %d\n", ch->level ); if ( ch->trust != 0 ) fprintf( fp, "Tru %d\n", ch->trust ); + fprintf( fp, "Sec %d\n", ch->pcdata->security ); /* OLC */ fprintf( fp, "Plyd %d\n", ch->played + ( int ) ( current_time - ch->logon ) ); fprintf( fp, "Not %d %d %d %d %d\n", ( int ) ch->pcdata->last_note, ( int ) ch->pcdata->last_idea, @@ -567,6 +568,7 @@ ch->pcdata->condition[COND_THIRST] = 48; ch->pcdata->condition[COND_FULL] = 48; ch->pcdata->condition[COND_HUNGER] = 48; + ch->pcdata->security = 0; /* OLC */ for ( iNest = 0; iNest < MAX_NEST; iNest++ ) rgObjNest[iNest] = NULL; } @@ -1051,6 +1053,7 @@ KEY( "Sex", ch->sex, fread_number( fp ) ); KEY( "ShortDescr", ch->short_descr, fread_string( fp ) ); KEY( "ShD", ch->short_descr, fread_string( fp ) ); + KEY( "Sec", ch->pcdata->security, fread_number( fp ) );/* OLC */ KEY( "Silv", ch->silver, fread_number( fp ) ); if ( !str_cmp( word, "Skill" ) || !str_cmp( word, "Sk" ) ) @@ -1339,6 +1342,8 @@ } } +extern OBJ_DATA *obj_free; + void fread_obj( CHAR_DATA *ch, FILE * fp ) { static char end[MAX_INPUT_LENGTH] = "End"; @@ -1492,14 +1495,21 @@ if ( !str_cmp( word, "End" ) ) { - if ( !fNest || !fVnum || obj->pIndexData == NULL ) + if ( !fNest || ( fVnum && obj->pIndexData == NULL ) ) { log_error( "%s", "Incomplete object" ); free_obj( obj ); return; } else - { + { + if ( !fVnum ) + { + log_info( "%s", "Replacing invalid object with dummy object" ); + free_obj( obj ); + obj = create_object( get_obj_index( OBJ_VNUM_DUMMY ), 0 ); + } + if ( !new_format ) { obj->next = object_list; diff -ur old/tables.c new/tables.c --- old/tables.c Mon Sep 14 17:46:16 1998 +++ new/tables.c Mon Sep 14 17:46:53 1998 @@ -306,6 +306,485 @@ {"afk", COMM_AFK, true}, {NULL, 0, 0} }; + +const struct flag_type mprog_flags[] = +{ + { "act", TRIG_ACT, TRUE }, + { "bribe", TRIG_BRIBE, TRUE }, + { "death", TRIG_DEATH, TRUE }, + { "entry", TRIG_ENTRY, TRUE }, + { "fight", TRIG_FIGHT, TRUE }, + { "give", TRIG_GIVE, TRUE }, + { "greet", TRIG_GREET, TRUE }, + { "grall", TRIG_GRALL, TRUE }, + { "kill", TRIG_KILL, TRUE }, + { "hpcnt", TRIG_HPCNT, TRUE }, + { "random", TRIG_RANDOM, TRUE }, + { "speech", TRIG_SPEECH, TRUE }, + { "exit", TRIG_EXIT, TRUE }, + { "exall", TRIG_EXALL, TRUE }, + { "delay", TRIG_DELAY, TRUE }, + { "surr", TRIG_SURR, TRUE }, + { NULL, 0, TRUE } +}; + +const struct flag_type area_flags[] = +{ + { "none", AREA_NONE, FALSE }, + { "changed", AREA_CHANGED, TRUE }, + { "added", AREA_ADDED, TRUE }, + { "loading", AREA_LOADING, FALSE }, + { NULL, 0, 0 } +}; + + + +const struct flag_type sex_flags[] = +{ + { "male", SEX_MALE, TRUE }, + { "female", SEX_FEMALE, TRUE }, + { "neutral", SEX_NEUTRAL, TRUE }, + { "random", 3, TRUE }, /* ROM */ + { "none", SEX_NEUTRAL, TRUE }, + { NULL, 0, 0 } +}; + + + +const struct flag_type exit_flags[] = +{ + { "door", EX_ISDOOR, TRUE }, + { "closed", EX_CLOSED, TRUE }, + { "locked", EX_LOCKED, TRUE }, + { "pickproof", EX_PICKPROOF, TRUE }, + { "nopass", EX_NOPASS, TRUE }, + { "easy", EX_EASY, TRUE }, + { "hard", EX_HARD, TRUE }, + { "infuriating", EX_INFURIATING, TRUE }, + { "noclose", EX_NOCLOSE, TRUE }, + { "nolock", EX_NOLOCK, TRUE }, + { NULL, 0, 0 } +}; + + + +const struct flag_type door_resets[] = +{ + { "open and unlocked", 0, TRUE }, + { "closed and unlocked", 1, TRUE }, + { "closed and locked", 2, TRUE }, + { NULL, 0, 0 } +}; + + + +const struct flag_type room_flags[] = +{ + { "dark", ROOM_DARK, TRUE }, + { "no_mob", ROOM_NO_MOB, TRUE }, + { "indoors", ROOM_INDOORS, TRUE }, + { "private", ROOM_PRIVATE, TRUE }, + { "safe", ROOM_SAFE, TRUE }, + { "solitary", ROOM_SOLITARY, TRUE }, + { "pet_shop", ROOM_PET_SHOP, TRUE }, + { "no_recall", ROOM_NO_RECALL, TRUE }, + { "imp_only", ROOM_IMP_ONLY, TRUE }, + { "gods_only", ROOM_GODS_ONLY, TRUE }, + { "heroes_only", ROOM_HEROES_ONLY, TRUE }, + { "newbies_only", ROOM_NEWBIES_ONLY, TRUE }, + { "law", ROOM_LAW, TRUE }, + { "nowhere", ROOM_NOWHERE, TRUE }, + { NULL, 0, 0 } +}; + + + +const struct flag_type sector_flags[] = +{ + { "inside", SECT_INSIDE, TRUE }, + { "city", SECT_CITY, TRUE }, + { "field", SECT_FIELD, TRUE }, + { "forest", SECT_FOREST, TRUE }, + { "hills", SECT_HILLS, TRUE }, + { "mountain", SECT_MOUNTAIN, TRUE }, + { "swim", SECT_WATER_SWIM, TRUE }, + { "noswim", SECT_WATER_NOSWIM, TRUE }, + { "unused", SECT_UNUSED, TRUE }, + { "air", SECT_AIR, TRUE }, + { "desert", SECT_DESERT, TRUE }, + { NULL, 0, 0 } +}; + + + +const struct flag_type type_flags[] = +{ + { "light", ITEM_LIGHT, TRUE }, + { "scroll", ITEM_SCROLL, TRUE }, + { "wand", ITEM_WAND, TRUE }, + { "staff", ITEM_STAFF, TRUE }, + { "weapon", ITEM_WEAPON, TRUE }, + { "treasure", ITEM_TREASURE, TRUE }, + { "armor", ITEM_ARMOR, TRUE }, + { "potion", ITEM_POTION, TRUE }, + { "furniture", ITEM_FURNITURE, TRUE }, + { "trash", ITEM_TRASH, TRUE }, + { "container", ITEM_CONTAINER, TRUE }, + { "drinkcontainer", ITEM_DRINK_CON, TRUE }, + { "key", ITEM_KEY, TRUE }, + { "food", ITEM_FOOD, TRUE }, + { "money", ITEM_MONEY, TRUE }, + { "boat", ITEM_BOAT, TRUE }, + { "npccorpse", ITEM_CORPSE_NPC, TRUE }, + { "pc corpse", ITEM_CORPSE_PC, FALSE }, + { "fountain", ITEM_FOUNTAIN, TRUE }, + { "pill", ITEM_PILL, TRUE }, + { "protect", ITEM_PROTECT, TRUE }, + { "map", ITEM_MAP, TRUE }, + { "portal", ITEM_PORTAL, TRUE }, + { "warpstone", ITEM_WARP_STONE, TRUE }, + { "roomkey", ITEM_ROOM_KEY, TRUE }, + { "gem", ITEM_GEM, TRUE }, + { "jewelry", ITEM_JEWELRY, TRUE }, +/* { "jukebox", ITEM_JUKEBOX, TRUE }, Legacy */ + { NULL, 0, 0 } +}; + + +const struct flag_type extra_flags[] = +{ + { "glow", ITEM_GLOW, TRUE }, + { "hum", ITEM_HUM, TRUE }, + { "dark", ITEM_DARK, TRUE }, + { "lock", ITEM_LOCK, TRUE }, + { "evil", ITEM_EVIL, TRUE }, + { "invis", ITEM_INVIS, TRUE }, + { "magic", ITEM_MAGIC, TRUE }, + { "nodrop", ITEM_NODROP, TRUE }, + { "bless", ITEM_BLESS, TRUE }, + { "antigood", ITEM_ANTI_GOOD, TRUE }, + { "antievil", ITEM_ANTI_EVIL, TRUE }, + { "antineutral", ITEM_ANTI_NEUTRAL, TRUE }, + { "noremove", ITEM_NOREMOVE, TRUE }, + { "inventory", ITEM_INVENTORY, TRUE }, + { "nopurge", ITEM_NOPURGE, TRUE }, + { "rotdeath", ITEM_ROT_DEATH, TRUE }, + { "visdeath", ITEM_VIS_DEATH, TRUE }, + { "nonmetal", ITEM_NONMETAL, TRUE }, + { "meltdrop", ITEM_MELT_DROP, TRUE }, + { "hadtimer", ITEM_HAD_TIMER, TRUE }, + { "sellextract", ITEM_SELL_EXTRACT, TRUE }, + { "burnproof", ITEM_BURN_PROOF, TRUE }, + { "nouncurse", ITEM_NOUNCURSE, TRUE }, + { NULL, 0, 0 } +}; + + + +const struct flag_type wear_flags[] = +{ + { "take", ITEM_TAKE, TRUE }, + { "finger", ITEM_WEAR_FINGER, TRUE }, + { "neck", ITEM_WEAR_NECK, TRUE }, + { "body", ITEM_WEAR_BODY, TRUE }, + { "head", ITEM_WEAR_HEAD, TRUE }, + { "legs", ITEM_WEAR_LEGS, TRUE }, + { "feet", ITEM_WEAR_FEET, TRUE }, + { "hands", ITEM_WEAR_HANDS, TRUE }, + { "arms", ITEM_WEAR_ARMS, TRUE }, + { "shield", ITEM_WEAR_SHIELD, TRUE }, + { "about", ITEM_WEAR_ABOUT, TRUE }, + { "waist", ITEM_WEAR_WAIST, TRUE }, + { "wrist", ITEM_WEAR_WRIST, TRUE }, + { "wield", ITEM_WIELD, TRUE }, + { "hold", ITEM_HOLD, TRUE }, + { "nosac", ITEM_NO_SAC, TRUE }, + { "wearfloat", ITEM_WEAR_FLOAT, TRUE }, +/* { "twohands", ITEM_TWO_HANDS, TRUE }, */ + { NULL, 0, 0 } +}; + +/* + * Used when adding an affect to tell where it goes. + * See addaffect and delaffect in act_olc.c + */ +const struct flag_type apply_flags[] = +{ + { "none", APPLY_NONE, TRUE }, + { "strength", APPLY_STR, TRUE }, + { "dexterity", APPLY_DEX, TRUE }, + { "intelligence", APPLY_INT, TRUE }, + { "wisdom", APPLY_WIS, TRUE }, + { "constitution", APPLY_CON, TRUE }, + { "sex", APPLY_SEX, TRUE }, + { "class", APPLY_CLASS, TRUE }, + { "level", APPLY_LEVEL, TRUE }, + { "age", APPLY_AGE, TRUE }, + { "height", APPLY_HEIGHT, TRUE }, + { "weight", APPLY_WEIGHT, TRUE }, + { "mana", APPLY_MANA, TRUE }, + { "hp", APPLY_HIT, TRUE }, + { "move", APPLY_MOVE, TRUE }, + { "gold", APPLY_GOLD, TRUE }, + { "experience", APPLY_EXP, TRUE }, + { "ac", APPLY_AC, TRUE }, + { "hitroll", APPLY_HITROLL, TRUE }, + { "damroll", APPLY_DAMROLL, TRUE }, + { "saves", APPLY_SAVES, TRUE }, + { "savingpara", APPLY_SAVING_PARA, TRUE }, + { "savingrod", APPLY_SAVING_ROD, TRUE }, + { "savingpetri", APPLY_SAVING_PETRI, TRUE }, + { "savingbreath", APPLY_SAVING_BREATH, TRUE }, + { "savingspell", APPLY_SAVING_SPELL, TRUE }, + { "spellaffect", APPLY_SPELL_AFFECT, FALSE }, + { NULL, 0, 0 } +}; + + + +/* + * What is seen. + */ +const struct flag_type wear_loc_strings[] = +{ + { "in the inventory", WEAR_NONE, TRUE }, + { "as a light", WEAR_LIGHT, TRUE }, + { "on the left finger", WEAR_FINGER_L, TRUE }, + { "on the right finger", WEAR_FINGER_R, TRUE }, + { "around the neck (1)", WEAR_NECK_1, TRUE }, + { "around the neck (2)", WEAR_NECK_2, TRUE }, + { "on the body", WEAR_BODY, TRUE }, + { "over the head", WEAR_HEAD, TRUE }, + { "on the legs", WEAR_LEGS, TRUE }, + { "on the feet", WEAR_FEET, TRUE }, + { "on the hands", WEAR_HANDS, TRUE }, + { "on the arms", WEAR_ARMS, TRUE }, + { "as a shield", WEAR_SHIELD, TRUE }, + { "about the shoulders", WEAR_ABOUT, TRUE }, + { "around the waist", WEAR_WAIST, TRUE }, + { "on the left wrist", WEAR_WRIST_L, TRUE }, + { "on the right wrist", WEAR_WRIST_R, TRUE }, + { "wielded", WEAR_WIELD, TRUE }, + { "held in the hands", WEAR_HOLD, TRUE }, + { "floating nearby", WEAR_FLOAT, TRUE }, + { NULL, 0 , 0 } +}; + + +const struct flag_type wear_loc_flags[] = +{ + { "none", WEAR_NONE, TRUE }, + { "light", WEAR_LIGHT, TRUE }, + { "lfinger", WEAR_FINGER_L, TRUE }, + { "rfinger", WEAR_FINGER_R, TRUE }, + { "neck1", WEAR_NECK_1, TRUE }, + { "neck2", WEAR_NECK_2, TRUE }, + { "body", WEAR_BODY, TRUE }, + { "head", WEAR_HEAD, TRUE }, + { "legs", WEAR_LEGS, TRUE }, + { "feet", WEAR_FEET, TRUE }, + { "hands", WEAR_HANDS, TRUE }, + { "arms", WEAR_ARMS, TRUE }, + { "shield", WEAR_SHIELD, TRUE }, + { "about", WEAR_ABOUT, TRUE }, + { "waist", WEAR_WAIST, TRUE }, + { "lwrist", WEAR_WRIST_L, TRUE }, + { "rwrist", WEAR_WRIST_R, TRUE }, + { "wielded", WEAR_WIELD, TRUE }, + { "hold", WEAR_HOLD, TRUE }, + { "floating", WEAR_FLOAT, TRUE }, + { NULL, 0, 0 } +}; + +const struct flag_type container_flags[] = +{ + { "closeable", 1, TRUE }, + { "pickproof", 2, TRUE }, + { "closed", 4, TRUE }, + { "locked", 8, TRUE }, + { "puton", 16, TRUE }, + { NULL, 0, 0 } +}; + +/***************************************************************************** + ROM - specific tables: + ****************************************************************************/ + + + + +const struct flag_type ac_type[] = +{ + { "pierce", AC_PIERCE, TRUE }, + { "bash", AC_BASH, TRUE }, + { "slash", AC_SLASH, TRUE }, + { "exotic", AC_EXOTIC, TRUE }, + { NULL, 0, 0 } +}; + + +const struct flag_type size_flags[] = +{ + { "tiny", SIZE_TINY, TRUE }, + { "small", SIZE_SMALL, TRUE }, + { "medium", SIZE_MEDIUM, TRUE }, + { "large", SIZE_LARGE, TRUE }, + { "huge", SIZE_HUGE, TRUE }, + { "giant", SIZE_GIANT, TRUE }, + { NULL, 0, 0 }, +}; + + +const struct flag_type weapon_class[] = +{ + { "exotic", WEAPON_EXOTIC, TRUE }, + { "sword", WEAPON_SWORD, TRUE }, + { "dagger", WEAPON_DAGGER, TRUE }, + { "spear", WEAPON_SPEAR, TRUE }, + { "mace", WEAPON_MACE, TRUE }, + { "axe", WEAPON_AXE, TRUE }, + { "flail", WEAPON_FLAIL, TRUE }, + { "whip", WEAPON_WHIP, TRUE }, + { "polearm", WEAPON_POLEARM, TRUE }, + { NULL, 0, 0 } +}; + + +const struct flag_type weapon_type2[] = +{ + { "flaming", WEAPON_FLAMING, TRUE }, + { "frost", WEAPON_FROST, TRUE }, + { "vampiric", WEAPON_VAMPIRIC, TRUE }, + { "sharp", WEAPON_SHARP, TRUE }, + { "vorpal", WEAPON_VORPAL, TRUE }, + { "twohands", WEAPON_TWO_HANDS, TRUE }, + { "shocking", WEAPON_SHOCKING, TRUE }, + { "poison", WEAPON_POISON, TRUE }, + { NULL, 0, 0 } +}; + +const struct flag_type res_flags[] = +{ + { "summon", RES_SUMMON, TRUE }, + { "charm", RES_CHARM, TRUE }, + { "magic", RES_MAGIC, TRUE }, + { "weapon", RES_WEAPON, TRUE }, + { "bash", RES_BASH, TRUE }, + { "pierce", RES_PIERCE, TRUE }, + { "slash", RES_SLASH, TRUE }, + { "fire", RES_FIRE, TRUE }, + { "cold", RES_COLD, TRUE }, + { "lightning", RES_LIGHTNING, TRUE }, + { "acid", RES_ACID, TRUE }, + { "poison", RES_POISON, TRUE }, + { "negative", RES_NEGATIVE, TRUE }, + { "holy", RES_HOLY, TRUE }, + { "energy", RES_ENERGY, TRUE }, + { "mental", RES_MENTAL, TRUE }, + { "disease", RES_DISEASE, TRUE }, + { "drowning", RES_DROWNING, TRUE }, + { "light", RES_LIGHT, TRUE }, + { "sound", RES_SOUND, TRUE }, + { "wood", RES_WOOD, TRUE }, + { "silver", RES_SILVER, TRUE }, + { "iron", RES_IRON, TRUE }, + { NULL, 0, 0 } +}; + + +const struct flag_type vuln_flags[] = +{ + { "summon", VULN_SUMMON, TRUE }, + { "charm", VULN_CHARM, TRUE }, + { "magic", VULN_MAGIC, TRUE }, + { "weapon", VULN_WEAPON, TRUE }, + { "bash", VULN_BASH, TRUE }, + { "pierce", VULN_PIERCE, TRUE }, + { "slash", VULN_SLASH, TRUE }, + { "fire", VULN_FIRE, TRUE }, + { "cold", VULN_COLD, TRUE }, + { "lightning", VULN_LIGHTNING, TRUE }, + { "acid", VULN_ACID, TRUE }, + { "poison", VULN_POISON, TRUE }, + { "negative", VULN_NEGATIVE, TRUE }, + { "holy", VULN_HOLY, TRUE }, + { "energy", VULN_ENERGY, TRUE }, + { "mental", VULN_MENTAL, TRUE }, + { "disease", VULN_DISEASE, TRUE }, + { "drowning", VULN_DROWNING, TRUE }, + { "light", VULN_LIGHT, TRUE }, + { "sound", VULN_SOUND, TRUE }, + { "wood", VULN_WOOD, TRUE }, + { "silver", VULN_SILVER, TRUE }, + { "iron", VULN_IRON, TRUE }, + { NULL, 0, 0 } +}; + +const struct flag_type position_flags[] = +{ + { "dead", POS_DEAD, FALSE }, + { "mortal", POS_MORTAL, FALSE }, + { "incap", POS_INCAP, FALSE }, + { "stunned", POS_STUNNED, FALSE }, + { "sleeping", POS_SLEEPING, TRUE }, + { "resting", POS_RESTING, TRUE }, + { "sitting", POS_SITTING, TRUE }, + { "fighting", POS_FIGHTING, FALSE }, + { "standing", POS_STANDING, TRUE }, + { NULL, 0, 0 } +}; + +const struct flag_type portal_flags[]= +{ + { "normal_exit", GATE_NORMAL_EXIT, TRUE }, + { "no_curse", GATE_NOCURSE, TRUE }, + { "go_with", GATE_GOWITH, TRUE }, + { "buggy", GATE_BUGGY, TRUE }, + { "random", GATE_RANDOM, TRUE }, + { NULL, 0, 0 } +}; + +const struct flag_type furniture_flags[]= +{ + { "stand_at", STAND_AT, TRUE }, + { "stand_on", STAND_ON, TRUE }, + { "stand_in", STAND_IN, TRUE }, + { "sit_at", SIT_AT, TRUE }, + { "sit_on", SIT_ON, TRUE }, + { "sit_in", SIT_IN, TRUE }, + { "rest_at", REST_AT, TRUE }, + { "rest_on", REST_ON, TRUE }, + { "rest_in", REST_IN, TRUE }, + { "sleep_at", SLEEP_AT, TRUE }, + { "sleep_on", SLEEP_ON, TRUE }, + { "sleep_in", SLEEP_IN, TRUE }, + { "put_at", PUT_AT, TRUE }, + { "put_on", PUT_ON, TRUE }, + { "put_in", PUT_IN, TRUE }, + { "put_inside", PUT_INSIDE, TRUE }, + { NULL, 0, 0 } +}; + +const struct flag_type apply_types [] = +{ + { "affects", TO_AFFECTS, TRUE }, + { "object", TO_OBJECT, TRUE }, + { "immune", TO_IMMUNE, TRUE }, + { "resist", TO_RESIST, TRUE }, + { "vuln", TO_VULN, TRUE }, + { "weapon", TO_WEAPON, TRUE }, + { NULL, 0, TRUE } +}; + +const struct bit_type bitvector_type [] = +{ + { affect_flags, "affect" }, + { apply_flags, "apply" }, + { imm_flags, "imm" }, + { res_flags, "res" }, + { vuln_flags, "vuln" }, + { weapon_type2, "weapon" } +}; int flag_lookup( const char *name, const struct flag_type *flag_table ) { @@ -316,7 +317,7 @@ return flag_table[flag].bit; } - return 0; + return NO_FLAG; } void do_flag( CHAR_DATA *ch, const char *argument ) @@ -493,7 +493,8 @@ break; pos = flag_lookup( word, flag_table ); - if ( pos == 0 ) + + if (pos == NO_FLAG) { ch_printf( ch, "That flag doesn't exist!\r\n" ); return; @@ -583,4 +584,81 @@ } return -1; +} + +/* returns race number */ +int race_lookup (const char *name) +{ + int race; + + for ( race = 0; race_table[race].name != NULL; race++) + { + if (LOWER(name[0]) == LOWER(race_table[race].name[0]) + && !str_prefix( name,race_table[race].name)) + return race; + } + + return 0; +} + +int item_lookup(const char *name) +{ + int type; + + for (type = 0; item_table[type].name != NULL; type++) + { + if (LOWER(name[0]) == LOWER(item_table[type].name[0]) + && !str_prefix(name,item_table[type].name)) + return item_table[type].type; + } + + return -1; +} + +int liq_lookup (const char *name) +{ + int liq; + + for ( liq = 0; liq_table[liq].liq_name != NULL; liq++) + { + if (LOWER(name[0]) == LOWER(liq_table[liq].liq_name[0]) + && !str_prefix(name,liq_table[liq].liq_name)) + return liq; + } + + return -1; +} + +HELP_DATA * help_lookup( const char *keyword ) +{ + HELP_DATA *pHelp; + char temp[MAX_INPUT_LENGTH], argall[MAX_INPUT_LENGTH]; + + argall[0] = '\0'; + + while (keyword[0] != '\0' ) + { + keyword = one_argument(keyword, temp); + if (argall[0] != '\0') + strcat(argall," "); + strcat(argall, temp); + } + + for ( pHelp = help_first; pHelp != NULL; pHelp = pHelp->next ) + if ( is_name( argall, pHelp->keyword ) ) + return pHelp; + + return NULL; +} + +HELP_AREA * had_lookup( const char *arg ) +{ + HELP_AREA * temp; + extern HELP_AREA * had_list; + + for ( temp = had_list; temp; temp = temp->next ) + if ( !str_cmp( arg, temp->filename ) ) + return temp; + + return NULL; } diff -ur old/tables.h new/tables.h --- old/tables.h Mon Sep 14 17:46:16 1998 +++ new/tables.h Mon Sep 14 17:46:53 1998 @@ -59,6 +80,12 @@ const char *name; }; +struct bit_type +{ + const struct flag_type *table; + const char *help; +}; + /* game tables */ extern const struct clan_type clan_table[MAX_CLAN]; extern const struct position_type position_table[]; @@ -67,16 +67,37 @@ extern const struct flag_type comm_flags[]; /* These appear to not be implemented, yet. */ -/* extern const struct flag_type extra_flags[]; extern const struct flag_type wear_flags[]; extern const struct flag_type weapon_flags[]; extern const struct flag_type container_flags[]; extern const struct flag_type portal_flags[]; extern const struct flag_type room_flags[]; extern const struct flag_type exit_flags[]; -*/ +/* OLC */ +extern const struct flag_type mprog_flags[]; +extern const struct flag_type area_flags[]; +extern const struct flag_type sector_flags[]; +extern const struct flag_type door_resets[]; +extern const struct flag_type wear_loc_strings[]; +extern const struct flag_type wear_loc_flags[]; +extern const struct flag_type res_flags[]; +extern const struct flag_type imm_flags[]; +extern const struct flag_type vuln_flags[]; +extern const struct flag_type type_flags[]; +extern const struct flag_type apply_flags[]; +extern const struct flag_type sex_flags[]; +extern const struct flag_type furniture_flags[]; +extern const struct flag_type weapon_class[]; +extern const struct flag_type apply_types[]; +extern const struct flag_type weapon_type2[]; +extern const struct flag_type apply_types[]; +extern const struct flag_type size_flags[]; +extern const struct flag_type position_flags[]; +extern const struct flag_type ac_type[]; +extern const struct bit_type bitvector_type[]; + int flag_lookup( const char *name, const struct flag_type *flag_table ); int clan_lookup( const char *name ); @@ -89,3 +110,8 @@ int position_lookup( const char *name ); int sex_lookup( const char *name ); int size_lookup( const char *name ); +HELP_DATA* help_lookup( const char * ); +HELP_AREA* had_lookup( const char * ); +int race_lookup( const char *name ); +int item_lookup( const char *name ); +int liq_lookup( const char *name ); diff -ur old/update.c new/update.c --- old/update.c Mon Sep 14 17:46:16 1998 +++ new/update.c Mon Sep 14 17:46:53 1998 @@ -403,6 +403,28 @@ ch->silver += ch->pIndexData->wealth * number_range( 1, 20 ) / 50000; } + /* + * Check triggers only if mobile still in default position + */ + if ( ch->position == ch->pIndexData->default_pos ) + { + /* Delay */ + if ( HAS_TRIGGER( ch, TRIG_DELAY) + && ch->mprog_delay > 0 ) + { + if ( --ch->mprog_delay <= 0 ) + { + mp_percent_trigger( ch, NULL, NULL, NULL, TRIG_DELAY ); + continue; + } + } + if ( HAS_TRIGGER( ch, TRIG_RANDOM) ) + { + if( mp_percent_trigger( ch, NULL, NULL, NULL, TRIG_RANDOM ) ) + continue; + } + } + /* * That's all for sleeping / busy monster, and empty zones */