/* ************************************************************************
* 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;
}
}