/* ************************************************************************ * File: empire.c EmpireMUD AD 1.0 * * Usage: stores all of the empire-related code and commands * * * * All rights reserved. See license.doc for complete information. * * * * Code base by Paul Clarke. EmpireMUD Project, a tbgMUD Production. * * Based upon CircleMUD 3.0, beta patch level 17, by Jeremy Elson. * * * * Copyright (C) 1993, 94 by the Trustees of the Johns Hopkins University * * CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991. * ************************************************************************ */ #include "conf.h" #include "sysdep.h" #include "structs.h" #include "utils.h" #include "interpreter.h" #include "comm.h" #include "handler.h" #include "db.h" #include "empire.h" #include "skills.h" #include "vnums.h" extern int top_of_p_table; void save_char_file_u(struct char_file_u st); extern struct player_index_element *player_table; /* Constants stored here for practical purposes */ const char *priv[] = { "claim", "build", "harvest", "promote", "chop", "cede", "enroll", "withdraw", "diplomacy", "\n" }; /* Local Data */ struct empire_data *empire = NULL; int top_of_empiret = -1; int real_empire(long id) { int i; if (top_of_empiret < 0) return -1; for (i = 0; i <= top_of_empiret; i++) if (empire[i].leader == ABSOLUTE(id)) return i; return -1; } int get_empire_by_name(char *name) { int e, num = -1; if (isdigit(*name)) num = atoi(name) - 1; for (e = 0; e <= top_of_empiret; e++) if (is_abbrev(name, empire[e].name) || e == num) return e; return -1; } /* This function sets up empire territory at startup and when two empires merge */ void read_empire_territory(void) { extern struct empire_storage_data *find_stored_resource(int emp, obj_vnum vnum); extern const int open_monument_fame[]; extern const int closed_monument_fame[]; struct empire_storage_data *store; int i, j, e; /* Init empires */ for (i = 0; i <= top_of_empiret; i++) { empire[i].territory = 0; for (j = 0; j < 6; j++) empire[i].vault[j] = 0; if ((store = find_stored_resource(i, o_SILVER))) empire[i].vault[0] = store->amount; if ((store = find_stored_resource(i, o_SILVER_DISC))) empire[i].vault[1] = store->amount; if ((store = find_stored_resource(i, o_SILVER_BAR))) empire[i].vault[2] = store->amount; if ((store = find_stored_resource(i, o_GOLD))) empire[i].vault[3] = store->amount; if ((store = find_stored_resource(i, o_GOLD_DISC))) empire[i].vault[4] = store->amount; if ((store = find_stored_resource(i, o_GOLD_BAR))) empire[i].vault[5] = store->amount; empire[i].haven = NOWHERE; empire[i].fame = 0; } for (i = 0; i <= top_of_world; i++) if (world[i].owner) { if ((e = real_empire(world[i].owner)) != -1 && world[i].owner != -1) { /* 1 haven per empire */ if (IS_HAVEN(i)) { if (empire[e].haven != NOWHERE) { world[i].owner = 0; continue; } else empire[e].haven = world[i].number; } if (world[i].home_room == NOWHERE) empire[e].territory += 1; if (SECT(i) == SECT_MONUMENT_OPEN && IS_COMPLETE(i)) empire[e].fame += open_monument_fame[(int) world[i].type]; if (SECT(i) == SECT_MONUMENT_CLOSED && IS_COMPLETE(i)) empire[e].fame += closed_monument_fame[(int) world[i].type]; } else if (world[i].owner != -1) world[i].owner = 0; } } int calculate_wealth(int e) { int val = 0; val += empire[e].vault[0]; val += 3 * empire[e].vault[1]; val += 6 * empire[e].vault[2]; val += 2 * empire[e].vault[3]; val += 5 * empire[e].vault[4]; val += 10 * empire[e].vault[5]; return val; } void read_empire_members(void) { extern int top_of_p_table; extern struct player_index_element *player_table; struct char_file_u chdata; int j, e; for (j = 0; j <= top_of_empiret; j++) empire[j].members = 0; for (j = 0; j <= top_of_p_table; j++) { load_char((player_table + j)->name, &chdata); if ((e = real_empire(chdata.player_specials_saved.loyalty)) >= 0) if (!IS_SET(chdata.char_specials_saved.act, PLR_DELETED | PLR_SLAIN)) { empire[e].members += 1; if (chdata.level >= LVL_GOD) empire[e].imm_only = 1; } } for (j = 0; j <= top_of_empiret; j++) if (empire[j].members == 0) { delete_empire(j); j--; } } /* Find a relationship between two given empires */ struct empire_political_data *find_relation(int a, int b) { struct empire_political_data *emp_pol; if (a == -1 || b == -1) return NULL; for (emp_pol = empire[a].diplomacy; emp_pol && emp_pol->id != empire[b].leader; emp_pol = emp_pol->next); return emp_pol; } void log_to_empire(int e, const char *str, ...) { char output[MAX_STRING_LENGTH]; Descr i; va_list tArgList; if (!str) return; va_start(tArgList, str); vsprintf(output, str, tArgList); for (i = descriptor_list; i; i = i->next) { if (STATE(i) != CON_PLAYING || IS_NPC(i->character)) continue; if (PLR_FLAGGED(i->character, PLR_WRITING | PLR_MAILING)) continue; if (real_empire(GET_LOYALTY(i->character)) != e) continue; msg_to_char(i->character, "%s[ %s ]&0\r\n", empire[e].banner, output); } va_end(tArgList); } void save_empire_index(void) { FILE *index; char fname[30]; int i; sprintf(fname, "%s%s", LIB_EMPIRE, INDEX_FILE); if (!(index = fopen(fname, "w"))) { log("SYSERR: Unable to create %s", fname); return; } for (i = 0; i <= top_of_empiret; i++) fprintf(index, "%ld.%s\n", empire[i].leader, SUF_EMPIRE); fprintf(index, "$~\n"); fclose(index); } void save_empire(int e) { struct empire_political_data *emp_pol; struct empire_storage_data *store; FILE *fl; char fname[30]; int j; if (e < 0 || e > top_of_empiret) return; sprintf(fname, "%s%ld.%s", LIB_EMPIRE, empire[e].leader, SUF_EMPIRE); if (!(fl = fopen(fname, "w"))) { log("SYSERR: Unable to write %s", fname); return; } fprintf(fl, "#%ld\n", empire[e].leader); fprintf(fl, "%s~\n", empire[e].name); fprintf(fl, "%s~\n", empire[e].banner); fprintf(fl, "%d\n", empire[e].num_ranks); for (j = 0; j < empire[e].num_ranks; j++) fprintf(fl, "R%d\n%s~\n", j, empire[e].rank[j]); for (j = 0; j < NUM_PRIVILEGES; j++) fprintf(fl, "P%d\n%d\n", j, empire[e].priv[j]); for (emp_pol = empire[e].diplomacy; emp_pol; emp_pol = emp_pol->next) fprintf(fl, "D\n%ld %d %d\n", emp_pol->id, emp_pol->type, emp_pol->offer); for (store = empire[e].store; store; store = store->next) fprintf(fl, "O\n%d %d\n", store->vnum, store->amount); fprintf(fl, "S\n$~\n"); fclose(fl); save_empire_index(); } void save_all_empires(void) { int i; if (top_of_empiret < 0) return; for (i = 0; i <= top_of_empiret; i++) save_empire(i); save_empire_index(); } void parse_empire(FILE *fl, int virtual_nr) { static int real_nr = 0; int t[6], j; char line[1024]; struct empire_political_data *emp_pol; struct empire_storage_data *store; sprintf(buf2, "empire #%d", virtual_nr); empire[real_nr].leader = virtual_nr; empire[real_nr].name = fread_string(fl, buf2); empire[real_nr].banner = fread_string(fl, buf2); if (!get_line(fl, line)) { log("SYSERR: Expecting ranks type of empire #%d but file ended!", virtual_nr); exit(1); } if (sscanf(line, "%d", t) != 1) { log("SYSERR: Format error in ranks of empire #%d", virtual_nr); exit(1); } empire[real_nr].num_ranks = t[0]; empire[real_nr].territory = 0; empire[real_nr].members = 0; sprintf(buf,"SYSERR: Format error in empire #%d (expecting letter, got %s)", virtual_nr, line); for (;;) { if (!get_line(fl, line)) { log(buf); exit(1); } switch (*line) { case 'R': j = atoi(line+1); if (j < 20) empire[real_nr].rank[j] = fread_string(fl, buf2); else { log("Invalid rank %d in empire #%d", j, virtual_nr); exit(1); } break; case 'P': j = atoi(line+1); if (!get_line(fl, line)) { log("SYSERR: Expecting privilege number for empire %d, but file ended!", virtual_nr); exit(1); } sscanf(line, "%d", t); empire[real_nr].priv[j] = t[0]; break; case 'D': if (!get_line(fl, line)) { log("SYSERR: Expecting political data for empire %d, but file ended!", virtual_nr); exit(1); } sscanf(line, "%d %d %d", t, t + 1, t + 2); CREATE(emp_pol, struct empire_political_data, 1); emp_pol->id = t[0]; emp_pol->type = t[1]; emp_pol->offer = t[2]; emp_pol->next = empire[real_nr].diplomacy; empire[real_nr].diplomacy = emp_pol; break; case 'O': if (!get_line(fl, line)) { log("SYSERR: Expecting store data for empire %d, but file ended!", virtual_nr); exit(1); } sscanf(line, "%d %d", t, t + 1); CREATE(store, struct empire_storage_data, 1); store->vnum = t[0]; store->amount = t[1]; store->next = empire[real_nr].store; empire[real_nr].store = store; break; case 'S': /* end of empire */ top_of_empiret = real_nr++; return; default: log(buf); exit(1); } } } int create_empire(Creature ch) { struct empire_data *new_empire; int i, j = 0, k; bool found = FALSE; if (IS_NPC(ch)) return -1; CREATE(new_empire, struct empire_data, top_of_empiret + 2); for (i = 0; i <= top_of_empiret; i++) if (found) new_empire[i+1] = empire[i]; else if (empire[i].leader > GET_IDNUM(ch)) { new_empire[i+1] = empire[i]; found = TRUE; new_empire[i].name = str_dup(PERS(ch, ch, 1)); new_empire[i].leader = GET_IDNUM(ch); new_empire[i].banner = str_dup("&0"); new_empire[i].num_ranks = 2; new_empire[i].rank[0] = str_dup("Follower"); new_empire[i].rank[1] = str_dup("Leader"); new_empire[i].territory = 0; new_empire[i].members = 1; new_empire[i].diplomacy = NULL; if (GET_LEVEL(ch) >= LVL_GOD) new_empire[i].imm_only = 1; for (k = 0; k < 6; k++) new_empire[i].vault[k] = 0; for (k = 0; k < NUM_PRIVILEGES; k++) new_empire[i].priv[k] = 2; j = i; } else new_empire[i] = empire[i]; top_of_empiret += 1; if (!found) { new_empire[top_of_empiret].name = str_dup(PERS(ch, ch, 1)); new_empire[top_of_empiret].leader = GET_IDNUM(ch); new_empire[top_of_empiret].banner = str_dup("&0"); new_empire[top_of_empiret].num_ranks = 2; new_empire[top_of_empiret].rank[0] = str_dup("Follower"); new_empire[top_of_empiret].rank[1] = str_dup("Leader"); new_empire[top_of_empiret].territory = 0; new_empire[top_of_empiret].members = 1; new_empire[top_of_empiret].diplomacy = NULL; if (GET_LEVEL(ch) >= LVL_GOD) new_empire[top_of_empiret].imm_only = 1; for (k = 0; k < 6; k++) new_empire[top_of_empiret].vault[k] = 0; for (k = 0; k < NUM_PRIVILEGES; k++) new_empire[top_of_empiret].priv[k] = 2; j = top_of_empiret; } if (empire) free(empire); empire = new_empire; GET_LOYALTY(ch) = GET_IDNUM(ch); GET_RANK(ch) = 2; save_empire(j); SAVE_CHAR(ch); add_lore(ch, LORE_FOUND_EMPIRE, GET_IDNUM(ch)); return j; } Creature is_playing(long id) { Creature ch; for (ch = character_list; ch; ch = ch->next) if (!IS_NPC(ch) && GET_IDNUM(ch) == id) return ch; return NULL; } void delete_empire(int rnum) { void save_char_file_u(struct char_file_u st); extern int top_of_p_table; extern struct player_index_element *player_table; struct char_file_u chdata; struct empire_data *new_empire; struct empire_political_data *emp_pol, *temp; Creature victim; int i, j; long idnum; room_rnum room; if (rnum < 0 || rnum > top_of_empiret) return; log_to_empire(rnum, "This empire has been deleted"); idnum = empire[rnum].leader; CREATE(new_empire, struct empire_data, top_of_empiret); for (i = 0; i <= top_of_empiret; i++) { /* Delete their diplomacy */ if (i != rnum) if ((emp_pol = find_relation(i, rnum))) { REMOVE_FROM_LIST(emp_pol, empire[i].diplomacy, next); free(emp_pol); save_empire(i); } if (i == rnum) { if (empire[i].name) free(empire[i].name); if (empire[i].banner) free(empire[i].banner); for (j = 0; j < 20; j++) if (empire[i].rank[j]) free(empire[i].rank[j]); if (i != top_of_empiret) new_empire[i] = empire[i+1]; } else if (i == top_of_empiret) break; else if (i > rnum) new_empire[i] = empire[i+1]; else if (i < rnum) new_empire[i] = empire[i]; } if (empire) free(empire); empire = new_empire; top_of_empiret--; save_empire_index(); for (j = 0; j <= top_of_p_table && empire[rnum].members; j++) { if ((victim = is_playing((player_table + j)->id))) { if (GET_LOYALTY(victim) == idnum) { msg_to_char(victim, "Your empire has been destroyed. You are no longer a member.\r\n"); GET_LOYALTY(victim) = 0; GET_RANK(victim) = 0; SAVE_CHAR(victim); empire[rnum].members -= 1; } } else { load_char((player_table + j)->name, &chdata); if (chdata.player_specials_saved.loyalty == idnum) { chdata.player_specials_saved.loyalty = 0; chdata.player_specials_saved.rank = 0; save_char_file_u(chdata); empire[rnum].members -= 1; } } } for (room = 0; room <= top_of_world; room++) if (world[room].owner == idnum || (-1 * world[room].owner) == idnum) if (world[room].owner != -1) world[room].owner = 0; sprintf(buf, "rm %s%ld.%s", LIB_EMPIRE, idnum, SUF_EMPIRE); system(buf); save_empire_index(); } /* * For acquiring territory. If ch is loyal to someone, he claims it for them (even if it's * himself). Otherwise, it creates an empire. */ long get_id_by_empire(Creature ch) { if (GET_LOYALTY(ch) && real_empire(GET_LOYALTY(ch)) != -1) return GET_LOYALTY(ch); if (GET_IDNUM(ch) != 0) create_empire(ch); return GET_IDNUM(ch); } bool can_claim(Creature ch) { int e; if (GET_IDNUM(ch) == 0 && GET_LOYALTY(ch) <= 0) return FALSE; if ((e = real_empire(GET_LOYALTY(ch))) == -1) return TRUE; if (empire[e].territory >= LAND_CAN_CLAIM(e)) return FALSE; if (GET_RANK(ch) < empire[e].priv[PRIV_CLAIM]) return FALSE; return TRUE; } /* Allows a leader to change over command */ ACMD(do_chgleader) { if (IS_NPC(ch)) return; msg_to_char(ch, "Report this message to an admin %s", GET_NAME(ch)); } ACMD(do_claim) { int e, i; long l; if (IS_NPC(ch)) return; e = real_empire((l = get_id_by_empire(ch))); if (e == NOTHING) msg_to_char(ch, "You don't belong to any empire.\r\n"); else if (world[ch->in_room].owner == l) msg_to_char(ch, "Your empire already owns this acre.\r\n"); else if (SECT(ch->in_room) == SECT_WASTELAND || SECT(ch->in_room) == SECT_TOWER_OF_SOULS) msg_to_char(ch, "You can't claim this.\r\n"); else if (GET_RANK(ch) < empire[e].priv[PRIV_CLAIM]) msg_to_char(ch, "You don't have permission to claim land for the empire.\r\n"); else if (world[ch->in_room].owner == -1) msg_to_char(ch, "This acre can't be claimed.\r\n"); else if (world[ch->in_room].owner) msg_to_char(ch, "This acre is already claimed.\r\n"); else if (SECT(ch->in_room) == SECT_OCEAN || SECT(ch->in_room) == SECT_RIVER) msg_to_char(ch, "You can't claim the water.\r\n"); else if (HOME_ROOM(ch->in_room) != ch->in_room) msg_to_char(ch, "Just claim the main room for the building.\r\n"); else if (empire[e].haven != NOWHERE && IS_HAVEN(ch->in_room)) msg_to_char(ch, "The empire already has a haven, you can't claim another.\r\n"); else if (!can_claim(ch)) msg_to_char(ch, "You can't claim any more land.\r\n"); else { msg_to_char(ch, OK); world[ch->in_room].owner = l; empire[e].territory += 1; if (SECT(ch->in_room) == SECT_MULTI || SECT(ch->in_room) == SECT_BUILDING || SECT(ch->in_room) == SECT_MONUMENT_CLOSED) { for (i = 0; i <= top_of_world; i++) if (world[i].home_room == world[ch->in_room].number) world[i].owner = l; /* Transfers wealth, etc */ read_empire_territory(); } save_empire(e); } } ACMD(do_abandon) { int e, i; if ((e = real_empire(world[ch->in_room].owner)) != real_empire(GET_LOYALTY(ch))) msg_to_char(ch, "You don't own this acre.\r\n"); else if (GET_RANK(ch) < empire[e].priv[PRIV_CEDE]) msg_to_char(ch, "You don't have permission to abandon land.\r\n"); else { if (IS_HAVEN(ch->in_room)) empire[e].haven = NOWHERE; empire[e].territory--; if (SECT(ch->in_room) == SECT_MULTI || SECT(ch->in_room) == SECT_BUILDING || SECT(ch->in_room) == SECT_MONUMENT_CLOSED) { for (i = 0; i <= top_of_world; i++) if (world[i].home_room == world[ch->in_room].number) world[i].owner = 0; /* Transfers wealth, etc */ read_empire_territory(); } msg_to_char(ch, "Territory abandoned.\r\n"); world[ch->in_room].owner = 0; } } ACMD(do_cede) { extern room_rnum find_target_room(Creature ch, char *rawroomstr); int e = 0, f, i, rnum; long l = 0, to; Creature targ; if (IS_NPC(ch)) return; if (GET_LOYALTY(ch) > 0) e = real_empire((l = get_id_by_empire(ch))); argument = one_argument(argument, arg); if (GET_LOYALTY(ch) <= 0 || e < 0 || l < 0) msg_to_char(ch, "You own no territory.\r\n"); else if (!*arg) msg_to_char(ch, "Usage: cede <person> (x, y)\r\n"); else if (!(targ = get_char_vis(ch, arg, FIND_CHAR_WORLD | FIND_NO_DARK))) msg_to_char(ch, NOPERSON); else if (IS_NPC(targ)) msg_to_char(ch, "You can't cede land to animals!\r\n"); else if (ch == targ) msg_to_char(ch, "You can't cede land to yourself!\r\n"); else if (*argument && (!strstr(argument, ",") || !strstr(argument, "(") || !strstr(argument, ")"))) msg_to_char(ch, "Usage: cede <person> (x, y)\r\n"); else if ((*argument ? (rnum = HOME_ROOM(find_target_room(ch, argument))) : (rnum = HOME_ROOM(ch->in_room))) == NOWHERE) msg_to_char(ch, "Invalid grid.\r\n"); else if (GET_RANK(ch) < empire[e].priv[PRIV_CEDE]) msg_to_char(ch, "You don't have permission to cede.\r\n"); else if (ABSOLUTE(world[rnum].owner) != l) msg_to_char(ch, "You don't even own %s acre.\r\n", rnum == ch->in_room ? "this" : "that"); else if ((f = real_empire((to = get_id_by_empire(targ)))) < 0) msg_to_char(ch, "You can't seem to cede land to %s.\r\n", HMHR(targ)); else if (f == e) msg_to_char(ch, "You can't seed land to your own empire!\r\n"); else if (empire[f].territory >= LAND_CAN_CLAIM(f) + 15) /* Extra 15 land */ msg_to_char(ch, "You can't cede land to %s, %s empire can't own any more land.\r\n", HMHR(targ), HSHR(targ)); else if (empire[f].haven != NOWHERE && IS_HAVEN(rnum)) msg_to_char(ch, "That empire already has a haven, you can't give them another.\r\n"); else { empire[e].territory -= 1; empire[f].territory += 1; world[rnum].owner = to; if (IS_HAVEN(rnum)) { empire[e].haven = NOWHERE; empire[f].haven = world[rnum].number; } save_empire(e); save_empire(f); if (SECT(rnum) == SECT_MULTI || SECT(rnum) == SECT_BUILDING || SECT(rnum) == SECT_MONUMENT_CLOSED) { for (i = 0; i <= top_of_world; i++) if (world[i].home_room == world[rnum].number) world[i].owner = to; /* Transfers wealth, etc */ read_empire_territory(); } log_to_empire(e, "%s has ceded (%d, %d) to %s", PERS(ch, ch, 1), X_COORD(rnum), Y_COORD(rnum), empire[f].name); log_to_empire(f, "%s has ceded (%d, %d) to this empire", PERS(ch, ch, 1), X_COORD(rnum), Y_COORD(rnum)); msg_to_char(ch, OK); } } ACMD(do_pledge) { int e; if (IS_NPC(ch)) return; one_argument(argument, arg); if (GET_LOYALTY(ch) != GET_IDNUM(ch) && GET_LOYALTY(ch) > 0) msg_to_char(ch, "You're already a member of an empire.\r\n"); else if ((e = get_empire_by_name(arg)) < 0) msg_to_char(ch, "There is no empire by that name.\r\n"); else if (GET_DEFECT_TIMER(ch)) msg_to_char(ch, "You can't pledge again yet.\r\n"); else if ((IS_GOD(ch) || IS_IMMORTAL(ch)) && !empire[e].imm_only) msg_to_char(ch, "You may not join an empire.\r\n"); else if (empire[e].imm_only && !IS_GOD(ch) && !IS_IMMORTAL(ch)) msg_to_char(ch, "You can't join that empire.\r\n"); else { GET_PLEDGE(ch) = empire[e].leader; log_to_empire(e, "%s has offered %s pledge to this empire", PERS(ch, ch, 1), HSHR(ch)); msg_to_char(ch, "You offer your pledge to %s.\r\n", empire[e].name); SAVE_CHAR(ch); } } ACMD(do_enroll) { void save_char_file_u(struct char_file_u st); extern struct empire_storage_data *find_stored_resource(int emp, obj_vnum vnum); extern int top_of_p_table; extern struct player_index_element *player_table; struct char_file_u chdata; struct empire_storage_data *store, *store2; int e, i, j; long l; Creature targ, victim; if (IS_NPC(ch)) return; if (GET_LOYALTY(ch) <= 0) { msg_to_char(ch, "You don't belong to any empire.\r\n"); return; } one_argument(argument, arg); e = real_empire((l = get_id_by_empire(ch))); if (e == NOTHING) msg_to_char(ch, "You don't belong to any empire.\r\n"); else if (GET_RANK(ch) < empire[e].priv[PRIV_ENROLL]) msg_to_char(ch, "You don't have the authority to enroll followers.\r\n"); else if (!*arg) msg_to_char(ch, "Whom did you want to enroll?\r\n"); else if (!(targ = get_char_vis(ch, arg, FIND_CHAR_WORLD | FIND_NO_DARK))) msg_to_char(ch, NOPERSON); else if (IS_NPC(targ)) msg_to_char(ch, "You can't enroll animals!\r\n"); else if (ch == targ) msg_to_char(ch, "You're already in the empire!\r\n"); else if (GET_PLEDGE(targ) != l) act("$E has not pledged $mself to your empire.", FALSE, ch, 0, targ, TO_CHAR | TO_SLEEP); else if (GET_LOYALTY(targ) != GET_IDNUM(targ) && GET_LOYALTY(targ) > 0) act("$E is already loyal to another empire.", FALSE, ch, 0, targ, TO_CHAR | TO_SLEEP); else { log_to_empire(e, "%s has been enrolled in the empire", PERS(targ, targ, 1)); msg_to_char(targ, "You have been enrolled in %s.\r\n", empire[e].name); msg_to_char(ch, OK); GET_LOYALTY(targ) = l; GET_RANK(targ) = 1; GET_PLEDGE(targ) = 0; empire[e].members += 1; add_lore(targ, LORE_JOIN_EMPIRE, l); /* Transfer land: checks for a duplicate haven */ if (real_empire(GET_IDNUM(targ)) != -1) { for (store = empire[real_empire(GET_IDNUM(targ))].store; store; store = store->next) { if (!(store2 = find_stored_resource(e, store->vnum))) { CREATE(store2, struct empire_storage_data, 1); store2->next = empire[e].store; empire[e].store = store2; store2->vnum = store->vnum; } store2->amount += store->amount; } for (i = 0; i <= top_of_world; i++) if (world[i].owner == GET_IDNUM(targ) || world[i].owner == -1 * GET_IDNUM(targ)) { if (IS_HAVEN(i) && empire[e].haven != NOWHERE) world[i].owner = 0; else { if (IS_HAVEN(i)) empire[e].haven = world[i].number; world[i].owner = l; if (world[i].home_room == NOWHERE) empire[e].territory += 1; } } } if (real_empire(GET_IDNUM(targ)) != -1) { /* The leader already joined.. */ empire[real_empire(GET_IDNUM(targ))].members -= 1; for (j = 0; j <= top_of_p_table && empire[real_empire(GET_IDNUM(targ))].members; j++) { if ((victim = is_playing((player_table + j)->id))) { if (GET_LOYALTY(victim) == GET_IDNUM(targ)) { msg_to_char(victim, "Your empire has merged with %s.\r\n", empire[e].name); add_lore(victim, LORE_JOIN_EMPIRE, l); GET_LOYALTY(victim) = l; GET_RANK(victim) = 1; SAVE_CHAR(victim); empire[e].members += 1; empire[real_empire(GET_IDNUM(targ))].members -= 1; } } else { load_char((player_table + j)->name, &chdata); if (chdata.player_specials_saved.loyalty == GET_IDNUM(targ)) { chdata.player_specials_saved.loyalty = l; chdata.player_specials_saved.rank = 1; save_char_file_u(chdata); empire[e].members += 1; empire[real_empire(GET_IDNUM(targ))].members -= 1; } } } /* Delete the old empire */ delete_empire(real_empire(GET_IDNUM(targ))); /* This will PROPERLY reset wealth and land */ read_empire_territory(); } } } ACMD(do_defect) { int e; if (IS_NPC(ch)) return; else if (GET_LOYALTY(ch) <= 0) msg_to_char(ch, "You don't belong to any empire.\r\n"); else if ((e = real_empire(GET_LOYALTY(ch))) < 0) msg_to_char(ch, "You don't seem to belong to any empire.\r\n"); else if (GET_IDNUM(ch) == empire[e].leader) msg_to_char(ch, "The leader can't defect!\r\n"); else { GET_LOYALTY(ch) = 0; GET_DEFECT_TIMER(ch) = 96; empire[e].members -= 1; log_to_empire(e, "%s has defected from the empire", PERS(ch, ch, 1)); msg_to_char(ch, "You defect from the empire!\r\n"); add_lore(ch, LORE_DEFECT_EMPIRE, empire[e].leader); SAVE_CHAR(ch); if (empire[e].members == 0) delete_empire(e); } } ACMD(do_expell) { int e; long l; Creature targ; if (IS_NPC(ch)) return; if (GET_LOYALTY(ch) <= 0) { msg_to_char(ch, "You don't belong to any empire.\r\n"); return; } one_argument(argument, arg); e = real_empire((l = get_id_by_empire(ch))); if (e == NOTHING) msg_to_char(ch, "You don't belong to any empire.\r\n"); else if (GET_RANK(ch) != empire[e].num_ranks) msg_to_char(ch, "You don't have the authority to expell followers.\r\n"); else if (!*arg) msg_to_char(ch, "Whom do you wish to expell?\r\n"); else if (!(targ = get_char_vis(ch, arg, FIND_CHAR_WORLD | FIND_NO_DARK))) msg_to_char(ch, NOPERSON); else if (IS_NPC(targ) || GET_LOYALTY(targ) != l) msg_to_char(ch, "That person is not a member of this empire.\r\n"); else if (targ == ch) msg_to_char(ch, "You can't expell yourself.\r\n"); else if (empire[e].leader == GET_IDNUM(targ)) msg_to_char(ch, "You can't expell the leader!\r\n"); else { GET_LOYALTY(targ) = 0; GET_DEFECT_TIMER(targ) = 96; empire[e].members -= 1; log_to_empire(e, "%s has been expelled from the empire", PERS(targ, targ, 1)); msg_to_char(ch, OK); msg_to_char(targ, "You have been expelled from the empire.\r\n"); add_lore(targ, LORE_KICKED_EMPIRE, l); SAVE_CHAR(targ); } } void show_detailed_empire(Creature ch, int e) { struct empire_political_data *emp_pol; int i; msg_to_char(ch, "%s%s&0\r\n", empire[e].banner, empire[e].name); msg_to_char(ch, "Led by %s\r\n", get_name_by_id(empire[e].leader) ? CAP(get_name_by_id(empire[e].leader)) : "(Unknown)"); msg_to_char(ch, "Ranks:\r\n"); for (i = 0; i < empire[e].num_ranks; i++) msg_to_char(ch, " %2d. %s\r\n", i+1, empire[e].rank[i]); msg_to_char(ch, "Privileges:\r\n"); for (i = 0; i < NUM_PRIVILEGES; i++) msg_to_char(ch, "%-12.12s %2d%s", priv[i], empire[e].priv[i], !((i+1)%4) ? "\r\n" : " "); if (i % 4) msg_to_char(ch, "\r\n"); msg_to_char(ch, "Territory: %d/%d\r\nMembers: %d\r\nWealth: %d\r\nFame: %d\r\n", empire[e].territory, LAND_CAN_CLAIM(e), empire[e].members, calculate_wealth(e), empire[e].fame); *buf1 = '\0'; for (emp_pol = empire[e].diplomacy; emp_pol; emp_pol = emp_pol->next) { if (!IS_IMMORTAL(ch) && GET_LOYALTY(ch) != emp_pol->id && GET_LOYALTY(ch) != empire[e].leader) continue; /* Sanity checking */ if (real_empire(emp_pol->id) < 0) continue; *buf = '\0'; if (IS_SET(emp_pol->type, DIPL_PEACE)) sprintf(buf + strlen(buf), "Peaceful relations with %s", empire[real_empire(emp_pol->id)].name); if (IS_SET(emp_pol->type, DIPL_WAR)) sprintf(buf + strlen(buf), "At war with %s", empire[real_empire(emp_pol->id)].name); if (IS_SET(emp_pol->type, DIPL_ALLIED)) sprintf(buf + strlen(buf), "Allied with %s", empire[real_empire(emp_pol->id)].name); if (IS_SET(emp_pol->type, DIPL_NONAGGR)) sprintf(buf + strlen(buf), "In a non-aggression pact with %s", empire[real_empire(emp_pol->id)].name); if (IS_SET(emp_pol->type, DIPL_DISTRUST)) sprintf(buf + strlen(buf), "Distrustful of %s", empire[real_empire(emp_pol->id)].name); if (IS_SET(emp_pol->type, DIPL_TRADE)) sprintf(buf + strlen(buf), " with trade relations"); if (IS_SET(emp_pol->offer, DIPL_ALLIED)) { sprintf(buf + strlen(buf), "%sroposing an alliance", *buf ? ", and are p" : "P"); if (*buf == 'P') sprintf(buf + strlen(buf), " with %s", empire[real_empire(emp_pol->id)].name); } if (IS_SET(emp_pol->offer, DIPL_PEACE)) { sprintf(buf + strlen(buf), "%sroposing peace", *buf ? ", and are p" : "P"); if (*buf == 'P') sprintf(buf + strlen(buf), " to %s", empire[real_empire(emp_pol->id)].name); } if (IS_SET(emp_pol->offer, DIPL_NONAGGR)) { sprintf(buf + strlen(buf), "%sroposing a non-aggression pact", *buf ? ", and are p" : "P"); if (*buf == 'P') sprintf(buf + strlen(buf), " to %s", empire[real_empire(emp_pol->id)].name); } if (IS_SET(emp_pol->offer, DIPL_TRADE)) { sprintf(buf + strlen(buf), "%sroposing a trade pact", *buf ? ", and are p" : "P"); if (*buf == 'P') sprintf(buf + strlen(buf), " with %s", empire[real_empire(emp_pol->id)].name); } if (*buf) { strcat(buf, ".\r\n"); strcat(buf1, buf); } } if (*buf1) msg_to_char(ch, "Current relations:\r\n%s", buf1); } ACMD(do_empires) { int e, min = 1; skip_spaces(&argument); if (top_of_empiret < 0) { msg_to_char(ch, "No empires have been formed.\r\n"); return; } if (*argument == '-') min = atoi((argument + 1)); else if (*argument) { if ((e = get_empire_by_name(argument)) != -1) show_detailed_empire(ch, e); else msg_to_char(ch, "There is no empire by that name or number.\r\n"); return; } for (e = 0; e <= top_of_empiret; e++) if (empire[e].members >= min) msg_to_char(ch, "%3d. %s%-30.30s&0 Members: %2d Territory: %2d\r\n", e+1, empire[e].banner, empire[e].name, empire[e].members, empire[e].territory); } ACMD(do_edelete) { Descr d; int e; skip_spaces(&argument); if (!*argument) msg_to_char(ch, "What empire do you want to delete?\r\n"); else if ((e = get_empire_by_name(argument)) < 0) msg_to_char(ch, "Invalid empire.\r\n"); else { for (d = descriptor_list; d; d = d->next) if (STATE(d) == CON_EMPIRE_EDIT && real_empire(GET_LOYALTY(d->character)) == e) { msg_to_char(ch, "You can't delete an empire which is being edited.\r\n"); return; } delete_empire(e); msg_to_char(ch, "Empire deleted.\r\n"); } } bool check_pact(int a, int b) { struct empire_political_data *emp_pol; if (a == -1 || b == -1) return FALSE; if ((emp_pol = find_relation(a, b))) if (IS_SET(emp_pol->type, DIPL_NONAGGR)) return TRUE; return FALSE; } /* * Returns true if it hit someone */ bool shoot_at_room(room_rnum from_room, room_rnum to_room) { Creature ch, next_ch, m; int to_hit, to_dodge = 0, dam, type; /* Rooms we can't hit */ if (SECT(to_room) == SECT_MOUNTAIN || SECT(to_room) == SECT_MONUMENT_CLOSED || SECT(to_room) == SECT_BUILDING || SECT(to_room) == SECT_MULTI || (SECT(to_room) == SECT_FOREST_4 && BUILDING_TYPE(from_room) != BUILDING_WATCH_TOWER)) if (IS_COMPLETE(to_room) || ALWAYS_CLOSED(to_room)) return FALSE; if (ROOM_AFF_FLAGGED(from_room, ROOM_AFF_DARK)) return FALSE; if (ROOM_AFF_FLAGGED(to_room, ROOM_AFF_DARK)) return FALSE; for (ch = world[to_room].people; ch; ch = next_ch) { next_ch = ch->next_in_room; if (IS_IMMORTAL(ch) || IS_GOD(ch)) continue; /* Special handling for mobs */ if (IS_NPC(ch)) { if (!GET_PULLING(ch) || !GET_OBJ_VAL(GET_PULLING(ch), 2)) continue; } if (!((m = ch->master) && AFF_FLAGGED(ch, AFF_PARTY) && AFF_FLAGGED(m, AFF_PARTY))) m = ch; if ((!IS_NPC(ch) && CAN_USE_ROOM(ch, from_room, 1)) || (!IS_NPC(m) && CAN_USE_ROOM(m, from_room, 1))) continue; if (!IS_NPC(ch) && check_pact(real_empire(GET_LOYALTY(ch)), real_empire(world[from_room].owner))) continue; if (!IS_NPC(m) && check_pact(real_empire(GET_LOYALTY(m)), real_empire(world[from_room].owner))) continue; if ((AFF_FLAGGED(ch, AFF_HIDE) || DSC_FLAGGED(ch, DSC_UNSEEN_PRESENCE)) && !GET_LEADING(ch)) continue; if (AFF_FLAGGED(ch, AFF_INVISIBLE) && !GET_LEADING(ch)) continue; if (DSC_FLAGGED(ch, DSC_MAJESTY)) continue; if (AFF_FLAGGED(ch, AFF_NO_TARGET_IN_ROOM | AFF_NO_ATTACK)) continue; if (MORPH_FLAGGED(ch, MORPH_FLAG_NPC)) continue; if (!number(0, 1) && next_ch) continue; to_hit = ww_dice(6, 6); if (AWAKE(ch)) to_dodge = ww_dice(GET_DEXTERITY(ch) + GET_DODGE(ch), 6); /* Now we're sure we can hit this person */ if (to_hit > to_dodge) dam = ww_dice(4 + (BUILDING_TYPE(from_room) == BUILDING_GUARD_TOWER3) + to_hit - to_dodge, 6); else dam = 0; type = ATTACK_GUARD_TOWER; if (real_empire(world[from_room].owner) != -1 && damage(ch, ch, dam, type, DAM_LETHAL) != 0) { log_to_empire(real_empire(world[from_room].owner), "%s at (%d, %d) is shooting at an infiltrator at (%d, %d)", SECT(from_room) == SECT_MULTI ? "Fort" : "Guard tower", X_COORD(from_room), Y_COORD(from_room), X_COORD(to_room), Y_COORD(to_room)); if (GET_PULLING(ch) && GET_OBJ_VAL(GET_PULLING(ch), 2)) log_to_empire(real_empire(world[from_room].owner), "A catapult has been spotted!"); } return TRUE; } return FALSE; } void process_tower(room_rnum room, bool fort) { extern int side_dir[][2]; int dir = 0, count = 0; room_rnum to_room; if (real_empire(world[room].owner) < 0) return; for (count = 0; count < 3; count++) { /* Pick a direction */ dir = number(0, NUM_2D_DIRS - 1); /* Radius 1 */ to_room = real_shift(room, shift_dir[dir][0], shift_dir[dir][1]); /* shoot */ if (shoot_at_room(room, to_room)) break; /* check for blocking sects */ if (SECT(to_room) == SECT_MOUNTAIN || (SECT(to_room) == SECT_BARRIER && world[to_room].type)) continue; /* Radius 2 */ to_room = real_shift(room, shift_dir[dir][0]*2, shift_dir[dir][1]*2); /* shoot */ if (shoot_at_room(room, to_room)) break; /* check for blocking sects */ if (SECT(to_room) == SECT_MOUNTAIN || (SECT(to_room) == SECT_BARRIER && world[to_room].type)) continue; /* Radius 1, to one side */ to_room = real_shift(room, shift_dir[side_dir[dir][0]][0], shift_dir[side_dir[dir][0]][1]); if (shoot_at_room(room, to_room)) break; /* Radius 1, to the other side */ to_room = real_shift(room, shift_dir[side_dir[dir][1]][0], shift_dir[side_dir[dir][1]][1]); if (shoot_at_room(room, to_room)) break; /* Radius 3 */ /* Make sure we can shoot this far */ if (!fort && BUILDING_TYPE(room) != BUILDING_GUARD_TOWER2 && BUILDING_TYPE(room) != BUILDING_GUARD_TOWER3 && BUILDING_TYPE(room) != BUILDING_WATCH_TOWER) continue; to_room = real_shift(room, shift_dir[dir][0]*2, shift_dir[dir][1]*2); /* shoot */ if (shoot_at_room(room, to_room)) break; /* Radius 2, to one side */ to_room = real_shift(room, shift_dir[dir][0] + shift_dir[side_dir[dir][0]][0], shift_dir[dir][1] + shift_dir[side_dir[dir][0]][1]); if (shoot_at_room(room, to_room)) break; /* Radius 2, to the other side */ to_room = real_shift(room, shift_dir[dir][0] + shift_dir[side_dir[dir][1]][0], shift_dir[dir][1] + shift_dir[side_dir[dir][1]][1]); if (shoot_at_room(room, to_room)) break; } } void update_guard_towers(void) { room_rnum i; for (i = 0; i <= top_of_world; i++) if (SECT(i) == SECT_BUILDING && IS_COMPLETE(i) && (world[i].type == BUILDING_GUARD_TOWER || world[i].type == BUILDING_GUARD_TOWER2 || world[i].type == BUILDING_GUARD_TOWER3 || world[i].type == BUILDING_WATCH_TOWER)) process_tower(i, FALSE); else if (SECT(i) == SECT_MULTI && IS_COMPLETE(i) && (world[i].type == MULTI_UL_DOOR || world[i].type == MULTI_LR_DOOR)) process_tower(i, TRUE); } ACMD(do_esay) { Descr d; Creature tch; int level = 0, e, i; bool emote = FALSE; char lstring[MAX_INPUT_LENGTH]; long l; if (IS_NPC(ch)) return; if ((e = real_empire(l = GET_LOYALTY(ch))) == -1) { msg_to_char(ch, "You don't belong to any empire.\r\n"); return; } if (PLR_FLAGGED(ch, PLR_MUTED)) { msg_to_char(ch, "You can't use the empire channel while muted.\r\n"); return; } skip_spaces(&argument); if (!*argument) { msg_to_char(ch, "What would you like to tell your empire?\r\n"); return; } if (*argument == '*') { argument++; emote = TRUE; } if (*argument == '#') { half_chop(argument, arg, buf); strcpy(argument, buf); for (i = 0; i < strlen(arg); i++) if (arg[i] == '_') arg[i] = ' '; for (i = 0; i < empire[e].num_ranks; i++) if (is_abbrev(arg+1, empire[e].rank[i])) break; if (i < empire[e].num_ranks) level = i; } if (*argument == '*') { argument++; emote = TRUE; } level++; if (level > 1) sprintf(lstring, " <%s&0>", empire[e].rank[level-1]); else *lstring = '\0'; /* Since we cut up the string, we have to check again */ if (!*argument) { msg_to_char(ch, "What would you like to tell your empire?\r\n"); return; } if (emote) sprintf(buf, "[%sEMPIRE&0%s] $n %s", empire[e].banner, lstring, argument); else /* Changed display to always show your name instead of your form. */ sprintf(buf, "[%sEMPIRE&0 $o %s] %s", empire[e].banner, lstring, argument); if (PRF_FLAGGED(ch, PRF_NOREPEAT)) msg_to_char(ch, OK); else act(buf, FALSE, ch, 0, 0, TO_CHAR | TO_SLEEP); for (d = descriptor_list; d; d = d->next) if (STATE(d) != CON_PLAYING || !(tch = d->character) || IS_NPC(tch) || GET_LOYALTY(tch) != l || GET_RANK(tch) < level || tch == ch) continue; else if (PRF_FLAGGED(tch, PRF_RP)) continue; else act(buf, FALSE, ch, 0, tch, TO_VICT | TO_SLEEP); } ACMD(do_promote) { int e, i; long l; Creature victim; if (IS_NPC(ch)) return; argument = one_argument(argument, arg); skip_spaces(&argument); e = real_empire(l = GET_LOYALTY(ch)); if (*argument && e != -1) { for (i = 0; i < strlen(argument); i++) if (argument[i] == '_') argument[i] = ' '; for (i = 0; i < empire[e].num_ranks; i++) if (is_abbrev(argument, empire[e].rank[i])) break; if (i == empire[e].num_ranks) { msg_to_char(ch, "Invalid rank.\r\n"); return; } i++; } else i = -1; if (e == NOTHING) msg_to_char(ch, "You don't belong to any empire.\r\n"); else if (GET_RANK(ch) < empire[e].priv[PRIV_PROMOTE]) msg_to_char(ch, "You can't promote anybody!\r\n"); else if (!*arg) msg_to_char(ch, "Promote whom?\r\n"); else if (!(victim = get_char_vis(ch, arg, FIND_CHAR_WORLD | FIND_NO_DARK))) msg_to_char(ch, NOPERSON); else if (victim == ch) msg_to_char(ch, "You can't promote yourself!\r\n"); else if (IS_NPC(victim) || GET_LOYALTY(victim) != l) msg_to_char(ch, "That person is not in your empire.\r\n"); else if ((i != -1 ? i : (i = GET_RANK(victim) + 1)) < GET_RANK(victim)) msg_to_char(ch, "Use demote for that.\r\n"); else if (i == GET_RANK(victim)) act("$E is already that rank.", FALSE, ch, 0, victim, TO_CHAR); else if (i > empire[e].num_ranks) msg_to_char(ch, "You can't promote someone over the top level.\r\n"); else if (i >= GET_RANK(ch) && GET_RANK(ch) < empire[e].num_ranks) msg_to_char(ch, "You can't promote someone to that level.\r\n"); else { GET_RANK(victim) = i; SAVE_CHAR(victim); log_to_empire(e, "%s has been promoted to %s%s!", PERS(victim, victim, 1), empire[e].rank[i-1], empire[e].banner); msg_to_char(ch, OK); } } ACMD(do_demote) { int e, i; long l; Creature victim; if (IS_NPC(ch)) return; argument = one_argument(argument, arg); skip_spaces(&argument); e = real_empire(l = GET_LOYALTY(ch)); if (*argument && e != -1) { for (i = 0; i < strlen(argument); i++) if (argument[i] == '_') argument[i] = ' '; for (i = 0; i < empire[e].num_ranks && !is_abbrev(argument, empire[e].rank[i]); i++); if (i == empire[e].num_ranks) { msg_to_char(ch, "Invalid rank.\r\n"); return; } i++; } else i = -1; if (e == NOTHING) msg_to_char(ch, "You don't belong to any empire.\r\n"); else if (GET_RANK(ch) < empire[e].priv[PRIV_PROMOTE]) msg_to_char(ch, "You can't demote anybody!\r\n"); else if (!*arg) msg_to_char(ch, "Demote whom?\r\n"); else if (!(victim = get_char_vis(ch, arg, FIND_CHAR_WORLD | FIND_NO_DARK))) msg_to_char(ch, NOPERSON); else if (ch == victim) msg_to_char(ch, "You can't demote yourself!\r\n"); else if (IS_NPC(victim) || GET_LOYALTY(victim) != l) msg_to_char(ch, "That person is not in your empire.\r\n"); else if ((i != -1 ? i : (i = GET_RANK(victim) - 1)) > GET_RANK(victim)) msg_to_char(ch, "Use promote for that.\r\n"); else if (i == GET_RANK(victim)) act("$E is already that rank.", FALSE, ch, 0, victim, TO_CHAR); else if (i < 1) act("You can't demote $M THAT low!", FALSE, ch, 0, victim, TO_CHAR); else { GET_RANK(victim) = i; SAVE_CHAR(victim); log_to_empire(e, "%s has been demoted to %s%s", PERS(victim, victim, 1), empire[e].rank[i-1], empire[e].banner); msg_to_char(ch, OK); } } ACMD(do_roster) { extern int top_of_p_table; extern struct player_index_element *player_table; struct char_file_u chdata; int j, e; long l; Creature tmp; skip_spaces(&argument); if (!*argument || !IS_IMMORTAL(ch)) { if ((e = real_empire(GET_LOYALTY(ch))) == -1) { msg_to_char(ch, "You don't belong to any empire!\r\n"); return; } } else if ((e = get_empire_by_name(argument)) == -1) { send_to_char("Unknown empire.\r\n", ch); return; } l = empire[e].leader; *buf = '\0'; for (j = 0; j <= top_of_p_table; j++) { load_char((player_table + j)->name, &chdata); if (!IS_SET(chdata.char_specials_saved.act, PLR_DELETED | PLR_SLAIN)) if (chdata.player_specials_saved.loyalty == l) { sprintf(buf + strlen(buf), "<%s> %s", empire[e].rank[chdata.player_specials_saved.rank - 1], chdata.name); if ((tmp = get_player_vis(ch, chdata.name, FIND_CHAR_WORLD | FIND_NO_DARK))) { strcat(buf, " - &6online&0"); if (IS_AFK(tmp)) strcat(buf, " - &1afk&0"); } strcat(buf, "\r\n"); } } sprintf(buf1, "Roster of %s%s&0:\r\n%s", empire[e].banner, empire[e].name, buf); page_string(ch->desc, buf1, 1); } #define DIPLOMACY_FORMAT \ "Usage: diplomacy <action> <empire>\r\n" \ "Actions are:\r\n" \ " peace - end a war or begin a relationship with a neutral empire\r\n" \ " war - declare war on an empire\r\n" \ " ally - propose or accept a full alliance\r\n" \ " pact - propose or accept a pact of non-aggression\r\n" \ " trade - propose or accept a trade agreement\r\n" \ " distrust - declare that your empire distrusts, but is not at war with, another\r\n" ACMD(do_diplomacy) { struct empire_political_data *pol_a, *pol_b; int e, f, i; char *dipl_commands[] = { "peace", "war", "ally", "pact", "trade", "distrust", "\n" }; argument = one_argument(argument, arg); skip_spaces(&argument); if (!*arg || !*argument) { msg_to_char(ch, DIPLOMACY_FORMAT); return; } if ((e = real_empire(GET_LOYALTY(ch))) == -1) { msg_to_char(ch, "You don't belong to any empire!\r\n"); return; } if (GET_RANK(ch) < empire[e].priv[PRIV_DIPLOMACY]) { msg_to_char(ch, "You don't have the authority to make diplomatic relations.\r\n"); return; } if ((f = get_empire_by_name(argument)) == -1) { msg_to_char(ch, "Unknown empire.\r\n"); return; } /* Find the command */ for (i = 0; str_cmp(dipl_commands[i], "\n") && !is_abbrev(arg, dipl_commands[i]); i++); if (!str_cmp(dipl_commands[i], "\n")) { msg_to_char(ch, DIPLOMACY_FORMAT); return; } if (!(pol_a = find_relation(e, f))) { CREATE(pol_a, struct empire_political_data, 1); pol_a->id = empire[f].leader; pol_a->next = empire[e].diplomacy; empire[e].diplomacy = pol_a; } if (!(pol_b = find_relation(f, e))) { CREATE(pol_b, struct empire_political_data, 1); pol_b->id = empire[e].leader; pol_b->next = empire[f].diplomacy; empire[f].diplomacy =pol_b; } switch (i) { case 0: /* Peace */ if (IS_SET(pol_b->offer, DIPL_PEACE)) { REMOVE_BIT(pol_b->offer, DIPL_PEACE); pol_a->type = pol_b->type = DIPL_PEACE; log_to_empire(e, "The empire is now at peace with %s", empire[f].name); log_to_empire(f, "The empire is now at peace with %s", empire[e].name); msg_to_char(ch, OK); } else if (IS_SET(pol_a->type, DIPL_WAR | DIPL_DISTRUST) || !pol_a->type) { SET_BIT(pol_a->offer, DIPL_PEACE); log_to_empire(e, "The empire has offered peace to %s", empire[f].name); log_to_empire(f, "%s has offered peace to the empire", empire[e].name); msg_to_char(ch, OK); } else if (IS_SET(pol_a->type, DIPL_ALLIED)) msg_to_char(ch, "But you're already allied!\r\n"); else if (IS_SET(pol_a->type, DIPL_NONAGGR)) msg_to_char(ch, "But you've already got a non-aggression pact!\r\n"); else msg_to_char(ch, "But you already have better relations!\r\n"); break; case 1: /* War */ if (IS_SET(pol_a->type, DIPL_WAR)) msg_to_char(ch, "You're already at war!\r\n"); else { pol_a->offer = pol_b->offer = 0; pol_a->type = pol_b->type = DIPL_WAR; log_to_empire(e, "War has been declared upon %s!", empire[f].name); log_to_empire(f, "%s has declared war!", empire[e].name); msg_to_char(ch, OK); } break; case 2: /* Ally */ if (IS_SET(pol_b->offer, DIPL_ALLIED)) { REMOVE_BIT(pol_b->offer, DIPL_ALLIED | DIPL_NONAGGR | DIPL_PEACE); REMOVE_BIT(pol_a->offer, DIPL_ALLIED | DIPL_NONAGGR | DIPL_PEACE); REMOVE_BIT(pol_b->type, DIPL_NONAGGR | DIPL_PEACE); REMOVE_BIT(pol_a->type, DIPL_NONAGGR | DIPL_PEACE); SET_BIT(pol_a->type, DIPL_ALLIED); SET_BIT(pol_b->type, DIPL_ALLIED); log_to_empire(e, "An alliance has been established with %s!", empire[f].name); log_to_empire(f, "%s has accepted the offer of alliance!", empire[e].name); msg_to_char(ch, OK); } else if (IS_SET(pol_a->type, DIPL_WAR | DIPL_DISTRUST)) msg_to_char(ch, "You'll have to establish peace first.\r\n"); else if (IS_SET(pol_a->type, DIPL_ALLIED)) msg_to_char(ch, "You're already allied!\r\n"); else { SET_BIT(pol_a->offer, DIPL_ALLIED); log_to_empire(e, "The empire has suggested an alliance to %s", empire[f].name); log_to_empire(f, "%s has suggested an alliance", empire[e].name); msg_to_char(ch, OK); } break; case 3: /* Pact */ if (IS_SET(pol_b->offer, DIPL_NONAGGR)) { REMOVE_BIT(pol_b->offer, DIPL_NONAGGR | DIPL_PEACE); REMOVE_BIT(pol_a->offer, DIPL_NONAGGR | DIPL_PEACE); REMOVE_BIT(pol_b->type, DIPL_PEACE); REMOVE_BIT(pol_a->type, DIPL_PEACE); SET_BIT(pol_a->type, DIPL_NONAGGR); SET_BIT(pol_b->type, DIPL_NONAGGR); log_to_empire(e, "A non-aggression pact has been established with %s!", empire[f].name); log_to_empire(f, "%s has accepted the offer of a non-aggression pact!", empire[e].name); msg_to_char(ch, OK); } else if (IS_SET(pol_a->type, DIPL_WAR | DIPL_DISTRUST)) msg_to_char(ch, "You'll have to establish peace first.\r\n"); else if (IS_SET(pol_a->type, DIPL_ALLIED)) msg_to_char(ch, "You're already allied!\r\n"); else if (IS_SET(pol_a->type, DIPL_NONAGGR)) msg_to_char(ch, "You've already got a pact!\r\n"); else { SET_BIT(pol_a->offer, DIPL_NONAGGR); log_to_empire(e, "The empire has offered a non-aggression pact to %s", empire[f].name); log_to_empire(f, "%s has offered a non-aggression pact", empire[e].name); msg_to_char(ch, OK); } break; case 4: /* Trade */ if (IS_SET(pol_b->offer, DIPL_TRADE)) { REMOVE_BIT(pol_b->offer, DIPL_TRADE); SET_BIT(pol_a->type, DIPL_TRADE); SET_BIT(pol_b->type, DIPL_TRADE); log_to_empire(e, "A trade agreement been established with %s!", empire[f].name); log_to_empire(f, "%s has accepted the offer of a trade agreement!", empire[e].name); msg_to_char(ch, OK); } else if (IS_SET(pol_a->type, DIPL_WAR | DIPL_DISTRUST) || !pol_a->type) msg_to_char(ch, "You'll have to establish peace first.\r\n"); else if (IS_SET(pol_a->type, DIPL_TRADE)) msg_to_char(ch, "You're already trading with them!\r\n"); else { SET_BIT(pol_a->offer, DIPL_TRADE); log_to_empire(e, "The empire has offered a trade agreement to %s", empire[f].name); log_to_empire(f, "%s has offered a trade agreement", empire[e].name); msg_to_char(ch, OK); } break; case 5: /* Distrust */ if (IS_SET(pol_a->type, DIPL_WAR)) msg_to_char(ch, "You're already at war!\r\n"); else if (IS_SET(pol_a->type, DIPL_DISTRUST)) msg_to_char(ch, "You already distrust them!\r\n"); else { pol_a->offer = pol_b->offer = 0; pol_a->type = pol_b->type = DIPL_DISTRUST; log_to_empire(e, "The empire now officially distrusts %s", empire[f].name); log_to_empire(f, "%s has declared that they official distrust the empire", empire[e].name); msg_to_char(ch, OK); } break; } save_empire(e); save_empire(f); } /* Determines whether or not a person can use a room */ bool CAN_USE_ROOM(Creature ch, room_rnum room, bool mode) { struct empire_political_data *emp_pol; if (IS_NPC(ch)) return FALSE; if (world[HOME_ROOM(room)].owner == 0) return TRUE; if (world[HOME_ROOM(room)].owner < 0 && !mode) return TRUE; if (real_empire(world[HOME_ROOM(room)].owner) == real_empire(GET_LOYALTY(ch))) return TRUE; if (world[HOME_ROOM(room)].owner == -1 * GET_LOYALTY(ch)) return TRUE; if ((emp_pol = find_relation(real_empire(GET_LOYALTY(ch)), real_empire(world[HOME_ROOM(room)].owner)))) if (IS_SET(emp_pol->type, DIPL_ALLIED)) return TRUE; return FALSE; } ACMD(do_publicize) { if (world[ch->in_room].home_room != NOWHERE) msg_to_char(ch, "You can't do that here.\r\n"); else if (real_empire(GET_LOYALTY(ch)) < 0) msg_to_char(ch, "You're not in an empire.\r\n"); else if (GET_RANK(ch) < empire[real_empire(GET_LOYALTY(ch))].priv[PRIV_CLAIM]) msg_to_char(ch, "You don't have permission to do that.\r\n"); else if (world[ch->in_room].owner == -1 * GET_LOYALTY(ch)) { world[ch->in_room].owner = GET_LOYALTY(ch); msg_to_char(ch, "This area is no longer public.\r\n"); } else if (world[ch->in_room].owner == GET_LOYALTY(ch)) { world[ch->in_room].owner = -1 * GET_LOYALTY(ch); msg_to_char(ch, "This room is now public.\r\n"); } else msg_to_char(ch, "Your empire doesn't own this area.\r\n"); } ACMD(do_unpublicize) { int e; room_rnum r; if ((e = real_empire(GET_LOYALTY(ch))) < 0) msg_to_char(ch, "You're not in an empire.\r\n"); else if (GET_RANK(ch) < empire[e].num_ranks) msg_to_char(ch, "You're of insufficient rank to remove all public status for the empire.\r\n"); else { for (r = 0; r <= top_of_world; r++) if (world[r].owner < -1 && real_empire(world[r].owner) == e) world[r].owner *= -1; msg_to_char(ch, "All public status for this empire's buildings has been renounced.\r\n"); } } /* ********** EMPIRE EDITOR *********************************************** */ const char *color_names[] = { "normal", "red", "green", "yellow", "blue", "magenta", "cyan", "\n" }; /* code works fine as long as you don't duplicate entries in these strings */ const char color_numbers[] = { '0', '1', '2', '3', '4', '5', '6', '\n' }; const char color_flag_letters[] = { 'b', 'u', '\n' }; const char *color_mod_bits[] = { "bold", "underlined", "\n" }; const char *color_mod_flag_bits[] = { "&b", "&u", "\n" }; #define COLOR_MOD_BOLD (1 << 0) #define COLOR_MOD_UNDERLINE (1 << 1) /* Utilities */ /* extracts color codes and flags from a string */ char *extract_color_codes(char *input, sh_int *color, sh_int *flags, bool ignore_trailing_white_code) { static char output[MAX_STRING_LENGTH]; int f, i, j; *color = 0; *flags = 0; *output = '\0'; for (i = 0, j = 0; i <= strlen(input); i++) { /* handle a color code unless it's a trailing &0 */ if (input[i] == '&' && (i < strlen(input) - 2 || !ignore_trailing_white_code)) { i++; for (f = 0; color_numbers[f] != '\n'; f++) if (input[i] == color_numbers[f]) *color = f; for (f = 0; color_flag_letters[f] != '\n'; f++) if (input[i] == color_flag_letters[f]) *flags |= (1 << f); } /* skipped color code */ else if (input[i] == '&') i++; /* copy the letter */ else { output[j] = input[i]; j++; } } return output; } /* creates a color code string from color flags */ char *make_color_string(sh_int color, sh_int flags) { static char output[MAX_STRING_LENGTH]; char buffer[MAX_INPUT_LENGTH]; sprintbit(flags, color_mod_flag_bits, buffer, FALSE); sprintf(output, "&%d%s", color, buffer); return output; } /* creates color codes as a phrase */ char *make_color_phrase(sh_int color, sh_int flags) { static char output[MAX_STRING_LENGTH]; char buffer[MAX_INPUT_LENGTH]; sprintbit(flags, color_mod_bits, buffer, FALSE); sprintf(output, "%s%s%s", buffer, *buffer ? " " : "", color_names[color]); return output; } /* setup the editor */ struct empire_edit_data *create_empire_editor(int emp) { struct empire_edit_data *editor; int i; CREATE(editor, struct empire_edit_data, 1); editor->mode = EEDIT_MENU; editor->submode = 0; editor->changed = FALSE; editor->leader = empire[emp].leader; editor->name = str_dup(empire[emp].name); extract_color_codes(empire[emp].banner, &editor->banner_color, &editor->banner_flags, FALSE); editor->num_ranks = empire[emp].num_ranks; for (i = 0; i < MAX_RANKS; i++) if (i >= editor->num_ranks) { editor->rank_colors[i] = 0; editor->rank_color_flags[i] = 0; } else editor->rank[i] = str_dup(extract_color_codes(empire[emp].rank[i], &editor->rank_colors[i], &editor->rank_color_flags[i], TRUE)); for (i = 0; i < NUM_PRIVILEGES; i++) editor->priv[i] = empire[emp].priv[i]; return editor; } /* copy the editor back to the empire */ void save_empire_editor(struct empire_edit_data *editor, int emp) { int i; /* reset changed in case this is a mid-way save */ editor->changed = FALSE; empire[emp].leader = editor->leader; if (empire[emp].name) free(empire[emp].name); empire[emp].name = str_dup(editor->name); if (empire[emp].banner) free(empire[emp].banner); empire[emp].banner = str_dup(make_color_string(editor->banner_color, editor->banner_flags)); empire[emp].num_ranks = editor->num_ranks; for (i = 0; i < editor->num_ranks; i++) { if (editor->rank_colors[i] || editor->rank_color_flags[i]) sprintf(buf, "%s%s&0", make_color_string(editor->rank_colors[i], editor->rank_color_flags[i]), editor->rank[i]); else strcpy(buf, editor->rank[i]); if (empire[emp].rank[i]) free (empire[emp].rank[i]); empire[emp].rank[i] = str_dup(buf); } for (i = 0; i < NUM_PRIVILEGES; i++) empire[emp].priv[i] = editor->priv[i]; save_empire(emp); } /* get out of the editor */ void exit_empire_editor(Descr d) { extern char *MENU; int i; if (d->empire->name) free (d->empire->name); for (i = 0; i < MAX_RANKS; i++) if (d->empire->rank[i]) free (d->empire->rank[i]); free(d->empire); STATE(d) = CON_MENU; SEND_TO_Q(MENU, d); } /* Displays */ /* main menu */ void send_empire_edit_menu(Descr d) { int i; /* header */ sprintf(buf, "\r\n --- Empire Editor Alpha ---\r\n"); /* name and banner */ sprintf(buf + strlen(buf), " 1. Name: %-30.30s 2. Banner: %s%s&0\r\n", d->empire->name, make_color_string(d->empire->banner_color, d->empire->banner_flags), make_color_phrase(d->empire->banner_color, d->empire->banner_flags)); /* ranks */ sprintf(buf + strlen(buf), " 3. Ranks:\r\n"); for (i = 0; i < d->empire->num_ranks; i++) sprintf(buf + strlen(buf), " r%-2d. %s%-25.25s&0%s", i + 1, make_color_string(d->empire->rank_colors[i], d->empire->rank_color_flags[i]), d->empire->rank[i], (!((i + 1) % 2)) ? "\r\n" : " "); if (i % 2) strcat(buf, "\r\n"); strcat(buf, "\r\n"); /* privileges */ sprintf(buf + strlen(buf), " Privileges:\r\n"); for (i = 0; i < NUM_PRIVILEGES; i++) sprintf(buf + strlen(buf), " p%-2d. %-12.12s %2d%s", i + 1, priv[i], d->empire->priv[i], !((i + 1) % 3) ? "\r\n" : ""); if (i % 3) strcat(buf, "\r\n"); strcat(buf, "\r\n"); /* misc menus */ sprintf(buf + strlen(buf), " 4. Resource Viewer\r\n"); /*sprintf(buf + strlen(buf), " 5. Territory Viewer - coming soon\r\n"); sprintf(buf + strlen(buf), " 6. Member Editor - coming soon\r\n"); sprintf(buf + strlen(buf), " 7. Change Leader - coming soon\r\n");*/ strcat(buf, "\r\n"); /* usage */ strcat(buf, " Usage: <option letter and number>\r\n"); strcat(buf, " Examples: r3, 1, 6\r\n"); strcat(buf, " Type 'exit' to finish.\r\n"); strcat(buf, "> "); msg_to_char(d->character, buf); } /* the banner menu */ void send_banner_menu(Descr d) { int i; /* header */ sprintf(buf, "\r\n Banner Menu\r\n"); /* colors */ for (i = 0; color_numbers[i] != '\n'; i++) sprintf(buf + strlen(buf), " %c. %-15.15s%s", color_numbers[i], color_names[i], (!((i + 1) % 2)) ? "\r\n" : " "); if (i % 2) strcat(buf, "\r\n"); strcat(buf, "\r\n"); /* color flags */ for (i = 0; color_flag_letters[i] != '\n'; i++) sprintf(buf + strlen(buf), " %c. %-15.15s\r\n", color_flag_letters[i], color_mod_bits[i]); /* current */ sprintf(buf + strlen(buf), "\r\nYour current banner color is %s%s&0.\r\n", make_color_string(d->empire->banner_color, d->empire->banner_flags), make_color_phrase(d->empire->banner_color, d->empire->banner_flags)); /* prompt */ strcat(buf, "Enter a color code or type 'done' to exit.\r\n> "); msg_to_char(d->character, buf); } /* the rank menu */ void send_rank_menu(Descr d) { /* header */ sprintf(buf, "\r\n Rank %d\r\n", d->empire->submode + 1); /* name */ sprintf(buf + strlen(buf), "1. Name: %s\r\n", d->empire->rank[d->empire->submode]); /* color */ sprintf(buf + strlen(buf), "2. Color: %s%s&0\r\n", make_color_string(d->empire->rank_colors[d->empire->submode], d->empire->rank_color_flags[d->empire->submode]), make_color_phrase(d->empire->rank_colors[d->empire->submode], d->empire->rank_color_flags[d->empire->submode])); /* result */ sprintf(buf + strlen(buf), "\r\nType a number to edit, or 'done' to exit.\r\n> "); msg_to_char(d->character, buf); } /* the rank color menu */ void send_rank_color_menu(Descr d) { int i; /* header */ sprintf(buf, "\r\n Rank Color Menu\r\n"); /* colors */ for (i = 0; color_numbers[i] != '\n'; i++) sprintf(buf + strlen(buf), " %c. %-15.15s%s", color_numbers[i], color_names[i], (!((i + 1) % 2)) ? "\r\n" : " "); if (i % 2) strcat(buf, "\r\n"); strcat(buf, "\r\n"); /* color flags */ for (i = 0; color_flag_letters[i] != '\n'; i++) sprintf(buf + strlen(buf), " %c. %-15.15s\r\n", color_flag_letters[i], color_mod_bits[i]); /* current */ sprintf(buf + strlen(buf), "\r\nYour current rank color is %s%s&0.\r\n", make_color_string(d->empire->rank_colors[d->empire->submode], d->empire->rank_color_flags[d->empire->submode]), make_color_phrase(d->empire->rank_colors[d->empire->submode], d->empire->rank_color_flags[d->empire->submode])); /* prompt */ strcat(buf, "Enter a color code or type 'done' to exit.\r\n> "); msg_to_char(d->character, buf); } /* shows all stored resources for the empire */ void display_resources(Descr d) { struct empire_storage_data *store; int e = real_empire(GET_LOYALTY(d->character)), c = 0; msg_to_char(d->character, "\r\n"); /* idiot-proofing */ if (e < 0) { msg_to_char(d->character, "Error: unable to locate empire!\r\n"); return; } *buf = '\0'; for (store = empire[e].store; store; store = store->next) { sprintf(buf1, "%.20s: %d", GET_OBJ_NAME_BY_PROTO(real_object(store->vnum)), store->amount); sprintf(buf + strlen(buf), " %-25.25s%s", buf1, !(++c % 3) ? "\r\n" : ""); } if (c % 3) strcat(buf, "\r\n"); if (*buf) msg_to_char(d->character, "Resources owned:\r\n%s", buf); else msg_to_char(d->character, "Your empire has no resources stored.\r\n"); } /* Parsers */ /* the menu parser */ void parse_empire_edit_menu(Descr d, char *arg) { int i; if (!str_cmp(arg, "exit")) { if (d->empire->changed) { d->empire->mode = EEDIT_EXIT; msg_to_char(d->character, "\r\nDo you want to save changes (y/n) ? "); } else exit_empire_editor(d); return; } switch (LOWER(*arg)) { case '1': d->empire->mode = EEDIT_NAME; msg_to_char(d->character, "Enter a new empire name: "); break; case '2': d->empire->mode = EEDIT_BANNER; send_banner_menu(d); break; case '3': d->empire->mode = EEDIT_RANK_NUMBER_CONFIRM; msg_to_char(d->character, "This will require saving your progress up to this point. Continue (y/N) ? "); break; case '4': display_resources(d); d->empire->mode = EEDIT_TO_MENU; msg_to_char(d->character, "Press ENTER to continue: "); break; case '5': msg_to_char(d->character, "Feature not available.\r\n> "); break; case '6': msg_to_char(d->character, "Feature not available.\r\n> "); break; case '7': msg_to_char(d->character, "Feature not available.\r\n> "); break; case 'r': if ((i = atoi(arg + 1)) < 1 || i > d->empire->num_ranks) { msg_to_char(d->character, "Invalid rank option %d!\r\n> ", i); break; } d->empire->mode = EEDIT_RANK_MENU; d->empire->submode = i - 1; send_rank_menu(d); break; case 'p': if ((i = atoi(arg + 1)) < 1 || i > NUM_PRIVILEGES) { msg_to_char(d->character, "Invalid privilege option %d!\r\n> ", i); break; } d->empire->mode = EEDIT_PRIVILEGE; d->empire->submode = i - 1; msg_to_char(d->character, "Enter a new rank number for %s: ", priv[d->empire->submode]); break; default: msg_to_char(d->character, "Unknown command '%c'!\r\n> ", *arg); return; } } /* the empire editor */ void parse_empire_edit(Descr d, char *arg) { int e, i, j, num, members; long l; bool found; Creature victim; struct char_file_u chdata; skip_spaces(&arg); switch (d->empire->mode) { case EEDIT_MENU: parse_empire_edit_menu(d, arg); break; case EEDIT_TO_MENU: d->empire->mode = EEDIT_MENU; send_empire_edit_menu(d); break; case EEDIT_NAME: if (strstr(arg, "&")) msg_to_char(d->character, "Empire names may not contain color codes.\r\n"); else if (strstr(arg, "%")) msg_to_char(d->character, "Empire names may not contain per cent signs.\r\n"); else { if (d->empire->name) free(d->empire->name); d->empire->name = str_dup(arg); d->empire->changed = TRUE; d->empire->mode = EEDIT_MENU; send_empire_edit_menu(d); break; } d->empire->mode = EEDIT_TO_MENU; msg_to_char(d->character, "Press ENTER to continue: "); break; case EEDIT_BANNER: if (!str_cmp(arg, "done")) { d->empire->mode = EEDIT_MENU; send_empire_edit_menu(d); break; } found = FALSE; for (i = 0; color_numbers[i] != '\n'; i++) if (*arg == color_numbers[i]) { found = TRUE; d->empire->banner_color = i; } for (i = 0; color_flag_letters[i] != '\n'; i++) if (*arg == color_flag_letters[i]) { if (d->empire->banner_flags & (1 << i)) d->empire->banner_flags &= ~(1 << i); else d->empire->banner_flags |= (1 << i); found = TRUE; } if (!found) { msg_to_char(d->character, "Invalid choice!\r\n> "); break; } d->empire->changed = TRUE; send_banner_menu(d); break; case EEDIT_RANK_NUMBER: if ((num = atoi(arg)) < 2 || num > MAX_RANKS) msg_to_char(d->character, "You can have between 2 and %d ranks.\r\n", MAX_RANKS); else if (num == d->empire->num_ranks) { d->empire->mode = EEDIT_MENU; send_empire_edit_menu(d); break; } else { l = d->empire->leader; e = real_empire(d->empire->leader); /* fix old peoples */ if (num < d->empire->num_ranks) { for (j = 0, members = empire[e].members; j <= top_of_p_table && members; j++) { if ((victim = is_playing((player_table + j)->id))) { if (GET_LOYALTY(victim) == l) { if (GET_RANK(victim) >= num) GET_RANK(victim) = num - 1; SAVE_CHAR(victim); members--; } } else { load_char((player_table + j)->name, &chdata); if (chdata.player_specials_saved.loyalty == l) { if (chdata.player_specials_saved.rank >= num) chdata.player_specials_saved.rank = num - 1; save_char_file_u(chdata); members--; } } } } GET_RANK(d->character) = num; SAVE_CHAR(d->character); if (num < d->empire->num_ranks) for (j = 0; j < NUM_PRIVILEGES; j++) d->empire->priv[j] = num; for (j = 0; j < MAX_RANKS; j++) if (j < num && !d->empire->rank[j]) { d->empire->rank[j] = str_dup("Follower"); d->empire->rank_colors[j] = 0; d->empire->rank_color_flags[j] = 0; } d->empire->num_ranks = num; /* must save now */ save_empire_editor(d->empire, e); d->empire->changed = TRUE; d->empire->mode = EEDIT_MENU; send_empire_edit_menu(d); break; } d->empire->mode = EEDIT_TO_MENU; msg_to_char(d->character, "Press ENTER to continue: "); break; case EEDIT_RANK_NUMBER_CONFIRM: switch (LOWER(*arg)) { case 'y': d->empire->mode = EEDIT_RANK_NUMBER; msg_to_char(d->character, "How many ranks would you like (2-20): "); break; default: d->empire->mode = EEDIT_MENU; send_empire_edit_menu(d); break; } break; case EEDIT_RANK_MENU: if (!str_cmp(arg, "done")) { d->empire->mode = EEDIT_MENU; send_empire_edit_menu(d); break; } switch (LOWER(*arg)) { case '1': d->empire->mode = EEDIT_RANK_NAME; msg_to_char(d->character, "Enter a new name for this rank: "); break; case '2': d->empire->mode = EEDIT_RANK_COLOR; send_rank_color_menu(d); break; default: msg_to_char(d->character, "Invalid choice!\r\n> "); break; } break; case EEDIT_RANK_NAME: if (strstr(arg, "&")) msg_to_char(d->character, "Rank names may not contain color codes.\r\n> "); else { if (d->empire->rank[d->empire->submode]) free (d->empire->rank[d->empire->submode]); d->empire->rank[d->empire->submode] = str_dup(arg); d->empire->changed = TRUE; d->empire->mode = EEDIT_RANK_MENU; send_rank_menu(d); } break; case EEDIT_RANK_COLOR: if (!str_cmp(arg, "done")) { d->empire->mode = EEDIT_RANK_MENU; send_rank_menu(d); break; } found = FALSE; for (i = 0; color_numbers[i] != '\n'; i++) if (*arg == color_numbers[i]) { found = TRUE; d->empire->rank_colors[d->empire->submode] = i; } for (i = 0; color_flag_letters[i] != '\n'; i++) if (*arg == color_flag_letters[i]) { if (d->empire->rank_color_flags[d->empire->submode] & (1 << i)) d->empire->rank_color_flags[d->empire->submode] &= ~(1 << i); else d->empire->rank_color_flags[d->empire->submode] |= (1 << i); found = TRUE; } if (!found) { msg_to_char(d->character, "Invalid choice!\r\n> "); break; } d->empire->changed = TRUE; send_rank_color_menu(d); break; case EEDIT_PRIVILEGE: if ((num = atoi(arg)) < 1 || num > d->empire->num_ranks) { msg_to_char(d->character, "The rank number must be between 1 and %d.\r\n", d->empire->num_ranks); d->empire->mode = EEDIT_TO_MENU; msg_to_char(d->character, "Press ENTER to continue: "); break; } d->empire->priv[d->empire->submode] = num; d->empire->changed = TRUE; d->empire->mode = EEDIT_MENU; send_empire_edit_menu(d); break; case EEDIT_EXIT: switch (LOWER(*arg)) { case 'y': save_empire_editor(d->empire, real_empire(GET_LOYALTY(d->character))); log_to_empire(real_empire(GET_LOYALTY(d->character)), "%s has edited the empire", PERS(d->character, d->character, 1)); syslog(GET_INVIS_LEV(d->character), FALSE, "%s has edited %s empire", PERS(d->character, d->character, 1), HSHR(d->character)); case 'n': exit_empire_editor(d); break; default: msg_to_char(d->character, "\r\nYou must type 'yes' or 'no': "); break; } break; default: syslog(0, TRUE, "SYSERR: Unknown editor mode!"); d->empire->mode = EEDIT_MENU; send_empire_edit_menu(d); return; } }