/*************************************************************************** * 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. * ***************************************************************************/ /*************************************************************************** * File: Clan.c * * Written by: Kyle Boyd * * Partially inspired by some code written by Zane(E.J. Wilburn), as well * * as clan code from SMAUG(?) and ROM muds. None of what you see here was * * directly copied from those versions of clan code, just some of the * * ideas were used. * ***************************************************************************/ #if defined(macintosh) #include <types.h> #else #include <sys/types.h> #endif #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <stdarg.h> #include "merc.h" #include "olc.h" DECLARE_DO_FUN( do_look ); DECLARE_DO_FUN( do_save ); #define CEDIT( fun ) bool fun( CHAR_DATA *ch, char *argument ) const struct olc_cmd_type cedit_table[] = { /* { command function }, */ {"create", cedit_create}, {"leader", cedit_leader}, {"sponsor", cedit_sponsor}, {"name", cedit_name}, {"whoname", cedit_whoname}, {"show", cedit_show}, {"minlevel", cedit_minlevel}, {"members", cedit_members}, {"recall", cedit_recall}, {"joinflags", cedit_joinflags}, {"clanflags", cedit_clanflags}, /* To be implemented later... */ /* These will add clan-specific skills and commands. */ /* { "skill", cedit_skill }, */ {"rank", cedit_rank}, {"cost", cedit_cost}, {"?", show_help}, {"version", show_version}, {"commands", show_commands}, {"", 0,} }; void save_clans( void ) { FILE *fp; CLAN_DATA *clan; char buf[MAX_INPUT_LENGTH]; int i; if ( clan_first == NULL ) return; sprintf( buf, "%s/%s", sysconfig.area_dir, sysconfig.clans_file ); fp = fopen( buf, "w" ); if ( fp == NULL ) { bug( "Cannot write to %s !!!", sysconfig.clans_file ); return; } fprintf( fp, "#CLANS\n" ); for ( clan = clan_first; clan != NULL; clan = clan->next ) { fprintf( fp, "%d\n", clan->number ); fprintf( fp, "%s~\n", clan->name ); fprintf( fp, "%s~\n", clan->whoname ); fprintf( fp, "%s~\n", clan->leader ); fprintf( fp, "%s~\n", clan->god ); fprintf( fp, "%d\n", clan->max_members ); fprintf( fp, "%d\n", clan->min_level ); fprintf( fp, "%d\n", clan->num_members ); buf[0] = '\0'; fprintf( fp, "%s\n", fwrite_flag( clan->clan_flags, buf ) ); buf[0] = '\0'; fprintf( fp, "%s\n", fwrite_flag( clan->join_flags, buf ) ); fprintf( fp, "%d\n", clan->cost_gold ); fprintf( fp, "%d\n", clan->recall_room ); fprintf( fp, "%d\n", clan->clan_fund ); /* The reason that all of these fprintf functions have a letter to start off with is in case the MAX_* change, so the lines will be identifyable as what they are, since the number of them may change. Note: if you DECREASE the MAX_*'s, you'll need to edit the clans file and remove the excess lines. -Kyle */ for ( i = 0; i < MAX_CLAN_MEMBERS; i++ ) { if ( clan->members[i][0] != '\0' ) fprintf( fp, "M %d %s~\n", i + 1, clan->members[i] ); } for ( i = 0; i < MAX_CLAN; i++ ) { if ( clan->kills[i] != 0 ) fprintf( fp, "K %d %d\n", i + 1, clan->kills[i] ); } for ( i = 0; i < MAX_CLAN; i++ ) { if ( clan->deaths[i] != 0 ) fprintf( fp, "D %d %d\n", i + 1, clan->deaths[i] ); } for ( i = 0; i < MAX_RANK; i++ ) { fprintf( fp, "R %d %s~\n", i + 1, clan->rank[i] ); } fprintf( fp, "E\n" ); /* End of this clan. */ } fprintf( fp, "999\n#$\n#$\n" ); /* I hope you don't make more than 998 clans... :) */ fclose( fp ); return; } /* Read in str as the next string of fp. Free it if there's a string there already. -Kyle */ #define GETSTR( str ) if ( str != NULL ) \ { \ free_string( &str ); \ str = fread_string( fp ); \ } \ else \ str = fread_string( fp ); void load_clans( FILE * fp ) { int i, x, num; CLAN_DATA *clan; bool done; for ( ;; ) { num = fread_number( fp ); if ( num == 999 ) break; else clan = new_clan( ); if ( num != clan->number ) { bug( "%s clan #%d misaligned.", sysconfig.clans_file, num ); return; } GETSTR( clan->name ); GETSTR( clan->whoname ); GETSTR( clan->leader ); GETSTR( clan->god ); clan->max_members = fread_number( fp ); clan->min_level = fread_number( fp ); clan->num_members = fread_number( fp ); clan->clan_flags = fread_flag( fp ); clan->join_flags = fread_flag( fp ); clan->cost_gold = fread_number( fp ); clan->recall_room = fread_number( fp ); clan->clan_fund = fread_number( fp ); done = FALSE; for ( ; done == FALSE; ) { switch ( fread_letter( fp ) ) { default: bug( "Bad letter in %s", sysconfig.clans_file ); break; case 'M': i = fread_number( fp ); GETSTR( clan->members[i - 1] ); { for ( x = 0; x < MAX_CLAN_MEMBERS; x++ ) { if ( x == ( i - 1 ) ) continue; if ( !str_cmp ( clan->members[i - 1], clan->members[x] ) ) { free_string( &clan->members[i - 1] ); clan->members[i - 1] = str_dup( "" ); } } } break; case 'K': i = fread_number( fp ); clan->kills[i - 1] = fread_number( fp ); break; case 'D': i = fread_number( fp ); clan->deaths[i - 1] = fread_number( fp ); break; case 'R': i = fread_number( fp ); GETSTR( clan->rank[i - 1] ); break; case 'E': done = TRUE; break; } } } return; } /* * This code written by Rahl (dwa1844@rit.edu) for Broken Shadows. * * Permission to use this code is given freely as long as my * name stays with it. * - Daniel Anderson */ /* This was originally a new "log_string" function by Rahl. I changed the name of the file it records and added printf-like stuff. -Kyle */ void clan_log( CLAN_DATA * clan, char *str, ... ) { char *strtime; char logfile[20]; char buf[10]; char temp[20]; int i, j; FILE *log_file; FILE *tempfile; char param[4 * MAX_STRING_LENGTH]; /* Thanks to Tyrluk of MornMUD for showing me how to do this... -Kyle */ { va_list args; va_start( args, str ); vsprintf( param, str, args ); va_end( args ); } buf[0] = '\0'; temp[0] = '\0'; log_file = NULL; sprintf( buf, "%s", get_curdate( ) ); for ( i = 0; i < 10; i++ ) { if ( buf[i] == '/' ) buf[i] = '-'; } /* The log for clan #1 will look like: ../clan/1.01-31-99 This log will be accesable to clan leaders. -Kyle */ sprintf( temp, "%s/%d.", sysconfig.clan_dir, clan->number ); strcat( temp, buf ); if ( strcmp( temp, logfile ) ) { tempfile = fopen( temp, "a" ); if ( log_file != NULL ) fclose( log_file ); for ( j = 0; j < 20; j++ ) logfile[j] = temp[j]; log_file = fopen( logfile, "a" ); if ( tempfile != NULL ) fclose( tempfile ); } if ( log_file == NULL ) { perror( "PERROR - " ); logf_string( "Could not write to clan log file '%s'", logfile ); return; } strtime = ctime( ¤t_time ); strtime[strlen( strtime ) - 1] = '\0'; fprintf( log_file, "%s:%s\n", &strtime[10], param ); fclose( log_file ); return; } CLAN_DATA *get_clan( int clannum ) { CLAN_DATA *clan; if ( top_clan == 0 ) return NULL; for ( clan = clan_first; clan != NULL; clan = clan->next ) { if ( clan->number == clannum ) return clan; } return NULL; } CLAN_DATA *new_clan( void ) { CLAN_DATA *clan; int i; clan = alloc_perm( sizeof( CLAN_DATA ) ); if ( clan == NULL ) { bug( "Could not create clan.", 0 ); return NULL; } if ( clan_first == NULL ) top_clan = 0; top_clan++; clan->next = NULL; clan->number = top_clan; clan->name = str_dup( "Unnamed" ); clan->leader = str_dup( "None" ); clan->god = str_dup( "None" ); clan->max_members = MAX_CLAN_MEMBERS; clan->min_level = MIN_CLAN_LEVEL; clan->recall_room = ROOM_VNUM_TEMPLE; clan->whoname = str_dup( "" ); clan->command = str_dup( "" ); clan->skill = str_dup( "" ); for ( i = 0; i < MAX_RANK; i++ ) clan->rank[i] = str_dup( "" ); for ( i = 0; i < MAX_CLAN_MEMBERS; i++ ) clan->members[i] = str_dup( "" ); if ( clan_first == NULL ) { clan_first = clan; clan_last = clan; return clan; } if ( clan_last == NULL ) { bug( "clan_first but no clan_last.", 0 ); clan_last = clan; return clan; } clan_last->next = clan; clan_last = clan; return clan; } void do_cedit( CHAR_DATA * ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; CLAN_DATA *clan; int value; if ( IS_NPC( ch ) ) return; argument = one_argument( argument, arg ); if ( is_number( arg ) ) { value = atoi( arg ); if ( !( clan = get_clan( value ) ) ) { send_to_char( "CEdit: That clan does not exist.\n\r", ch ); return; } ch->desc->pEdit = ( void * ) clan; ch->desc->editor = ED_CLAN; SET_BIT( ch->act, PLR_BUILDING ); act( "$n has entered the Clan Editor.", ch, NULL, NULL, TO_ROOM ); return; } else { if ( !str_cmp( arg, "create" ) ) { if ( cedit_create( ch, argument ) ) { ch->desc->editor = ED_CLAN; SET_BIT( ch->act, PLR_BUILDING ); act( "$n has entered the Clan Editor.", ch, NULL, NULL, TO_ROOM ); } return; } } send_to_char( "CEdit: There is no default clan to edit.\n\r", ch ); return; } void cedit( CHAR_DATA * ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; CLAN_DATA *clan; char command[MAX_INPUT_LENGTH]; int cmd; smash_tilde( argument ); strcpy( arg, argument ); argument = one_argument( argument, command ); EDIT_CLAN( ch, clan ); if ( !str_cmp( command, "done" ) ) { edit_done( ch ); return; } /* Change this depending on who you want to be able to edit clans. */ if ( get_trust( ch ) < ( MAX_LEVEL - 1 ) ) { send_to_char( "CEdit: Insufficient security to modify clans.\n\r", ch ); interpret( ch, arg ); return; } if ( command[0] == '\0' ) { cedit_show( ch, argument ); return; } if ( clan == NULL ) { send_to_char( "You are not currently editing a clan.", ch ); interpret( ch, arg ); return; } /* Search Table and Dispatch Command. */ for ( cmd = 0; cedit_table[cmd].name[0] != '\0'; cmd++ ) { if ( !str_prefix( command, cedit_table[cmd].name ) ) { if ( ( *cedit_table[cmd].olc_fun ) ( ch, argument ) ) { return; } else return; } } /* Default to Standard Interpreter. */ interpret( ch, arg ); return; } CEDIT( cedit_show ) { CLAN_DATA *clan; int i; EDIT_CLAN( ch, clan ); if ( clan == NULL ) { send_to_char( "You are not currently editing a clan.", ch ); return FALSE; } printf_to_char( ch, "Name: [%s]\n\rNumber: [%2d]\n\rLeader: [%12s]\n\rSponsor: [%12s]\n\r", clan->name, clan->number, clan->leader, clan->god ); printf_to_char( ch, "Whoname: [%s]\n\rMaximum members: %d\n\rMinimum level: %d\n\r", clan->whoname, clan->max_members, clan->min_level ); printf_to_char( ch, "Clan recall: %d\n\rCost to join: %d\n\r", clan->recall_room, clan->cost_gold ); for ( i = 0; i < MAX_RANK; i++ ) { printf_to_char( ch, "Rank %d:[%30s]\n\r", i + 1, clan->rank[i][0] == '\0' ? "None" : clan->rank[i] ); } /* printf_to_char( ch, "Command: [%s]\n\rSkill: [%s]\n\r", clan->command, clan->skill ); */ printf_to_char( ch, "Clan flags: [%s]\n\r", flag_string( clan_flags, clan->clan_flags ) ); printf_to_char( ch, "Join flags: [%s]\n\r", flag_string( clan_join_flags, clan->join_flags ) ); return FALSE; } CEDIT( cedit_create ) { CLAN_DATA *clan; if ( top_clan >= MAX_CLAN ) { send_to_char( "Limit on clans has been reached.\n\r", ch ); return FALSE; } clan = new_clan( ); if ( clan == NULL ) { send_to_char( "ERROR! Could not create clan!\n\r", ch ); return FALSE; } SET_BIT( clan->clan_flags, CLAN_CREATING ); send_to_char( "Clan created.\n\r", ch ); clan_log( clan, "Clan created today!" ); ch->desc->pEdit = ( void * ) clan; return TRUE; } CEDIT( cedit_name ) { CLAN_DATA *clan; EDIT_CLAN( ch, clan ); if ( argument[0] == '\0' ) { send_to_char( "Syntax: name <clan name>\n\r", ch ); return FALSE; } if ( strlen( argument ) != str_len( argument ) ) /* Check for color codes in the name */ { send_to_char( "You may not use color codes in the clan name.\n\r", ch ); return FALSE; } if ( strlen( argument ) > 20 ) { send_to_char( "Clan names must be 20 characters or less.\n\r", ch ); return FALSE; } free_string( &clan->name ); clan->name = str_dup( argument ); send_to_char( "Clan name set.\n\r", ch ); return TRUE; } CEDIT( cedit_whoname ) { CLAN_DATA *clan; EDIT_CLAN( ch, clan ); if ( argument[0] == '\0' ) { send_to_char( "Syntax: whoname <string>\n\r", ch ); return FALSE; } if ( str_len( argument ) > 20 ) { send_to_char( "Clan whonames must be 20 characters or less.\n\r", ch ); return FALSE; } free_string( &clan->whoname ); clan->whoname = str_dup( argument ); send_to_char( "Name visible on the \"who\" listing has been set.\n\r", ch ); return TRUE; } CEDIT( cedit_rank ) { CLAN_DATA *clan; int i; char arg1[MAX_INPUT_LENGTH]; EDIT_CLAN( ch, clan ); if ( argument[0] == '\0' ) { send_to_char( "Syntax: rank <#> <title>\n\r", ch ); return FALSE; } argument = one_argument( argument, arg1 ); if ( !is_number( arg1 ) ) { send_to_char( "Syntax: rank <#> <title>\n\r", ch ); return FALSE; } i = atoi( arg1 ); if ( i < 1 || i > MAX_RANK ) { printf_to_char( ch, "Allowable rank numbers are 1 through %d.\n\r", MAX_RANK ); return FALSE; } if ( str_len( argument ) > 40 ) { send_to_char( "Rank titles must be 40 characters or shorter.\n\r", ch ); return FALSE; } free_string( &clan->rank[i - 1] ); clan->rank[i - 1] = str_dup( argument ); send_to_char( "Rank set.\n\r", ch ); return TRUE; } CEDIT( cedit_cost ) { CLAN_DATA *clan; int i; EDIT_CLAN( ch, clan ); if ( argument[0] == '\0' || !is_number( argument ) ) { send_to_char( "Syntax: cost <cost in gold>\n\r", ch ); return FALSE; } i = atoi( argument ); if ( i < 0 || i > 100000000 ) /* I think 100 million should be about the limit for cost... */ { send_to_char( "Illegal cost.\n\r", ch ); return FALSE; } clan->cost_gold = i; send_to_char( "Cost to join set.\n\r", ch ); return TRUE; } CEDIT( cedit_members ) { CLAN_DATA *clan; int i; EDIT_CLAN( ch, clan ); if ( argument[0] == '\0' || !is_number( argument ) ) { send_to_char( "Syntax: members <max members>\n\r", ch ); return FALSE; } i = atoi( argument ); if ( i < 1 || i > MAX_CLAN_MEMBERS ) { send_to_char( "That number of members is not allowed.\n\r", ch ); return FALSE; } clan->max_members = i; send_to_char( "Max members set.\n\r", ch ); return TRUE; } CEDIT( cedit_minlevel ) { CLAN_DATA *clan; char buff[MAX_STRING_LENGTH]; int i; EDIT_CLAN( ch, clan ); if ( argument[0] == '\0' || !is_number( argument ) ) { send_to_char( "Syntax: minlevel <level>\n\r", ch ); return FALSE; } i = atoi( argument ); if ( i < 1 || i > MAX_LEVEL ) { sprintf( buff, "Range is 1 to %d.\n\r", MAX_LEVEL ); send_to_char( buff, ch ); return FALSE; } clan->min_level = i; send_to_char( "Minimum level to join set.\n\r", ch ); return TRUE; } CEDIT( cedit_recall ) { CLAN_DATA *clan; int room; EDIT_CLAN( ch, clan ); if ( argument[0] == '\0' || !is_number( argument ) ) { send_to_char( "Syntax: recall <room vnum>\n\r", ch ); return FALSE; } room = atoi( argument ); if ( room < 0 || room > 32767 ) { send_to_char( "Illegal room number.\n\r", ch ); return FALSE; } if ( get_room_index( room ) == NULL ) { send_to_char( "That room does not exist.\n\r", ch ); return FALSE; } clan->recall_room = room; send_to_char( "Clan recall room set.\n\r", ch ); return TRUE; } CEDIT( cedit_leader ) { CLAN_DATA *clan; FILE *fp; char buf[MAX_INPUT_LENGTH]; EDIT_CLAN( ch, clan ); if ( argument[0] == '\0' ) { send_to_char( "You must supply an argument.\n\r", ch ); return FALSE; } #if defined(unix) /* decompress if .gz file exists */ sprintf( buf, "%s/%s%s", sysconfig.player_dir, capitalize( argument ), ".gz" ); if ( ( fp = fopen( buf, "r" ) ) != NULL ) { char buf1[MAX_INPUT_LENGTH]; fclose( fp ); sprintf( buf1, "gzip -dfq %s", buf ); system( buf1 ); } #endif sprintf( buf, "%s/%s", sysconfig.player_dir, capitalize( argument ) ); if ( ( fp = fopen( buf, "r" ) ) != NULL ) { printf_to_char( ch, "%s is now the the leader of %s.\n\r", capitalize( argument ), clan->name ); clan->leader = str_dup( capitalize( argument ) ); fclose( fp ); return TRUE; } send_to_char( "That character is not a player on this mud.\n\r", ch ); if ( fp != NULL ) fclose( fp ); return FALSE; } CEDIT( cedit_sponsor ) { CLAN_DATA *clan; char buf[MAX_INPUT_LENGTH]; FILE *fp; EDIT_CLAN( ch, clan ); if ( argument[0] == '\0' ) { send_to_char( "You must supply an argument.\n\r", ch ); return FALSE; } sprintf( buf, "%s/%s", sysconfig.god_dir, capitalize( argument ) ); if ( ( fp = fopen( buf, "r" ) ) != NULL ) { printf_to_char( ch, "%s is now the god sponsor for %s.\n\r", capitalize( argument ), clan->name ); clan->god = str_dup( capitalize( argument ) ); fclose( fp ); return TRUE; } send_to_char( "That player is not a god on this mud.\n\r", ch ); if ( fp != NULL ) fclose( fp ); return FALSE; } CEDIT( cedit_joinflags ) { CLAN_DATA *clan; int value; EDIT_CLAN( ch, clan ); if ( argument[0] != '\0' ) { if ( ( value = flag_value( clan_join_flags, argument ) ) != NO_FLAG ) { if ( value == CLAN_NO_PK && IS_SET( clan->join_flags, CLAN_REQ_PK ) ) { clan->join_flags ^= CLAN_REQ_PK; } else if ( value == CLAN_REQ_PK && IS_SET( clan->join_flags, CLAN_NO_PK ) ) { clan->join_flags ^= CLAN_NO_PK; } clan->join_flags ^= value; send_to_char( "Join flag toggled.\n\r", ch ); return TRUE; } } send_to_char( "Syntax: joinflags [flag]\n\r" "Type '? joinflags' for a list of flags.\n\r", ch ); return FALSE; } CEDIT( cedit_clanflags ) { CLAN_DATA *clan; int value; EDIT_CLAN( ch, clan ); if ( argument[0] != '\0' ) { if ( ( value = flag_value( clan_flags, argument ) ) != NO_FLAG ) { clan->clan_flags ^= value; send_to_char( "Clan flag toggled.\n\r", ch ); return TRUE; } } send_to_char( "Syntax: clanflags <auto-accept/private/secret>\n\r", ch ); return FALSE; } bool can_ch_join( CHAR_DATA * ch, CLAN_DATA * clan, bool is_petitioning ) { if ( ch->level < clan->min_level ) { printf_to_char( ch, "You must be level %d to join this clan.\n\r", clan->min_level ); return FALSE; } if ( ( IS_SET( clan->join_flags, CLAN_ANTI_MAGE ) && ch->Class == CLASS_MAGE ) || ( IS_SET( clan->join_flags, CLAN_ANTI_CLERIC ) && ch->Class == CLASS_CLERIC ) || ( IS_SET( clan->join_flags, CLAN_ANTI_WARRIOR ) && ch->Class == CLASS_WARRIOR ) || ( IS_SET( clan->join_flags, CLAN_ANTI_THIEF ) && ch->Class == CLASS_THIEF ) ) { send_to_char( "This clan does not allow your class to join.\n\r", ch ); return FALSE; } if ( IS_SET( clan->join_flags, CLAN_REQ_PK ) && !IS_SET( ch->act, PLR_KILLER ) ) { send_to_char( "You must be a player killer to join this clan.\n\r", ch ); send_to_char( "Type PK twice to become a player killer.\n\r", ch ); return FALSE; } if ( IS_SET( clan->join_flags, CLAN_NO_PK ) && IS_SET( ch->act, PLR_KILLER ) ) { send_to_char( "You may not be a player killer and join this clan.\n\r", ch ); send_to_char ( "Ask a high level god to remove your killer flag if you still wish to join.\n\r", ch ); return FALSE; } if ( IS_SET( clan->join_flags, CLAN_ANTI_EVIL ) && IS_EVIL( ch ) ) { send_to_char( "Evil-aligned players may not join this clan.\n\r", ch ); return FALSE; } if ( IS_SET( clan->join_flags, CLAN_ANTI_GOOD ) && IS_GOOD( ch ) ) { send_to_char( "Good-aligned players may not join this clan.\n\r", ch ); return FALSE; } if ( !IS_SET( clan->clan_flags, CLAN_AUTO_ACCEPT ) && !is_petitioning ) { send_to_char( "This clan does not auto-accept new members.\n\r", ch ); send_to_char( "Use the PETITION command on one of its members.\n\r", ch ); return FALSE; } return TRUE; } void add_member( CHAR_DATA * ch, CLAN_DATA * clan ) { int i; for ( i = 0; i < clan->max_members; i++ ) { if ( clan->members[i][0] == '\0' ) { free_string( &clan->members[i] ); clan->members[i] = str_dup( ch->name ); clan->num_members++; clan_log( clan, "New member: %s", ch->name ); save_clans( ); do_save( ch, "" ); return; } } bug( "Add_member: No spots in clan %d!", clan->number ); return; } void remove_member( CHAR_DATA * ch, CLAN_DATA * clan ) { int i; for ( i = 0; i < clan->max_members; i++ ) { if ( !str_cmp( clan->members[i], ch->name ) ) { free_string( &clan->members[i] ); clan->members[i] = str_dup( "" ); clan->num_members--; clan_log( clan, "Removed from clan: %s", ch->name ); save_clans( ); do_save( ch, "" ); return; } } bug( "Add_member: Name not found in clan %d!", clan->number ); return; } void do_show( CHAR_DATA * ch, char *argument ) { CLAN_DATA *clan; char arg1[MAX_INPUT_LENGTH]; int num = 0; bool found = FALSE; argument = one_argument( argument, arg1 ); if ( clan_first == NULL ) { send_to_char( "There are no clans at all yet.\n\r", ch ); return; } if ( !str_cmp( arg1, "active" ) ) { found = FALSE; send_to_char( "Clans actively recruiting:\n\r", ch ); send_to_char( "===============================\n\r", ch ); for ( clan = clan_first; clan != NULL; clan = clan->next ) { if ( IS_SET( clan->clan_flags, CLAN_ACTIVE ) && ( !IS_SET( clan->clan_flags, CLAN_SECRET ) || IS_IMMORTAL( ch ) ) && clan->num_members < MAX_CLAN_MEMBERS ) { num++; printf_to_char( ch, "[%3d] %s\n\r", num, clan->name ); found = TRUE; } } if ( found == FALSE ) { send_to_char( "No clans are publicly recruiting.\n\r", ch ); } return; } if ( !str_cmp( arg1, "inactive" ) ) { found = FALSE; send_to_char( "Clans not actively recruiting:\n\r", ch ); send_to_char( "===============================\n\r", ch ); for ( clan = clan_first; clan != NULL; clan = clan->next ) { if ( ( IS_SET( clan->clan_flags, CLAN_INACTIVE ) && ( !IS_SET( clan->clan_flags, CLAN_SECRET ) || IS_IMMORTAL( ch ) ) ) || ( ( IS_SET( clan->clan_flags, CLAN_ACTIVE ) && !IS_SET( clan->clan_flags, CLAN_SECRET ) && clan->num_members >= MAX_CLAN_MEMBERS ) ) ) { num++; printf_to_char( ch, "[%3d] %s\n\r", num, clan->name ); found = TRUE; } } if ( found == FALSE ) { send_to_char( "No clans are inactive at this time.\n\r", ch ); } return; } if ( !str_cmp( arg1, "all" ) ) { found = FALSE; send_to_char( "Current existing clans:\n\r", ch ); send_to_char( "===============================\n\r", ch ); for ( clan = clan_first; clan != NULL; clan = clan->next ) { if ( ( !IS_SET( clan->clan_flags, CLAN_SECRET ) && ( IS_SET( clan->clan_flags, CLAN_ACTIVE ) || IS_SET( clan->clan_flags, CLAN_INACTIVE ) ) ) || IS_IMMORTAL( ch ) ) { num++; printf_to_char( ch, "[%3d] %s\n\r", num, clan->name ); found = TRUE; } } if ( found == FALSE ) { send_to_char( "None.\n\r", ch ); } return; } if ( !str_cmp( arg1, "members" ) ) { if ( IS_NPC( ch ) ) return; if ( ch->pcdata->clan > 0 ) { clan = get_clan( ch->pcdata->clan ); printf_to_char( ch, "Sponsor: %s\n\rLeader: %s\n\r", clan->god, clan->leader ); send_to_char( "Members:\n\r", ch ); for ( num = 0; num < MAX_CLAN_MEMBERS; num++ ) { printf_to_char( ch, "%s ", clan->members[num] ); if ( num != 0 && num % 5 == 0 ) send_to_char( "\n\r", ch ); } send_to_char( "\n\r", ch ); } return; } if ( IS_NPC( ch ) ) return; if ( ch->pcdata->clan == 0 ) { send_to_char( "Syntax: show <active/inactive/all>\n\r", ch ); return; } send_to_char( "Syntax: show <active/inactive/all/members>\n\r", ch ); return; } void do_join( CHAR_DATA * ch, char *argument ) { CLAN_DATA *clan; int num, i = 0; char arg1[MAX_INPUT_LENGTH]; if ( IS_NPC( ch ) ) { send_to_char( "Are you nuts? NPC's may not join clans!\n\r", ch ); return; } if ( ch->pcdata == NULL ) return; if ( ch->pcdata->clan != 0 ) { send_to_char( "You are already a member of a clan! Duh!\n\r", ch ); return; } if ( argument[0] == '\0' && ch->pcdata->join_status != JOIN_START ) { send_to_char( "Syntax: join <clan number, 0 to cancel>\n\r", ch ); return; } argument = one_argument( argument, arg1 ); switch ( ch->pcdata->join_status ) { case JOIN_START: send_to_char( "This is a list of actively recruiting clans.\n\r", ch ); do_show( ch, "active" ); send_to_char( "\n\rTo see this list again, type 'show active'.\n\r", ch ); send_to_char ( "To join a clan, type JOIN followed by the number of the clan.\n\r", ch ); ch->pcdata->join_status = JOIN_SEE_LIST; return; case JOIN_SEE_LIST: if ( !is_number( arg1 ) ) { send_to_char( "You must join a clan by using its number.\n\r", ch ); return; } num = atoi( arg1 ); if ( num == 0 ) { send_to_char( "Cancelling your joining of a clan.\n\r", ch ); ch->pcdata->join_status = JOIN_START; return; } for ( clan = clan_first; clan != NULL; clan = clan->next ) { if ( IS_SET( clan->clan_flags, CLAN_ACTIVE ) && !IS_SET( clan->clan_flags, CLAN_SECRET ) && clan->num_members < MAX_CLAN_MEMBERS ) { i++; if ( num == i ) { printf_to_char( ch, "You are attempting to join clan #%d, %s.\n\r", num, clan->name ); if ( can_ch_join( ch, clan, FALSE ) == FALSE ) return; send_to_char( "You are eligable to join.\n\r", ch ); if ( clan->cost_gold > 0 ) { printf_to_char( ch, "This clan costs %d gold to join.\n\r", clan->cost_gold ); if ( ch->gold < clan->cost_gold ) { send_to_char( "You cannot afford to join!\n\r", ch ); return; } } printf_to_char( ch, "To confirm, please type JOIN %d\n\r", num ); send_to_char( "Type JOIN 0 to cancel this choice.\n\r", ch ); ch->pcdata->join_status = JOIN_CONFIRM; ch->pcdata->join_clan = num; return; } } } send_to_char( "That clan does not exist.\n\r", ch ); return; case JOIN_CONFIRM: if ( !is_number( arg1 ) ) { send_to_char( "You must join a clan by using its number.\n\r", ch ); return; } num = atoi( arg1 ); if ( num == 0 ) { send_to_char( "Your selection of a clan has been canceled.\n\r", ch ); ch->pcdata->join_status = JOIN_START; ch->pcdata->join_clan = 0; return; } if ( num != ch->pcdata->join_clan ) { send_to_char( "Your clan selections do not match.\n\r", ch ); printf_to_char( ch, "Type JOIN 0 to cancel or JOIN %d to confirm.\n\r", ch->pcdata->join_clan ); } for ( clan = clan_first; clan != NULL; clan = clan->next ) { if ( IS_SET( clan->clan_flags, CLAN_ACTIVE ) && !IS_SET( clan->clan_flags, CLAN_SECRET ) && clan->num_members < MAX_CLAN_MEMBERS ) { i++; if ( num == i ) { if ( clan->cost_gold > 0 ) { printf_to_char( ch, "This clan costs %d gold to join.\n\r", clan->cost_gold ); if ( clan->cost_gold > ch->gold ) { send_to_char( "You cannot afford this clan!\n\r", ch ); do_join( ch, "0" ); return; } ch->gold -= clan->cost_gold; clan->clan_fund += clan->cost_gold; printf_to_char( ch, "You now have %d gold left.\n\r", ch->gold ); } printf_to_char( ch, "You are now a member of clan #%d, %s!\n\r", i, clan->name ); ch->pcdata->clan = clan->number; ch->pcdata->join_status = JOIN_START; add_member( ch, clan ); ch->pcdata->clan_rank = MAX_RANK; return; } } } case JOIN_PETITIONING: send_to_char( "You are currently petitioning to join a clan.\n\r", ch ); send_to_char ( "If you are refused, then you may use the JOIN command again.\n\r", ch ); return; case JOIN_DECIDING: send_to_char( "You have already been invited to join a clan.\n\r", ch ); send_to_char( "Use the ACCEPT or DECLINE commands to join or not.\n\r", ch ); return; case JOIN_CONSIDERING: case JOIN_OFFERING: send_to_char( "Doh, a bug. Ignore this.\n\r", ch ); bug( "Ch without clan in JOIN_CONSIDERING or JOIN_OFFERING", 0 ); ch->pcdata->join_status = JOIN_START; return; default: send_to_char( "Doh, a bug. Ignore this.\n\r", ch ); bug( "Unknown join_status %d!", ch->pcdata->join_status ); ch->pcdata->join_status = JOIN_START; return; } return; } void do_petition( CHAR_DATA * ch, char *argument ) { char arg1[MAX_INPUT_LENGTH]; CLAN_DATA *clan; CHAR_DATA *victim; if ( IS_NPC( ch ) ) return; if ( ch->pcdata == NULL ) return; if ( ch->pcdata->clan != 0 ) { send_to_char( "You are already a member of a clan!\n\r", ch ); return; } if ( ch->pcdata->join_status == JOIN_PETITIONING ) { send_to_char( "You are already petitioning to join a clan!\n\r", ch ); return; } if ( ch->pcdata->join_status == JOIN_DECIDING ) { send_to_char( "You have already been offered membership in a clan!\n\r", ch ); send_to_char( "Type ACCEPT or DECLINE.\n\r", ch ); } if ( argument[0] == '\0' ) { send_to_char( "Petition who?\n\r", ch ); return; } argument = one_argument( argument, arg1 ); victim = get_char_world( ch, arg1 ); if ( victim == NULL ) { send_to_char( "Petition who?\n\r", ch ); return; } if ( IS_NPC( victim ) ) { send_to_char( "Only players can be petitioned!\n\r", ch ); return; } if ( victim->pcdata == NULL ) return; if ( victim->pcdata->clan == 0 ) { send_to_char( "That person is not a member of a clan.\n\r", ch ); return; } if ( victim->pcdata->clan_ch != ch && victim->pcdata->clan_ch != NULL ) { send_to_char ( "That person is currently being petitioned by someone else.\n\r", ch ); return; } if ( victim->pcdata->clan_ch == ch ) { send_to_char( "You are already petitioning them! Be patient!\n\r", ch ); return; } clan = get_clan( victim->pcdata->clan ); if ( clan == NULL ) { bug( "NULL clan %d", victim->pcdata->clan ); return; } if ( IS_SET( clan->clan_flags, CLAN_SECRET ) ) { send_to_char( "That person is not a member of a clan.\n\r", ch ); return; } if ( victim->pcdata->clan_rank > RANK_CAN_ACCEPT || victim->pcdata->clan_rank < 1 ) { send_to_char ( "That person is not of sufficient rank to accept you.\n\r", ch ); return; } if ( can_ch_join( ch, clan, TRUE ) == FALSE ) return; if ( clan->cost_gold > 0 ) { printf_to_char( ch, "It costs %d gold to join.\n\r", clan->cost_gold ); if ( clan->cost_gold > ch->gold ) { send_to_char( "You cannot afford it!\n\r", ch ); return; } } clan_log( clan, "%s petitions %s to join.", ch->name, victim->name ); printf_to_char( victim, "%s has petitioned to join your clan!\n\r", ch->name ); send_to_char( "Type ACCEPT or DECLINE, or talk to them for a while.\n\r", victim ); send_to_char( "Petition sent!\n\r", ch ); ch->pcdata->join_status = JOIN_PETITIONING; victim->pcdata->join_status = JOIN_CONSIDERING; ch->pcdata->clan_ch = victim; victim->pcdata->clan_ch = ch; return; } void do_accept( CHAR_DATA * ch, char *argument ) { CLAN_DATA *clan; if ( IS_NPC( ch ) ) return; if ( ch->pcdata == NULL ) return; if ( ch->pcdata->join_status != JOIN_DECIDING && ch->pcdata->join_status != JOIN_CONSIDERING ) { send_to_char( "What, exactly, are you trying to accept?\n\r", ch ); return; } if ( ch->pcdata->join_status == JOIN_CONSIDERING ) { clan = get_clan( ch->pcdata->clan ); if ( clan->cost_gold > ch->pcdata->clan_ch->gold ) { send_to_char( "They can no longer afford to join.\n\r", ch ); send_to_char( "Use DECLINE to refuse, or wait come more.\n\r", ch ); return; } clan_log( clan, "Petition accepted by %s", ch->name ); printf_to_char( ch, "You accept %s into clan %s!\n\r", ch->pcdata->clan_ch->name, clan->name ); printf_to_char( ch->pcdata->clan_ch, "You have been accepted into clan %s!\n\r", clan->name ); ch->pcdata->clan_ch->gold -= clan->cost_gold; clan->clan_fund += clan->cost_gold; ch->pcdata->clan_ch->pcdata->clan = clan->number; ch->pcdata->clan_ch->pcdata->clan_rank = MAX_RANK; ch->pcdata->clan_ch->pcdata->join_status = JOIN_START; ch->pcdata->clan_ch->pcdata->clan_ch = NULL; ch->pcdata->clan_ch->pcdata->join_clan = 0; add_member( ch->pcdata->clan_ch, clan ); ch->pcdata->clan_ch = NULL; ch->pcdata->join_status = JOIN_START; return; } clan = get_clan( ch->pcdata->clan_ch->pcdata->clan ); if ( ch->gold < clan->cost_gold ) { send_to_char( "You cannot afford to join that clan!\n\r", ch ); send_to_char ( "Use DECLINE to turn them down or go get more gold fast.\n\r", ch ); return; } clan_log( clan, "%s accepts membership.", ch->name ); printf_to_char( ch, "You accept membership in clan %s!\n\r", clan->name ); printf_to_char( ch->pcdata->clan_ch, "%s has accepted membership in your clan!\n\r", ch->name ); ch->gold -= clan->cost_gold; clan->clan_fund += clan->cost_gold; ch->pcdata->clan = clan->number; ch->pcdata->clan_rank = MAX_RANK; ch->pcdata->join_status = JOIN_START; add_member( ch, clan ); ch->pcdata->clan_ch->pcdata->clan_ch = NULL; ch->pcdata->clan_ch->pcdata->join_status = JOIN_START; ch->pcdata->clan_ch = NULL; return; } void do_decline( CHAR_DATA * ch, char *argument ) { CLAN_DATA *clan; if ( IS_NPC( ch ) ) return; if ( ch->pcdata == NULL ) return; if ( ch->pcdata->join_status != JOIN_DECIDING && ch->pcdata->join_status != JOIN_CONSIDERING ) { send_to_char( "What, exactly, are you trying to decline?\n\r", ch ); return; } if ( ch->pcdata->join_status == JOIN_CONSIDERING ) { clan = get_clan( ch->pcdata->clan ); clan_log( clan, "%s declines the petition.", ch->name ); printf_to_char( ch, "You decline to accept %s into clan %s.\n\r", ch->pcdata->clan_ch->name, clan->name ); printf_to_char( ch->pcdata->clan_ch, "You have been denied membership into clan %s.\n\r", clan->name ); ch->pcdata->clan_ch->pcdata->join_status = JOIN_START; ch->pcdata->clan_ch->pcdata->clan_ch = NULL; ch->pcdata->clan_ch = NULL; ch->pcdata->join_status = JOIN_START; return; } clan = get_clan( ch->pcdata->clan_ch->pcdata->clan ); clan_log( clan, "%s declines to join.", ch->name ); printf_to_char( ch, "You decline membership in clan %s.\n\r", clan->name ); printf_to_char( ch->pcdata->clan_ch, "%s has declined membership in your clan.\n\r", ch->name ); ch->pcdata->clan_ch->pcdata->join_status = JOIN_START; ch->pcdata->clan_ch->pcdata->clan_ch = NULL; ch->pcdata->clan_ch = NULL; ch->pcdata->join_status = JOIN_START; return; } void do_offer( CHAR_DATA * ch, char *argument ) { CLAN_DATA *clan; CHAR_DATA *victim; if ( IS_NPC( ch ) || ch->pcdata == NULL ) return; if ( ch->pcdata->clan == 0 ) { send_to_char ( "You can't offer membership in a clan if you are clanless!\n\r", ch ); return; } victim = get_char_world( ch, argument ); if ( victim == NULL ) { send_to_char( "Offer membership to who?\n\r", ch ); return; } if ( IS_NPC( victim ) || victim->pcdata == NULL ) { send_to_char( "You cannot offer membership to NPC's.\n\r", ch ); return; } if ( ch->pcdata->join_status != 0 && ch->pcdata->clan_ch != NULL ) { printf_to_char( ch, "You are currently being petitioned by or offering membership to %s.\n\r", ch->pcdata->clan_ch->name ); return; } clan = get_clan( ch->pcdata->clan ); if ( ch->pcdata->clan_rank < 1 || ch->pcdata->clan_rank > RANK_CAN_ACCEPT ) { send_to_char ( "You are not of high enough rank to offer membership to anyone.\n\r", ch ); return; } if ( victim->pcdata->join_status > JOIN_SEE_LIST ) { send_to_char ( "That player is considering membership in another clan.\n\r", ch ); send_to_char( "Better make them change their mind, fast! :)\n\r", ch ); return; } /* The reason the "That person is ineligable to join your clan." message is everywhere is to preserve the secretness of the secret clans. */ if ( victim->pcdata->clan != 0 ) { CLAN_DATA *tmpclan; tmpclan = get_clan( victim->pcdata->clan ); if ( IS_SET( tmpclan->clan_flags, CLAN_SECRET ) ) send_to_char( "That person is ineligable to join your clan.\n\r", ch ); else send_to_char( "That person is already a member of a clan!\n\r", ch ); return; } if ( victim->level < clan->min_level ) { send_to_char( "That person is ineligable to join your clan.\n\r", ch ); send_to_char( "To find out why, they must petition you.\n\r", ch ); return; } if ( ( IS_SET( clan->join_flags, CLAN_ANTI_MAGE ) && victim->Class == CLASS_MAGE ) || ( IS_SET( clan->join_flags, CLAN_ANTI_CLERIC ) && victim->Class == CLASS_CLERIC ) || ( IS_SET( clan->join_flags, CLAN_ANTI_WARRIOR ) && victim->Class == CLASS_WARRIOR ) || ( IS_SET( clan->join_flags, CLAN_ANTI_THIEF ) && victim->Class == CLASS_THIEF ) ) { send_to_char( "That person is ineligable to join your clan.\n\r", ch ); return; } if ( IS_SET( clan->join_flags, CLAN_REQ_PK ) && !IS_SET( victim->act, PLR_KILLER ) ) { send_to_char( "That person is ineligable to join your clan.\n\r", ch ); return; } if ( IS_SET( clan->join_flags, CLAN_NO_PK ) && IS_SET( victim->act, PLR_KILLER ) ) { send_to_char( "That person is ineligable to join your clan.\n\r", ch ); return; } if ( IS_SET( clan->join_flags, CLAN_ANTI_EVIL ) && IS_EVIL( victim ) ) { send_to_char( "That person is ineligable to join your clan.\n\r", ch ); return; } if ( IS_SET( clan->join_flags, CLAN_ANTI_GOOD ) && IS_GOOD( victim ) ) { send_to_char( "That person is ineligable to join your clan.\n\r", ch ); return; } if ( victim->gold < clan->cost_gold ) { send_to_char( "They cannot afford to join! they are too poor!\n\r", ch ); return; } printf_to_char( ch, "You offer %s membership in clan %s.\n\r", victim->name, clan->name ); printf_to_char( victim, "You have been offered membership in clan %s by %s!\n\r", clan->name, ch->name ); if ( clan->cost_gold > 0 ) printf_to_char( victim, "It will cost %d gold to join.\n\r", clan->cost_gold ); clan_log( clan, "Membership offered to %s by %s.", victim->name, ch->name ); ch->pcdata->clan_ch = victim; ch->pcdata->join_status = JOIN_OFFERING; victim->pcdata->clan_ch = ch; victim->pcdata->join_status = JOIN_DECIDING; return; } void do_promote( CHAR_DATA * ch, char *argument ) { CLAN_DATA *clan; CHAR_DATA *victim; char buf[MAX_INPUT_LENGTH]; if ( IS_NPC( ch ) ) return; if ( ch->pcdata == NULL ) return; if ( argument[0] == '\0' ) { send_to_char( "Promote who?\n\r", ch ); return; } victim = get_char_world( ch, argument ); if ( victim == NULL ) { send_to_char( "Promote who?\n\r", ch ); return; } if ( IS_NPC( victim ) ) { send_to_char( "Um, you can't promote mobs.\n\r", ch ); return; } if ( victim->pcdata->clan == 0 ) { send_to_char( "Um, they must join a clan to be promoted.\n\r", ch ); return; } if ( get_trust( ch ) < MAX_LEVEL ) /* IMPS can promote anyone :) */ { if ( ch->pcdata->clan == 0 ) { send_to_char( "You are not a member of a clan!\n\r", ch ); return; } if ( ch->pcdata->clan != victim->pcdata->clan ) { send_to_char( "They are not even IN your clan!\n\r", ch ); return; } if ( victim->pcdata->clan_rank < 1 ) { victim->pcdata->clan_rank = MAX_RANK; } if ( ch->pcdata->clan_rank > 2 ) { send_to_char( "You are not high enough rank to promote anyone.\n\r", ch ); return; } clan = get_clan( ch->pcdata->clan ); if ( str_cmp( ch->name, clan->leader ) ) { if ( ( ch->pcdata->clan_rank == 2 && victim->pcdata->clan_rank < 4 ) || ( ch->pcdata->clan_rank == 1 && victim->pcdata->clan_rank < 3 ) ) { send_to_char ( "Only the clan leader, an IMP, or a higher rank can promote them.\n\r", ch ); return; } } } else { clan = get_clan( victim->pcdata->clan ); } if ( victim->pcdata->clan_rank < 2 ) { send_to_char( "That person's rank is as high as it can be!\n\r", ch ); return; } printf_to_char( ch, "You promote %s to %s!\n\r", victim->name, clan->rank[victim->pcdata->clan_rank - 2] ); victim->pcdata->clan_rank--; printf_to_char( victim, "%s promotes you to %s in clan %s!\n\r", ch->name, clan->rank[victim->pcdata->clan_rank - 1], clan->name ); sprintf( buf, "%s promoted %s in clan %d.", ch->name, victim->name, clan->number ); log_string( buf ); clan_log( clan, "%s promoted %s to %s.", ch->name, victim->name, clan->rank[victim->pcdata->clan_rank - 1] ); return; } void do_clan( CHAR_DATA * ch, char *argument ) { CLAN_DATA *clan; const char syntax[] = "Syntax: clan list\n\r clan snoop\n\r clan <clan #> view\n\r clan <clan #> member <add/remove> <member name>\n\r clan <clan #> bank <deposit/withdraw> <amount>\n\r clan <clan #> status <creating/active/inactive/disbanding/dead>\n\r"; char arg1[MAX_INPUT_LENGTH]; char arg2[MAX_INPUT_LENGTH]; char arg3[MAX_INPUT_LENGTH]; int i, active = 0, recruit = 0, x; argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); argument = one_argument( argument, arg3 ); if ( arg1[0] == '\0' ) { send_to_char( syntax, ch ); return; } if ( !str_cmp( arg1, "list" ) ) { if ( clan_first == NULL ) { send_to_char( "There are no clans. Use 'edit clan create'.\n\r", ch ); return; } send_to_char ( "`wNumber Name Status Fund\n\r", ch ); send_to_char ( "`K====== ============================== ==================== ==========`w\n\r", ch ); for ( clan = clan_first; clan != NULL; clan = clan->next ) { printf_to_char( ch, "%6d %30s %20s %10d\n\r", clan->number, clan->name, flag_string( clan_flags, clan->clan_flags ), clan->clan_fund ); if ( clan->num_members < clan->max_members && IS_SET( clan->clan_flags, CLAN_ACTIVE ) ) recruit++; if ( IS_SET( clan->clan_flags, CLAN_ACTIVE ) ) active++; } printf_to_char( ch, "Active Clans: %d\n\rRecruiting Clans: %d\n\r", active, recruit ); return; } if ( !str_cmp( arg1, "snoop" ) ) { if ( IS_SET( ch->comm, COMM_SNOOP_CLAN ) ) { REMOVE_BIT( ch->comm, COMM_SNOOP_CLAN ); send_to_char( "You no longer are snooping the clan channels.\n\r", ch ); return; } else { SET_BIT( ch->comm, COMM_SNOOP_CLAN ); send_to_char( "You are now snooping clans.\n\r", ch ); return; } return; } if ( !is_number( arg1 ) ) { send_to_char( syntax, ch ); return; } i = atoi( arg1 ); clan = get_clan( i ); if ( clan == NULL ) { send_to_char( "No such clan.\n\r", ch ); return; } if ( !str_cmp( arg2, "view" ) ) { printf_to_char( ch, "Name: [%s]\n\rNumber: [%2d]\n\rLeader: [%12s]\n\rSponsor:[%12s]\n\r", clan->name, clan->number, clan->leader, clan->god ); send_to_char( "Members:", ch ); for ( x = 0; x < MAX_CLAN_MEMBERS; x++ ) { printf_to_char( ch, " %s", clan->members[x] ); } send_to_char( "\n\r", ch ); printf_to_char( ch, "Recall: %d\n\rClan fund: %d\n\r", clan->recall_room, clan->clan_fund ); printf_to_char( ch, "Clan status: %s\n\r", flag_string( clan_flags, clan->clan_flags ) ); return; } if ( !str_cmp( arg2, "member" ) ) { CHAR_DATA *victim; victim = get_char_world( ch, argument ); if ( ( victim == NULL ) || ( argument[0] == '\0' ) ) { send_to_char( "Player not found!\n\r", ch ); return; } if ( IS_NPC( victim ) ) { send_to_char( "Not on NPCs.\n\r", ch ); return; } if ( !str_cmp( arg3, "add" ) ) { if ( victim->pcdata->clan != 0 ) { send_to_char( "They are already in a clan.", ch ); return; } if ( !can_ch_join( victim, clan, TRUE ) == FALSE ) { send_to_char ( "WARNING! This player does not meet the requirements of that clan!\n\r", ch ); } victim->pcdata->clan = clan->number; victim->pcdata->clan_rank = MAX_RANK; victim->pcdata->join_status = JOIN_START; victim->pcdata->clan_ch = NULL; add_member( victim, clan ); printf_to_char( victim, "You have been made a member of %s.\n\r", clan->name ); send_to_char( "Member added.\n\r", ch ); return; } if ( !str_cmp( arg3, "remove" ) ) { if ( victim->pcdata->clan != clan->number ) { send_to_char( "They are not a member of that clan!", ch ); return; } victim->pcdata->clan = 0; victim->pcdata->clan_rank = 0; victim->pcdata->join_status = 0; victim->pcdata->clan_ch = NULL; remove_member( victim, clan ); printf_to_char( victim, "You have been removed from %s.\n\r", clan->name ); send_to_char( "Member removed.\n\r", ch ); return; } send_to_char( syntax, ch ); return; } if ( !str_cmp( arg2, "bank" ) || !str_cmp( arg2, "fund" ) ) { int mod; if ( argument[0] == '\0' || !is_number( argument ) ) { send_to_char( syntax, ch ); return; } mod = atoi( argument ); if ( mod <= 0 ) { send_to_char( "Positive numbers ONLY.\n\r", ch ); return; } if ( !str_cmp( arg3, "deposit" ) ) { clan->clan_fund += mod; printf_to_char( ch, "Balance: %d\n\r", clan->clan_fund ); clan_log( clan, "%d credited by %s.", mod, ch->name ); save_clans( ); return; } if ( !str_cmp( arg3, "withdraw" ) ) { if ( mod > clan->clan_fund ) { send_to_char( "The clan cannot afford that.\n\r", ch ); return; } clan->clan_fund -= mod; printf_to_char( ch, "Balance: %d\n\r", clan->clan_fund ); clan_log( clan, "%d funds deducted by %s.", mod, ch->name ); save_clans( ); return; } send_to_char( syntax, ch ); return; } if ( !str_cmp( arg2, "status" ) ) { if ( !str_cmp( arg3, "creating" ) ) { REMOVE_BIT( clan->clan_flags, CLAN_ACTIVE ); REMOVE_BIT( clan->clan_flags, CLAN_INACTIVE ); REMOVE_BIT( clan->clan_flags, CLAN_DISBANDING ); REMOVE_BIT( clan->clan_flags, CLAN_DEAD ); SET_BIT( clan->clan_flags, CLAN_CREATING ); printf_to_char( ch, "Clan %s is now in the 'creating' stage.\n\r", clan->name ); save_clans( ); return; } if ( !str_cmp( arg3, "active" ) ) { REMOVE_BIT( clan->clan_flags, CLAN_INACTIVE ); REMOVE_BIT( clan->clan_flags, CLAN_CREATING ); REMOVE_BIT( clan->clan_flags, CLAN_DISBANDING ); REMOVE_BIT( clan->clan_flags, CLAN_DEAD ); SET_BIT( clan->clan_flags, CLAN_ACTIVE ); printf_to_char( ch, "Clan %s is now in the 'active' stage.\n\r", clan->name ); clan_log( clan, "Clan is now active." ); save_clans( ); return; } if ( !str_cmp( arg3, "inactive" ) ) { REMOVE_BIT( clan->clan_flags, CLAN_ACTIVE ); REMOVE_BIT( clan->clan_flags, CLAN_CREATING ); REMOVE_BIT( clan->clan_flags, CLAN_DISBANDING ); REMOVE_BIT( clan->clan_flags, CLAN_DEAD ); SET_BIT( clan->clan_flags, CLAN_INACTIVE ); printf_to_char( ch, "Clan %s is now in the 'inactive' stage.\n\r", clan->name ); clan_log( clan, "The clan is no longer recruiting." ); save_clans( ); return; } if ( !str_cmp( arg3, "disbanding" ) ) { REMOVE_BIT( clan->clan_flags, CLAN_ACTIVE ); REMOVE_BIT( clan->clan_flags, CLAN_INACTIVE ); REMOVE_BIT( clan->clan_flags, CLAN_CREATING ); REMOVE_BIT( clan->clan_flags, CLAN_DEAD ); SET_BIT( clan->clan_flags, CLAN_DISBANDING ); printf_to_char( ch, "Clan %s is now in the 'disbanding' stage.\n\r", clan->name ); clan_log( clan, "The clan is now disbanding." ); save_clans( ); return; } if ( !str_cmp( arg3, "dead" ) ) { REMOVE_BIT( clan->clan_flags, CLAN_ACTIVE ); REMOVE_BIT( clan->clan_flags, CLAN_INACTIVE ); REMOVE_BIT( clan->clan_flags, CLAN_CREATING ); REMOVE_BIT( clan->clan_flags, CLAN_DISBANDING ); SET_BIT( clan->clan_flags, CLAN_DEAD ); printf_to_char( ch, "Clan %s is now in the 'dead' stage.\n\r", clan->name ); clan_log( clan, "The clan is now dead." ); save_clans( ); return; } send_to_char( syntax, ch ); return; } send_to_char( syntax, ch ); return; } void do_clantalk( CHAR_DATA * ch, char *argument ) { DESCRIPTOR_DATA *d; CLAN_DATA *clan; if ( IS_NPC( ch ) ) { send_to_char( "Getting lonely?\n\r", ch ); return; } if ( ( clan = get_clan( ch->pcdata->clan ) ) == NULL ) { send_to_char( "You are not even in a clan!\n\r", ch ); return; } if ( IS_SET( ch->comm, COMM_QUIET ) ) { send_to_char( "You must turn off quiet mode first.\n\r", ch ); return; } if ( IS_SET( ch->comm, COMM_NOCHANNELS ) ) { send_to_char( "The gods have revoked your channel priviliges.\n\r", ch ); return; } if ( argument[0] == '\0' ) { if ( IS_SET( ch->comm, COMM_NOCLAN ) ) { send_to_char( "`BClan channel is now ON.\n\r`w", ch ); REMOVE_BIT( ch->comm, COMM_NOCLAN ); } else { send_to_char( "`BClan channel is now OFF.\n\r`w", ch ); SET_BIT( ch->comm, COMM_NOCLAN ); } } /* Re-enable the channel if it was disabled */ REMOVE_BIT( ch->comm, COMM_NOCLAN ); #ifdef CLANTALK_DRUNK /* Make the words drunk if needed */ if ( !IS_NPC( ch ) && ch->pcdata->condition[COND_DRUNK] > 10 ) argument = makedrunk( argument, ch ); #endif /* * Loop through the players that are online and send the clan message to * fellow clan members. */ for ( d = descriptor_list; d != NULL; d = d->next ) { CHAR_DATA *victim; victim = d->original ? d->original : d->character; if ( d->connected == CON_PLAYING && ( ( !IS_NPC( victim ) && d->character->position >= POS_SLEEPING && victim->pcdata->clan == ch->pcdata->clan ) || IS_SET( victim->comm, COMM_SNOOP_CLAN ) ) && !IS_SET( victim->comm, COMM_DEAF ) && !IS_SET( victim->comm, COMM_QUIET ) && !IS_SET( victim->comm, COMM_NOCLAN ) ) { printf_to_char( victim, "`B%s`R<`w%s`R>`w %s`w\n\r", clan->whoname[0] != '\0' ? clan->whoname : clan->name, IS_NPC( ch ) ? ch->short_descr : ch->name, argument ); } } /* Descriptor Loop */ } void do_resign( CHAR_DATA * ch, char *argument ) { CLAN_DATA *clan; if ( IS_NPC( ch ) ) { send_to_char( "You cannot resign from a clan, you're a mob!\n\r", ch ); return; } if ( ch->pcdata->clan == 0 ) { send_to_char ( "You're not in a clan, so how can you resign from one?\n\r", ch ); return; } clan = get_clan( ch->pcdata->clan ); if ( !str_cmp( clan->leader, ch->name ) || !str_cmp( clan->god, ch->name ) ) { send_to_char ( "You cannot resign from this clan, you're too high ranked!\n\r", ch ); return; } if ( ch->pcdata->join_status != JOIN_RESIGNING ) { send_to_char ( "You are attempting to remove yourself from your clan.\n\r", ch ); send_to_char( "Please type RESIGN again to confirm.\n\r", ch ); ch->pcdata->join_status = JOIN_RESIGNING; return; } clan_log( clan, "%s resigned from the clan!", ch->name ); ch->pcdata->clan = 0; ch->pcdata->clan_rank = 0; ch->pcdata->join_status = 0; remove_member( ch, clan ); send_to_char( "You are no longer a member of the clan.\n\r", ch ); return; } void do_cdeposit( CHAR_DATA * ch, char *argument ) { CLAN_DATA *clan; char arg1[MAX_INPUT_LENGTH]; int mod; argument = one_argument( argument, arg1 ); if ( IS_NPC( ch ) && !IS_SET( ch->act, ACT_PET ) ) { send_to_char( "Only players can deposit clan gold.\n\r", ch ); return; } if ( !IS_NPC( ch ) && ch->pcdata->clan < 1 ) { send_to_char( "The clan deposit command is for clan members only.\n\r", ch ); return; } clan = get_clan( ch->pcdata->clan ); if ( arg1[0] == '\0' ) { printf_to_char( ch, "Balance: %d\n\r", clan->clan_fund ); return; } mod = atoi( arg1 ); if ( mod <= 0 ) { send_to_char( "Positive numbers ONLY.\n\r", ch ); return; } if ( ch->gold < mod ) { send_to_char( "CLAN FUND: You don't have that much gold.\n\r", ch ); return; } { clan->clan_fund += mod; ch->gold -= mod; printf_to_char( ch, "Balance: %d\n\r", clan->clan_fund ); clan_log( clan, "%d credited by %s.", mod, ch->name ); save_clans( ); return; } } void do_crecall( CHAR_DATA * ch, char *argument ) { char buf[MAX_STRING_LENGTH]; CHAR_DATA *victim; ROOM_INDEX_DATA *location; CLAN_DATA *clan; if ( IS_NPC( ch ) && !IS_SET( ch->act, ACT_PET ) ) { send_to_char( "Only players can recall.\n\r", ch ); return; } if ( !IS_NPC( ch ) && ch->pcdata->clan < 1 ) { send_to_char( "The clan recall command is for clan members only.\n\r", ch ); return; } act( "$n prays for transportation!", ch, 0, 0, TO_ROOM ); if ( !IS_NPC( ch ) ) { if ( ch->pcdata->clan == 0 ) { send_to_char( "You can't use clan recall, you're not in a clan!", ch ); return; } clan = get_clan( ch->pcdata->clan ); location = get_room_index( clan->recall_room ); } else { clan = get_clan( ch->master->pcdata->clan ); location = get_room_index( clan->recall_room ); } if ( location == NULL ) { send_to_char( "Whoops, no such room.\n\r", ch ); bug( "NULL recall room %d", clan->recall_room ); return; } if ( ch->in_room == location ) { send_to_char( "Look around, look familiar?\n\r", ch ); return; } if ( IS_SET( ch->in_room->room_flags, ROOM_NO_RECALL ) || IS_AFFECTED( ch, AFF_CURSE ) ) { send_to_char( "The gods have forsaken you.\n\r", ch ); return; } if ( ( victim = ch->fighting ) != NULL ) { int lose, skill; if ( IS_NPC( ch ) ) skill = 40 + ch->level; else skill = ch->pcdata->learned[gsn_recall]; if ( number_percent( ) < 80 * skill / 100 ) { check_improve( ch, gsn_recall, FALSE, 6 ); WAIT_STATE( ch, 4 ); send_to_char( "You failed!\n\r", ch ); return; } if ( !IS_NPC( ch ) ) { lose = ( int ) ( 0.02 * exp_per_level( ch, ch->pcdata->points ) ); gain_exp( ch, 0 - lose ); check_improve( ch, gsn_recall, TRUE, 4 ); sprintf( buf, "You recall from combat! You lose %d exps.\n\r", lose ); send_to_char( buf, ch ); } stop_fighting( ch, TRUE ); } ch->move /= 2; send_to_char( "You pray to the gods for transportation!\n\r", ch ); act( "$n disappears.", ch, NULL, NULL, TO_ROOM ); char_from_room( ch ); char_to_room( ch, location ); act( "$n appears in the room.", ch, NULL, NULL, TO_ROOM ); do_look( ch, "auto" ); if ( ch->pet != NULL ) do_crecall( ch->pet, "" ); return; } void do_demote( CHAR_DATA * ch, char *argument ) { CLAN_DATA *clan; CHAR_DATA *victim; char buf[MAX_INPUT_LENGTH]; if ( IS_NPC( ch ) ) return; if ( ch->pcdata == NULL ) return; if ( argument[0] == '\0' ) { send_to_char( "Demote who?\n\r", ch ); return; } victim = get_char_world( ch, argument ); if ( victim == NULL ) { send_to_char( "Demote who?\n\r", ch ); return; } if ( IS_NPC( victim ) ) { send_to_char( "Um, you can't demote mobs.\n\r", ch ); return; } if ( victim->pcdata->clan == 0 ) { send_to_char( "Um, they must join a clan to be demoted.\n\r", ch ); return; } if ( get_trust( ch ) < MAX_LEVEL ) /* IMPS can demote anyone :) */ { if ( ch->pcdata->clan == 0 ) { send_to_char( "You are not a member of a clan!\n\r", ch ); return; } if ( ch->pcdata->clan != victim->pcdata->clan ) { send_to_char( "They are not even IN your clan!\n\r", ch ); return; } if ( victim->pcdata->clan_rank < 1 ) { victim->pcdata->clan_rank = MAX_RANK; } if ( ch->pcdata->clan_rank > 1 ) { send_to_char( "You are not high enough rank to demote anyone.\n\r", ch ); return; } clan = get_clan( ch->pcdata->clan ); if ( str_cmp( ch->name, clan->leader ) ) { if ( ( ch->pcdata->clan_rank == 2 && victim->pcdata->clan_rank <= 3 ) || ( ch->pcdata->clan_rank == 1 && victim->pcdata->clan_rank <= 2 ) ) { send_to_char ( "Only the clan leader, an IMP, or a higher rank can demote them.\n\r", ch ); return; } } } else { clan = get_clan( victim->pcdata->clan ); } if ( victim->pcdata->clan_rank == MAX_RANK ) { send_to_char( "That person's rank is as low as it can be!\n\r", ch ); return; } printf_to_char( ch, "You demote %s to %s!\n\r", victim->name, clan->rank[victim->pcdata->clan_rank] ); victim->pcdata->clan_rank++; printf_to_char( victim, "%s demotes you to %s in clan %s! :(\n\r", ch->name, clan->rank[victim->pcdata->clan_rank - 1], clan->name ); sprintf( buf, "%s demoted %s in clan %d.", ch->name, victim->name, clan->number ); log_string( buf ); clan_log( clan, "%s demoted %s to %s.", ch->name, victim->name, clan->rank[victim->pcdata->clan_rank - 1] ); return; } /* Clan Roster command written by Dorzak */ void do_roster( CHAR_DATA * ch, char *argument ) { ROOM_INDEX_DATA *pRoom; CLAN_DATA *clan; int i, x; i = ( ch->pcdata->clan ); if ( IS_NPC( ch ) ) return; if ( i < 1 ) { send_to_char( "You must join a clan to check its roster.\n\r", ch ); return; } clan = get_clan( i ); if ( clan == NULL ) { send_to_char( "No such clan.\n\r", ch ); return; } pRoom = ( get_room_index( clan->recall_room ) ); printf_to_char( ch, "Name: [%s]\n\rLeader: [%12s]\n\rSponsor:[%12s]\n\r", clan->name, clan->leader, clan->god ); send_to_char( "Members:", ch ); for ( x = 0; x < MAX_CLAN_MEMBERS; x++ ) { printf_to_char( ch, " %s", clan->members[x] ); } send_to_char( "\n\r", ch ); printf_to_char( ch, "Recall: %s\n\rClan fund: %d\n\r", pRoom->name, clan->clan_fund ); printf_to_char( ch, "Clan status: %s\n\r", flag_string( clan_flags, clan->clan_flags ) ); return; }