/************************************************************************ Realms of Aurealis James Rhone aka Vall of RoA offensive.c Routines of an offensive nature. Some assorted skills, but mostly generic offensive commands used to initiate battle. ******** Heavily modified and expanded ******** *** BE AWARE OF ALL RIGHTS AND RESERVATIONS *** ******** Heavily modified and expanded ******** All rights reserved henceforth. Please note that no guarantees are associated with any code from Realms of Aurealis. All code which has been released to the general public has been done so with an 'as is' pretense. RoA is based on both Diku and CircleMUD and ALL licenses from both *MUST* be adhered to as well as the RoA license. *** Read, Learn, Understand, Improve *** *************************************************************************/ #include "conf.h" #include "sysdep.h" #include "structures.h" #include "utils.h" #include "comm.h" #include "interpreter.h" #include "acmd.h" #include "handler.h" #include "db.h" #include "magic.h" #include "mudlimits.h" #include "fight.h" #include "lists.h" #include "global.h" /* extern functions */ int do_simple_move(chdata *ch, int cmd, int following); ACMD(do_assist) { chdata *helpee, *opp; if (IN_NOWHERE(ch)) return; if (FIGHTING(ch)) { send_to_char("You're already fighting!\n\r", ch); return; } one_argument(argument, arg); if (!*arg) { send_to_char("Assist whom?\n\r",ch); return; } if (!(helpee = get_char_room_vis(ch, arg))) { send_to_char("Assist whom?\n\r", ch); return; } if (helpee == ch) { send_to_char("You can't help yourself any more than this!\n\r", ch); return; } for(opp = world[ch->in_room].people; opp && (FIGHTING(opp) != helpee); opp = opp->next_in_room) ; if (!opp) { act("But nobody is fighting $M!", FALSE, ch, 0, helpee, TO_CHAR); return; } if (!can_see(ch, opp)) { act("You can't see who's fighting $M!", FALSE, ch, 0, helpee, TO_CHAR); return; } if (!check_truce(ch, opp)) return; if (!check_mortal_combat(ch, opp)) return; send_to_char("%BYou join the fight%0!\n\r", ch); act("$N assists you!", TRUE, helpee, 0, ch, TO_CHAR); act("$n assists $N.", TRUE, ch, 0, helpee, TO_NOTVICT); // have to set fighting here... might return prematurely from hit() if (!(FIGHTING(ch))) set_fighting(ch, opp); hit(ch, opp, TYPE_UNDEFINED, TRUE); } ACMD(do_hit) { chdata *victim; extern void start_cityguard_hunt(chdata *ch); if (IN_NOWHERE(ch)) return; if (IS_IMMORTAL(ch) && GET_LEVEL(ch) < LEV_AIMP) { send_to_char("You, being an Immortal, are forbidden to kill.\n\r",ch); return; } if (GET_LEVEL(ch) < LEV_AIMP && ROOM_FLAGGED(ch->in_room, PEACEFUL)) { send_to_char("Your offensive actions lead to naught in this peaceful area.\n\r",ch); return; } one_argument(argument, arg); if (!*arg) { send_to_char("Hit who?\n\r",ch); return; } switch (GET_POS(ch)) { case POS_MOUNTED: send_to_char("You must dismount first!\n\r",ch); return; case POS_FLOATING: send_to_char("You cannot fight while in flight.\n\r",ch); return; case POS_FIGHTING: send_to_char("You %Bare%0 fighting!\n\r",ch); return; default: break; }; if (!(victim = get_char_room_vis(ch, arg))) { send_to_char("They aren't here.\n\r",ch); return; } if (victim == ch) { send_to_char("You hit yourself...OUCH!.\n\r", ch); act("$n hits $mself, doh!", FALSE, ch, 0, 0, TO_ROOM); return; } if (IS_PC(victim) && IS_PC(ch) && !IN_ARENA(ch) && !IN_ARENA(victim)) { if (subcmd == SCMD_MURDER) { if (IS_ASSASSIN(ch) && IS_ASSASSIN(victim)) act("You attempt to assassinate $N.", TRUE, ch, 0, victim, TO_CHAR); else { send_to_char("Only Assassins may fight other Assassins.\n\r\n\r",ch); send_to_char("To learn more, %Bhelp assassin%0.\n\r",ch); return; } } else { /* not murder command */ send_to_char("You must type %BMURDER%0 to kill another player.\n\r",ch); return; } } if (CHARMED(ch) && ch->master && IS_PC(ch->master) && IS_PC(victim)) return; /* you can't order a charmed pet to attack a player */ if (CHARMED(ch) && (ch->master == victim)) { act("You find yourself unable to hit $N.", FALSE, ch, 0, victim, TO_CHAR); return; } if ((GET_POS(ch) == POS_STANDING) && (victim != FIGHTING(ch)) && check_truce(ch, victim)) { if (SPC_FLAGGED(victim, SPC_CITYGUARD) && !number(0, 1)) start_cityguard_hunt(ch); hit(ch, victim, TYPE_UNDEFINED, TRUE); WAIT_STATE(ch, PULSE_VIOLENCE); } } ACMD(do_kill) { chdata *victim; if (IN_NOWHERE(ch)) return; if (IS_IMMORTAL(ch) && GET_LEVEL(ch) < LEV_AIMP) { send_to_char("You, being an Immortal, are forbidden to kill.\n\r",ch); return; } if (GET_LEVEL(ch) < LEV_AIMP && ROOM_FLAGGED(ch->in_room, PEACEFUL)) { send_to_char("Your offensive actions lead to naught in this peaceful area.\n\r",ch); return; } /* normal killin gets sent to do_hit from here */ if ((GET_LEVEL(ch) < LEV_IMPL) || IS_NPC(ch)) { do_hit(ch, argument, cmd, subcmd); return; } one_argument(argument, arg); if (!*arg) { send_to_char("Kill who?\n\r", ch); return; } if (!(victim = get_char_room_vis(ch, arg))) { send_to_char("They aren't here.\n\r", ch); return; } if (ch == victim) { send_to_char("There are clinics for that type of thing... :(\n\r", ch); return; } act("You chop $M to pieces! Ah! The blood!", FALSE, ch, 0, victim, TO_CHAR); act("$N chops you to pieces!", TRUE, victim, 0, ch, TO_CHAR); act("$n brutally slays $N!", TRUE, ch, 0, victim, TO_NOTVICT); raw_kill(victim); } ACMD(do_order) { char name[512], message[512]; BOOL found = FALSE; chdata *victim; struct follow_type *k; if (strlen(argument) > 1000) { send_to_char("Argument length too long. Your actions have been logged.\n\r",ch); sprintf(buf, "PLRUPD: Excessive argument length to do_order (%s).", GET_NAME(ch)); mudlog(buf, BRF, LEV_IMM, TRUE); return; } half_chop(argument, name, message); if (!*name || !*message) { send_to_char("Order who to do what?\n\r", ch); return; } if (!(victim = get_char_room_vis(ch, name)) && !is_abbrev(name, "followers")) { send_to_char("That person isn't here.\n\r", ch); return; } if (ch == victim) { send_to_char("You obviously suffer from skitzofrenia.\n\r", ch); return; } if (CHARMED(ch)) { send_to_char("Your superior would not approve of you giving orders.\n\r", ch); return; } if (victim) { sprintf(buf, "$N orders you to '%s'", message); act(buf, FALSE, victim, 0, ch, TO_CHAR); act("$n gives $N an order.", FALSE, ch, 0, victim, TO_ROOM); if (victim->master != ch || !CHARMED(victim)) act("$n has an indifferent look.", FALSE, victim, 0, 0, TO_ROOM); else { send_to_char("Ok.\n\r", ch); command_interpreter(victim, message); } } else // must have ordered followers { sprintf(buf, "$n issues the order '%s'.", message); act(buf, FALSE, ch, 0, 0, TO_ROOM); for (k = ch->followers; k; k = k->next) if (SAME_ROOM(ch, k->follower) && CHARMED(k->follower)) { found = TRUE; command_interpreter(k->follower, message); } if (found) send_to_char("Ok.\n\r", ch); else send_to_char("Nobody here is a loyal subject of yours!\n\r", ch); } } #define NUM_FLEE_CHANCES 6 ACMD(do_flee) { int i, attempt, lose, die; int gain_exp(chdata *ch, int gain); int special(chdata *ch, int cmd, char *arg); chdata *enemy = 0; if (IS_NPC(ch) && (GET_POS(ch) == POS_SITTING)) { send_to_char("Stand up bozo! \n\r", ch); do_stand(ch, "", 0, 0); GET_POS(ch) = POS_FIGHTING; return; } if (!(FIGHTING(ch))) { for (i = 1; i < NUM_FLEE_CHANCES; i++) { attempt = number(0, NUM_OF_DIRS-1); /* Select a random direction */ if (CAN_GO(ch, attempt) && !ROOM_FLAGGED(EXIT(ch, attempt)->to_room, DEATH) && !ROOM_FLAGGED(EXIT(ch, attempt)->to_room, FLY_DEATH)) { act("$n panics, and attempts to flee!", TRUE, ch, 0, 0, TO_ROOM); if ((die = do_simple_move(ch, attempt, FALSE)) == TRUE) // success! send_to_char("You flee head over heels.\n\r", ch); else { if (!die) act("$n tries to flee, but is too exhausted!", TRUE, ch, 0, 0, TO_ROOM); } return; } } send_to_char("%BPANIC!%0 You couldn't escape!\n\r", ch); return; } for (i = 0; i < NUM_FLEE_CHANCES - 1; i++) { attempt = number(0, NUM_OF_DIRS-1); /* Select a random direction */ if (CAN_GO(ch, attempt) && !ROOM_FLAGGED(EXIT(ch, attempt)->to_room, DEATH) && !ROOM_FLAGGED(EXIT(ch, attempt)->to_room, FLY_DEATH)) { act("$n panics, and attempts to flee!", TRUE, ch, 0, 0, TO_ROOM); /* if the move succeeds, i.e. not death and dir */ if ((die = do_simple_move(ch, attempt, FALSE)) == TRUE) { lose = GET_MAX_HIT(FIGHTING(ch)) - GET_HIT(FIGHTING(ch)); lose *= GET_LEVEL(FIGHTING(ch)); lose = MIN(lose, maxfleeexploss); /* max loss cause of fleeing 200k*/ // if thief, lose less per flee... if (IS_THIEF(ch)) lose /= 2; if (IS_PC(ch) && !IN_ARENA(ch)) gain_exp(ch, -lose); send_to_char("You flee head over heels.\n\r", ch); enemy = FIGHTING(ch); HUNTING(enemy) = ch; /* before we stop fighting, make sure combat was disengaged */ if (IS_PC(enemy) && GET_SKILL(enemy, SKILL_FENGAGE) > number(5, 110) && !CHAR_FLAGGED(enemy, CH_SUBDUED)) { /* move enemy with ch, do not disengage -roa */ do_simple_move(enemy, attempt, FALSE); act("You follow $N!",TRUE,enemy,0,ch,TO_CHAR); act("$n follows you!",TRUE,enemy,0,ch,TO_VICT); act("$n follows $N!",TRUE,enemy,0,ch,TO_ROOM); return; } /* ok, it was disengaged properly, stop the fight */ if (FIGHTING(enemy) == ch) stop_fighting(enemy); stop_fighting(ch); return; } else { if (!die) act("$n tries to flee, but cannot!", TRUE, ch, 0, 0, TO_ROOM); return; } } } send_to_char("%BPANIC!!!%0 You couldn't escape!\n\r", ch); }