/************************************************************************ Realms of Aurealis James Rhone aka Vall of RoA warrior.c Skills and commands which are 'usually' unique to the warrior class. ******** 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 "affect.h" #include "lists.h" /* extern variables */ extern int rev_dir[]; extern struct str_app_type str_app[]; extern int check_room_affects(chdata *ch, int room); extern char *dirs[]; extern char *comm_dirs[]; // allow a warrior to open door without key :) // also opens jammed doors... 4/26/98 -jtrhone ACMD(do_doorbash) { char *argu = argument; int dir, other_room; rmdirdata *d, *back; if (IS_NPC(ch)) return; if (!GET_SKILL(ch, SKILL_DOORBASH)) { act("You do not posess that ability.", FALSE, ch, 0,0,TO_CHAR); return; } skip_spaces(&argu); if (!*argu) { act("Doorbash what?", FALSE, ch, 0, 0, TO_CHAR); return; } dir = search_block(argu, comm_dirs, FALSE); if (dir < 0 || dir > NUM_OF_DIRS) { send_to_char("Usage: doorbash <[direction]>.\n\r",ch); return; } if (!(d = EXIT(ch, dir))) { act("It would be fairly difficult to do that there.",FALSE,ch,0,0,TO_CHAR); return; } if (!EXIT_ISDOOR(d)) act("It would be fairly difficult to do that there.",FALSE,ch,0,0,TO_CHAR); else if (EXIT_OPEN(d)) send_to_char("It's open!\n\r", ch); else if (!EXIT_LOCKED(d) && !EXIT_JAMMED(d)) send_to_char("It's not locked or jammed!\n\r", ch); else if (EXIT_FLAGGED(d, EX_NOBASH) || EXIT_FLAGGED(d, EX_PICKPROOF)) { send_to_char("OUCH! You only hurt your shoulder.\n\r", ch); GET_HIT(ch) -= number(1, 10); GET_HIT(ch) = MAX(GET_HIT(ch), 1); } else { // skill check :) if (GET_SKILL(ch, SKILL_DOORBASH) < number(1, 101)) { act("OUCH! You only hurt your shoulder.", FALSE, ch, 0,0,TO_CHAR); GET_HIT(ch) -= number(1, 10); GET_HIT(ch) = MAX(GET_HIT(ch), 1); return; } UNFLAG_EXIT(d, EX_LOCKED | EX_JAMMED); if (d->keyword) { act("You bash the $F open!", FALSE, ch, 0, d->keyword, TO_CHAR); act("$n bashes the $F open!", TRUE, ch, 0, d->keyword, TO_ROOM); } else { act("You bash it open!", FALSE, ch, 0, 0, TO_CHAR); act("$n bashes something open!", TRUE, ch, 0, 0, TO_ROOM); } /* now for jamming the other side, too */ if ((other_room = d->to_room) != NOWHERE) if ((back = DIR(other_room, rev_dir[dir]))) if (back->to_room == ch->in_room) UNFLAG_EXIT(back, EX_LOCKED | EX_JAMMED); } } ACMD(do_bash) { chdata *victim; if (IS_PC(ch) && (GET_LEVEL(ch) == LEV_IMM || GET_LEVEL(ch) == LEV_GOD)) { 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 (!IS_WARRIOR(ch)) { send_to_char("You'd better leave all the martial arts to fighters.\n\r", ch); return; } if (!(victim = get_char_room_vis(ch, arg)) && !(victim = FIGHTING(ch))) { send_to_char("Bash who?\n\r", ch); return; } if (victim == ch) { send_to_char("You bash yourself on the head...\n\r", ch); return; } if (!check_mortal_combat(ch, victim)) return; if (!EQ(ch, W_HOLD) || !IS_ARMOR(EQ(ch, W_HOLD))) { send_to_char("You need to hold a shield to make it a success.\n\r", ch); return; } if (!check_truce(ch, victim)) return; if (GET_SKILL(ch, SKILL_BASH) < number(1, 101)) { // they failed damage(ch, victim, 0, SKILL_BASH, TRUE); if (GET_POS(ch) > POS_SITTING) GET_POS(ch) = POS_SITTING; } else // they succeeded { if (damage(ch, victim, 1, SKILL_BASH, TRUE) == CHAR_OK) { VWAIT(victim) = 1; WAIT_STATE(victim, PULSE_VIOLENCE * 2); if (GET_POS(victim) > POS_SITTING) GET_POS(victim) = POS_SITTING; } damage_object(EQ(ch, W_HOLD), ch); } WAIT_STATE(ch, PULSE_VIOLENCE * 2); } ACMD(do_rescue) { chdata *victim, *tmp_ch; if (IN_NOWHERE(ch)) return; if (!GET_SKILL(ch, SKILL_RESCUE)) { send_to_char("You know not how to rescue!\n\r",ch); return; } one_argument(argument, arg); if (!(victim = get_char_room_vis(ch, arg))) { send_to_char("Who do you want to rescue?\n\r", ch); return; } if (victim == ch) { send_to_char("What about fleeing instead?\n\r", ch); return; } if (FIGHTING(ch) == victim) { send_to_char("How can you rescue someone you are trying to kill?\n\r", ch); return; } for (tmp_ch = world[ch->in_room].people; tmp_ch && (FIGHTING(tmp_ch) != victim); tmp_ch = tmp_ch->next_in_room) ; if (!tmp_ch) { act("But nobody is fighting $M!", FALSE, ch, 0, victim, TO_CHAR); return; } if (GET_SKILL(ch, SKILL_RESCUE) < number(1, 101)) { send_to_char("You fail the rescue!\n\r", ch); return; } send_to_char("Banzai! To the rescue...\n\r", ch); act("You are rescued by $N, you are confused!", FALSE, victim, 0, ch, TO_CHAR); act("$n heroically rescues $N!", FALSE, ch, 0, victim, TO_NOTVICT); if (FIGHTING(victim) == tmp_ch) stop_fighting(victim); if (FIGHTING(tmp_ch)) stop_fighting(tmp_ch); if (FIGHTING(ch)) stop_fighting(ch); set_fighting(ch, tmp_ch); set_fighting(tmp_ch, ch); WAIT_STATE(victim, 2 * PULSE_VIOLENCE); } ACMD(do_kick) { chdata *victim; byte percent, prob; if (IS_PC(ch) && (GET_LEVEL(ch) == LEV_IMM || GET_LEVEL(ch) == LEV_GOD)) { 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; } if (!IS_WARRIOR(ch) && !IS_WARLOCK(ch) && !IS_MONK(ch) && !IS_RANGER(ch)) { send_to_char("You'd better leave all the martial arts to fighters.\n\r", ch); return; } one_argument(argument, arg); if (!(victim = get_char_room_vis(ch, arg))) { if (ch->specials.fighting) { victim = ch->specials.fighting; } else { send_to_char("Kick who?\n\r", ch); return; } } if (victim == ch) { send_to_char("Aren't we funny today...\n\r", ch); return; } if (!check_mortal_combat(ch, victim)) return; if (!check_truce(ch, victim)) return; percent = ((10 - (GET_AC(victim) / 10)) << 1) + number(1, 101); prob = GET_SKILL(ch, SKILL_KICK); if (percent > prob) damage(ch, victim, 0, SKILL_KICK, TRUE); else { damage(ch, victim, GET_LEVEL(ch) >> 1, SKILL_KICK, FALSE); if (!EQ(ch, W_FEET) && GET_HIT(ch) > 1) { send_to_char("You're kicking with bare feet!\n\r",ch); GET_HIT(ch)--; } else damage_object(EQ(ch, W_FEET), ch); } WAIT_STATE(ch, PULSE_VIOLENCE * 3); } int find_exit(chdata *ch) { int deflt = -1, attempt; int i; for(attempt = 0; attempt < NUM_OF_DIRS; attempt++) if(CAN_GO(ch, attempt)) { deflt = attempt; break; } if (deflt == -1) return -1; else for(i = 0; i < 6; i++) { attempt = number(0, NUM_OF_DIRS - 1); if (CAN_GO(ch, attempt)) return attempt; } return deflt; } ACMD(do_hurl) { chdata *vict, *k; int prob = GET_SKILL(ch, SKILL_HURL); int chweight, victweight; int door; BOOL bodyslam = FALSE; int was_in; if (IN_NOWHERE(ch)) return; if(!prob) { send_to_char("But you don't yet know how to hurl your opponents.\r\n", ch); return; } if(!(vict = FIGHTING(ch))) { send_to_char("You need to be fighting in order to hurl!\r\n", ch); return; } chweight = (int) GET_WEIGHT(ch); victweight = (int) GET_WEIGHT(vict); if( (prob < number(1, 101)) || (2 * chweight < victweight) ) { damage(ch, vict, 0, SKILL_HURL, TRUE); WAIT_STATE(ch, 2 * PULSE_VIOLENCE); return; } was_in = vict->in_room; door = find_exit(ch); if ((door == -1) || (was_in == (world[ch->in_room].dir_option[door])->to_room)) bodyslam = TRUE; /* In 1/2 of the cases, throw the vict out of the room, in 1/2 of the cases, bodyslam them to the ground */ if(number(0,1) || bodyslam) { GET_POS(vict) = POS_SITTING; WAIT_STATE(vict, PULSE_VIOLENCE); WAIT_STATE(ch, 3 * PULSE_VIOLENCE); damage(ch, vict, (GET_LEVEL(ch) + GET_DAMROLL(ch))/3, SKILL_HURL, FALSE); return; } /* Now, do the actual throw thing */ else { if (damage(ch, vict, (GET_LEVEL(ch) + GET_DAMROLL(ch))/3, 250, FALSE) == CHAR_DIED) { WAIT_STATE(ch, 3 * PULSE_VIOLENCE); return; } for(k = world[vict->in_room].people;k;k=k->next_in_room) if(vict == FIGHTING(k)) stop_fighting(k); if (FIGHTING(vict)) stop_fighting(vict); char_from_room(vict); char_to_room(vict, DIR(was_in, door)->to_room); act("$n arrives hurling into the room!", FALSE, vict, 0, 0, TO_ROOM); GET_POS(vict) = POS_SITTING; WAIT_STATE(vict, 2 * PULSE_VIOLENCE); WAIT_STATE(ch, 2 * PULSE_VIOLENCE); do_look_at_room(vict, 0, 0); // remove all songs from character being thrown if (SINGING(vict)) do_finish(vict, "song", 0, 0); if (PLAYING(vict)) do_finish(vict, "tune", 0, 0); if (check_room_affects(vict, vict->in_room) == CHAR_DIED) return; if (check_death_trap(vict, NULL)) return; } } /* Disarm - warrior/thief skill - 6/3/95 */ ACMD(do_disarm) { int prob = GET_SKILL(ch, SKILL_DISARM); int lvldiff; chdata *vict; obdata *ob; if(!prob) { send_to_char("But you don't yet know how to disarm your opponents!\r\n", ch); return; } if(!FIGHTING(ch)) { send_to_char("You need to be fighting in order to disarm!\r\n", ch); return; } vict = FIGHTING(ch); /* check if victim is wielding anything */ if (!EQ(vict, W_WIELD)) { send_to_char("Your opponent is already bare-handed.\r\n", ch); return; } lvldiff = GET_LEVEL(vict) - GET_LEVEL(ch); lvldiff = (lvldiff > 0 ? lvldiff : 0); if(prob > number(1, 250) + lvldiff) { /* Send the messages */ ob = unequip_char(vict, W_WIELD, TRUE); act("You skillfully force $p out of $N's hands.", TRUE, ch, ob, vict, TO_CHAR); act("$N disarms you!", TRUE, vict, NULL, ch, TO_CHAR); act("With a quick draw, $n forces $N to lose control of $S weapon!", TRUE, ch, ob, vict, TO_NOTVICT); obj_to_char(ob, vict); } else { /* Failed disarm */ ob = EQ(vict, W_WIELD); act("You fail to disarm $N.", TRUE, ch, NULL, vict, TO_CHAR); act("$N tries to disarm you, but fails.", TRUE, vict, NULL, ch, TO_CHAR); act("$n's puny attempt to knock $p out of $N's hands fails.", TRUE, ch, ob, vict, TO_NOTVICT); } /* Wait state and return */ WAIT_STATE(ch, 3 * PULSE_VIOLENCE); } ACMD(do_shieldblock) { chdata *vict = 0; if (!(vict = FIGHTING(ch))) return; /* not fighting anybody */ act("You %5block%0 $N's attack with your shield!", TRUE, ch, NULL, vict, TO_CHAR); act("$n %5blocks%0 your attack!.", TRUE, ch, NULL, vict, TO_VICT); act("$n %5blocks%0 $N's attack!.", TRUE, ch, NULL, vict, TO_NOTVICT); } ACMD(do_grapple) { int percent, prob, cycles; if (!IS_WARRIOR(ch)) { send_to_char("You know not how to hold your opponent.\n\r",ch); return; } if (!FIGHTING(ch)) { send_to_char("You must be fighting in order to grapple.\n\r",ch); return; } percent = number (1,101); prob = GET_SKILL(ch, SKILL_GRAPPLE); prob += (GET_DEX(ch) - GET_DEX(FIGHTING(ch))) * 5; prob += (GET_LEVEL(ch) - GET_LEVEL(FIGHTING(ch))) * 5; prob = MIN(prob, 100); if (percent <= prob && !MOB_FLAGGED(FIGHTING(ch), MOB_NO_HOLD)) { if (GET_LEVEL(ch) <= 20) cycles = 1; else cycles = 2; if (affected_by_spell(FIGHTING(ch), SPELL_MIRRORIMAGE)) { act("You hold $N's image!", TRUE, ch, 0, FIGHTING(ch), TO_CHAR); act("$n holds $N's image!", TRUE, ch, 0, FIGHTING(ch), TO_ROOM); VWAIT(ch) = cycles - 1; WAIT_STATE(ch, PULSE_VIOLENCE * 5); return; } act("You hold $N, rendering $M motionless.", TRUE, ch, 0, FIGHTING(ch), TO_CHAR); act("$n holds $N, rendering $M motionless.", TRUE, ch, 0, FIGHTING(ch), TO_ROOM); VWAIT(ch) = cycles - 1; WAIT_STATE(ch, PULSE_VIOLENCE * 5); VWAIT(FIGHTING(ch)) = cycles; WAIT_STATE(FIGHTING(ch), PULSE_VIOLENCE * 5); } else { act("You fail to hold $N.", TRUE, ch, 0, FIGHTING(ch), TO_CHAR); act("$n fails to hold $N.", TRUE, ch, 0, FIGHTING(ch), TO_ROOM); WAIT_STATE(ch, PULSE_VIOLENCE * 2); } } // add a certain amount to hit regeneration, warriors ACMD(do_fortify) { struct affected_type af; if (IN_NOWHERE(ch)) return; if (IS_NPC(ch)) return; if (!GET_SKILL(ch, SKILL_FORTIFY)) { send_to_char("You know not of that skill.\n\r",ch); return; } if (GET_MOVE(ch) < 30) { send_to_char("You feel too weak to fortify yourself.\n\r",ch); return; } if (affected_by_spell(ch, SKILL_FORTIFY)) { send_to_char("You are already fortified.\n\r",ch); return; } GET_MOVE(ch) -= 30; if (GET_SKILL(ch, SKILL_FORTIFY) < number(1, 101)) { send_to_char("You fail to fortify yourself.\n\r",ch); return; } af.type = SKILL_FORTIFY; af.duration = GET_LEVEL(ch) / 4; af.modifier = GET_LEVEL(ch) / 3; af.location = APPLY_HIT_REGEN; af.bitvector = 0; af.bitvector2 = 0; affect_to_char(ch, &af); act("$n fortifies $mself.", TRUE, ch, 0, 0, TO_ROOM); act("You feel fortified!", TRUE, ch, 0, 0, TO_CHAR); } // cripple an opponent, reduce # of attacks and dex on opponent ACMD(do_cripple) { struct affected_type af; chdata *vict; if (IN_NOWHERE(ch)) return; if (IS_NPC(ch)) return; if (!GET_SKILL(ch, SKILL_CRIPPLE)) { send_to_char("You know not of that skill.\n\r",ch); return; } if (!(vict = FIGHTING(ch))) { send_to_char("You must be fighting to use this skill.\n\r",ch); return; } if (GET_MOVE(ch) < 30) { send_to_char("You feel too weak to cripple your opponent.\n\r",ch); return; } if (affected_by_spell(vict, SKILL_CRIPPLE)) { send_to_char("Your opponent is already crippled.\n\r",ch); return; } GET_MOVE(ch) -= 30; if (GET_SKILL(ch, SKILL_CRIPPLE) < number(1, 101) || GET_DEX(vict) > number(1, 18)) { send_to_char("You fail to cripple your opponent.\n\r",ch); WAIT_STATE(ch, 2 * PULSE_VIOLENCE); return; } af.type = SKILL_CRIPPLE; af.duration = 1; af.modifier = -3; af.location = APPLY_DEX; af.bitvector = 0; af.bitvector2 = 0; affect_to_char(vict, &af); WAIT_STATE(ch, 3 * PULSE_VIOLENCE); act("You cripple $N!", TRUE, ch, 0, vict, TO_CHAR); act("%BAHHHHH!!%0 $n hits you with a crippling force!", FALSE, ch, 0, vict, TO_VICT); act("$n flings $mself towards $N and cripples $M!", TRUE, ch, 0, vict, TO_NOTVICT); }