/*************************************************************************** * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. * * * * Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * * * In order to use any part of this Merc Diku Mud, you must comply with * * both the original Diku license in 'license.doc' as well the Merc * * license in 'license.txt'. 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. * ***************************************************************************/ /*************************************************************************** * ROM 2.4 is copyright 1993-1995 Russ Taylor * * ROM has been brought to you by the ROM consortium * * Russ Taylor (rtaylor@pacinfo.com) * * Gabrielle Taylor (gtaylor@pacinfo.com) * * Brian Moore (rom@rom.efn.org) * * By using this code, you have agreed to follow the terms of the * * ROM license, in the file 'rom.license' * ***************************************************************************/ /*************************************************************************** * ROT 2.0 is copyright 1996-1999 by Russ Walsh * * By using this code, you have agreed to follow the terms of the * * ROT license, in the file 'rot.license' * ***************************************************************************/ #include <sys/types.h> #include <ctype.h> #include <errno.h> #include <stdio.h> #include <signal.h> #include <string.h> #include <stdlib.h> #include <time.h> #include <stdarg.h> #include "merc.h" #include "interp.h" #include "tables.h" #include "lookup.h" #include "magic.h" #include "recycle.h" DEITY_DATA *first_deity; DEITY_DATA *last_deity; /* Local Routines */ void fread_deity args ( ( DEITY_DATA *deity, FILE *fp ) ); bool load_deity args ( ( char *deity_file ) ); DEITY_DATA *get_deity( char *name ) { DEITY_DATA *deity; deity = first_deity; while (deity) { if ( !str_cmp( name, deity->name ) ) return deity; else deity = deity->next; } return NULL; } void do_mod_favor( CHAR_DATA *ch, int mod_type ) { if( IS_NPC( ch ) || !ch->pcdata->deity ) return; /* if( ( ch->alignment - ch->pcdata->deity->alignment > 750 || ch->alignment - ch->pcdata->deity->alignment < 750 ) && ch->pcdata->deity->alignment != 0 ) { ch->pcdata->favor -= 5; ch->pcdata->favor = URANGE( -2500, ch->pcdata->favor, 2500 ); return; } */ switch( mod_type ) { case 0: ch->pcdata->favor += ch->pcdata->deity->steal; break; case 1: ch->pcdata->favor += ch->pcdata->deity->backstab; break; case 2: ch->pcdata->favor += ch->pcdata->deity->flee; break; case 3: ch->pcdata->favor += ch->pcdata->deity->sacrifice; break; case 4: ch->pcdata->favor += ch->pcdata->deity->death; break; case 5: ch->pcdata->favor += ch->pcdata->deity->pkill; break; case 6: ch->pcdata->favor += ch->pcdata->deity->aid; break; case 7: ch->pcdata->favor += ch->pcdata->deity->spell_aid; break; case 8: ch->pcdata->favor += ch->pcdata->deity->spell_harm; break; case 9: ch->pcdata->favor += ch->pcdata->deity->kill_race; break; } ch->pcdata->favor = URANGE( -2500, ch->pcdata->favor, 2500 ); return; } #if defined (KEY) #undef KEY #endif #define KEY( literal, field, value ) \ if ( !str_cmp( word, literal ) ) \ { \ field = value; \ fMatch = TRUE; \ break; \ } void fread_deity( DEITY_DATA *deity, FILE *fp ) { char buf[MSL]; char *word; bool fMatch; for ( ; ; ) { word = feof( fp ) ? "End" : fread_word( fp ); fMatch = FALSE; switch ( UPPER( word[0] ) ) { case '*': fMatch = TRUE; fread_to_eol( fp ); break; case 'A': KEY( "Aid", deity->aid, fread_number( fp ) ); KEY( "Align", deity->alignment, fread_number( fp ) ); KEY( "AfBy", deity->affected_by, fread_flag( fp ) ); break; case 'B': KEY( "Backstab", deity->backstab, fread_number( fp ) ); break; case 'C': KEY( "Class", deity->class, fread_number( fp ) ); KEY( "Cobj", deity->cost_obj, fread_number( fp ) ); KEY( "Ccorpse", deity->cost_corpse, fread_number( fp ) ); KEY( "Cavatar", deity->cost_avatar, fread_number( fp ) ); KEY( "Crecall", deity->cost_recall, fread_number( fp ) ); break; case 'D': KEY( "Death", deity->death, fread_number( fp ) ); KEY( "Desc", deity->desc, fread_string( fp ) ); break; case 'E': if ( !str_cmp( word, "End" ) ) { if ( !deity->name ) deity->name = " "; if ( !deity->desc ) deity->desc = " "; return; } break; case 'F': KEY( "Filename", deity->filename, fread_string( fp ) ); KEY( "Flee", deity->flee, fread_number( fp ) ); break; case 'I': KEY( "Immune", deity->immune, fread_flag( fp ) ); break; case 'K': KEY( "KillRace", deity->kill_race, fread_number( fp ) ); break; case 'N': KEY( "Name", deity->name, fread_string( fp ) ); break; case 'P': KEY( "Pkill", deity->pkill, fread_number( fp ) ); break; case 'R': KEY( "Race", deity->race, fread_number( fp ) ); KEY( "Resist", deity->resist, fread_flag( fp ) ); break; case 'S': KEY( "Sex", deity->sex, fread_number( fp ) ); KEY( "Sacrifice", deity->sacrifice, fread_number( fp ) ); KEY( "ShBy", deity->shielded_by, fread_flag( fp ) ); KEY( "Steal", deity->steal, fread_number( fp ) ); KEY( "SpellAid", deity->spell_aid, fread_number( fp ) ); KEY( "SpellHarm", deity->spell_harm, fread_number( fp ) ); break; case 'V': KEY( "Vuln", deity->vuln, fread_flag( fp ) ); KEY( "Vobj", deity->vnum_obj, fread_number( fp ) ); KEY( "Vava", deity->vnum_avatar, fread_number( fp ) ); break; case 'W': KEY( "Worship", deity->worshippers, fread_number( fp ) ); break; } if( deity->name ) smash_tilde( deity->name ); if ( !fMatch ) { sprintf( buf, "fread_deity: no match %s", word ); bug( buf, 0 ); } } } bool load_deity( char *deity_file ) { char filename[256]; DEITY_DATA *deity; FILE *fp; bool found = FALSE; sprintf( filename, "%s%s", DEITY_DIR, deity_file ); fp = fopen( filename, "r" ); if ( fp ) { for ( ; ; ) { char letter; char *word; letter = fread_letter( fp ); if ( letter == '*' ) { fread_to_eol( fp ); continue; } if ( letter != '#' ) { bug( "load_deity: # not found.", 0 ); break; } word = fread_word( fp ); if ( !str_cmp( word, "DEITY" ) ) { deity = alloc_perm( sizeof(*deity) ); fread_deity( deity, fp ); if ( !first_deity ) { first_deity = deity; last_deity = deity; } else { last_deity->next = deity; deity->prev = last_deity; last_deity = deity; } found = TRUE; break; } else { char buf[MSL]; sprintf( buf, "load_deity: bad line %s", word); bug( buf, 0 ); break; } } fclose( fp ); } return found; } void boot_deities( ) { FILE *fpDeityList; char *filename; char deitylist[256]; char buf[MSL]; first_deity = NULL; last_deity = NULL; log_string( "Booting Deities.." ); sprintf( deitylist, "%s%s", DEITY_DIR, DEITY_FILE ); fpDeityList = fopen( deitylist, "r" ); if ( !fpDeityList ) { perror( deitylist ); exit( 1 ); } for ( ; ; ) { filename = feof( fpDeityList) ? "$" : fread_word( fpDeityList ); if ( filename[0] == '$' ) break; log_string( filename ); if ( !load_deity( filename ) ) { sprintf( buf, "Cannot load deity file: %s", filename ); bug( buf, 0 ); } } fclose( fpDeityList ); log_string( "Done Loading Deities " ); return; } void save_deity( DEITY_DATA *deity ) { FILE *fp; char filename[256]; char buf[MSL]; if ( !deity ) { bug( "save_deity: null deity pointer!", 0 ); return; } if( !deity->filename || deity->filename[0] == '\0' ) { sprintf( buf, "save_deity: %s has no filename", deity->name ); bug( buf, 0 ); return; } sprintf( filename, "%s%s", DEITY_DIR, deity->filename ); fclose( fpReserve ); fp = fopen( filename, "w" ); if ( !fp ) { bug( "save_deity: Opening Data File", 0 ); perror( filename ); } else { fprintf( fp, "#DEITY\n" ); fprintf( fp, "Filename %s~\n", deity->filename ); fprintf( fp, "Name %s~\n", deity->name ); fprintf( fp, "Desc %s~\n", deity->desc ); fprintf( fp, "Vuln %s\n", print_flags( deity->vuln )); fprintf( fp, "Resist %s\n", print_flags( deity->resist )); fprintf( fp, "Immune %s\n", print_flags( deity->immune )); fprintf( fp, "AfBy %s\n", print_flags( deity->affected_by ) ); fprintf( fp, "ShBy %s\n", print_flags( deity->shielded_by ) ); fprintf( fp, "Sex %d\n", deity->sex ); fprintf( fp, "Class %d\n", deity->class ); fprintf( fp, "Race %d\n", deity->race ); fprintf( fp, "Death %d\n", deity->death ); fprintf( fp, "Worship %d\n", deity->worshippers ); fprintf( fp, "Vobj %d\n", deity->vnum_obj ); fprintf( fp, "Vava %d\n", deity->vnum_avatar ); fprintf( fp, "Cobj %d\n", deity->cost_obj ); fprintf( fp, "Ccorpse %d\n", deity->cost_corpse ); fprintf( fp, "Cavatar %d\n", deity->cost_avatar ); fprintf( fp, "Crecall %d\n", deity->cost_recall ); fprintf( fp, "Align %d\n", deity->alignment ); fprintf( fp, "Steal %d\n", deity->steal ); fprintf( fp, "Backstab %d\n", deity->backstab ); fprintf( fp, "Flee %d\n", deity->flee ); fprintf( fp, "Sacrifice %d\n", deity->sacrifice ); fprintf( fp, "Death %d\n", deity->death ); fprintf( fp, "Aid %d\n", deity->aid ); fprintf( fp, "Pkill %d\n", deity->pkill ); fprintf( fp, "SpellAid %d\n", deity->spell_aid ); fprintf( fp, "SpellHarm %d\n", deity->spell_harm ); fprintf( fp, "KillRace %d\n", deity->kill_race ); fprintf( fp, "End\n" ); fclose( fp ); } fpReserve = fopen ( NULL_FILE, "r" ); return; } void do_deities( CHAR_DATA *ch, char *argument ) { DEITY_DATA *deity; int count = 0; char buf[MSL]; char buf2[MSL]; if ( argument[0] == '\0' ) { send_to_char ( "For specific information on a specific deity use the command: deities <deity>\n\r", ch ); send_to_char ( "\n\rDeity Worshippers\n\r", ch ); for ( deity = first_deity; deity; deity = deity->next ) { sprintf( buf, "%s %d\n\r", deity->name, deity->worshippers ); send_to_char( buf, ch ); count++; } if ( !count ) { send_to_char( "No deities exist on this world!\n\r", ch ); return; } return; } deity = get_deity( argument ); if ( !deity ) { send_to_char( "That deity does not exist!", ch ); return; } sprintf( buf2, "Deity: %s\n\rDescription:\n\r%s", deity->name, deity->desc ); send_to_char( buf2, ch ); return; } void do_devote( CHAR_DATA *ch, char *argument ) { char arg[MIL]; DEITY_DATA *deity; if ( IS_NPC( ch ) ) { send_to_char( "Huh?\n\r", ch ); return; } if ( ch->level < 10 ) { send_to_char( "You are not yet prepared for such devotion.\n\r", ch ); return; } argument = one_argument( argument, arg ); if ( arg[0] == '\0' ) { send_to_char( "Devote yourself to which deity?\n\r", ch ); return; } if ( !str_cmp( arg, "none" ) ) { AFFECT_DATA af; if ( !ch->pcdata->deity ) { send_to_char( "You have already chosen to worhsip no deity.\n\r", ch ); return; } --ch->pcdata->deity->worshippers; ch->pcdata->favor = -1000; send_to_char ( "A terrible curse afflicts you as you forsake your deity!\n\r", ch ); if ( IS_SET( ch->affected_by, ch->pcdata->deity->affected_by ) ) { REMOVE_BIT( ch->affected_by, ch->pcdata->deity->affected_by ); } if ( IS_SET( ch->shielded_by, ch->pcdata->deity->shielded_by ) ) { REMOVE_BIT( ch->shielded_by, ch->pcdata->deity->shielded_by ); } if ( IS_SET ( ch->res_flags, ch->pcdata->deity->resist ) ) { REMOVE_BIT( ch->res_flags, ch->pcdata->deity->resist ); } if ( IS_SET ( ch->vuln_flags, ch->pcdata->deity->vuln ) ) { REMOVE_BIT( ch->vuln_flags, ch->pcdata->deity->vuln ); } if ( IS_AFFECTED( ch, gsn_blindness ) ) affect_strip( ch, gsn_blindness ); af.type = gsn_blindness; af.location = APPLY_HITROLL; af.modifier = -4; af.duration = 125; af.bitvector = AFF_BLIND; affect_to_char( ch, &af ); save_deity( ch->pcdata->deity ); send_to_char ( "You cease to worship any deity.\n\r", ch ); ch->pcdata->deity = NULL; save_char_obj( ch ); return; } deity = get_deity( arg ); if( !deity ) { send_to_char( "No such deity exists.\n\r", ch ); return; } if( ch->pcdata->deity ) { send_to_char( "You are already devoted to a deity.\n\r", ch ); return; } if( ( deity->class != -1 ) && ( deity->class != ch->class ) ) { if (ch->pcdata->tier != 2) { send_to_char( "That deity does not accept worshippers of your class.\n\r", ch ); return; } else if ( deity->class != ch->clasb ) { send_to_char( "That deity does not accept worshippers of either of your classes.\n\r", ch ); return; } } if ( ( deity->race != -1 ) && ( deity->race != ch->race ) ) { send_to_char( "That deity does not accept worshippers of your race.\n\r", ch ); return; } ch->pcdata->deity = deity; ch->pcdata->deity_name = deity->name; if ( !IS_SET( ch->affected_by, ch->pcdata->deity->affected_by ) ) { SET_BIT( ch->affected_by, ch->pcdata->deity->affected_by ); } if ( !IS_SET( ch->shielded_by, ch->pcdata->deity->shielded_by ) ) { SET_BIT( ch->shielded_by, ch->pcdata->deity->shielded_by ); } if ( !IS_SET( ch->res_flags, ch->pcdata->deity->resist ) ) { SET_BIT( ch->res_flags, ch->pcdata->deity->resist ); } if ( !IS_SET( ch->vuln_flags, ch->pcdata->deity->vuln ) ) { SET_BIT( ch->vuln_flags, ch->pcdata->deity->vuln ); } act( "Body and Soul, you devote yourself to $t", ch, ch->pcdata->deity->name, NULL, TO_CHAR ); ++ch->pcdata->deity->worshippers; save_deity( ch->pcdata->deity ); save_char_obj( ch ); return; } void do_supplicate( CHAR_DATA *ch, char *argument ) { char arg[MIL]; one_argument( argument, arg ); if( IS_NPC(ch) || !ch->pcdata->deity ) { send_to_char( "You have no deity to supplicate to.\n\r", ch ); return; } if( arg[0] == '\0' ) { send_to_char( "Supplicate for what?\n\r", ch ); return; } if ( !str_cmp( arg, "corpse" ) ) { char buf2[MSL]; char buf3[MSL]; OBJ_DATA *obj; bool found; if( ch->pcdata->favor < ch->pcdata->deity->cost_corpse ) { send_to_char( "You are not favored enough for a corpse retrieval.\n\r", ch ); return; } found = FALSE; sprintf( buf3, " " ); sprintf( buf2, "the corpse of %s", ch->name ); for ( obj = object_list; obj; obj = obj->next ) { if( obj->in_room && !str_cmp( buf2 , obj->short_descr ) && ( (int) obj->pIndexData->vnum == 11 ) ) { found = TRUE; obj_from_room(obj); obj_to_room( obj, ch->in_room ); ch->pcdata->favor -= ch->pcdata->deity->cost_corpse; } } if ( !found ) { send_to_char( "No corpse of yours litters the world...\n\r", ch ); return; } return; } if ( !str_cmp( arg, "avatar" ) ) { MOB_INDEX_DATA *pMobIndex; CHAR_DATA *victim; if ( ch->pcdata->favor < ch->pcdata->deity->cost_avatar) { send_to_char( "You are not favored enough for an Avatar.\n\r", ch ); return; } if ( ch->pcdata->deity->vnum_avatar < 1 ) { send_to_char( "Your deity does not have an Avatar to summon.\n\r", ch ); return; } pMobIndex = get_mob_index( ch->pcdata->deity->vnum_avatar ); victim = create_mobile( pMobIndex ); char_to_room( victim, ch->in_room ); victim->master = ch; victim->leader = ch; SET_BIT( victim->act, ACT_PET ); ch->pet = victim; add_follower( victim, ch ); ch->pcdata->favor -= ch->pcdata->deity->cost_avatar; return; } if ( !str_cmp( arg, "object" ) ) { OBJ_DATA *obj; OBJ_INDEX_DATA *pObjIndex; if ( ch->pcdata->favor < ch->pcdata->deity->cost_obj ) { send_to_char( "You are not favored enough for that.\n\r", ch ); return; } if ( ch->pcdata->deity->vnum_obj < 1 ) { send_to_char( "Your deity does not have a sigil of worship.\n\r", ch ); return; } pObjIndex = get_obj_index( ch->pcdata->deity->vnum_obj ); obj = create_object( pObjIndex, ch->level ); if ( CAN_WEAR( obj, ITEM_TAKE ) ) obj_to_char( obj, ch ); else obj_to_room( obj, ch->in_room ); act("$n weaves $p from divine matter!", ch, obj, NULL, TO_ROOM); act("You weave $p from divine matter!", ch, obj, NULL, TO_CHAR); ch->pcdata->favor -= ch->pcdata->deity->cost_obj; return; } if ( !str_cmp( arg, "recall" ) ) { ROOM_INDEX_DATA *location; if ( ch->pcdata->favor < ch->pcdata->deity->cost_recall ) { send_to_char( "You do not have enough favor for such a supplication.\n\r", ch ); return; } location = NULL; if ( IS_NPC( ch ) ) return; if ( ch->alignment < 0 ) { if ( ( location = get_room_index( ROOM_VNUM_TEMPLEB ) ) == NULL ) { send_to_char( "You are completely lost.\n\r", ch ); return; } } else { if ( ( location = get_room_index( ROOM_VNUM_TEMPLE ) ) == NULL ) { send_to_char( "You are completely lost.\n\r", ch ); return; } } if ( ch->in_room == location ) return; if ( is_clan(ch) ) location = get_room_index( clan_table[ch->clan].hall ); if ( !location ) { send_to_char( "You are completely lost.\n\r", ch ); return; } act("$n disappears in a column of divine power.", ch, NULL, NULL, TO_ROOM ); char_from_room( ch ); char_to_room( ch, location ); if ( ch->pet ) { char_from_room( ch->pet ); char_to_room( ch->pet, location ); } act("$n appears in the room from a column of divine mist.", ch, NULL, NULL, TO_ROOM ); do_look( ch, "auto" ); ch->pcdata->favor -= ch->pcdata->deity->cost_recall; return; } send_to_char( "You cannot supplicate for that.\n\r", ch ); return; }