/************************************************************************** * 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->people; 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_list; 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_list; 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_list; 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_list; 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_list; 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_list; 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")) { char buf[MSL]; stringf (buf, 0, ALIGN_CENTER, "-", "[ {WWAR INFO{g ]"); chprintf (ch, "{g%s{x\n\r", buf); chprintf (ch, "{RStarted by : {W%s\n\r", IS_NULLSTR (war_info.who) ? "Unknown" : war_info.who); chprintf (ch, "{RFighting : {W%d player%s.\n\r", war_info.inwar, war_info.inwar == 1 ? "" : "s"); chprintf (ch, "{RLevels : {W%d - %d{x\n\r", war_info.min_level, war_info.max_level); chprintf (ch, "{RStatus : {W%s for %d minutes.{x\n\r", war_info.iswar == WAR_WAITING ? "Waiting" : "Running", war_info.timer); chprintf (ch, "{RType : {W%s war.{x\n\r", wartype_name (war_info.wartype)); chprintf (ch, "{g%s{x\n\r", draw_line (NULL, 0)); return; } else if (!str_cmp (arg, "status")) { CHAR_DATA *wch; char buf[MSL]; bool found = FALSE; stringf (buf, 0, ALIGN_CENTER, "-", "[ {WWAR COMBATENTS{g ]"); chprintf (ch, "{g%s{x\n\r", buf); for (wch = player_list; 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_list; ch != NULL; ch = ch->next_player) { if (IS_SET (ch->act, PLR_WAR)) { for (vict = player_list; 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_list; ch != NULL; ch = ch->next_player) { if (IS_SET (ch->act, PLR_WAR)) { for (vict = player_list; 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_list; ch != NULL; ch = ch->next_player) { if (IS_SET (ch->act, PLR_WAR) && is_clan (ch)) { for (vict = player_list; 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_list; 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_list; 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_list; 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_list; 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_list; 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_list; 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)); } }