/************************************************************************** * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. * * * * Merc Diku Mud improvements copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * * * In order to use any part of this Merc Diku Mud, you must comply with * * both the original Diku license in 'license.doc' as well the Merc * * license in 'license.txt'. In particular, you may not remove either of * * these copyright notices. * * * * Much time and thought has gone into this software and you are * * benefiting. We hope that you share your changes too. What goes * * around, comes around. * *************************************************************************** * ROM 2.4 is copyright 1993-1998 Russ Taylor * * ROM has been brought to you by the ROM consortium * * Russ Taylor (rtaylor@hypercube.org) * * Gabrielle Taylor (gtaylor@hypercube.org) * * Brian Moore (zump@rom.org) * * By using this code, you have agreed to follow the terms of the * * ROM license, in the file Rom24/doc/rom.license * *************************************************************************** * 1stMUD ROM Derivative (c) 2001-2002 by Ryan Jennings * * http://1stmud.dlmud.com/ <r-jenn@shaw.ca> * ***************************************************************************/ #include <sys/types.h> #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <time.h> #include <string.h> #include "merc.h" #include "tables.h" #include "recycle.h" #include "interp.h" void make_note(const char *board_name, const char *sender, const char *to, const char *subject, const int expire_days, const char *text); #define IS_SET_WAR(ch) (IS_SET((ch)->act, PLR_WAR) || (ch)->pcdata->still_in_war == TRUE) #define WAR_NONE 0 #define WAR_RACE 1 #define WAR_CLASS 2 #define WAR_GENOCIDE 3 #define WAR_CLAN 4 #define MAX_WAR 5 struct war_type { const char *name; int type; }; const struct war_type war_table[] = { {"none", WAR_NONE}, {"race", WAR_RACE}, {"class", WAR_CLASS}, {"genocide", WAR_GENOCIDE}, {"clan", WAR_CLAN}, {NULL, -1}, }; char *wartype_name(int type) { int i; for (i = 0; war_table[i].name != NULL; i++) if (war_table[i].type == type) return capitalize(war_table[i].name); return "Unknown"; } #define WAR_COST 3 // in trivia points bool start_war(CHAR_DATA * ch, const char *argument) { char arg1[MIL], arg2[MIL]; char arg3[MIL]; CHAR_DATA *wch, *warmaster = NULL; int blevel, elevel, type; for (warmaster = ch->in_room->first_person; warmaster != NULL; warmaster = warmaster->next_in_room) { if (!IS_NPC(warmaster)) continue; if (warmaster->spec_fun == spec_lookup("spec_warmaster")) break; } if (!IS_IMMORTAL(ch) && (warmaster == NULL || warmaster->spec_fun != spec_lookup("spec_warmaster"))) { chprintln(ch, "You can't do that here."); return FALSE; } if (!IS_IMMORTAL(ch) && warmaster->fighting != NULL) { chprintln(ch, "Wait until the fighting stops."); return FALSE; } argument = one_argument(argument, arg1); argument = one_argument(argument, arg2); argument = one_argument(argument, arg3); if (arg1[0] == '\0' || arg2[0] == '\0' || arg3[0] == '\0') { int i; chprintln(ch, "Syntax: war start <min_level> <max_level> <type>\n\r" "where <type> is either:"); for (i = 1; war_table[i].name != NULL; i++) chprintf(ch, "%d - %s war\n\r", war_table[i].type, war_table[i].name); return FALSE; } blevel = atoi(arg1); elevel = atoi(arg2); type = atoi(arg3); if (blevel <= 0 || blevel > MAX_LEVEL) { chprintf(ch, "Level must be between 1 and %d.\n\r", MAX_LEVEL); return FALSE; } if (blevel <= 0 || elevel > MAX_LEVEL) { chprintf(ch, "Level must be between 1 and %d.\n\r", MAX_LEVEL); return FALSE; } if (elevel < blevel) { chprintln(ch, "Max level must be greater than the min level."); return FALSE; } if (elevel - blevel < 5) { chprintln(ch, "Levels must have a difference of at least 5."); return FALSE; } if (type <= WAR_NONE || type >= MAX_WAR) { int i; chprintln(ch, "The type either has to be:"); for (i = 1; war_table[i].name != NULL; i++) chprintf(ch, "%d (%s)\n\r", war_table[i].type, war_table[i].name); return FALSE; } if (war_info.iswar != WAR_OFF) { chprintln(ch, "There is already a war going!"); return FALSE; } if (!IS_IMMORTAL(ch)) { char buf[MSL]; if (ch->pcdata->trivia < WAR_COST) { sprintf(buf, "It costs %d Trivia Points to start a %s war.", WAR_COST, wartype_name(type)); do_mob_tell(ch, warmaster, buf); return FALSE; } else { sprintf(buf, "Thank you %s, %s war started, you are %d trivia points lighter.", ch->name, wartype_name(type), WAR_COST); do_mob_tell(ch, warmaster, buf); } } war_info.iswar = WAR_WAITING; replace_string(war_info.who, ch->name); war_info.min_level = blevel; war_info.max_level = elevel; war_info.wartype = type; announce(ch, INFO_WAR, "$n announces a %s war for levels %d to %d. Type 'WAR JOIN' to kill or be killed.", wartype_name(war_info.wartype), war_info.min_level, war_info.max_level); if (ch) chprintf(ch, "You announce a %s war for levels %d to %d. Type 'WAR JOIN' to kill or be killed.", wartype_name(war_info.wartype), war_info.min_level, war_info.max_level); war_info.timer = 3; war_info.next = 0; for (wch = player_first; wch != NULL; wch = wch->next_player) { if (IS_SET(wch->act, PLR_WAR)) REMOVE_BIT(wch->act, PLR_WAR); if (wch->pcdata->still_in_war) wch->pcdata->still_in_war = FALSE; } return TRUE; } void auto_war(void) { CHAR_DATA *wch, *wch_last, *warmaster; int maxlvl = 0, minlvl = MAX_LEVEL, middle = LEVEL_HERO / 2; int clan = 0, count = 0, lbonus = 0, half = 0; int heros = 0; if (war_info.iswar != WAR_OFF) return; for (wch = player_first; wch != NULL; wch = wch->next_player) { if (!wch->desc) continue; if (!IS_NPC(wch) && !IS_IMMORTAL(wch)) { count++; maxlvl = UMAX(maxlvl, wch->level); minlvl = UMIN(minlvl, wch->level); if (wch->level == LEVEL_HERO || wch->level == LEVEL_HERO) heros++; if (is_clan(wch)) { for (wch_last = player_first; wch_last != NULL; wch_last = wch_last->next_player) { if (!IS_NPC(wch_last) && !IS_IMMORTAL(wch_last) && is_clan(wch_last) && !is_same_clan(wch, wch_last)) clan++; } } } } if (count < 2) { end_war(); return; } lbonus = number_range(15, 30); minlvl = UMAX(1, minlvl - lbonus); maxlvl = UMIN(LEVEL_HERO, maxlvl + lbonus); half = ((maxlvl - minlvl) / 2); middle = URANGE(minlvl, maxlvl - half, maxlvl); minlvl = UMAX(1, number_range(minlvl, (middle * 2) / 3)); if (heros > 2 && number_percent() < 25) maxlvl = LEVEL_HERO; else maxlvl = UMIN(LEVEL_HERO, number_range((middle * 3) / 2, maxlvl)); for (warmaster = char_first; warmaster != NULL; warmaster = warmaster->next) if (warmaster->pIndexData && warmaster->pIndexData->vnum == MOB_VNUM_WARMASTER) break; war_info.iswar = WAR_WAITING; replace_string(war_info.who, (!warmaster ? "AutoWar (tm)" : warmaster->short_descr)); war_info.min_level = minlvl; war_info.max_level = maxlvl; if (clan >= 2) war_info.wartype = number_range(WAR_NONE, MAX_WAR - 1); else war_info.wartype = number_range(WAR_NONE, MAX_WAR - 2); if (war_info.wartype == WAR_NONE) war_info.wartype = WAR_GENOCIDE; announce(warmaster, INFO_WAR, "%s %s war for levels %d to %d%s. Type 'WAR JOIN' to kill or be killed.", !warmaster ? "A" : "$n announces a", wartype_name(war_info.wartype), war_info.min_level, war_info.max_level, !warmaster ? " has started" : ""); if (warmaster) chprintf(warmaster, "You announce a %s war for levels %d" " to %d. Type 'WAR JOIN' to kill or be killed.", wartype_name(war_info.wartype), war_info.min_level, war_info.max_level); war_info.timer = 3; war_info.next = 0; for (wch = player_first; wch != NULL; wch = wch->next_player) { if (IS_SET(wch->act, PLR_WAR)) REMOVE_BIT(wch->act, PLR_WAR); if (wch->pcdata->still_in_war) wch->pcdata->still_in_war = FALSE; } } void end_war(void) { CHAR_DATA *wch; replace_string(war_info.who, ""); war_info.wartype = WAR_NONE; war_info.min_level = 0; war_info.max_level = 0; war_info.iswar = WAR_OFF; war_info.inwar = 0; war_info.timer = 0; war_info.next = number_range(100, 200); for (wch = player_first; wch != NULL; wch = wch->next_player) { if (IS_SET_WAR(wch)) { stop_fighting(wch, TRUE); REMOVE_BIT(wch->act, PLR_WAR); wch->pcdata->still_in_war = FALSE; if (IS_SET(wch->in_room->room_flags, ROOM_ARENA) || wch->in_room->vnum == ROOM_VNUM_WAITROOM) { char_from_room(wch); char_to_room(wch, get_room_index(ROOM_VNUM_TEMPLE)); } wch->hit = wch->max_hit; wch->mana = wch->max_mana; wch->move = wch->max_move; update_pos(wch); do_function(wch, &do_look, "auto"); } } } const char *wartype_info(CHAR_DATA * ch) { switch (war_info.wartype) { default: return ""; case WAR_RACE: return race_table[ch->race].name; case WAR_CLASS: return class_table[ch->Class[0]].name; case WAR_GENOCIDE: return ""; case WAR_CLAN: return clan_table[ch->clan].who_name; } } CH_CMD(do_war) { char arg[MIL]; ROOM_INDEX_DATA *location; int i = 0; if (IS_NPC(ch)) { chprintln(ch, "Mobiles not supported yet."); return; } argument = one_argument(argument, arg); if (arg[0] == '\0') { chprintln(ch, "{gSyntax:{R war {Wstart <minlev> <maxlev> <#type>"); chprintln(ch, " {Rwar {Wtalk <message>"); chprintln(ch, " {Rwar {Wstatus"); chprintln(ch, " {Rwar {Winfo"); chprintln(ch, " {Rwar {Wjoin{x"); if (IS_IMMORTAL(ch)) chprintln(ch, " {Rwar {Wend{x"); return; } else if (!str_cmp(arg, "start")) { if (ch->pcdata->trivia < WAR_COST && !IS_IMMORTAL(ch)) { chprintf(ch, "It costs %d Trivia Points to start a war.\n\r", WAR_COST); return; } if (start_war(ch, argument) && !IS_IMMORTAL(ch)) ch->pcdata->trivia -= WAR_COST; return; } else if (!str_cmp(arg, "talk")) { war_talk(ch, argument); return; } else if (!str_cmp(arg, "next") && IS_IMMORTAL(ch)) { if (war_info.iswar == WAR_RUNNING) { chprintln(ch, "Not while a war is running."); return; } i = is_number(argument) ? atoi(argument) : number_range(30, 100); war_info.next = i; chprintf(ch, "The next war will start in %d minutes.\n\r", war_info.next); return; } if (war_info.iswar != WAR_RUNNING && war_info.iswar != WAR_WAITING) { chprintf(ch, "There is no war going! The next war will start in %d minutes.", war_info.next); return; } if (!str_cmp(arg, "end") && IS_IMMORTAL(ch)) { end_war(); announce(ch, INFO_WAR, "$n has ended the war. The next autowar will start in %d minutes.", war_info.next); announce(ch, INFO_WAR | INFO_PRIVATE, "You have ended the war. The next autowar will start in %d minutes.", war_info.next); return; } else if (!str_cmp(arg, "info")) { stringf(0, ALIGN_CENTER, "-", "[ {WWAR INFO{g ]"); chprintlnf(ch, "{g%s{x", stringf(0, ALIGN_CENTER, "-", "[ {WWAR INFO{g ]")); chprintlnf(ch, "{RStarted by : {W%s", IS_NULLSTR(war_info.who) ? "Unknown" : war_info.who); chprintlnf(ch, "{RFighting : {W%d player%s.", war_info.inwar, war_info.inwar == 1 ? "" : "s"); chprintlnf(ch, "{RLevels : {W%d - %d{x", war_info.min_level, war_info.max_level); chprintlnf(ch, "{RStatus : {W%s for %d minutes.{x", war_info.iswar == WAR_WAITING ? "Waiting" : "Running", war_info.timer); chprintlnf(ch, "{RType : {W%s war.{x", wartype_name(war_info.wartype)); chprintlnf(ch, "{g%s{x", draw_line(NULL, 0)); return; } else if (!str_cmp(arg, "status")) { CHAR_DATA *wch; bool found = FALSE; chprintlnf(ch, "{g%s{x", stringf(0, ALIGN_CENTER, "-", "[ {WWAR COMBATENTS{g ]")); for (wch = player_first; wch != NULL; wch = wch->next_player) { if (IS_SET(wch->act, PLR_WAR)) { chprintf(ch, "{W%-12s : [{R%ld%% hit{W] [{M%ld%% mana{W] [Pos: {G%s{W]{x", wch == ch ? "You" : wch->name, wch->hit * 100 / wch->max_hit, wch->mana * 100 / wch->max_mana, position_flags[wch->position].name); found = TRUE; } } if (!found) chprintln(ch, "No one in the war yet."); chprintf(ch, "{g%s{x\n\r", draw_line(NULL, 0)); return; } else if (!str_cmp(arg, "join")) { if (ch->fighting != NULL) { chprintln(ch, "You're a little busy right now."); return; } if (war_info.iswar == WAR_RUNNING) { chprintln(ch, "The war has already started, your too late."); return; } if (ch->level < war_info.min_level || ch->level > war_info.max_level) { chprintln(ch, "Sorry, you can't join this war."); return; } if (IS_SET_WAR(ch)) { chprintln(ch, "You are already in the war."); return; } if (IS_QUESTOR(ch) || ON_GQUEST(ch)) { chprintln(ch, "What? And leave your quest?"); return; } if (IS_SET(ch->in_room->room_flags, ROOM_NO_RECALL)) { chprintln(ch, "Something prevents you from leaving."); return; } if (war_info.wartype == WAR_CLAN && !is_clan(ch)) { chprintln(ch, "You aren't in a clan, you can't join this war."); return; } if ((location = get_room_index(ROOM_VNUM_WAITROOM)) == NULL) { chprintln(ch, "Arena is not yet completed, sorry."); return; } else { act("$n goes to get $s ass whipped in war!", ch, NULL, NULL, TO_ROOM); char_from_room(ch); char_to_room(ch, location); ch->pcdata->still_in_war = TRUE; SET_BIT(ch->act, PLR_WAR); if (war_info.wartype == WAR_GENOCIDE) announce(NULL, INFO_WAR, "%s (Level %d) joins the war!", ch->name, ch->level); else announce(NULL, INFO_WAR, "%s (Level %d, %s) joins the war!", ch->name, ch->level, wartype_info(ch)); act("$n arrives to get $s ass whipped!", ch, NULL, NULL, TO_ROOM); war_info.inwar++; do_function(ch, &do_look, "auto"); } return; } do_war(ch, ""); return; } bool abort_race_war(void) { CHAR_DATA *ch; CHAR_DATA *vict; for (ch = player_first; ch != NULL; ch = ch->next_player) { if (IS_SET(ch->act, PLR_WAR)) { for (vict = player_first; vict != NULL; vict = vict->next_player) { if (IS_SET(vict->act, PLR_WAR)) { if (ch->race == vict->race) continue; else return FALSE; } } } } return TRUE; } bool abort_class_war(void) { CHAR_DATA *ch; CHAR_DATA *vict; for (ch = player_first; ch != NULL; ch = ch->next_player) { if (IS_SET(ch->act, PLR_WAR)) { for (vict = player_first; vict != NULL; vict = vict->next_player) { if (IS_SET(vict->act, PLR_WAR)) { if (prime_class(ch) == prime_class(vict)) continue; else return FALSE; } } } } return TRUE; } bool abort_clan_war(void) { CHAR_DATA *ch; CHAR_DATA *vict; for (ch = player_first; ch != NULL; ch = ch->next_player) { if (IS_SET(ch->act, PLR_WAR) && is_clan(ch)) { for (vict = player_first; vict != NULL; vict = vict->next_player) { if (IS_SET(vict->act, PLR_WAR) && is_clan(vict)) { if (is_same_clan(ch, vict)) continue; else return FALSE; } } } } return TRUE; } void note_war(CHAR_DATA * ch) { BUFFER *output; char sender[MIL], subject[MIL], buf[MSL]; CHAR_DATA *wch; if (war_info.iswar != WAR_RUNNING) return; output = new_buf(); add_buf(output, "{WWAR INFO{g\n\r--------{x"); sprintf(buf, "{RStarted by : {W%s", IS_NULLSTR(war_info.who) ? "AutoWar (Tm)" : war_info.who); add_buf(output, buf); sprintf(buf, "{RLevels : {W%d - %d{x", war_info.min_level, war_info.max_level); add_buf(output, buf); sprintf(buf, "{RType : {W%s war.{x", wartype_name(war_info.wartype)); add_buf(output, buf); add_buf(output, "{WWAR COMBATENTS{g\n\r--------------{x"); for (wch = player_first; wch != NULL; wch = wch->next_player) { if (!IS_SET_WAR(wch)) continue; if (war_info.wartype != 3) sprintf(buf, "{W%12s : (%s){x", wch->name, wartype_info(wch)); else sprintf(buf, "{W%s{x", wch->name); add_buf(output, buf); } add_buf(output, "{g--------------{x"); switch (war_info.wartype) { case WAR_RACE: sprintf(buf, "{WThe {R%s's{W won this war.{x", race_table[ch->race].name); add_buf(output, buf); break; case WAR_CLASS: sprintf(buf, "{WThe {R%s's{W won this war.{x", class_table[ch->Class[0]].name); add_buf(output, buf); break; case WAR_GENOCIDE: sprintf(buf, "{R%s{W won the Genocide war.{x", ch->name); add_buf(output, buf); break; case WAR_CLAN: sprintf(buf, "{R%s{W won this war.{x", clan_table[ch->clan].who_name); add_buf(output, buf); break; } sprintf(subject, "War Info %s", ctime(¤t_time)); sprintf(sender, "%s", IS_NULLSTR(war_info.who) ? "AutoWar (Tm)" : war_info.who); make_note("General", sender, "All", subject, 15, buf_string(output)); free_buf(output); return; } void war_update(void) { if (war_info.iswar == WAR_OFF && war_info.next > 0) { if (--war_info.next <= 0) auto_war(); } else if (war_info.iswar == WAR_WAITING) { vnum_t randm = 0; war_info.timer--; if (war_info.timer > 0) { announce(NULL, INFO_WAR, "%d minute%s left to join the war. (Levels %d - %d, %s War)", war_info.timer, war_info.timer == 1 ? "" : "s", war_info.min_level, war_info.max_level, wartype_name(war_info.wartype)); } else { if (war_info.inwar < 2) { end_war(); announce(NULL, INFO_WAR, "Not enough people for war."); } else if (war_info.wartype == WAR_RACE && abort_race_war()) { end_war(); announce(NULL, INFO_WAR, "Not enough races for war."); } else if (war_info.wartype == WAR_CLASS && abort_class_war()) { end_war(); announce(NULL, INFO_WAR, "Not enough classes for war."); } else if (war_info.wartype == WAR_CLAN && abort_clan_war()) { end_war(); announce(NULL, INFO_WAR, "Not enough clans for war"); } else { CHAR_DATA *wch; announce(NULL, INFO_WAR, "The battle begins! %d players are fighting!", war_info.inwar); war_info.timer = number_range(3 * war_info.inwar, 5 * war_info.inwar); war_info.iswar = WAR_RUNNING; for (wch = player_first; wch != NULL; wch = wch->next_player) { if (IS_SET(wch->act, PLR_WAR)) { randm = number_range(17601, 17636); char_from_room(wch); char_to_room(wch, get_room_index(randm)); do_function(wch, &do_look, "auto"); } } } } } else if (war_info.iswar == WAR_RUNNING) { if (war_info.inwar == 0) { end_war(); announce(NULL, INFO_WAR, "No one left in the war"); return; } switch (war_info.timer) { case 0: end_war(); announce(NULL, INFO_WAR, "Time has run out!"); return; case 1: case 2: case 3: case 4: case 5: case 10: case 15: announce(NULL, INFO_WAR, "%d minute%s remaining in the war.", war_info.timer, war_info.timer > 1 ? "s" : ""); default: war_info.timer--; break; } return; } } void check_war(CHAR_DATA * ch, CHAR_DATA * victim) { CHAR_DATA *wch; int reward; int qreward; if (IS_NPC(ch) || IS_NPC(victim)) return; reward = number_range(500, 1500); qreward = number_range(50, 150); REMOVE_BIT(victim->act, PLR_WAR); victim->pcdata->still_in_war = TRUE; war_info.inwar--; stop_fighting(victim, TRUE); stop_fighting(ch, TRUE); char_from_room(victim); char_to_room(victim, get_room_index(ROOM_VNUM_WAITROOM)); if (victim->hit < 1) victim->hit = 1; if (victim->mana < 1) victim->mana = 1; if (victim->move < 1) victim->move = 1; update_pos(victim); do_function(victim, &do_look, "auto"); chprintln(victim, "Please wait here untill the war ends and you'll be transfered and healed."); chprintln(ch, ""); chprintln(victim, ""); announce(NULL, INFO_WAR, "%s was killed in combat by %s!{x", victim->name, ch->name); switch (war_info.wartype) { case WAR_RACE: if (abort_race_war()) { announce(NULL, INFO_WAR, "The %s's have won the War!", race_table[ch->race].name); note_war(ch); for (wch = player_first; wch != NULL; wch = wch->next_player) { if (!IS_SET_WAR(wch)) continue; if (wch->race == ch->race) { wch->gold += reward; wch->pcdata->questpoints += qreward; chprintf(wch, "You recieve %d gold and %d questpoints from the war tribunal!", reward, qreward); } } end_war(); return; } // end abort break; case WAR_CLASS: if (abort_class_war()) { announce(NULL, INFO_WAR, "The %s's have won the War!{x", class_table[ch->Class[0]].name); note_war(ch); for (wch = player_first; wch != NULL; wch = wch->next_player) { if (!IS_SET_WAR(wch)) continue; if (wch->Class[0] == ch->Class[0]) { wch->gold += reward; wch->pcdata->questpoints += qreward; chprintf(wch, "You recieve %d gold and %d questpoints from the war tribunal!", reward, qreward); } } end_war(); return; } break; case WAR_CLAN: if (abort_clan_war()) { announce(NULL, INFO_WAR, "%s has won the War!{x", clan_table[ch->clan].who_name); note_war(ch); for (wch = player_first; wch != NULL; wch = wch->next_player) { if (!IS_SET_WAR(wch)) continue; if (is_same_clan(ch, wch)) { wch->gold += reward; wch->pcdata->questpoints += qreward; chprintf(wch, "You recieve %d gold and %d questpoints from the war tribunal!", reward, qreward); } } end_war(); return; } break; case WAR_GENOCIDE: if (war_info.inwar == 1) { announce(ch, INFO_WAR, "$n has won the War!"); chprintln(ch, "You have won the War!"); note_war(ch); ch->gold += reward; ch->pcdata->questpoints += qreward; chprintf(ch, "You recieve %d gold and %d questpoints from the war tribunal!", reward, qreward); end_war(); return; } break; } return; } bool is_safe_war(CHAR_DATA * ch, CHAR_DATA * wch) { if (war_info.iswar == WAR_OFF) return FALSE; if (!IS_IN_WAR(ch) || !IS_IN_WAR(wch)) return FALSE; if (war_info.wartype == WAR_GENOCIDE) return FALSE; if (war_info.wartype == WAR_RACE && ch->race == wch->race) return TRUE; if (war_info.wartype == WAR_CLASS && ch->Class[0] == wch->Class[0]) return TRUE; if (war_info.wartype == WAR_CLAN && is_same_clan(ch, wch)) return TRUE; return FALSE; } void war_talk(CHAR_DATA * ch, const char *argument) { DESCRIPTOR_DATA *d; if (argument[0] == '\0') { chprintln(ch, "Wartalk about what?\n\rUse 'info war' to toggle this channel."); return; } chprintf(ch, "{Y({RWarTalk{Y) {gYou drum: %s{x\n\r", argument); for (d = descriptor_first; d != NULL; d = d->next) { CHAR_DATA *victim; if (d->connected == CON_PLAYING && (victim = CH(d)) != ch && !IS_SET(victim->info_settings, INFO_WAR) && !IS_SET(victim->comm, COMM_QUIET)) { chprintf(victim, "{Y({RWarTalk{Y) {g%s drums: %s{x", PERS(ch, victim), argument); } } return; } void extract_war(CHAR_DATA * ch) { if (war_info.iswar != WAR_OFF && IS_SET(ch->act, PLR_WAR)) { REMOVE_BIT(ch->act, PLR_WAR); war_info.inwar--; if (war_info.iswar == WAR_RUNNING) { if (war_info.inwar == 0 || war_info.inwar == 1) { announce(ch, INFO_WAR, "$n has left. War over."); end_war(); } if (abort_race_war()) { announce(ch, INFO_WAR, "$n has left. War over."); end_war(); } else if (abort_class_war()) { announce(ch, INFO_WAR, "$n has left. War over."); end_war(); } else if (abort_clan_war()) { announce(ch, INFO_WAR, "$n has left. War over."); end_war(); } else { announce(ch, INFO_WAR, "$n has left. %d players in the war.", war_info.inwar); } } char_from_room(ch); char_to_room(ch, get_room_index(ROOM_VNUM_TEMPLE)); } }