/***************************************************************************** * DikuMUD (C) 1990, 1991 by: * * Sebastian Hammer, Michael Seifert, Hans Henrik Staefeldt, Tom Madsen, * * and Katja Nyboe. * *---------------------------------------------------------------------------* * MERC 2.1 (C) 1992, 1993 by: * * Michael Chastain, Michael Quan, and Mitchell Tse. * *---------------------------------------------------------------------------* * SMAUG 1.4 (C) 1994, 1995, 1996, 1998 by: Derek Snider. * * Team: Thoric, Altrag, Blodkai, Narn, Haus, Scryn, Rennard, Swordbearer, * * gorog, Grishnakh, Nivek, Tricops, and Fireblade. * *---------------------------------------------------------------------------* * SMAUG 1.7 FUSS by: Samson and others of the SMAUG community. * * Their contributions are greatly appreciated. * *---------------------------------------------------------------------------* * LoP (C) 2006, 2007, 2008 by: the LoP team. * *---------------------------------------------------------------------------* * Special clan module * *****************************************************************************/ #include <ctype.h> #include <stdio.h> #include "h/mud.h" static OBJ_DATA *rgObjNest[MAX_NEST]; CLAN_DATA *first_clan, *last_clan; COUNCIL_DATA *first_council, *last_council; int get_pc_class( char *Class ); int get_pc_race( char *type ); /* local routines */ void fread_clan( CLAN_DATA *clan, FILE *fp ); void write_clan_list( void ); void fread_council( COUNCIL_DATA *council, FILE *fp ); void write_council_list( void ); void free_member( MEMBER_DATA *member ) { if( !member ) return; STRFREE( member->name ); DISPOSE( member ); } void free_clan_members( CLAN_DATA *clan ) { MEMBER_DATA *member, *member_next; if( !clan ) return; for( member = clan->first_member; member; member = member_next ) { member_next = member->next; UNLINK( member, clan->first_member, clan->last_member, next, prev ); free_member( member ); } } bool is_clan_member( CLAN_DATA *clan, char *name ) { MEMBER_DATA *member; if( !clan || !name || name[0] == '\0' ) return false; for( member = clan->first_member; member; member = member->next ) { if( !str_cmp( member->name, name ) ) return true; } return false; } bool remove_clan_member( CLAN_DATA *clan, char *name ) { MEMBER_DATA *member; if( !clan || !name || name[0] == '\0' ) return false; for( member = clan->first_member; member; member = member->next ) { if( !str_cmp( member->name, name ) ) { if( !str_cmp( name, clan->leader ) ) STRFREE( clan->leader ); if( !str_cmp( name, clan->number1 ) ) STRFREE( clan->number1 ); if( !str_cmp( name, clan->number2 ) ) STRFREE( clan->number2 ); UNLINK( member, clan->first_member, clan->last_member, next, prev ); free_member( member ); if( --clan->members < 0 ) clan->members = 0; return true; } } return false; } void add_clan_member( CLAN_DATA *clan, char *name ) { MEMBER_DATA *member; if( !clan || !name || name[0] == '\0' ) return; if( is_clan_member( clan, name ) ) return; CREATE( member, MEMBER_DATA, 1 ); member->name = STRALLOC( name ); LINK( member, clan->first_member, clan->last_member, next, prev ); if( ( clan->members + 1 ) > 0 ) clan->members++; } void free_one_clan( CLAN_DATA *clan ) { if( !clan ) return; free_clan_members( clan ); UNLINK( clan, first_clan, last_clan, next, prev ); STRFREE( clan->filename ); STRFREE( clan->name ); STRFREE( clan->motto ); STRFREE( clan->description ); STRFREE( clan->leader ); STRFREE( clan->number1 ); STRFREE( clan->number2 ); STRFREE( clan->leadrank ); STRFREE( clan->onerank ); STRFREE( clan->tworank ); STRFREE( clan->badge ); DISPOSE( clan ); } void free_clans( void ) { CLAN_DATA *clan, *clan_next; for( clan = first_clan; clan; clan = clan_next ) { clan_next = clan->next; free_one_clan( clan ); } } /* Get pointer to clan structure from clan name. */ CLAN_DATA *get_clan( char *name ) { CLAN_DATA *clan; for( clan = first_clan; clan; clan = clan->next ) if( clan->name && name && !str_cmp( name, clan->name ) ) return clan; return NULL; } void write_clan_list( void ) { CLAN_DATA *tclan; FILE *fp; if( !( fp = fopen( CLAN_LIST, "w" ) ) ) { bug( "%s: can't open %s for writing!", __FUNCTION__, CLAN_LIST ); return; } for( tclan = first_clan; tclan; tclan = tclan->next ) fprintf( fp, "%s\n", tclan->filename ); fprintf( fp, "$\n" ); fclose( fp ); fp = NULL; } /* Save a clan's data to its data file */ void save_clan( CLAN_DATA *clan ) { FILE *fp; char filename[256]; MEMBER_DATA *member; if( !clan ) { bug( "%s: NULL clan", __FUNCTION__ ); return; } if( !clan->name ) { bug( "%s: NULL clan->name", __FUNCTION__ ); return; } if( !clan->filename ) { bug( "%s: %s NULL filename", __FUNCTION__, clan->name ); return; } snprintf( filename, sizeof( filename ), "%s%s", CLAN_DIR, clan->filename ); if( !( fp = fopen( filename, "w" ) ) ) { perror( filename ); return; } fprintf( fp, "Name %s~\n", clan->name ); fprintf( fp, "Filename %s~\n", clan->filename ); if( clan->motto ) fprintf( fp, "Motto %s~\n", clan->motto ); if( clan->description ) fprintf( fp, "Description %s~\n", clan->description ); if( clan->leader ) { fprintf( fp, "Leader %s~\n", clan->leader ); if( clan->leadrank ) fprintf( fp, "Leadrank %s~\n", clan->leadrank ); } if( clan->number1 ) { fprintf( fp, "NumberOne %s~\n", clan->number1 ); if( clan->onerank ) fprintf( fp, "Onerank %s~\n", clan->onerank ); } if( clan->number2 ) { fprintf( fp, "NumberTwo %s~\n", clan->number2 ); if( clan->tworank ) fprintf( fp, "Tworank %s~\n", clan->tworank ); } if( clan->badge ) fprintf( fp, "Badge %s~\n", clan->badge ); if( clan->clan_type ) fprintf( fp, "Type %d\n", clan->clan_type ); if( clan->race ) fprintf( fp, "Race %d\n", clan->race ); for( member = clan->first_member; member; member = member->next ) fprintf( fp, "Member %s~\n", member->name ); if( clan->recall ) fprintf( fp, "Recall %d\n", clan->recall ); if( clan->storeroom ) fprintf( fp, "Storeroom %d\n", clan->storeroom ); fprintf( fp, "End\n\n" ); fclose( fp ); fp = NULL; } /* Read in actual clan data. */ CLAN_DATA *fread_clan( FILE *fp ) { CLAN_DATA *clan = NULL; const char *word; bool fMatch; CREATE( clan, CLAN_DATA, 1 ); if( !clan ) return NULL; clan->first_member = NULL; clan->last_member = NULL; clan->members = 0; for( ;; ) { word = feof( fp ) ? "End" : fread_word( fp ); fMatch = false; switch( UPPER( word[0] ) ) { case '*': fMatch = true; fread_to_eol( fp ); break; case 'B': KEY( "Badge", clan->badge, fread_string( fp ) ); break; case 'D': KEY( "Description", clan->description, fread_string( fp ) ); break; case 'E': if( !str_cmp( word, "End" ) ) return clan; break; case 'F': KEY( "Filename", clan->filename, fread_string( fp ) ); break; case 'L': KEY( "Leader", clan->leader, fread_string( fp ) ); KEY( "Leadrank", clan->leadrank, fread_string( fp ) ); break; case 'M': if( !str_cmp( word, "Member" ) ) { char *name = fread_flagstring( fp ); if( valid_pfile( name ) ) add_clan_member( clan, name ); else bug( "%s: not adding member %s because no pfile found.", __FUNCTION__, name ); fMatch = true; break; } KEY( "Motto", clan->motto, fread_string( fp ) ); break; case 'N': KEY( "Name", clan->name, fread_string( fp ) ); KEY( "NumberOne", clan->number1, fread_string( fp ) ); KEY( "NumberTwo", clan->number2, fread_string( fp ) ); break; case 'O': KEY( "Onerank", clan->onerank, fread_string( fp ) ); break; case 'R': KEY( "Recall", clan->recall, fread_number( fp ) ); KEY( "Race", clan->race, fread_number( fp ) ); break; case 'S': KEY( "Storeroom", clan->storeroom, fread_number( fp ) ); break; case 'T': KEY( "Tworank", clan->tworank, fread_string( fp ) ); KEY( "Type", clan->clan_type, fread_number( fp ) ); break; } if( !fMatch ) { bug( "%s: no match: %s", __FUNCTION__, word ); fread_to_eol( fp ); } } /* Made it here? Then lets free the clan and return NULL */ free_one_clan( clan ); return NULL; } /* Load a clan file */ void load_clan_file( const char *clanfile ) { char filename[256]; CLAN_DATA *clan; FILE *fp; ROOM_INDEX_DATA *storeroom; int iNest; OBJ_DATA *tobj, *tobj_next; snprintf( filename, sizeof( filename ), "%s%s", CLAN_DIR, clanfile ); if( !( fp = fopen( filename, "r" ) ) ) { perror( filename ); return; } clan = fread_clan( fp ); fclose( fp ); fp = NULL; if( !clan ) return; LINK( clan, first_clan, last_clan, next, prev ); if( clan->storeroom == 0 || !( storeroom = get_room_index( clan->storeroom ) ) ) { log_string( "Storeroom not found" ); return; } snprintf( filename, sizeof( filename ), "%s%s.vault", CLAN_DIR, clan->filename ); if( !( fp = fopen( filename, "r" ) ) ) { perror( filename ); return; } log_string( "Loading clan storage room" ); rset_supermob( storeroom ); for( iNest = 0; iNest < MAX_NEST; iNest++ ) rgObjNest[iNest] = NULL; for( ;; ) { char letter; char *word; letter = fread_letter( fp ); if( letter == '*' ) { fread_to_eol( fp ); continue; } if( letter != '#' ) { bug( "%s: # not found for %s.", __FUNCTION__, clan->name ); break; } word = fread_word( fp ); if( !str_cmp( word, "OBJECT" ) ) /* Objects */ fread_obj( supermob, NULL, fp, OS_CARRY ); else if( !str_cmp( word, "END" ) ) /* Done */ break; else { bug( "%s: bad section (%s) for %s.", __FUNCTION__, word, clan->name ); break; } } fclose( fp ); fp = NULL; for( tobj = supermob->first_carrying; tobj; tobj = tobj_next ) { tobj_next = tobj->next_content; obj_from_char( tobj ); obj_to_room( tobj, storeroom ); } release_supermob( ); } /* Load in all the clan files. */ void load_clans( void ) { FILE *fp; const char *filename; first_clan = last_clan = NULL; log_string( "Loading clans..." ); if( !( fp = fopen( CLAN_LIST, "r" ) ) ) { perror( CLAN_LIST ); return; } for( ;; ) { filename = feof( fp ) ? "$" : fread_word( fp ); if( !filename || filename[0] == '\0' || filename[0] == '$' ) break; log_string( filename ); load_clan_file( filename ); } fclose( fp ); fp = NULL; log_string( " Done loading clans " ); } CMDF( do_induct ) { char arg[MIL], buf[MSL]; CHAR_DATA *victim; CLAN_DATA *clan; if( is_npc( ch ) || !ch->pcdata->clan ) { send_to_char( "Huh?\r\n", ch ); return; } clan = ch->pcdata->clan; if( !is_name( "induct", ch->pcdata->bestowments ) && str_cmp( ch->name, clan->leader ) && str_cmp( ch->name, clan->number1 ) && str_cmp( ch->name, clan->number2 ) ) { send_to_char( "Huh?\r\n", ch ); return; } argument = one_argument( argument, arg ); if( !arg || arg[0] == '\0' ) { send_to_char( "Induct whom?\r\n", ch ); return; } if( !( victim = get_char_room( ch, arg ) ) ) { send_to_char( "That player is not here.\r\n", ch ); return; } if( is_npc( victim ) ) { send_to_char( "Not on NPC's.\r\n", ch ); return; } if( is_immortal( victim ) ) { send_to_char( "You can't induct such a godly presence.\r\n", ch ); return; } if( clan->clan_type == CLAN_NATION ) { if( victim->race != clan->race ) { send_to_char( "This player's race is not in accordance with your clan.\r\n", ch ); return; } } else { if( victim->level < 10 ) { send_to_char( "This player is not worthy of joining yet.\r\n", ch ); return; } if( victim->level > ch->level ) { send_to_char( "This player is too powerful for you to induct.\r\n", ch ); return; } } if( victim->pcdata->clan ) { ch_printf( ch, "This player already belongs to %s clan!\r\n", victim->pcdata->clan == clan ? "your" : "a" ); return; } if( xIS_SET( victim->act, PLR_NOINDUCT ) ) { send_to_char( "This player doesn't currently wish to be inducted into a clan.\r\n", ch ); return; } if( clan->clan_type == CLAN_PLAIN ) xSET_BIT( victim->pcdata->flags, PCFLAG_DEADLY ); victim->pcdata->clan = clan; add_clan_member( clan, victim->name ); act( AT_MAGIC, "You induct $N into $t", ch, clan->name, victim, TO_CHAR ); act( AT_MAGIC, "$n inducts $N into $t", ch, clan->name, victim, TO_NOTVICT ); act( AT_MAGIC, "$n inducts you into $t", ch, clan->name, victim, TO_VICT ); snprintf( buf, sizeof( buf ), "%s has been inducted into %s!", victim->name, clan->name ); echo_to_all( AT_MAGIC, buf, ECHOTAR_ALL ); save_char_obj( victim ); save_clan( clan ); } CMDF( do_nation_induct ) { char buf[MSL]; CHAR_DATA *victim; CLAN_DATA *nation; if( is_npc( ch ) || !ch->pcdata->nation ) { send_to_char( "Huh?\r\n", ch ); return; } nation = ch->pcdata->nation; if( !is_name( "ninduct", ch->pcdata->bestowments ) && str_cmp( ch->name, nation->leader ) && str_cmp( ch->name, nation->number1 ) && str_cmp( ch->name, nation->number2 ) ) { send_to_char( "Huh?\r\n", ch ); return; } if( !argument || argument[0] == '\0' ) { send_to_char( "Ninduct whom?\r\n", ch ); return; } if( !( victim = get_char_room( ch, argument ) ) ) { send_to_char( "That player is not here.\r\n", ch ); return; } if( is_npc( victim ) || victim->pcdata->nation || is_immortal( victim ) || victim->race != nation->race ) { send_to_char( "You can't ninduct them.\r\n", ch ); return; } if( xIS_SET( victim->act, PLR_NOINDUCT ) ) { send_to_char( "This player doesn't currently wish to be inducted into a nation.\r\n", ch ); return; } victim->pcdata->nation = nation; add_clan_member( nation, victim->name ); act( AT_MAGIC, "You induct $N into $t", ch, nation->name, victim, TO_CHAR ); act( AT_MAGIC, "$n inducts $N into $t", ch, nation->name, victim, TO_NOTVICT ); act( AT_MAGIC, "$n inducts you into $t", ch, nation->name, victim, TO_VICT ); snprintf( buf, sizeof( buf ), "%s has been inducted into %s!", victim->name, nation->name ); echo_to_all( AT_MAGIC, buf, ECHOTAR_ALL ); save_char_obj( victim ); save_clan( nation ); } /* Can the character outcast the victim? */ bool can_outcast( CLAN_DATA *clan, CHAR_DATA *ch, CHAR_DATA *victim ) { if( !clan || !ch || !victim ) return false; if( !str_cmp( ch->name, clan->leader ) ) return true; if( !str_cmp( victim->name, clan->leader ) ) return false; if( !str_cmp( ch->name, clan->number1 ) ) return true; if( !str_cmp( victim->name, clan->number1 ) ) return false; if( !str_cmp( ch->name, clan->number2 ) ) return true; if( !str_cmp( victim->name, clan->number2 ) ) return false; return true; } CMDF( do_outcast ) { char buf[MSL]; CHAR_DATA *victim; CLAN_DATA *clan; if( is_npc( ch ) || !ch->pcdata->clan ) { send_to_char( "Huh?\r\n", ch ); return; } clan = ch->pcdata->clan; if( !is_name( "outcast", ch->pcdata->bestowments ) && str_cmp( ch->name, clan->leader ) && str_cmp( ch->name, clan->number1 ) && str_cmp( ch->name, clan->number2 ) ) { send_to_char( "Huh?\r\n", ch ); return; } if( !argument || argument[0] == '\0' ) { send_to_char( "Outcast whom?\r\n", ch ); return; } if( !str_cmp( ch->name, clan->leader ) ) victim = get_char_world( ch, argument ); else victim = get_char_room( ch, argument ); if( !victim || is_npc( victim ) ) { if( !victim && !str_cmp( ch->name, clan->leader ) && remove_clan_member( clan, argument ) ) { send_to_char( "That player has been removed from your clan.\r\n", ch ); snprintf( buf, sizeof( buf ), "%s has been outcast from %s!", capitalize( argument ), clan->name ); echo_to_all( AT_MAGIC, buf, ECHOTAR_ALL ); save_clan( clan ); } else send_to_char( "That player is not here.\r\n", ch ); return; } if( victim == ch ) { ch_printf( ch, "Kick yourself out of your own %s?\r\n", "clan" ); return; } if( victim->pcdata->clan != ch->pcdata->clan ) { ch_printf( ch, "This player does not belong to your %s!\r\n", "clan" ); return; } if( !can_outcast( clan, ch, victim ) ) { send_to_char( "You aren't able to outcast them.\r\n", ch ); return; } remove_clan_member( clan, victim->name ); victim->pcdata->clan = NULL; act( AT_MAGIC, "You outcast $N from $t", ch, clan->name, victim, TO_CHAR ); act( AT_MAGIC, "$n outcasts $N from $t", ch, clan->name, victim, TO_ROOM ); act( AT_MAGIC, "$n outcasts you from $t", ch, clan->name, victim, TO_VICT ); snprintf( buf, sizeof( buf ), "%s has been outcast from %s!", victim->name, clan->name ); echo_to_all( AT_MAGIC, buf, ECHOTAR_ALL ); save_char_obj( victim ); save_clan( clan ); } CMDF( do_nation_outcast ) { char buf[MSL]; CHAR_DATA *victim; CLAN_DATA *nation; if( is_npc( ch ) || !ch->pcdata->clan ) { send_to_char( "Huh?\r\n", ch ); return; } nation = ch->pcdata->nation; if( !is_name( "noutcast", ch->pcdata->bestowments ) && str_cmp( ch->name, nation->leader ) && str_cmp( ch->name, nation->number1 ) && str_cmp( ch->name, nation->number2 ) ) { send_to_char( "Huh?\r\n", ch ); return; } if( !argument || argument[0] == '\0' ) { send_to_char( "Noutcast whom?\r\n", ch ); return; } if( !str_cmp( ch->name, nation->leader ) ) victim = get_char_world( ch, argument ); else victim = get_char_room( ch, argument ); if( !victim || is_npc( victim ) ) { if( !victim && !str_cmp( ch->name, nation->leader ) && remove_clan_member( nation, argument ) ) { send_to_char( "That player has been removed from your nation.\r\n", ch ); snprintf( buf, sizeof( buf ), "%s has been outcast from %s!", capitalize( argument ), nation->name ); echo_to_all( AT_MAGIC, buf, ECHOTAR_ALL ); save_clan( nation ); } else send_to_char( "That player is not here.\r\n", ch ); return; } if( victim == ch || victim->pcdata->nation != nation ) { ch_printf( ch, "You can't kick %s out of your nation!\r\n", victim == ch ? "yourself" : "them" ); return; } if( !can_outcast( nation, ch, victim ) ) { send_to_char( "You aren't able to outcast them.\r\n", ch ); return; } remove_clan_member( nation, victim->name ); victim->pcdata->nation = NULL; act( AT_MAGIC, "You outcast $N from $t", ch, nation->name, victim, TO_CHAR ); act( AT_MAGIC, "$n outcasts $N from $t", ch, nation->name, victim, TO_ROOM ); act( AT_MAGIC, "$n outcasts you from $t", ch, nation->name, victim, TO_VICT ); snprintf( buf, sizeof( buf ), "%s has been outcast from %s!", victim->name, nation->name ); echo_to_all( AT_MAGIC, buf, ECHOTAR_ALL ); save_char_obj( victim ); save_clan( nation ); } void show_clan( CHAR_DATA *ch, CLAN_DATA *clan ) { MEMBER_DATA *member; int cnt = 0; set_char_color( AT_PLAIN, ch ); if( is_npc( ch ) ) { send_to_char( "Huh?\r\n", ch ); return; } if( !clan ) { send_to_char( "No such clan or nation.\r\n", ch ); return; } ch_printf( ch, "\r\n&w%s : &W%s\r\n&wBadge: &W%s\r\n&wFilename : &W%s\r\n&wMotto : &W%s\r\n", clan->clan_type == CLAN_NATION ? "Nation" : "Clan ", clan->name ? clan->name : "(Not Set)", clan->badge ? clan->badge : "(Not Set)", clan->filename ? clan->filename : "(Not Set)", clan->motto ? clan->motto : "(Not Set)" ); ch_printf( ch, "&wDesc : &W%s\r\n", clan->description ? clan->description : "(Not Set)" ); ch_printf( ch, "&wLeader : &W%-19.19s &wRank: &W%s\r\n", clan->leader ? clan->leader : "(Not Set)", clan->leadrank ? clan->leadrank : "(Not Set)" ); ch_printf( ch, "&wNumber1 : &W%-19.19s &wRank: &W%s\r\n", clan->number1 ? clan->number1 : "(Not Set)", clan->onerank ? clan->onerank : "(Not Set)" ); ch_printf( ch, "&wNumber2 : &W%-19.19s &wRank: &W%s\r\n", clan->number2 ? clan->number2 : "(Not Set)", clan->tworank ? clan->tworank : "(Not Set)" ); ch_printf( ch, "&wMembers : &W%-6d ", clan->members ); ch_printf( ch, "&wRace : &W%d &w(&W%s&w)", clan->race, dis_race_name( clan->race ) ); send_to_char( "\r\n", ch ); ch_printf( ch, "&wRecall : &W%-5d &wStorage: &W%-5d\r\n", clan->recall, clan->storeroom ); send_to_char( "Members:\r\n", ch ); if( !clan->first_member ) send_to_char( " This clan currently has no members.\r\n", ch ); for( member = clan->first_member; member; member = member->next ) { ch_printf( ch, " %15.15s", member->name ); if( ++cnt == 4 ) { cnt = 0; send_to_char( "\r\n", ch ); } } if( cnt != 0 ) send_to_char( "\r\n", ch ); } CMDF( do_setclan ) { char arg1[MIL], arg2[MIL]; CLAN_DATA *clan; set_char_color( AT_PLAIN, ch ); if( is_npc( ch ) ) { send_to_char( "Huh?\r\n", ch ); return; } argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); if( !arg1 || arg1[0] == '\0' ) { send_to_char( "Usage: setclan <clan> [create]\r\n", ch ); send_to_char( "Usage: setclan <clan> <field> <leader|number1|number2> <player>\r\n", ch ); send_to_char( "\r\nField being one of:\r\n", ch ); send_to_char( " leader leadrank number1 onerank tworank\r\n", ch ); send_to_char( " recall storage number2\r\n", ch ); if( get_trust( ch ) >= PERM_LEADER ) { send_to_char( " name filename motto desc race\r\n", ch ); send_to_char( " type class\r\n", ch ); } return; } clan = get_clan( arg1 ); if( !str_cmp( arg2, "create" ) ) { if( clan ) { send_to_char( "There is already a clan with that name.\r\n", ch ); return; } CREATE( clan, CLAN_DATA, 1 ); if( !clan ) { bug( "%s: failed to CREATE clan.", __FUNCTION__ ); return; } LINK( clan, first_clan, last_clan, next, prev ); clan->name = STRALLOC( arg1 ); clan->filename = NULL; clan->motto = NULL; clan->first_member = clan->last_member = NULL; clan->description = NULL; clan->leader = NULL; clan->number1 = NULL; clan->number2 = NULL; clan->leadrank = NULL; clan->onerank = NULL; clan->tworank = NULL; clan->badge = NULL; ch_printf( ch, "%s clan created.\r\n", clan->name ); return; } if( !clan ) { send_to_char( "No such clan.\r\n", ch ); return; } if( !arg2 || arg2[0] == '\0' ) { show_clan( ch, clan ); return; } if( !str_cmp( arg2, "leader" ) ) { STRSET( clan->leader, argument ); send_to_char( "Leader Set.\r\n", ch ); save_clan( clan ); return; } if( !str_cmp( arg2, "number1" ) ) { STRSET( clan->number1, argument ); send_to_char( "Number1 Set.\r\n", ch ); save_clan( clan ); return; } if( !str_cmp( arg2, "number2" ) ) { STRSET( clan->number2, argument ); send_to_char( "Number2 Set.\r\n", ch ); save_clan( clan ); return; } if( !str_cmp( arg2, "leadrank" ) ) { STRSET( clan->leadrank, argument ); send_to_char( "Leadrank Set.\r\n", ch ); save_clan( clan ); return; } if( !str_cmp( arg2, "onerank" ) ) { STRSET( clan->onerank, argument ); send_to_char( "Onerank Set.\r\n", ch ); save_clan( clan ); return; } if( !str_cmp( arg2, "tworank" ) ) { STRSET( clan->tworank, argument ); send_to_char( "Tworank Set.\r\n", ch ); save_clan( clan ); return; } if( !str_cmp( arg2, "badge" ) ) { STRSET( clan->badge, argument ); send_to_char( "Done.\r\n", ch ); save_clan( clan ); return; } if( !str_cmp( arg2, "recall" ) ) { clan->recall = UMAX( 0, atoi( argument ) ); ch_printf( ch, "Recall set to %d.\r\n", clan->recall ); save_clan( clan ); return; } if( !str_cmp( arg2, "storage" ) ) { clan->storeroom = UMAX( 0, atoi( argument ) ); ch_printf( ch, "Storage set to %d.\r\n", clan->storeroom ); save_clan( clan ); return; } if( get_trust( ch ) < PERM_LEADER ) { do_setclan( ch, "" ); return; } if( !str_cmp( arg2, "type" ) ) { if( !str_cmp( argument, "nation" ) ) clan->clan_type = CLAN_NATION; else if( !str_cmp( argument, "clan" ) ) clan->clan_type = CLAN_PLAIN; else if( is_number( argument ) ) { int value = atoi( argument ); if( value < CLAN_PLAIN || value > CLAN_NATION ) { send_to_char( "Usage: setclan <clan> type <nation/clan>\r\n", ch ); return; } clan->clan_type = value; } else { send_to_char( "Usage: setclan <clan> type <nation/clan>\r\n", ch ); return; } send_to_char( "Done.\r\n", ch ); save_clan( clan ); return; } if( !str_cmp( arg2, "race" ) ) { int value; if( is_number( argument ) ) value = atoi( argument ); else value = get_pc_race( argument ); if( value < -1 || value >= MAX_PC_RACE ) { send_to_char( "Invalid race.\r\n", ch ); return; } clan->race = value; ch_printf( ch, "Race set to %d[%s].\r\n", clan->race, dis_race_name( clan->race ) ); save_clan( clan ); return; } if( !str_cmp( arg2, "name" ) ) { CLAN_DATA *uclan = NULL; if( !argument || argument[0] == '\0' ) { send_to_char( "You can't name a clan nothing.\r\n", ch ); return; } if( ( uclan = get_clan( argument ) ) ) { send_to_char( "There is already another clan with that name.\r\n", ch ); return; } STRSET( clan->name, argument ); send_to_char( "Name Set.\r\n", ch ); save_clan( clan ); return; } if( !str_cmp( arg2, "filename" ) ) { char filename[256]; if( !argument || argument[0] == '\0' ) { send_to_char( "You can't set a clans's filename to nothing.\r\n", ch ); return; } if( !can_use_path( ch, CLAN_DIR, argument ) ) return; if( clan->filename ) { snprintf( filename, sizeof( filename ), "%s%s", CLAN_DIR, clan->filename ); if( !remove( filename ) ) send_to_char( "Old clan file deleted.\r\n", ch ); } STRSET( clan->filename, argument ); send_to_char( "Filename Set.\r\n", ch ); save_clan( clan ); write_clan_list( ); return; } if( !str_cmp( arg2, "motto" ) ) { STRSET( clan->motto, argument ); send_to_char( "Motto Set.\r\n", ch ); save_clan( clan ); return; } if( !str_cmp( arg2, "desc" ) ) { STRSET( clan->description, argument ); send_to_char( "Desc Set.\r\n", ch ); save_clan( clan ); return; } do_setclan( ch, "" ); } void free_council_members( COUNCIL_DATA *council ) { MEMBER_DATA *member, *member_next; if( !council ) return; for( member = council->first_member; member; member = member_next ) { member_next = member->next; UNLINK( member, council->first_member, council->last_member, next, prev ); free_member( member ); } } void remove_council_member( COUNCIL_DATA *council, char *name ) { MEMBER_DATA *member; if( !council || !name || name[0] == '\0' ) return; for( member = council->first_member; member; member = member->next ) { if( !str_cmp( member->name, name ) ) { if( !str_cmp( name, council->head ) ) STRFREE( council->head ); if( !str_cmp( name, council->head2 ) ) STRFREE( council->head2 ); UNLINK( member, council->first_member, council->last_member, next, prev ); free_member( member ); if( --council->members < 0 ) council->members = 0; return; } } } void add_council_member( COUNCIL_DATA *council, char *name ) { MEMBER_DATA *member; if( !council || !name || name[0] == '\0' ) return; CREATE( member, MEMBER_DATA, 1 ); member->name = STRALLOC( name ); LINK( member, council->first_member, council->last_member, next, prev ); if( ( council->members + 1 ) > 0 ) council->members++; } void free_one_council( COUNCIL_DATA *council ) { if( !council ) return; free_council_members( council ); UNLINK( council, first_council, last_council, next, prev ); STRFREE( council->description ); STRFREE( council->filename ); STRFREE( council->head ); STRFREE( council->head2 ); STRFREE( council->name ); STRFREE( council->powers ); DISPOSE( council ); } void free_councils( void ) { COUNCIL_DATA *council, *council_next; for( council = first_council; council; council = council_next ) { council_next = council->next; free_one_council( council ); } } COUNCIL_DATA *get_council( char *name ) { COUNCIL_DATA *council; for( council = first_council; council; council = council->next ) if( council->name && name && !str_cmp( name, council->name ) ) return council; return NULL; } void write_council_list( void ) { COUNCIL_DATA *tcouncil; FILE *fp; if( !( fp = fopen( COUNCIL_LIST, "w" ) ) ) { bug( "%s: can't open %s for writing!", __FUNCTION__, COUNCIL_LIST ); return; } for( tcouncil = first_council; tcouncil; tcouncil = tcouncil->next ) fprintf( fp, "%s\n", tcouncil->filename ); fprintf( fp, "$\n" ); fclose( fp ); fp = NULL; } /* Save a council's data to its data file */ void save_council( COUNCIL_DATA *council ) { FILE *fp; MEMBER_DATA *member; char filename[256]; if( !council ) { bug( "%s: NULL council!", __FUNCTION__ ); return; } if( !council->name ) { bug( "%s: NULL council->name", __FUNCTION__ ); return; } if( !council->filename || council->filename[0] == '\0' ) { bug( "%s: %s has no filename", __FUNCTION__, council->name ); return; } snprintf( filename, sizeof( filename ), "%s%s", COUNCIL_DIR, council->filename ); if( !( fp = fopen( filename, "w" ) ) ) { perror( filename ); return; } fprintf( fp, "Name %s~\n", council->name ); fprintf( fp, "Filename %s~\n", council->filename ); if( council->description ) fprintf( fp, "Description %s~\n", council->description ); if( council->head ) fprintf( fp, "Head %s~\n", council->head ); if( council->head2 ) fprintf( fp, "Head2 %s~\n", council->head2 ); if( council->powers ) fprintf( fp, "Powers %s~\n", council->powers ); for( member = council->first_member; member; member = member->next ) fprintf( fp, "Member %s~\n", member->name ); fprintf( fp, "End\n\n" ); fclose( fp ); fp = NULL; } /* Read in actual council data. */ COUNCIL_DATA *fread_council( FILE *fp ) { COUNCIL_DATA *council = NULL; const char *word; bool fMatch; CREATE( council, COUNCIL_DATA, 1 ); if( !council ) return NULL; council->first_member = NULL; council->last_member = NULL; for( ;; ) { word = feof( fp ) ? "End" : fread_word( fp ); fMatch = false; switch( UPPER( word[0] ) ) { case '*': fMatch = true; fread_to_eol( fp ); break; case 'D': KEY( "Description", council->description, fread_string( fp ) ); break; case 'E': if( !str_cmp( word, "End" ) ) return council; break; case 'F': KEY( "Filename", council->filename, fread_string( fp ) ); break; case 'H': KEY( "Head", council->head, fread_string( fp ) ); KEY( "Head2", council->head2, fread_string( fp ) ); break; case 'M': if( !str_cmp( word, "Member" ) ) { char *name = fread_flagstring( fp ); if( valid_pfile( name ) ) add_council_member( council, name ); else bug( "%s: not adding member %s because no pfile found.", __FUNCTION__, name ); fMatch = true; break; } break; case 'N': KEY( "Name", council->name, fread_string( fp ) ); break; case 'P': KEY( "Powers", council->powers, fread_string( fp ) ); break; } if( !fMatch ) { bug( "%s: no match: %s", __FUNCTION__, word ); fread_to_eol( fp ); } } free_one_council( council ); return NULL; } /* Load a council file */ void load_council_file( const char *councilfile ) { char filename[256]; COUNCIL_DATA *council; FILE *fp; snprintf( filename, sizeof( filename ), "%s%s", COUNCIL_DIR, councilfile ); if( !( fp = fopen( filename, "r" ) ) ) { perror( filename ); return; } council = fread_council( fp ); fclose( fp ); if( !council ) return; LINK( council, first_council, last_council, next, prev ); } /* Load in all the council files. */ void load_councils( void ) { FILE *fpList; const char *filename; first_council = last_council = NULL; log_string( "Loading councils..." ); if( !( fpList = fopen( COUNCIL_LIST, "r" ) ) ) { bug( "%s: Can't read file: %s", __FUNCTION__, COUNCIL_LIST ); perror( COUNCIL_LIST ); return; } for( ;; ) { filename = feof( fpList ) ? "$" : fread_word( fpList ); if( filename[0] == '$' ) break; log_string( filename ); load_council_file( filename ); } fclose( fpList ); fpList = NULL; log_string( " Done loading councils " ); } CMDF( do_council_induct ) { char arg[MIL], buf[MSL]; CHAR_DATA *victim; COUNCIL_DATA *council; if( is_npc( ch ) || !ch->pcdata->council ) { send_to_char( "Huh?\r\n", ch ); return; } council = ch->pcdata->council; if( str_cmp( ch->name, council->head ) && str_cmp( ch->name, council->head2 ) && str_cmp( council->name, "mortal council" ) ) { send_to_char( "Huh?\r\n", ch ); return; } argument = one_argument( argument, arg ); if( !arg || arg[0] == '\0' ) { send_to_char( "Induct whom into your council?\r\n", ch ); return; } if( !( victim = get_char_room( ch, arg ) ) ) { send_to_char( "That player is not here.\r\n", ch ); return; } if( is_npc( victim ) ) { send_to_char( "Not on NPC's.\r\n", ch ); return; } if( victim->pcdata->council ) { send_to_char( "This player already belongs to a council!\r\n", ch ); return; } if( xIS_SET( victim->act, PLR_NOINDUCT ) ) { send_to_char( "This player doesn't currently wish to be inducted into a council.\r\n", ch ); return; } victim->pcdata->council = council; add_council_member( council, victim->name ); act( AT_MAGIC, "You induct $N into $t", ch, council->name, victim, TO_CHAR ); act( AT_MAGIC, "$n inducts $N into $t", ch, council->name, victim, TO_ROOM ); act( AT_MAGIC, "$n inducts you into $t", ch, council->name, victim, TO_VICT ); snprintf( buf, sizeof( buf ), "%s has been inducted into %s!", victim->name, council->name ); echo_to_all( AT_MAGIC, buf, ECHOTAR_ALL ); save_char_obj( victim ); save_council( council ); } CMDF( do_council_outcast ) { char arg[MIL], buf[MSL]; CHAR_DATA *victim; COUNCIL_DATA *council; if( is_npc( ch ) || !ch->pcdata->council ) { send_to_char( "Huh?\r\n", ch ); return; } council = ch->pcdata->council; if( str_cmp( ch->name, council->head ) && str_cmp( ch->name, council->head2 ) && str_cmp( council->name, "mortal council" ) ) { send_to_char( "Huh?\r\n", ch ); return; } argument = one_argument( argument, arg ); if( !arg || arg[0] == '\0' ) { send_to_char( "Outcast whom from your council?\r\n", ch ); return; } if( !( victim = get_char_room( ch, arg ) ) ) { send_to_char( "That player is not here.\r\n", ch ); return; } if( is_npc( victim ) ) { send_to_char( "Not on NPC's.\r\n", ch ); return; } if( victim == ch ) { send_to_char( "Kick yourself out of your own council?\r\n", ch ); return; } if( victim->pcdata->council != ch->pcdata->council ) { send_to_char( "This player does not belong to your council!\r\n", ch ); return; } if( !str_cmp( victim->name, ch->pcdata->council->head2 ) ) { STRFREE( ch->pcdata->council->head2 ); ch->pcdata->council->head2 = NULL; } remove_council_member( council, victim->name ); victim->pcdata->council = NULL; act( AT_MAGIC, "You outcast $N from $t", ch, council->name, victim, TO_CHAR ); act( AT_MAGIC, "$n outcasts $N from $t", ch, council->name, victim, TO_ROOM ); act( AT_MAGIC, "$n outcasts you from $t", ch, council->name, victim, TO_VICT ); snprintf( buf, sizeof( buf ), "%s has been outcast from %s!", victim->name, council->name ); echo_to_all( AT_MAGIC, buf, ECHOTAR_ALL ); save_char_obj( victim ); save_council( council ); } void show_council( CHAR_DATA *ch, COUNCIL_DATA *council ) { MEMBER_DATA *member; int cnt = 0; set_char_color( AT_PLAIN, ch ); if( is_npc( ch ) ) { send_to_char( "Huh?\r\n", ch ); return; } if( !council ) { send_to_char( "No such council.\r\n", ch ); return; } ch_printf( ch, "\r\n&wCouncil : &W%s\r\n&wFilename: &W%s\r\n", council->name ? council->name : "(Not Set)", council->filename ? council->filename : "(Not Set)" ); ch_printf( ch, "&wHead: &W%s\r\n", council->head ? council->head : "(Not Set)" ); ch_printf( ch, "&wHead2: &W%s\r\n", council->head2 ? council->head2 : "(Not Set)" ); ch_printf( ch, "&wPowers: &W%s\r\n", council->powers ? council->powers : "(Not Set)" ); ch_printf( ch, "&wDescription:\r\n&W%s\r\n", council->description ? council->description : "(Not Set)" ); send_to_char( "Members:\r\n", ch ); if( !council->first_member ) send_to_char( " This council has no members.\r\n", ch ); for( member = council->first_member; member; member = member->next ) { ch_printf( ch, " %15.15s", member->name ); if( ++cnt == 4 ) { cnt = 0; send_to_char( "\r\n", ch ); } } if( cnt != 0 ) send_to_char( "\r\n", ch ); } CMDF( do_setcouncil ) { char arg1[MIL], arg2[MIL]; COUNCIL_DATA *council; set_char_color( AT_PLAIN, ch ); if( is_npc( ch ) ) { send_to_char( "Huh?\r\n", ch ); return; } argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); if( !arg1 || arg1[0] == '\0' ) { send_to_char( "Usage: setcouncil <council> [create]\r\n", ch ); send_to_char( "Usage: setcouncil <council> <field> <value>\r\n", ch ); send_to_char( "\r\nField being one of:\r\n", ch ); send_to_char( " head head2 members", ch ); if( get_trust( ch ) >= PERM_LEADER ) send_to_char( " name filename desc", ch ); if( get_trust( ch ) >= PERM_HEAD ) send_to_char( " powers", ch ); send_to_char( "\r\n", ch ); return; } council = get_council( arg1 ); if( !str_cmp( arg2, "create" ) ) { if( council ) { send_to_char( "A council is already using that name.\r\n", ch ); return; } CREATE( council, COUNCIL_DATA, 1 ); if( !council ) { bug( "%s: failed to CREATE council.", __FUNCTION__ ); return; } LINK( council, first_council, last_council, next, prev ); council->first_member = council->last_member = NULL; council->name = STRALLOC( arg1 ); council->filename = NULL; council->head = NULL; council->head2 = NULL; council->powers = NULL; ch_printf( ch, "%s council created.\r\n", council->name ); return; } if( !council ) { send_to_char( "No such council.\r\n", ch ); return; } if( !arg2 || arg2[0] == '\0' ) { show_council( ch, council ); return; } if( !str_cmp( arg2, "head" ) ) { STRSET( council->head, argument ); send_to_char( "Head Set.\r\n", ch ); save_council( council ); return; } if( !str_cmp( arg2, "head2" ) ) { STRSET( council->head2, argument ); send_to_char( "Head2 Set.\r\n", ch ); save_council( council ); return; } if( !str_cmp( arg2, "members" ) ) { council->members = UMAX( 0, atoi( argument ) ); send_to_char( "Done.\r\n", ch ); save_council( council ); return; } if( get_trust( ch ) < PERM_LEADER ) { do_setcouncil( ch, "" ); return; } if( !str_cmp( arg2, "name" ) ) { COUNCIL_DATA *ucouncil; if( !argument || argument[0] == '\0' ) { send_to_char( "Can't set a council name to nothing.\r\n", ch ); return; } if( ( ucouncil = get_council( argument ) ) ) { send_to_char( "A council is already using that name.\r\n", ch ); return; } STRSET( council->name, argument ); send_to_char( "Name Set.\r\n", ch ); save_council( council ); return; } if( !str_cmp( arg2, "filename" ) ) { char filename[256]; if( !argument || argument[0] == '\0' ) { send_to_char( "You can't set a council's filename to nothing.\r\n", ch ); return; } if( !can_use_path( ch, COUNCIL_DIR, argument ) ) return; if( council->filename ) { snprintf( filename, sizeof( filename ), "%s%s", COUNCIL_DIR, council->filename ); if( !remove( filename ) ) send_to_char( "Old council file deleted.\r\n", ch ); } STRSET( council->filename, argument ); send_to_char( "Filename Set.\r\n", ch ); save_council( council ); write_council_list( ); return; } if( !str_cmp( arg2, "desc" ) ) { STRSET( council->description, argument ); send_to_char( "Desc Set.\r\n", ch ); save_council( council ); return; } if( get_trust( ch ) < PERM_HEAD ) { do_setcouncil( ch, "" ); return; } if( !str_cmp( arg2, "powers" ) ) { STRSET( council->powers, argument ); send_to_char( "Powers Set.\r\n", ch ); save_council( council ); return; } do_setcouncil( ch, "" ); } void quit_clan( CHAR_DATA *ch, CLAN_DATA *clan ) { char buf[MSL]; if( !ch || is_npc( ch ) || !clan ) return; if( ch->pcdata->clan == clan ) ch->pcdata->clan = NULL; else if( ch->pcdata->nation == clan ) ch->pcdata->nation = NULL; else { send_to_char( "You don't belong to that clan or nation.\r\n", ch ); return; } remove_clan_member( clan, ch->name ); act( AT_MAGIC, "You quit $t", ch, clan->name, NULL, TO_CHAR ); act( AT_MAGIC, "$n quit $t", ch, clan->name, NULL, TO_ROOM ); snprintf( buf, sizeof( buf ), "%s has quit %s!", ch->name, clan->name ); echo_to_all( AT_MAGIC, buf, ECHOTAR_ALL ); save_char_obj( ch ); save_clan( clan ); } CMDF( do_clan_quit ) { if( !ch || is_npc( ch ) ) return; if( !ch->pcdata->clan || ch->pcdata->clan->clan_type != CLAN_PLAIN ) { send_to_char( "You aren't in a clan.\r\n", ch ); return; } if( !str_cmp( argument, "now" ) ) quit_clan( ch, ch->pcdata->clan ); else send_to_char( "Usage: cquit now\r\n", ch ); } CMDF( do_nation_quit ) { if( !ch || is_npc( ch ) ) return; if( !ch->pcdata->nation || ch->pcdata->nation->clan_type != CLAN_NATION ) { send_to_char( "You aren't in a nation.\r\n", ch ); return; } if( !str_cmp( argument, "now" ) ) quit_clan( ch, ch->pcdata->nation ); else send_to_char( "Usage: nquit now\r\n", ch ); } void show_clans( CHAR_DATA *ch, CLAN_DATA *clan, int type ) { char *disname = "Clan", *argname = "clans", *oargname = "clan"; int count = 0, color1 = AT_BLOOD, color2 = AT_GREY; MEMBER_DATA *member; if( !ch ) return; if( type == CLAN_NATION ) { color1 = AT_YELLOW; color2 = AT_GREEN; disname = "Nation"; oargname = "nation"; argname = "nations"; } if( !clan ) { set_char_color( color1, ch ); ch_printf( ch, "\r\n%-13s %-13s %-7s\r\n", disname, "Leader", "Members" ); send_to_char( "________________________________________________\r\n\r\n", ch ); set_char_color( color2, ch ); for( clan = first_clan; clan; clan = clan->next ) { if( clan->clan_type != type ) continue; ch_printf( ch, "%-13s %-13s %7d\r\n", clan->name ? clan->name : "(Not Set)", clan->leader ? clan->leader : "(Not Set)", clan->members ); count++; } if( !count ) ch_printf( ch, "There are no %s currently formed.\r\n", argname ); set_char_color( color1, ch ); send_to_char( "________________________________________________\r\n\r\n", ch ); ch_printf( ch, "Use '%s <%s>' for detailed information.\r\n", argname, oargname ); return; } set_char_color( color1, ch ); ch_printf( ch, "\r\n%s, '%s'\r\n\r\n", clan->name ? clan->name : "(Not Set)", clan->motto ? clan->motto : "(Not Set)" ); set_char_color( color2, ch ); ch_printf( ch, "Leader: %s\r\nNumber One : %s\r\nNumber Two : %s\r\n", clan->leader ? clan->leader : "(Not Set)", clan->number1 ? clan->number1 : "(Not Set)", clan->number2 ? clan->number2 : "(Not Set)" ); ch_printf( ch, "Members : %d\r\n", clan->members ); set_char_color( color1, ch ); ch_printf( ch, "\r\nDescription: %s\r\n", clan->description ? clan->description : "(Not Set)" ); send_to_char( "Members:\r\n", ch ); set_char_color( color2, ch ); for( member = clan->first_member; member; member = member->next ) { ch_printf( ch, " %15.15s", member->name ); if( ++count == 4 ) { count = 0; send_to_char( "\r\n", ch ); } } if( count != 0 ) send_to_char( "\r\n", ch ); } /* Added multiple level pkill and pdeath support. --Shaddai */ CMDF( do_clans ) { CLAN_DATA *clan; if( !argument || argument[0] == '\0' ) { show_clans( ch, NULL, CLAN_PLAIN ); return; } if( !( clan = get_clan( argument ) ) || clan->clan_type != CLAN_PLAIN ) { set_char_color( AT_BLOOD, ch ); ch_printf( ch, "No clan called %s.\r\n", argument ); return; } show_clans( ch, clan, CLAN_PLAIN ); } CMDF( do_nations ) { CLAN_DATA *nation; if( !argument || argument[0] == '\0' ) { show_clans( ch, NULL, CLAN_NATION ); return; } if( !( nation = get_clan( argument ) ) || nation->clan_type != CLAN_NATION ) { set_char_color( AT_YELLOW, ch ); ch_printf( ch, "No nation called %s.\r\n", argument ); return; } show_clans( ch, nation, CLAN_NATION ); } CMDF( do_councils ) { COUNCIL_DATA *council; int count = 0; set_char_color( AT_CYAN, ch ); if( !first_council ) { send_to_char( "There are no councils currently formed.\r\n", ch ); return; } if( !argument || argument[0] == '\0' ) { set_char_color( AT_CYAN, ch ); send_to_char( "\r\nTitle Head\r\n", ch ); send_to_char( "__________________________________________________\r\n\r\n", ch ); set_char_color( AT_GREY, ch ); for( council = first_council; council; council = council->next ) { ch_printf( ch, "&w%-24s", council->name ? council->name : "(Not Set)" ); ch_printf( ch, " %s", council->head ? council->head : "(Not Set)" ); if( council->head2 ) ch_printf( ch, " and %s", council->head2 ); send_to_char( "\r\n", ch ); count++; } if( !count ) send_to_char( "There are no councils currently formed.\r\n", ch ); set_char_color( AT_CYAN, ch ); send_to_char( "__________________________________________________\r\n\r\n", ch ); send_to_char( "Use 'councils <council>' for detailed information.\r\n", ch ); return; } if( !( council = get_council( argument ) ) ) { ch_printf( ch, "&cNo council called %s exists...\r\n", argument ); return; } ch_printf( ch, "&c\r\n%s\r\n", council->name ? council->name : "(Not Set)" ); ch_printf( ch, "&cHead: &w%s\r\n", council->head ? council->head : "(Not Set)" ); if( council->head2 ) ch_printf( ch, "&cCo-Head: &w%s\r\n", council->head2 ); ch_printf( ch, "&cMembers: &w%d\r\n", council->members ); ch_printf( ch, "&cDescription:\r\n&w%s\r\n", council->description ? council->description : "(Not Set)" ); } CMDF( do_victories ) { char filename[256], arg[MSL]; CLAN_DATA *clan; bool clear = false; if( !ch || is_npc( ch ) ) return; argument = one_argument( argument, arg ); if( arg && arg[0] != '\0' ) { if( ( clan = get_clan( arg ) ) ) argument = one_argument( argument, arg ); } else clan = ch->pcdata->clan; if( is_immortal( ch ) && arg && arg[0] != '\0' && !str_cmp( arg, "clear" ) ) clear = true; if( !clan ) { send_to_char( "No clan to display victories for.\r\n", ch ); return; } if( clan->clan_type != CLAN_PLAIN ) { send_to_char( "The specified clan isn't able to legaly pkill others.\r\n", ch ); return; } snprintf( filename, sizeof( filename ), "%s%s.record", CLAN_DIR, clan->name ); set_pager_color( AT_PURPLE, ch ); if( clear ) { remove_file( filename ); ch_printf( ch, "%s victories ledger has been cleared.\r\n", clan->name ); } else { send_to_pager( "\r\nLVL Character LVL Character\r\n", ch ); show_file( ch, filename ); } } CMDF( do_shove ) { char arg[MIL], arg2[MIL]; int exit_dir, schance = 0; EXIT_DATA *pexit; CHAR_DATA *victim; ROOM_INDEX_DATA *to_room; bool nogo; argument = one_argument( argument, arg ); argument = one_argument( argument, arg2 ); if( is_npc( ch ) || !xIS_SET( ch->pcdata->flags, PCFLAG_DEADLY ) ) { send_to_char( "Only deadly characters can shove.\r\n", ch ); return; } if( get_timer( ch, TIMER_PKILLED ) > 0 ) { send_to_char( "You can't shove a player right now.\r\n", ch ); return; } if( !arg || arg[0] == '\0' ) { send_to_char( "Shove whom?\r\n", ch ); return; } if( !( victim = get_char_room( ch, arg ) ) ) { send_to_char( "They aren't here.\r\n", ch ); return; } if( victim == ch ) { send_to_char( "You shove yourself around, to no avail.\r\n", ch ); return; } if( is_npc( victim ) || !xIS_SET( victim->pcdata->flags, PCFLAG_DEADLY ) ) { send_to_char( "You can only shove deadly characters.\r\n", ch ); return; } if( ch->level - victim->level > 5 || victim->level - ch->level > 5 ) { send_to_char( "There is too great an experience difference for you to even bother.\r\n", ch ); return; } if( get_timer( victim, TIMER_PKILLED ) > 0 ) { send_to_char( "You can't shove that player right now.\r\n", ch ); return; } if( victim->position != POS_STANDING ) { act( AT_PLAIN, "$N isn't standing up.", ch, NULL, victim, TO_CHAR ); return; } if( !arg2 || arg2[0] == '\0' ) { send_to_char( "Shove them in which direction?\r\n", ch ); return; } exit_dir = get_dir( arg2 ); if( xIS_SET( victim->in_room->room_flags, ROOM_SAFE ) && get_timer( victim, TIMER_SHOVEDRAG ) <= 0 ) { send_to_char( "That character can't be shoved right now.\r\n", ch ); return; } victim->position = POS_SHOVE; nogo = false; if( !( pexit = get_exit( ch->in_room, exit_dir ) ) ) nogo = true; else if( xIS_SET( pexit->exit_info, EX_CLOSED ) && ( !IS_AFFECTED( victim, AFF_PASS_DOOR ) || xIS_SET( pexit->exit_info, EX_NOPASSDOOR ) ) ) nogo = true; if( nogo ) { send_to_char( "There's no exit in that direction.\r\n", ch ); victim->position = POS_STANDING; return; } to_room = pexit->to_room; if( xIS_SET( to_room->room_flags, ROOM_DEATH ) ) { send_to_char( "You can't shove someone into a death trap.\r\n", ch ); victim->position = POS_STANDING; return; } if( ch->in_room->area != to_room->area && !in_hard_range( victim, to_room->area ) ) { send_to_char( "That character can't enter that area.\r\n", ch ); victim->position = POS_STANDING; return; } /* Add 3 points to chance for every str point above 15, subtract for below 15 */ schance += ( ( get_curr_str( ch ) - 15 ) * 3 ); schance += ( ch->level - victim->level ); if( schance < number_percent( ) ) { send_to_char( "You failed.\r\n", ch ); victim->position = POS_STANDING; return; } act( AT_ACTION, "You shove $M.", ch, NULL, victim, TO_CHAR ); act( AT_ACTION, "$n shoves you.", ch, NULL, victim, TO_VICT ); move_char( victim, get_exit( ch->in_room, exit_dir ), 0 ); if( !char_died( victim ) ) victim->position = POS_STANDING; wait_state( ch, 12 ); /* Remove protection from shove/drag if char shoves -- Blodkai */ if( xIS_SET( ch->in_room->room_flags, ROOM_SAFE ) && get_timer( ch, TIMER_SHOVEDRAG ) <= 0 ) add_timer( ch, TIMER_SHOVEDRAG, 10, NULL, 0 ); } CMDF( do_drag ) { char arg[MIL], arg2[MIL]; int exit_dir, schance = 0; CHAR_DATA *victim; EXIT_DATA *pexit; ROOM_INDEX_DATA *to_room; argument = one_argument( argument, arg ); argument = one_argument( argument, arg2 ); if( is_npc( ch ) ) { send_to_char( "Only characters can drag.\r\n", ch ); return; } if( get_timer( ch, TIMER_PKILLED ) > 0 ) { send_to_char( "You can't drag a player right now.\r\n", ch ); return; } if( !arg || arg[0] == '\0' ) { send_to_char( "Drag whom?\r\n", ch ); return; } if( !( victim = get_char_room( ch, arg ) ) ) { send_to_char( "They aren't here.\r\n", ch ); return; } if( victim == ch ) { send_to_char( "You take yourself by the scruff of your neck, but go nowhere.\r\n", ch ); return; } if( is_npc( victim ) ) { send_to_char( "You can only drag characters.\r\n", ch ); return; } if( !xIS_SET( victim->act, PLR_SHOVEDRAG ) && !xIS_SET( victim->pcdata->flags, PCFLAG_DEADLY ) ) { send_to_char( "That character doesn't seem to appreciate your attentions.\r\n", ch ); return; } if( get_timer( victim, TIMER_PKILLED ) > 0 ) { send_to_char( "You can't drag that player right now.\r\n", ch ); return; } if( victim->fighting ) { send_to_char( "You try, but can't get close enough.\r\n", ch ); return; } if( !xIS_SET( ch->pcdata->flags, PCFLAG_DEADLY ) && xIS_SET( victim->pcdata->flags, PCFLAG_DEADLY ) ) { send_to_char( "You can't drag a deadly character.\r\n", ch ); return; } if( !xIS_SET( victim->pcdata->flags, PCFLAG_DEADLY ) && victim->position > 3 ) { send_to_char( "They don't seem to need your assistance.\r\n", ch ); return; } if( !arg2 || arg2[0] == '\0' ) { send_to_char( "Drag them in which direction?\r\n", ch ); return; } if( ch->level - victim->level > 5 || victim->level - ch->level > 5 ) { if( xIS_SET( victim->pcdata->flags, PCFLAG_DEADLY ) && xIS_SET( ch->pcdata->flags, PCFLAG_DEADLY ) ) { send_to_char( "There is too great an experience difference for you to even bother.\r\n", ch ); return; } } if( xIS_SET( victim->in_room->room_flags, ROOM_SAFE ) && get_timer( victim, TIMER_SHOVEDRAG ) <= 0 ) { send_to_char( "That character can't be dragged right now.\r\n", ch ); return; } exit_dir = get_dir( arg2 ); if( !( pexit = get_exit( ch->in_room, exit_dir ) ) || xIS_SET( pexit->exit_info, EX_HIDDEN ) ) { send_to_char( "There's no exit in that direction.\r\n", ch ); return; } if( xIS_SET( pexit->exit_info, EX_CLOSED ) && ( !IS_AFFECTED( victim, AFF_PASS_DOOR ) || xIS_SET( pexit->exit_info, EX_NOPASSDOOR ) ) ) { send_to_char( "That exit is closed.\r\n", ch ); return; } to_room = pexit->to_room; if( xIS_SET( to_room->room_flags, ROOM_DEATH ) ) { send_to_char( "You can't drag someone into a death trap.\r\n", ch ); return; } if( ch->in_room->area != to_room->area && !in_hard_range( victim, to_room->area ) ) { send_to_char( "That character can't enter that area.\r\n", ch ); return; } /* Add 3 points to chance for every str point above 15, subtract for below 15 */ schance += ( ( get_curr_str( ch ) - 15 ) * 3 ); schance += ( ch->level - victim->level ); if( schance < number_percent( ) ) { send_to_char( "You failed.\r\n", ch ); victim->position = POS_STANDING; return; } if( victim->position < POS_STANDING ) { short temp; temp = victim->position; victim->position = POS_DRAG; act( AT_ACTION, "You drag $M into the next room.", ch, NULL, victim, TO_CHAR ); act( AT_ACTION, "$n grabs your hair and drags you.", ch, NULL, victim, TO_VICT ); move_char( victim, get_exit( ch->in_room, exit_dir ), 0 ); if( !char_died( victim ) ) victim->position = temp; move_char( ch, get_exit( ch->in_room, exit_dir ), 0 ); wait_state( ch, 12 ); return; } send_to_char( "You can't do that to someone who is standing.\r\n", ch ); } /* Save items in a clan storage room - Scryn & Thoric */ void save_clan_storeroom( CHAR_DATA *ch, CLAN_DATA *clan ) { FILE *fp; char filename[256]; short templvl; if( !clan ) { bug( "%s: Null clan pointer!", __FUNCTION__ ); return; } if( !ch ) { bug( "%s: Null ch pointer!", __FUNCTION__ ); return; } snprintf( filename, sizeof( filename ), "%s%s.vault", CLAN_DIR, clan->filename ); if( !ch->in_room->last_content ) { remove_file( filename ); return; } if( !( fp = fopen( filename, "w" ) ) ) { bug( "%s: cant open %s", __FUNCTION__, filename ); perror( filename ); return; } templvl = ch->level; ch->level = MAX_LEVEL; fwrite_obj( ch, ch->in_room->last_content, fp, 0, OS_CARRY, false ); fprintf( fp, "#END\n" ); ch->level = templvl; fclose( fp ); fp = NULL; }