/**************************************************************************/ // clan.cpp - Clan Class and clan related functions - Tibault & Kal /*************************************************************************** * The Dawn of Time v1.69r (c)1997-2004 Michael Garratt * * >> A number of people have contributed to the Dawn codebase, with the * * majority of code written by Michael Garratt - www.dawnoftime.org * * >> To use this source code, you must fully comply with the dawn license * * in licenses.txt... In particular, you may not remove this copyright * * notice. * **************************************************************************/ #include "include.h" #include "olc.h" #include "clan.h" void save_clan_db( void ); CClanType *clan_list=NULL; /**************************************************************************/ CClanType::CClanType() { m_pSaveName = str_dup(""); m_pName = str_dup(""); m_pNoteName = str_dup(""); m_pWhoName = str_dup(""); m_pDescription = str_dup(""); m_pWhoCat = str_dup(""); m_pColorStr = str_dup(""); m_RecallRoom = 0; m_BankRoom = 0; m_pClanRankTitle[0] = str_dup( "toprank" ); m_CanAdd[0] = true; m_CanPromote[0] = true; m_CanRemove[0] = true; m_CanWithdraw[0] = true; for ( int i=1; i< MAX_RANK; i++ ) { m_pClanRankTitle[i] = str_dup( "" ); m_CanAdd[i] = false; m_CanPromote[i] = false; m_CanRemove[i] = false; m_CanWithdraw[i] = false; } next=NULL; } /**************************************************************************/ CClanType::~CClanType() { free_string(m_pSaveName); free_string(m_pName); free_string(m_pNoteName); free_string(m_pWhoName); free_string(m_pDescription); free_string(m_pWhoCat); free_string(m_pColorStr); for ( int i=0; i< MAX_RANK; i++ ) { free_string(m_pClanRankTitle[i]); } } /**************************************************************************/ void CClanType::printDetails(char_data *ch) { if(IS_ADMIN(ch)){ ch->printlnf( " `#%s%-40s`& %-15s %6d %8d", m_pColorStr, m_pName, m_pNoteName, m_RecallRoom, (int)m_BankFunds); }else if(IS_IMMORTAL(ch)){ ch->printlnf( " `#%s%-40s`& %-15s %6d", m_pColorStr, m_pName, m_pNoteName, m_RecallRoom ); }else{ ch->printlnf( " `#%s%-40s`& %-15s ???", m_pColorStr, m_pName, m_pNoteName); } } /**************************************************************************/ void CClanType::printRanks( char_data *ch ) { int i; int count=0; for ( i=0; i< MAX_RANK; i++ ) { if ( !IS_NULLSTR(m_pClanRankTitle[i]) ) { ch->printlnf( "`sRank %d `s- Title %s%s", i, m_pColorStr, m_pClanRankTitle[i] ); count++; } } ch->printlnf("There %s a total of %d rank%s in %s", count==1?"is":"are", count, count==1?"":"s", cname()); } /**************************************************************************/ int CClanType::minRank() { int lIdx; for ( lIdx=MAX_RANK-1; lIdx>=0; lIdx-- ) { if( !IS_NULLSTR(m_pClanRankTitle[lIdx])){ return lIdx; } } return 0; } /**************************************************************************/ /**************************************************************************/ // GENERIC CLAN FUNCTIONS /**************************************************************************/ /**************************************************************************/ /**************************************************************************/ // do_addclan Tibault:Sep 00 // Function for admin or headclan for setting the clan on players. // You can also set the rank with this command. If ommited, the top rank // will be set. /**************************************************************************/ void do_addclan( char_data *ch, char *argument ) { char arg1[MIL],arg2[MIL],arg3[MIL]; char_data *victim; int rank = 0; CClanType* pClan; if (!IS_ADMIN(ch) && !IS_SET(TRUE_CH(ch)->pcdata->council, COUNCIL_HEADCLAN)) { ch->println( "Addclan can only be used by the head of the clan council or admin." ); return; } argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); argument = one_argument( argument, arg3 ); if ( arg1[0] == '\0' || arg2[0] == '\0' ) { ch->println( "Syntax: addclan <char> <clan name> <clan rank>" ); ch->println( "Syntax: addclan <char> none (to remove them from a clan)" ); return; } if ( ( victim = get_whovis_player_world( ch, arg1 ) ) == NULL ) { ch->println( "They aren't playing." ); return; } if (!str_prefix(arg2,"none")) { ch->println( "They are now clanless." ); victim->println( "You are now a member of no clan!" ); victim->clan = NULL; victim->clanrank = 0; return; } if (!IS_LETGAINED(victim)){ ch->printlnf( "%s hasn't been letgained yet.", PERS(victim, ch) ); return; } if ((pClan = clan_lookup(arg2)) == NULL) { ch->printlnf( "No such clan '%s' exists.", arg2 ); return; } if (IS_NULLSTR(arg3)) { rank=pClan->minRank(); } else { if ((rank = pClan->rank_lookup(arg3) ) == -1) { ch->printlnf( "No such rank '%s' exists in the clan '%s'.", arg3, pClan->cname()); return; } } { ch->printlnf( "They are now a %s (%d) of clan %s.", pClan->clan_rank_title(rank), rank, pClan->cname() ); victim->printlnf("You are now a %s of clan %s.", pClan->clan_rank_title(rank), pClan->cname() ); } victim->clan = pClan; victim->clanrank = rank; } /************************************************************************** do_clanlist Tibault:Sep 00 Prints the details for every clan in the global variable clan_list. If you want to change the way these details are shown, change the CClanType function printdetails(). **************************************************************************/ void do_clanlist(char_data *ch, char *) { CClanType *pClan; if(!clan_list){ ch->println("There are currently no clans, clans can be added using clanedit create."); return; } ch->print( "`#`S-`YClanname`S===================================`YNoteName`S========`YRecall`S"); if(IS_ADMIN(ch)){ ch->println("====`YFunds`S-`^"); }else{ ch->println("-`^"); } for (pClan = clan_list; pClan; pClan = pClan->next ){ pClan->printDetails(ch); } } /**************************************************************************/ // Kal, Feb 02 void clan_show_clanrank_syntax(char_data *ch) { if(IS_IMMORTAL(ch)){ ch->println("syntax: clanrank <clanname> - to see the ranks of a given clan."); ch->println("syntax: clanrank <player> - to see the rank of a given player."); }else{ ch->println("syntax: clanrank <clanmember> - to see the rank of another clan member in the same room."); } } /**************************************************************************/ // Kal, Feb 02 void clan_show_ranks(char_data *ch, char_data *victim, CClanType *pClan) { if(pClan){ pClan->printRanks(ch); if(victim){ ch->printlnf( "%s's rank in this clan is: `#%s%s`^", PERS(victim, ch), pClan->color_str(), pClan->clan_rank_title(victim->clanrank) ); } if ( ch->clan == pClan){ ch->printlnf( "Your rank in this clan is: `#%s%s`^", pClan->color_str(), pClan->clan_rank_title(ch->clanrank) ); } } } /**************************************************************************/ // Kal, Feb 02 void do_clanranks(char_data *ch, char *argument) { char_data *victim; // non clanned players can not use the command if(!IS_IMMORTAL(ch) && !ch->clan){ ch->println("You are clanless, you have no use for this command."); return; } // if no argument is specified, show a player/immortal // the clan they are in if(IS_NULLSTR(argument)){ clan_show_ranks(ch, NULL, ch->clan); clan_show_clanrank_syntax(ch); return; } // attempt to find a specified player victim = get_whovis_player_world(ch, argument); if(!victim){ // character not found if(IS_IMMORTAL(ch)){ // imms can also specify the clan name // picking a clan CClanType* pClan= clan_lookup(argument); if(!pClan){ ch->printlnf( "No such clan or player '%s' is currently in the game.", argument ); clan_show_clanrank_syntax(ch); return; } // clan found, show the ranks clan_show_ranks(ch, NULL, pClan); return; } ch->printlnf( "No such clanmember '%s' is currently in the game.", argument ); return; } // victim was found, do some checks if(IS_IMMORTAL(ch)){ if(!victim->clan){ ch->printlnf("%s is not in a clan.", PERS(victim, ch)); clan_show_clanrank_syntax(ch); return; } }else{ if(!victim->clan || victim->clan!=ch->clan){ ch->printlnf("%s is not in the same clan as you.", PERS(victim, ch)); clan_show_clanrank_syntax(ch); return; } if(ch->in_room!=victim->in_room){ ch->printlnf("%s is not in the same room as you.", PERS(victim, ch)); clan_show_clanrank_syntax(ch); return; } } // victim found, show the ranks clan_show_ranks(ch, victim, victim->clan); } /************************************************************************** do_add Tibault:Sep 00 Function for mortals to add members to their clan. **************************************************************************/ void do_add( char_data *ch, char *argument ) { char arg1[MIL]; char_data *victim; if ( IS_OOC(ch) ) { ch->println( "Add is an IC command, you can't use it in OOC rooms." ); return; } argument = one_argument( argument, arg1 ); if( ch->clan == NULL ) { ch->println( "You are not in a clan yourself!" ); return; } if( ch->clan->m_CanAdd[ch->clanrank] == false ) { ch->println( "You don't have the authority to do that." ); return; } if ( ( victim = get_char_world( ch, arg1 ) ) == NULL ) { ch->println( "They aren't playing." ); return; } if ( victim->in_room != ch->in_room ) { ch->println( "They aren't here." ); return; } if ( !IS_LETGAINED(victim) ) { ch->printlnf( "%s hasn't been letgained yet.", PERS(victim, ch) ); return; } if( victim->clan ) { ch->printlnf( "%s is already in a clan.", PERS(victim, ch) ); return; } if( victim->seeks != ch->clan ) { ch->wraplnf("They are not seeking to join your clan." "They have been told you invited them to join, and to seek your clan if interested" "- try again shortly."); victim->wraplnf("%s invited you to become a member of a " "clan which goes by the name '%s'. You weren't seeking that " "clan, type 'seek %s' if you want to join, and when they invite " "you again... you will automatically join.", PERS(ch, victim), ch->clan->name(), ch->clan->notename()); return; } victim->clan = ch->clan ; victim->clanrank = ch->clan->minRank(); victim->seeks = NULL; ch->printlnf( "They are now a %s of your clan.", victim->clan->clan_rank_title(victim->clanrank)); victim->printlnf( "You are now a %s of clan %s.", victim->clan->clan_rank_title(victim->clanrank), victim->clan->name()); return; } /************************************************************************** do_demote Tibault:Sep 00 Function for mortals to demote members to their clan. **************************************************************************/ void do_demote( char_data *ch, char *argument ) { char arg1[MIL]; char_data *victim; if ( IS_OOC(ch) ) { ch->println( "Demote is an IC command, you can't use it in OOC rooms." ); return; } if( ch->clan == NULL ) { ch->println( "You are not in a clan yourself!" ); return; } if( ch->clan->m_CanPromote[ch->clanrank] == false ) { ch->println( "You don't have the authority to do that." ); return; } argument = one_argument( argument, arg1 ); if ( ( victim = get_char_world( ch, arg1 ) ) == NULL ) { ch->println( "They aren't playing." ); return; } if ( victim->in_room != ch->in_room ) { ch->println( "They aren't here." ); return; } if( victim->clan != ch->clan ) { ch->println( "They are not in your clan." ); return; } if( victim->clanrank <= ch->clanrank ) { ch->println( "They are too high in rank for your authority." ); ch->println( "You Must ask an Immortal to remove another leader." ); return; } if( victim->clanrank >= victim->clan->minRank() ) { ch->println( "They are already of the lowest rank." ); return; } victim->clanrank++; ch->printlnf( "They are now a %s of your clan.", ch->clan->clan_rank_title(victim->clanrank) ); victim->printlnf( "You are now a %s of clan %s.", victim->clan->clan_rank_title(victim->clanrank), victim->clan->name()); return; } /************************************************************************** do_outcast Tibault:Sep 00 Function for mortals to outcast members to their clan. **************************************************************************/ void do_outcast( char_data *ch, char *argument ) { char arg1[MIL]; char_data *victim; if ( IS_OOC(ch) ) { ch->println( "Outcast is an IC command, you can't use it in OOC rooms." ); return; } if( ch->clan == NULL ) { ch->println( "You are not in a clan yourself!" ); return; } if( ch->clan->m_CanRemove[ch->clanrank] == false ) { ch->println( "You don't have the authority to do that." ); return; } argument = one_argument( argument, arg1 ); if ( (victim=get_char_world(ch, arg1)) == NULL ) { ch->println( "They aren't playing." ); return; } if ( victim->in_room != ch->in_room ) { ch->println( "They aren't here." ); return; } if( victim->clan != ch->clan ){ ch->println( "They are not in your clan." ); return; } if(ch->clanrank >= victim->clanrank ) { ch->println( "You don't have the authority to do that." ); return; } ch->printlnf( "They are no longer a %s of your clan.", victim->clan->clan_rank_title(victim->clanrank) ); victim->printlnf( "You are no longer a %s of clan %s.", victim->clan->clan_rank_title(victim->clanrank), victim->clan->name()); victim->println("You have been outcast!"); victim->clan = NULL; victim->clanrank = 0; return; } /************************************************************************** do_promote Tibault:Sep 00 Function for mortals to outcast members to their clan. **************************************************************************/ void do_promote( char_data *ch, char *argument ) { char arg1[MIL]; char_data *victim; if ( IS_OOC(ch) ) { ch->println( "Promote is an IC command, you can't use it in OOC rooms." ); return; } if( ch->clan == NULL ) { ch->println("You are not in a clan yourself!" ); return; } if( ch->clan->m_CanPromote[ch->clanrank] == false ) { ch->println( "You don't have the authority to do that." ); return; } argument = one_argument( argument, arg1 ); if ( (victim = get_char_world(ch, arg1)) == NULL ) { ch->println( "They aren't playing." ); return; } if ( victim->in_room != ch->in_room ) { ch->println( "They aren't here." ); return; } if( victim->clan != ch->clan ) { ch->println( "They are not in your clan." ); return; } if( victim->clanrank<=ch->clanrank ){ ch->println( "They are already too high in rank for your authority." ); return; } if(victim->clanrank==0){ ch->println( "They are already the highest rank in your clan." ); return; } victim->clanrank--; ch->printlnf( "They are now a %s of your clan.", ch->clan->clan_rank_title(victim->clanrank) ); victim->printlnf( "Congratulations, you are now a %s of clan %s.", ch->clan->clan_rank_title(victim->clanrank), ch->clan->name()); return; } /************************************************************************** do_seek Tibault:Sep 00 Function for mortals to seek the clan they wish to join. **************************************************************************/ void do_seek( char_data *ch, char *argument ) { char arg1[MIL]; CClanType* pClan; argument = one_argument(argument, arg1); if ( !str_cmp(arg1,"none") ) { ch->seeks = NULL; ch->println( "You are seeking no clan." ); return; } if ( ch->clan ) { ch->println( "You are already in a clan." ); return; } if ( (pClan = clan_lookup(arg1)) == NULL ) { ch->println( "No such clan exists." ); return; } ch->seeks = pClan; ch->printlnf( "You are seeking to join %s.", pClan->name() ); ch->println("(type 'seek none' to stop seeking a clan.)"); return; } /**************************************************************************/ const char * CClanType::name() { if(!this){ return ""; } return m_pName; } /**************************************************************************/ const char * CClanType::cname() { if(!this){ return ""; } static char result[MIL]; sprintf(result, "`#%s%s`&", m_pColorStr, m_pName); return result; } /**************************************************************************/ // name used to save to disk, never changes const char * CClanType::savename() { if(!this){ return ""; } return m_pSaveName; } /**************************************************************************/ const char * CClanType::notename() { if(!this){ return ""; } return m_pNoteName; } /**************************************************************************/ const char * CClanType::color_str() { if(!this){ return ""; } return m_pColorStr; } /**************************************************************************/ const char * CClanType::who_name() { if(!this){ return ""; } return m_pWhoName; } /**************************************************************************/ const char * CClanType::cwho_name() { if(!this){ return ""; } static char result[MIL]; sprintf(result, "`#%s%s`&", m_pColorStr, m_pWhoName); return result; } /**************************************************************************/ const char * CClanType::who_cat() { if(!this){ return ""; } return m_pWhoCat; } /**************************************************************************/ const char * CClanType::clan_rank_title(int rank) { return m_pClanRankTitle[rank]; } /**************************************************************************/ int CClanType::recall_room() { return m_RecallRoom; } /**************************************************************************/ // Kal - Sept 2000 int CClanType::rank_lookup(const char *ranktitle) { int rnk; if(this==NULL){ // clanless return 0; } for (rnk = 0; rnk < MAX_RANK; rnk++) { if (!str_prefix(ranktitle,m_pClanRankTitle[rnk])){ return rnk; } } return -1; } /**************************************************************************/ CClanType* clan_lookup( const char *name ) { CClanType *pClan; if(IS_NULLSTR(name)){ return NULL; } // first try an exact match for(pClan=clan_list;pClan;pClan=pClan->next){ if(!str_cmp(name,pClan->name() )){ return pClan; } } // now try a prefix match for(pClan=clan_list;pClan;pClan=pClan->next){ if(!str_prefix(name,pClan->name())){ return pClan; } } // not found return NULL; } /**************************************************************************/ // lookup a clan by their note name - Kalahn oct97 CClanType* clan_nlookup( const char *name ) { CClanType *pClan; // first try an exact match for(pClan=clan_list;pClan;pClan=pClan->next){ if(!str_cmp(name,pClan->notename())){ return pClan; } } // now try a prefix match for(pClan=clan_list;pClan;pClan=pClan->next){ if(!str_prefix(name,pClan->notename())){ return pClan; } } // not found return NULL; } /**************************************************************************/ // lookup a clan by their save name - Kalahn Sept2000 CClanType* clan_slookup( const char *savename ) { CClanType *pClan; // only do exact matching for(pClan=clan_list;pClan;pClan=pClan->next){ if(!str_cmp(savename,pClan->savename())){ return pClan; } } // not found return NULL; } /**************************************************************************/ void clan_bank( char_data *ch, char *task, char *amount) { int number; if(IS_NPC(ch)){ ch->println("clan banking by players only sorry."); return; } if(!str_prefix(task,"balance") ) { ch->printlnf( "Your clan has %ld gold in its coffers.", ch->clan->m_BankFunds ); // the clanbank transaction trail append_datetimestring_to_file( CLANBANKING_FILE, FORMATF("%s[%d] got a clanbank balance of %s - balance is %d`x", TRUE_CH(ch)->name, ch->clanrank, ch->clan->who_name(), (int)ch->clan->m_BankFunds)); return; } if(!is_number(amount)) { ch->printlnf( "clanbank: The second argument must be a number, '%s' is not.", amount ); return; } number=atoi(amount); if(number<=0) { ch->println( "clanbank: The second argument must be a number greater than 0." ); return; } if(number>1250000){ ch->println( "clanbank: Sorry, we don't deal with such large amounts!" ); return; } if(!str_prefix(task,"deposit")) { if( number+5>ch->gold ) { if( number>ch->gold ){ ch->println( "You do not have that much money." ); }else{ ch->wrapln( "There is a 5 gold piece fee per deposit. Banking all that money will not leave you with enough to pay our deposit fee." ); } return; } ch->gold -= number + 5; ch->clan->m_BankFunds += number; ch->printlnf( "Deposit made.\r\nYour clan now has %ld gold pieces in its coffers.", ch->clan->m_BankFunds ); logf("[clanbank] %s deposited %d gold into clan bank account %s - balance now %d", ch->name, number, ch->clan->who_name(), (int)ch->clan->m_BankFunds); // the clanbank transaction trail append_datetimestring_to_file( CLANBANKING_FILE, FORMATF("%s[%d] deposited %d gold into clan bank account %s - balance now %d`x", TRUE_CH(ch)->name, ch->clanrank, number, ch->clan->who_name(), (int)ch->clan->m_BankFunds)); // resave the clan database save_clan_db(); save_char_obj(ch); // resave them WAIT_STATE(ch, PULSE_PER_SECOND*3); return; } if(!str_prefix(task,"withdraw")) { if ( !ch->clan->m_CanWithdraw[ch->clanrank]) { // the clanbank transaction trail append_datetimestring_to_file( CLANBANKING_FILE, FORMATF("%s[%d] attempted to withdraw %d gold from clan bank account %s but didn't have authority - balance is %d`x", TRUE_CH(ch)->name, ch->clanrank, number, ch->clan->who_name(), (int)ch->clan->m_BankFunds)); ch->println( "You do not have the authority to withdraw money from your clan." ); return; } if( number < 6 ) { ch->println("Due to the surcharge of 5 gold you can not withdraw that small of an amount."); return; } if( number > ch->clan->m_BankFunds-5 ) { ch->println("You do not have that much in the bank."); return; } ch->gold += number; ch->clan->m_BankFunds -= number + 5; ch->printlnf( "Withdrawal made. There was a 5 gold piece surcharge.\r\nYour clan now has %ld gold pieces in its coffers.", ch->clan->m_BankFunds ); logf("[clanbank] %s withdrew %d gold from clan bank account %s - balance now %d", ch->name, number, ch->clan->who_name(), (int)ch->clan->m_BankFunds); // the clanbank transaction trail append_datetimestring_to_file( CLANBANKING_FILE, FORMATF("%s[%d] withdrew %d gold from clan bank account %s - balance now %d`x", TRUE_CH(ch)->name, ch->clanrank, number, ch->clan->who_name(), (int)ch->clan->m_BankFunds)); // resave the clan database save_clan_db(); save_char_obj(ch); // resave them WAIT_STATE(ch, PULSE_PER_SECOND*3); return; } ch->printlnf( "'%s' is not a valid clanbank transaction.", task ); return; } /**************************************************************************/ /**************************************************************************/ /**************************************************************************/ /**************************************************************************/