/* * Initial version created by Dral 21 Aug 1999, * based on kingdom code from Incoherent Dreams. */ // standard includes #include <sys/types.h> #include <stdio.h> #include <stdlib.h> #include <time.h> // mud includes #include "merc.h" #include "clantable.h" // external vars //extern bool fBootDb; // from db.c, true if the mud is still loading // internal defines #define CLANPK_CURRENT_FILEFORMAT_VERSION 3 #define CLANPK_DO_CLANTABLE_CLAN_NAME_LEGEND "clan name" #define CLANPK_DO_CLANTABLE_CLAN_LEADER_NAME_LEGEND "leader" #define CLANPK_DO_CLANTABLE_CLAN_COLEADER_NAME_LEGEND " coleader " // internal structures typedef struct clanpktable_data CLANPKTABLE_DATA; struct clanpktable_data { int num; char *name; char *leader_name; char *coleader_name; // number of times any member of this clan has ... int kills; // ...killed a player who's not of this clan int deaths; // ...been killed by a player who's not of this clan int self_kills; // ...killed any other member of this clan int clan_points; int arena_kills; int arena_deaths; int arena_self_kills; CLANPKTABLE_DATA *next; }; // internal vars static CLANPKTABLE_DATA *clanpk_list; static CLANPKTABLE_DATA *clanless_clan; // normally same as first clan in clanpk_list static bool loading_clanpktable; static bool pending_save_clanpktable; // internal functions void save_clanpktable (); CLANPKTABLE_DATA *create_clanpktable_data(char *clan_name, char *leader_name,char *coleader_name, int kills, int deaths, int self_kills, int cp, int arena_kills, int arena_deaths, int arena_self_kills); CLANPKTABLE_DATA *get_clan_by_clanname (char *clan_name); CLANPKTABLE_DATA *get_clan_by_char (CHAR_DATA *ch); //CLANPKTABLE_DATA *get_clan_by_num (int num); void internal_register_clanpk (CHAR_DATA *killer, CHAR_DATA *victim, bool is_arenakill); void clanpktable__set_clan(CHAR_DATA *ch, CLANPKTABLE_DATA *clan); void clanpktable__set_leader(CHAR_DATA *ch, CLANPKTABLE_DATA *clan); void clanpktable__set_coleader(CHAR_DATA *ch, CLANPKTABLE_DATA *clan); void dump_clantable(); //CLANPKTABLE_DATA *raw_get_clan_by_num(int num); CLANPKTABLE_DATA *get_clanless_clan(); CLANPKTABLE_DATA *get_first_clan(); CLANPKTABLE_DATA *get_next_clan(CLANPKTABLE_DATA *a_clan); //char *ratio2str(int value, int max, char *buf); // appends to buf and returns buf void load_clanpktable () { char buf[MAX_STRING_LENGTH]; FILE *fp; int i = 1; int fileformat_version; CLANPKTABLE_DATA *a_clan; char *name; char *leader_name; char *coleader_name; int kills; int deaths; int cp; int self_kills; int arena_kills; int arena_deaths; int arena_self_kills; loading_clanpktable = TRUE; pending_save_clanpktable = FALSE; if ((fp = fopen (CLANTABLE_FILENAME, "r")) == NULL) { sprintf (buf, "Error: load_clanpktable: %.200s not found!", CLANTABLE_FILENAME); log_string (buf); exit (1); } if (feof(fp)) { log_string("Warning: load_clanpktable: empty clantable data file, no clans available"); // create a reasonable default entry for clan 0 a_clan = create_clanpktable_data("", "","", 0, 0, 0, 0, 0, 0, 0); if (a_clan == NULL) { log_string("Error: load_clanpktable: empty clantable data file..."); log_string("...and I couldn't even create a default clan"); fclose (fp); exit (1); } } fileformat_version = fread_number(fp); fread_to_eol(fp); if ( (fileformat_version < 1) || (fileformat_version > CLANPK_CURRENT_FILEFORMAT_VERSION) ) { log_string("Error: load_clanpktable: unable to read clantable file..."); sprintf(buf, "...this version of load_clantable() can only read version 1 to %d files", CLANPK_CURRENT_FILEFORMAT_VERSION); fclose(fp); exit (1); } if (fileformat_version == 1) { // file format version 1 didn't include clan 0 stats a_clan = create_clanpktable_data("", "","", 0, 0, 0, 0, 0, 0, 0); if (a_clan == NULL) { log_string("Error: load_clanpktable: reading ver 1 file: couldn't create the default clan"); fclose (fp); exit (1); } save_clanpktable (); i = 1; } else { i = 0; } for ( ; !feof(fp); i++) { name = fread_string(fp); // 1: clan name leader_name = fread_string(fp); // 2: leader name coleader_name = fread_string(fp); kills = fread_number(fp); // 3: clan kills deaths = fread_number(fp); // 4: clan deaths self_kills = fread_number(fp); // 5: clan self kills (intra clan kills) if ( fileformat_version < 3 ) { cp = 0; arena_kills = 0; arena_deaths = 0; arena_self_kills = 0; } else { cp = fread_number(fp); arena_kills = fread_number(fp); // 6: clan kills in arena arena_deaths = fread_number(fp); // 7: clan deaths in arena arena_self_kills = fread_number(fp); // 8: clan self kills (intra clan kills) in arena } a_clan = create_clanpktable_data( name, // 1: clan name leader_name, // 2: leader name coleader_name, kills, // 3: clan kills deaths, // 4: clan deaths self_kills, // 5: clan self kills (intra clan kills) cp, arena_kills, // 6: clan kills in arena arena_deaths, // 7: clan deaths in arena arena_self_kills // 8: clan self kills (intra clan kills) in arena ); if (a_clan == NULL) { sprintf(buf, "Error: load_clanpktable: couldn't create clan %d", i); log_string(buf); fclose (fp); exit (1); } fread_to_eol(fp); } /*#ifdef MAGE_CLAN_NAME if (get_clan_by_clanname(MAGE_CLAN_NAME) == NULL) { a_clan = create_clanpktable_data(MAGE_CLAN_NAME, "", 0, 0, 0, 0, 0, 0, 0); if (a_clan == NULL) { sprintf(buf, "Error: load_clanpktable: mage clan \"%.30s\" didn't exist in %s", MAGE_CLAN_NAME, CLANTABLE_FILENAME); log_string(buf); log_string ("Error: load_clanpktable: and an error occured trying to create it."); fclose (fp); exit (1); } sprintf(buf, "Warning: load_clanpktable: mage clan \"%.30s\" didn't exist in %s", MAGE_CLAN_NAME, CLANTABLE_FILENAME); log_string(buf); log_string ("Warning: load_clanpktable: had to create it afresh with 0 in all stats."); save_clanpktable (); } #endif*/ sprintf(buf, "debug: load_clanpktable: loaded %d clans from a version %d %s", i, fileformat_version, CLANTABLE_FILENAME); log_string(buf); fclose (fp); loading_clanpktable = FALSE; #ifndef DEBUG_CLANPK if ( pending_save_clanpktable || (fileformat_version < CLANPK_CURRENT_FILEFORMAT_VERSION) ) #endif { save_clanpktable(); } } // only need to call this in functions where clanpktable_data members // are changed directly void save_clanpktable () { char buf[MAX_STRING_LENGTH]; FILE *fp; CLANPKTABLE_DATA *a_clan; if (loading_clanpktable) { pending_save_clanpktable = TRUE; return; } pending_save_clanpktable = FALSE; fclose( fpReserve ); if ((fp = fopen (CLANTABLE_FILENAME, "w")) == NULL) { sprintf (buf, "Error: unable to open %.200s for writing!", CLANTABLE_FILENAME); log_string (buf); if ( !loading_clanpktable ) { fpReserve = fopen( NULL_FILE, "r" ); } return; } // file format version fprintf (fp, "3\n"); for (a_clan = get_first_clan(); a_clan != NULL; a_clan=get_next_clan(a_clan) ) { fprintf (fp, "%s~\n", a_clan->name); fprintf (fp, "%s~\n", a_clan->leader_name); fprintf (fp, "%s~\n", a_clan->coleader_name); fprintf (fp, "%d\n", a_clan->kills); fprintf (fp, "%d\n", a_clan->deaths); fprintf (fp, "%d\n", a_clan->self_kills); fprintf (fp, "%d\n", a_clan->clan_points); fprintf (fp, "%d\n", a_clan->arena_kills); fprintf (fp, "%d\n", a_clan->arena_deaths); fprintf (fp, "%d\n", a_clan->arena_self_kills); } fclose (fp); fpReserve = fopen( NULL_FILE, "r" ); } /* This is one of the few clan pk table functions that * might return a NULL. It does this - rather than return * clan 0 - to distinguish between not finding the named * clan, and finding clan 0. */ CLANPKTABLE_DATA *get_clan_by_clanname (char *clan_name) { #ifdef DEBUG_CLANPK_VERBOSE char buf[MAX_STRING_LENGTH]; #endif CLANPKTABLE_DATA *a_clan; if ( (clan_name == NULL) || (clan_name[0] == '\0') ) { // please excuse this messy code - I'm tired if (clan_name == NULL) { bug("get_clan_by_name: NULL clan_name given", 0); } return get_clanless_clan(); } for (a_clan=get_first_clan(); a_clan!=NULL; a_clan=get_next_clan(a_clan)) { #ifdef DEBUG_CLANPK_VERBOSE sprintf(buf, "get_clan_by_clanname: checking against clan %d", a_clan->num); log_string(buf); #endif if (!str_cmp(a_clan->name, clan_name)) { //clans[i].name == clan_name //so we found the clan we're looking for #ifdef DEBUG_CLANPK_VERBOSE log_string("get_clan_by_clanname: found"); #endif return a_clan; } } // if we didn't return in the for loop, we didn't find the clan // so return NULL to indicate failure #ifdef DEBUG_CLANPK_VERBOSE log_string("get_clan_by_clanname: not found"); #endif return NULL; } CLANPKTABLE_DATA *get_clan_by_char (CHAR_DATA *ch) { #ifdef CHAR_CLANS_AS_NUMBER int clan_num; #else char *clan_name; #endif char buf[MAX_STRING_LENGTH]; CLANPKTABLE_DATA *the_clan; if (ch == NULL) { bug("get_clan_by_char: null char given", 0); // if an invalid clan is found, return "clanless"/"final" (ie, no clan) return get_clanless_clan(); } clan_name = ch->clan; if (clan_name == NULL) { clan_name = ch->clan = str_dup(get_clanless_clan()->name); } the_clan = get_clan_by_clanname(clan_name); // if that clan doesn't exist... if (the_clan == NULL) { // ...report that... sprintf(buf, "get_clan_by_char: %s->clan=%.30s, doesn't exist, changing to clan 0", ch->name, clan_name); bug(buf, 0); // ...and use the default clan the_clan = get_clanless_clan(); clanpktable__set_clan(ch, the_clan); } return the_clan; } /* CLANPKTABLE_DATA *get_clan_by_num (int clan_num) { int i; char buf[MAX_STRING_LENGTH]; CLANPKTABLE_DATA *result; if ( (clan_num<0) || (clan_num>=MAX_CLANS) ) { sprintf(buf, "get_clan_by_num: %d out of range [0-%d]", clan_num, MAX_CLANS-1); bug(buf, 0); // if an invalid clan is found, return "clanless"/"rogue" (ie, no clan) clan_num = 0; } result = raw_get_clan_by_num(clan_num); i = result->num; if ( i != clan_num ) { CLANPKTABLE_DATA *other_clan = raw_get_clan_by_num(i); sprintf(buf, "get_clan_by_num: clan %d[%.30s] thinks it's clan %d[%.30s]", clan_num, result->name, i, (other_clan==NULL?"No such clan":other_clan->name)); bug(buf, 0); // if an invalid clan is found, return "clanless"/"rogue" (ie, no clan) result = raw_get_clan_by_num(0); } return result; } */ /* This doesn't handle non-avatar related kills, * mainly because they should never happen. */ void register_clanpk (CHAR_DATA *killer, CHAR_DATA *victim) { internal_register_clanpk(killer, victim, FALSE); } void register_arena_clanpk (CHAR_DATA *killer, CHAR_DATA *victim) { internal_register_clanpk(killer, victim, TRUE); } void internal_register_clanpk (CHAR_DATA *killer, CHAR_DATA *victim, bool is_arenakill) { char buf[MAX_STRING_LENGTH]; CLANPKTABLE_DATA *killer_clan, *victim_clan; char *killer_name, *victim_name; // most kills are players killing a mob, so check // for that first if ( IS_NPC(victim) || IS_NPC(killer) ) { // ignore kills involving mobs // TODO (maybe): check to see if the mob a clan guardian // or charmed by anyone and, if so, // calculate the real clans involved return; } // this function mustn't be passed any NULL args killer_name = (killer==NULL?"NULL":killer->name); victim_name = (victim==NULL?"NULL":victim->name); if ( (killer == NULL) || (victim == NULL) ) { sprintf(buf, "register_clanpk: invalid args: killer=%s, victim=%s", killer_name, victim_name); bug(buf, 0); return; } // at this point we know this kill was a pk (player killing a player) // check for clan numbers // nb: we don't need to log invalid clans, // because get_clan_by_num() already does // this (and returns us clan 0 - clanless) killer_clan = get_clan_by_char(killer); victim_clan = get_clan_by_char(victim); if (killer_clan == victim_clan) { // intra clan kill (self_kill) if (killer_clan != get_clanless_clan()) { // ohh! a clannie just killed one of their own! // TODO: announce intra clan kill } if (is_arenakill) { killer_clan->arena_self_kills++; } else { killer_clan->self_kills++; } // nb: I don't add to deaths on purpose // so to get all deaths you must look // at deaths+self_kills } else { if (killer_clan->num != 0) { if (victim_clan->num != 0) { //TODO: announce clankill by killer_clan of victim_clan } else { //TODO (maybe): announce non-clankill by killer_clan } } else if (victim_clan->num != 0) { //TODO (maybe): announce non-clandeath of victim_clan } if (is_arenakill) { killer_clan->arena_kills++; victim_clan->arena_deaths++; } else { killer_clan->kills++; killer_clan->clan_points += victim->race; victim_clan->deaths++; } } save_clanpktable(); } void transfer_clanpk_leadership(CHAR_DATA *old_leader, CHAR_DATA *new_leader) { char buf[MAX_STRING_LENGTH]; CLANPKTABLE_DATA *clan_a; CLANPKTABLE_DATA *clan_b; if ( (old_leader==NULL) || (new_leader==NULL) ) { sprintf(buf, "transfer_clanpk_leadership: old_leader==%.30s new_leader==%.30s - both much be non-NULL", (old_leader==NULL?"NULL":old_leader->name), (new_leader==NULL?"NULL":new_leader->name)); bug(buf, 0); return; } clan_a = get_clan_by_char(old_leader); clan_b = get_clan_by_char(new_leader); if (clan_a != clan_b) { // the intended leader isn't in the same clan as the old leader. // as leadership changing for some clans involves changes // to ch->generation, I can't handle changing leader unless // all other attribues have changed (eg, ch->clan and ch->generation) sprintf(buf, "transfer_clanpk_leadership: old_leader \"%.30s\" is in clan \"%.30s\" but new_leader \"%.30s\" is in clan \"%.30s\" - they must be in the same clan _before_ leadership can be transfered by this function.", old_leader->name, new_leader->name, clan_a->name, clan_b->name); bug(buf, 0); return; } if (str_cmp(old_leader->name, clan_a->leader_name)) { sprintf(buf, "transfer_clanpk_leadership: \"%.30s\" isn't the leader of \"%.30s\" - can't transfer leadership to \"%.30s\".", old_leader->name, clan_a->leader_name, new_leader->name); bug(buf, 0); return; } clanpktable__set_leader(new_leader, clan_a); } CLANPKTABLE_DATA *create_clanpktable_data(char *clan_name, char *leader_name,char *coleader, int kills, int deaths, int self_kills, int cp, int arena_kills, int arena_deaths, int arena_self_kills) { char buf[MAX_STRING_LENGTH]; CLANPKTABLE_DATA *a_clan, *new_clan = NULL; if (clanpk_list == NULL) { // this is the first clan created // assume it's meant to be the "default" clan // ie, the clan that people belong to if they're not in a clan #ifdef DEBUG_CLANPK_VERBOSE log_string("create_clanpktable_data: default clan (clan 0)"); #endif } else { // for all normal clans, have to check the name is unique #ifdef DEBUG_CLANPK_VERBOSE log_string("create_clanpktable_data: checking to see if another clan is using that name"); #endif a_clan = get_clan_by_clanname(clan_name); if (a_clan != NULL) { sprintf(buf, "create_clanpktable_data: clan %.30s[%d] already uses that name", a_clan->name, a_clan->num); bug(buf, 0); return NULL; } } new_clan = (CLANPKTABLE_DATA *) malloc(sizeof(CLANPKTABLE_DATA)); if (new_clan == NULL) { sprintf(buf, "create_clanpktable_data: malloc: no memory to create clan: %.30s", clan_name); bug(buf, 0); } else { new_clan->name = str_dup(clan_name); new_clan->leader_name = str_dup(leader_name); new_clan->coleader_name = str_dup(coleader); new_clan->kills = kills; new_clan->deaths = deaths; new_clan->self_kills = self_kills; new_clan->clan_points = cp; new_clan->arena_kills = arena_kills; new_clan->arena_deaths = arena_deaths; new_clan->arena_self_kills = arena_self_kills; // add new clans to the end of the list, // uses very slightly more cpu, but the // list makes more sense (to me) that way new_clan->next = NULL; if (clanpk_list == NULL) { // if this is the first clan clanless_clan = new_clan; clanpk_list = new_clan; new_clan->num = 0; } else { // find tail for (a_clan=clanpk_list; (a_clan->next)!=NULL; a_clan=a_clan->next) { // do nothing, just loop through until a_clan is the last clan } // a_clan should now be the last clan in the list a_clan->next = new_clan; new_clan->num = a_clan->num + 1; } if (!loading_clanpktable) { save_clanpktable(); } } return new_clan; } void do_found_clan(CHAR_DATA *ch, char *argument) { char buf[MAX_STRING_LENGTH]; //CLANPKTABLE_DATA *ch_clan; CLANPKTABLE_DATA *new_clan; if (IS_NPC(ch)) { send_to_char("Sorry, an NPC may not found a clan.\n\r", ch); return; } if ( !IS_IMMORTAL(ch) ) { sprintf(buf, "Sorry, you don't have the power required to found a new clan.\n\r"); send_to_char(buf, ch); return; } /*ch_clan = get_clan_by_char(ch); if ( !str_cmp(ch->name, ch_clan->leader_name) ) { send_to_char("You cannot found a new clan while you are the leader of your current clan:\n\r", ch); sprintf(buf, " %s\n\r", get_clan_by_char(ch)->name); send_to_char(buf, ch); return; }*/ if (strlen(argument) < MIN_CLAN_NAME_LENGTH) { send_to_char("Clan name too short.\n\r", ch); return; } if (strlen(argument) > MAX_CLAN_NAME_LENGTH) { argument[MAX_CLAN_NAME_LENGTH + 1] = '\0'; sprintf(buf, "Clan name too long, try \"%s\" instead.\n\r", argument); send_to_char(buf, ch); return; } smash_tilde(argument); if ( get_clan_by_clanname(argument) != NULL ) { send_to_char("A clan with that name already exists.\n\r", ch); return; } // at this point, we know the clan: // is being created by an immortal, // has the right length name, which doesn't contain any tilde, // doesn't already exist // so lets go ahead and create the clan new_clan = create_clanpktable_data(str_dup(argument), str_dup(""), str_dup(""),0, 0, 0, 0, 0, 0,0); if (new_clan == NULL) { send_to_char("Eep! An internal error occured while trying to found your clan.\n\r", ch); send_to_char("(Probably caused by there being too many clans.)\n\r", ch); send_to_char("Please inform the admin ASAP.\n\r", ch); return; } //don't do this any more, this function is now for immortal use only //// and set ch as being a member //clanpktable__set_clan(ch, new_clan); sprintf(buf, "Created clan: %s\n\r", new_clan->name); send_to_char(buf, ch); } void clanpktable__set_clan(CHAR_DATA *ch, CLANPKTABLE_DATA *clan) { #ifdef CHAR_CLANS_AS_NUMBER ch->clan = clan->num; #else free_string(ch->clan); ch->clan = str_dup(clan->name); #endif } void clanpktable__set_leader(CHAR_DATA *ch, CLANPKTABLE_DATA *clan) { free_string ( clan->leader_name ); clan->leader_name = str_dup ( ch->name ); save_clanpktable (); } void clanpktable__set_coleader(CHAR_DATA *ch, CLANPKTABLE_DATA *clan) { free_string(clan->coleader_name); clan->coleader_name = str_dup(ch->name); save_clanpktable(); } void do_clantable(CHAR_DATA *ch, char *argument) { char buf[MAX_STRING_LENGTH]; int i; int clan_count = 0; float kill_ratio; // should only need to be 5 (eg, "0.79\0") // but this allows room for error char ratio_buf[10]; int total_fights; CLANPKTABLE_DATA *a_clan; int max_clan_name_len; int max_clan_leader_name_len; int max_clan_coleader_name_len; char horizontal_seperator[MAX_STRING_LENGTH]; int hs_pos; // index (POSition) withint the Horizontal_Seperator int name_padding; int leader_name_padding; int coleader_padding; max_clan_name_len = 0; max_clan_leader_name_len = 0; max_clan_coleader_name_len = 0; for (a_clan=get_first_clan(); a_clan!=NULL; a_clan=get_next_clan(a_clan)) { /* these shouldn't happen with get_next_clan if (a_clan->num == -1) { // unused slot continue; } else if (a_clan->num != i) { // invalid clan continue; } else */ if ( a_clan->num == 0 ) { continue; } else { clan_count++; if ( strlen(a_clan->name) > max_clan_name_len ) { max_clan_name_len = strlen(a_clan->name); } if ( strlen(a_clan->leader_name) > max_clan_leader_name_len ) { max_clan_leader_name_len = strlen(a_clan->leader_name); } } } if ( (max_clan_name_len+2) < strlen(CLANPK_DO_CLANTABLE_CLAN_NAME_LEGEND) ) { max_clan_name_len = strlen(CLANPK_DO_CLANTABLE_CLAN_NAME_LEGEND) - 2; } if ( (max_clan_leader_name_len+2) < strlen(CLANPK_DO_CLANTABLE_CLAN_LEADER_NAME_LEGEND) ) { max_clan_leader_name_len = strlen(CLANPK_DO_CLANTABLE_CLAN_LEADER_NAME_LEGEND) - 2; } if( (max_clan_coleader_name_len+2) < strlen(CLANPK_DO_CLANTABLE_CLAN_COLEADER_NAME_LEGEND) ) { max_clan_coleader_name_len = strlen(CLANPK_DO_CLANTABLE_CLAN_COLEADER_NAME_LEGEND) - 2; } hs_pos = 0; for (i = 0; i < (max_clan_name_len+2); i++) { horizontal_seperator[hs_pos++] = '-'; } horizontal_seperator[hs_pos++] = '+'; for (i = 0; i < (max_clan_leader_name_len+2); i++) { horizontal_seperator[hs_pos++] = '-'; } horizontal_seperator[hs_pos++] = '+'; for( i = 0; i < (max_clan_coleader_name_len+2); i++) { horizontal_seperator[hs_pos++] = '-'; } horizontal_seperator[hs_pos++] = '+'; for (i = 0; i < strlen(" kills deaths ratio clanpoints "); i++) { horizontal_seperator[hs_pos++] = '-'; } horizontal_seperator[hs_pos++] = '+'; for (i = 0; i < strlen(" awin aloss aintr "); i++) { horizontal_seperator[hs_pos++] = '-'; } horizontal_seperator[hs_pos++] = '\0'; sprintf(buf, "/%s\\\n\r", horizontal_seperator); send_to_char(buf, ch); name_padding = (max_clan_name_len+2) - strlen(CLANPK_DO_CLANTABLE_CLAN_NAME_LEGEND); leader_name_padding = (max_clan_leader_name_len+2) - strlen(CLANPK_DO_CLANTABLE_CLAN_LEADER_NAME_LEGEND); coleader_padding = (max_clan_coleader_name_len+2) - strlen(CLANPK_DO_CLANTABLE_CLAN_COLEADER_NAME_LEGEND); sprintf(buf, "|%*s%s%*s|%*s%s%*s|%*s%s%*s| kills deaths ratio clanpoints | awin aloss aintr |\n\r", // left padding for "clan name" ( name_padding - (name_padding/2) ), "", // "clan name" CLANPK_DO_CLANTABLE_CLAN_NAME_LEGEND, // right padding for "clan name" ( name_padding / 2 ), "", // left padding for "leader" ( leader_name_padding - (leader_name_padding/2) ), "", // "leader" CLANPK_DO_CLANTABLE_CLAN_LEADER_NAME_LEGEND, // right padding for "leader" ( leader_name_padding / 2 ), "", // left padding co-leader (coleader_padding - (coleader_padding/2)), "", CLANPK_DO_CLANTABLE_CLAN_COLEADER_NAME_LEGEND, ( coleader_padding / 2 ), ""); send_to_char(buf, ch); sprintf(buf, "+%s+\n\r", horizontal_seperator); send_to_char(buf, ch); for (a_clan=get_first_clan(); a_clan!=NULL; a_clan=get_next_clan(a_clan)) { #ifdef DEBUG_CLANPK sprintf(buf, "do_clantable: [%02d:%.20s]", a_clan->num, a_clan->name); log_string(buf); #endif /* these shouldn't happen with get_next_clan if (a_clan->num == -1) { // unused slot continue; } else if (a_clan->num != i) { // invalid clan continue; } else */ if ( a_clan->num == 0 ) { continue; } else { clan_count++; total_fights = a_clan->kills + a_clan->deaths; if ( total_fights < 1 ) { sprintf(ratio_buf, "None"); } else { kill_ratio = (float) a_clan->kills / total_fights; sprintf(ratio_buf, "%1.2f", kill_ratio); } sprintf(buf, "| %-*.*s | %-*.12s | %-*.12s | %5d %5d %-.4s %10d | %5d %5d %5d |\n\r", max_clan_name_len, MAX_CLAN_NAME_LENGTH, a_clan->name, max_clan_leader_name_len, a_clan->leader_name, max_clan_coleader_name_len, a_clan->coleader_name, a_clan->kills, a_clan->deaths, ratio_buf,a_clan->clan_points, a_clan->arena_kills, a_clan->arena_deaths, a_clan->arena_self_kills); /* sprintf(buf, " | %-18s | %-12s | %5d %5d %-.4s |\n\r", a_clan->name, a_clan->leader_name, a_clan->kills, a_clan->deaths, ratio_buf); */ send_to_char(buf, ch); } } sprintf(buf, "\\%s/\n\r", horizontal_seperator); send_to_char(buf, ch); /* send_to_char(" \\--------------------+--------------+---------------------/\n\r", ch); */ } void do_clanpk_leader(CHAR_DATA *ch, char *argument) { char buf[MAX_STRING_LENGTH]; char *old_leader_name; CHAR_DATA *new_leader; CLANPKTABLE_DATA *the_clan; if ( !IS_IMMORTAL(ch) ) { do_huh(ch, argument); return; } new_leader = get_char_world(ch, argument); if ( new_leader == NULL ) { sprintf(buf, "Unable to find player \"%.30s\", are you sure they're loaded?", argument); send_to_char(buf, ch); return; } if ( IS_NPC(new_leader) ) { sprintf(buf, "No, \"%.30s\" is an NPC.", new_leader->name); send_to_char(buf, ch); return; } the_clan = get_clan_by_char(new_leader); if ( the_clan == get_clanless_clan() ) { sprintf(buf, "No, \"%.30s\" isn't in a clan.", new_leader->name); send_to_char(buf, ch); } old_leader_name = the_clan->leader_name; if (strlen(old_leader_name) == 0) { sprintf(buf, "Ok, giving leadership of \"%.30s\" to \"%.30s\".", the_clan->name, new_leader->name); } else { sprintf(buf, "Ok, usurping \"%.30s\" in favour of \"%.30s\" as leader of \"%.30s\".", the_clan->leader_name, new_leader->name, the_clan->name); } send_to_char(buf, ch); if( !IS_SET(new_leader->clanbits, CLAN_LDR)) SET_BIT(new_leader->clanbits, CLAN_LDR); if( IS_SET(new_leader->clanbits, CLAN_CO)) REMOVE_BIT(new_leader->clanbits, CLAN_CO); clanpktable__set_leader(new_leader, the_clan); } void do_clanpk_coleader(CHAR_DATA *ch, char *argument) { char buf[MAX_STRING_LENGTH]; char *old_coleader_name; CHAR_DATA *new_coleader; CLANPKTABLE_DATA *the_clan; if ( !IS_IMMORTAL(ch) ) { do_huh(ch, argument); return; } new_coleader = get_char_world(ch, argument); if ( new_coleader == NULL ) { sprintf(buf, "Unable to find player \"%.30s\", are you sure they're loaded?", argument); send_to_char(buf, ch); return; } if ( IS_NPC(new_coleader) ) { sprintf(buf, "No, \"%.30s\" is an NPC.", new_coleader->name); send_to_char(buf, ch); return; } the_clan = get_clan_by_char(new_coleader); if ( the_clan == get_clanless_clan() ) { sprintf(buf, "No, \"%.30s\" isn't in a clan.", new_coleader->name); send_to_char(buf, ch); } old_coleader_name = the_clan->coleader_name; if (strlen(old_coleader_name) == 0) { sprintf(buf, "Ok, giving co-leadership of \"%.30s\" to \"%.30s\".", the_clan->name, new_coleader->name); } else { sprintf(buf, "Ok, usurping \"%.30s\" in favour of \"%.30s\" as co-leader of \"%.30s\".", the_clan->coleader_name, new_coleader->name, the_clan->name); } send_to_char(buf, ch); if( !IS_SET(new_coleader->clanbits, CLAN_CO)) SET_BIT(new_coleader->clanbits, CLAN_CO); if( IS_SET(new_coleader->clanbits, CLAN_LDR)) REMOVE_BIT(new_coleader->clanbits, CLAN_LDR); clanpktable__set_coleader(new_coleader, the_clan); } void dump_clantable() { char buf[MAX_STRING_LENGTH]; int clan_count = 0; CLANPKTABLE_DATA *a_clan; log_string("/--------|--------------------+--------------+---------------\\"); log_string("| i/num | clan name | leader | kills deaths |"); log_string("+--------|--------------------+--------------+---------------+"); for (a_clan=get_first_clan(); a_clan!=NULL; a_clan=get_next_clan(a_clan)) { clan_count++; sprintf(buf, "| %02d/%02d | %-18s | %-12s | %5d %5d |", clan_count, a_clan->num, a_clan->name, a_clan->leader_name, a_clan->kills, a_clan->deaths); log_string(buf); } log_string("\\--------|--------------------+--------------+---------------/"); } /* CLANPKTABLE_DATA *raw_get_clan_by_num(int num) { CLANPKTABLE *cur; CLANPKTABLE *prev; int i; #ifdef DEBUG_CLANPK_VERBOSE char buf[MAX_STRING_LENGTH]; sprintf(buf, "raw_get_clan_by_num(%d)", num); log_string(buf); #endif cur = prev = clanpk_list; for (i=0; (i<num) && (cur!=NULL); i++) { prev = cur; cur = cur->next; } return cur; } */ CLANPKTABLE_DATA *get_clanless_clan() { return clanless_clan; } CLANPKTABLE_DATA *get_first_clan() { #ifdef DEBUG_CLANPK_VERBOSE char buf[MAX_STRING_LENGTH]; #endif CLANPKTABLE_DATA *a_clan; a_clan = clanpk_list; #ifdef DEBUG_CLANPK_VERBOSE sprintf(buf, "get_first_clan: [%02d:%.20s]", a_clan->num, a_clan->name); log_string(buf); #endif return a_clan; } CLANPKTABLE_DATA *get_next_clan(CLANPKTABLE_DATA *a_clan) { #ifdef DEBUG_CLANPK char buf[MAX_STRING_LENGTH]; #endif CLANPKTABLE_DATA *another_clan = NULL; if (a_clan == NULL) { // should probably bug() here return NULL; } another_clan = a_clan->next; #ifdef DEBUG_CLANPK if (another_clan == NULL) { sprintf(buf, "get_next_clan: exiting, no next clan found"); } else { sprintf(buf, "get_next_clan: [%02d:%.20s]", another_clan->num, another_clan->name); } log_string(buf); #endif return another_clan; } /* // appends to buf and returns buf char *ratio2str(int value, int max, char *buf) { // but that has p if ( max < 1 ) { sprintf(buf, "None"); } else if ( value < 1 ) { sprint(buf, "0.00"); } else if ( value >= max ) { sprint(buf, "1.00"); } else { // would probably be better to use sprintf with a "%02f" sprintf(buf, "0.%02d", (int)((value*100)/max)); } return buf; } */