#include <sys/types.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "mud.h" void remove_from_fighting_list (CHAR_DATA *); void show_hitdam(int, char*, int, CHAR_DATA*, CHAR_DATA*); bool victim_is_dead = FALSE; bool being_attacked_yell = FALSE; bool used_flash = FALSE; int ghit_pos = 0; char reasonfd[30]; bool consid = FALSE; bool wpn_broke = FALSE; int consider_damage; void check_char_fight_init (CHAR_DATA *ch, CHAR_DATA *victim) { char log_buf[200]; int i; CHAR_DATA *guarder; if (IS_MOB(victim) || !ch->in_room) return; if ((ch != victim) && (IS_PLAYER(victim)) && (!ch->fgt || ch->fgt->fighting != victim) && ch->in_room->vnum >= 1000) { sprintf(log_buf, "%s attacked %s at %s (vnum %d).\n\r", NAME(ch), NAME(victim), ch->in_room->name, ch->in_room->vnum); log_string(log_buf); } if (IS_PLAYER(ch) && (IS_PLAYER(victim) || victim->society) && FIGHTING(ch) == NULL && FIGHTING(victim) == NULL && number_range(1,5) == 3) { CHAR_DATA *oldatt; being_attacked_yell = TRUE; check_fgt (victim); oldatt = victim->fgt->fighting; victim->fgt->fighting = ch; victim->fgt->fighting = oldatt; being_attacked_yell = FALSE; } if(number_range(1,4) == 2) for (i = 0; i < 4; i ++) { if ((guarder = victim->pcdata->guarded_by[i]) != NULL && IS_PLAYER(guarder) && (guarder->pcdata->guarding == victim) && (guarder->in_room == victim->in_room)) { if (check_skill(ch, gsn_guard)) { act("$n heroically steps in front of $N!", guarder, NULL, victim, TO_NOTVICT); act("You heroically step in front of $N", guarder, NULL, victim, TO_CHAR); act("$n heroically steps in front of you", guarder, NULL, victim, TO_VICT); check_fgt(ch); check_fgt(guarder); ch->fgt->fighting = guarder; if (!guarder->fgt->fighting) set_fighting(guarder, ch); return; } } } return; } void do_tackle (CHAR_DATA * ch, char *argy) { CHAR_DATA *victim; int chan; int xn; int i; char buf[STD_LENGTH]; DEFINE_COMMAND ("tackle", do_tackle, POSITION_FIGHTING, 0, LOG_NORMAL, "This command makes your character attempt to tackle his/her opponent.") check_fgt (ch); if (IS_PLAYER(ch)) if (!IS_SET (ch->pcdata->fight_ops, F_GROUND)) { send_to_char("You cannot tackle someone while you are trying to avoid groundfighting.\n\r", ch); return; } if (ch->fgt->ears > 9) { send_to_char ("You can't tackle this soon after giving or recieving a bash.\n\r", ch); return; } chan = 0; if (ch->wait > 2) return; if (FIGHTING (ch) == NULL) { if (argy[0] == '\0' || argy == "") { send_to_char ("Tackle who?\n\r", ch); WAIT_STATE(ch, 1*PULSE_VIOLENCE); return; } if ((victim = get_char_room (ch, argy)) == NULL) { send_to_char ("Tackle who?\n\r", ch); WAIT_STATE(ch, 1*PULSE_VIOLENCE); return; } if (victim == ch) { send_to_char ("You really do look like an idiot!\n\r", ch); return; } } else victim = FIGHTING (ch); if (FIGHTING(ch) == NULL && FIGHTING(victim) != NULL && !IS_IN_MELEE(ch, victim)) { send_to_char("You cannot get close enough to tackle them!\n\r", ch); return; } if (RIDING (ch) != NULL) { send_to_char ("You can't tackle someone when you are riding!\n\r", ch); return; } if (is_safe (ch, victim)) { return; } if (!can_see (ch, victim)) { send_to_char ("How can you tackle someone you can't see!?\n\r", ch); return; } if (!can_groundfight (victim) && (IS_MOB(ch) || str_cmp(race_info[ch->pcdata->race].name, "minotaur"))) { act ("You do not want to tackle that kind of creature!", ch, NULL, victim, TO_CHAR); return; } if (victim->position == POSITION_GROUNDFIGHTING) { act ("$N is already on the ground, tackled!", ch, NULL, victim, TO_CHAR); WAIT_STATE(ch, 2*PULSE_VIOLENCE); return; } if (victim->position == POSITION_BASHED) { act ("$N has been bashed, and you stumble past them!", ch, NULL,victim, TO_CHAR); WAIT_STATE(ch, 1*PULSE_VIOLENCE); return; } if (FIGHTING(victim) != NULL && !(IS_IN_MELEE (ch, victim))) { send_to_char ("You are not in the main melee!\n\r", ch); return; } if (!(IS_IN_MELEE (ch, victim))) { send_to_char ("You are not in the main melee!\n\r", ch); return; } if (!pow.tackle_with_weapon) { for (i = 0; i < MAX_HOLD; i++) { if (ch->hold[i] && (ch->hold[i]->pIndexData->item_type == ITEM_WEAPON || ch->hold[i]->pIndexData->item_type == ITEM_GEM)) { send_to_char ("You cannot tackle with a weapon or gem in hand!\n\r", ch); return; } } } if (!pow.tackle_person_with_weapon) { for (i = 0; i < MAX_HOLD; i++) { if (victim->hold[i] && (victim->hold[i]->pIndexData->item_type == ITEM_WEAPON || victim->hold[i]->pIndexData->item_type == ITEM_GEM)) { send_to_char ("Are you CRAZY!? Tackle someone with a weapon!??\n\r", ch); send_to_char ("You'd surely get whacked on your approach...\n\r", ch); return; } } } check_char_fight_init (ch, victim); if (IS_HURT(ch, FEAR) && number_range(1,5) != 3) { send_to_char("You are too afraid to attack!\n\r", ch); WAIT_STATE(ch, PULSE_VIOLENCE); return; } if (IS_MOB (ch)) chan = (LEVEL (ch) * 2) + 20; else chan = (get_stat (ch, DEX) * 5) + (LEVEL(ch)/3); chan -= ( get_stat(victim, DEX) * 3 - LEVEL (victim)/3); if (chan > 110) chan = 110; if (IS_PLAYER(ch)) chan += (ch->pcdata->learned[gsn_grapple]/3); if (IS_AUGMENTED(ch, AUG_HAND_SPD)) chan += 10; if (IS_AUGMENTED(ch, AUG_HAND_STR)) chan += 10; if (IS_AUGMENTED(victim, AUG_FOOT_SPD)) chan -= 10; if (IS_AUGMENTED(victim, AUG_LEG_SPD)) chan -= 10; if (IS_PLAYER(victim)) { chan -= (victim->pcdata->learned[gsn_steadiness]/3); check_skill(victim, gsn_steadiness); } if (IS_SET (victim->pcdata->fight_ops, F_GROUND)) xn = 150; else xn = 570; if (IS_PLAYER(ch) && !str_cmp(race_info[ch->pcdata->race].name, "minotaur")) { xn = UMIN(210, xn); chan = UMAX(chan, 50); } if ((number_range (0, xn) > chan && IS_AWAKE (victim)) || !check_skill(ch, gsn_tackle)) { send_to_char ("You miss the tackle and almost fall on the ground!\n\r", ch); act ("$n tries to tackle you, but almost falls over instead!", ch, NULL, victim, TO_VICT); act ("$n misses a tackle at $N and almost falls over!", ch, NULL, victim, TO_NOTVICT); WAIT_STATE (ch, 2 * PULSE_VIOLENCE); if (FIGHTING (victim) == NULL) set_fighting (victim, ch); set_fighting (ch, victim); return; } check_fgt(ch); check_fgt(victim); victim->fgt->ground_pos = 0; ch->fgt->ground_pos = 0; NEW_POSITION(victim, POSITION_GROUNDFIGHTING); NEW_POSITION(ch, POSITION_GROUNDFIGHTING); if (RIDING (victim) != NULL) { sprintf (buf, "As you jump up and tackle $N, $S flies off of %s and lands hard on the ground!", PERS (RIDING (victim), ch)); act (buf, ch, NULL, victim, TO_CHAR); sprintf (buf, "$n's flying tackle makes $N fall off of %s. $N lands on his back on the ground.", NAME (RIDING (victim))); act (buf, ch, NULL, victim, TO_NOTVICT); sprintf (buf, "You fall off of %s as $n tackles you!", PERS (RIDING (victim), victim)); act (buf, ch, NULL, victim, TO_VICT); check_fgt (victim->fgt->riding); victim->fgt->riding->fgt->mounted_by = NULL; victim->fgt->riding = NULL; } else if (RIDING (victim) == NULL) { act ("You tackle $N! The fight is taken to the ground!", ch, NULL, victim, TO_CHAR); act ("$n tackles $N and they both end up on the ground!", ch, NULL, victim, TO_NOTVICT); act ("$n tackles you! The fight is taken to the ground!", ch, NULL, victim, TO_VICT); } set_fighting (ch, victim); set_fighting (victim, ch); victim->fgt->fighting = ch; ch->fgt->fighting = victim; victim->fgt->ground_pos = 0; ch->fgt->ground_pos = 0; NEW_POSITION(victim, POSITION_GROUNDFIGHTING); NEW_POSITION(ch, POSITION_GROUNDFIGHTING); WAIT_STATE (victim, 2 * PULSE_VIOLENCE); WAIT_STATE (ch, (3 * PULSE_VIOLENCE)); return; } void violence_update (void) { CHAR_DATA *ch; CHAR_DATA *ch_next; CHAR_DATA *victim; CHAR_DATA *rch; CHAR_DATA *rch_next; int posorg; for (ch = f_first; ch != NULL; ch = ch_next) { ch_next = ch->next_fighting; check_fgt (ch); if (--ch->fgt->ears <= 10) { ch->fgt->ears = 2; if (ch->position == POSITION_BASHED) do_stand (ch, ""); } if ((victim = FIGHTING(ch)) == NULL) { if (ch->position == POSITION_FIGHTING) NEW_POSITION(ch, POSITION_STANDING); if (IS_MOB(ch)) { if (IS_SET (ch->pIndexData->act, ACT_FASTHUNT) && ch->fgt->hunting != NULL && ch->position == POSITION_STANDING) { hunt_victim (ch); } if (IS_HURT (ch, CHARM) && ch->fgt->master != NULL && ch->fgt->master->in_room == ch->in_room && ch->fgt->master->fgt != NULL && ch->fgt->master->fgt->fighting != NULL) multi_hit (ch, ch->fgt->master->fgt->fighting, TYPE_UNDEFINED); else continue; } else continue; } if (victim == ch) { ch->fgt->fighting = NULL; ch->position = POSITION_STANDING; } else if (FIGHTING (victim) == NULL) { check_fgt(victim); victim->fgt->fighting = ch; } if (IS_AWAKE (ch) && ch->in_room == victim->in_room) { if (IS_MOB (ch) && IS_SET (ch->act, ACT_KILLSQUISHY)) { CHAR_DATA *cir; CHAR_DATA *mostsquishy = NULL; int currhps = 0; for (cir = ch->in_room->people; cir != NULL; cir = cir->next_in_room) { if (FIGHTING (cir) == ch && cir->hit < currhps) { currhps = cir->hit; mostsquishy = cir; } } if (mostsquishy) { act ("$n turns and attacks $N!", ch, NULL, mostsquishy, TO_NOTVICT); act ("$n turns towards you and attacks!", ch, NULL, mostsquishy, TO_CHAR); set_fighting (ch, mostsquishy); break; } } posorg = victim->position; if (ch->fgt->challenge == 10 && number_range (1, 3) == 2) { char bufr[500]; sprintf (bufr, "($B$1Arena$N$7) $B%s: $4%s $7%s: $4%s", NAME (ch), STRING_HITS (ch), NAME (victim), STRING_HITS (victim)); do_arenaecho (ch, bufr, TRUE); } if (ch != victim && ch->position == POSITION_GROUNDFIGHTING && victim->position == POSITION_GROUNDFIGHTING) { ground_hit (ch, victim, TYPE_UNDEFINED); if ((victim = FIGHTING(ch)) != NULL && number_range(1,3) == 2 && (IS_MOB(ch) || (IS_AUGMENTED(ch, AUG_FACE_SPIKE) && check_skill(ch, gsn_grapple)))) ground_hit(ch, victim, TYPE_UNDEFINED); if (IS_MOB(ch) && number_range(1,15) == 9) do_stand(ch, ""); } else if (ch->position != POSITION_CASTING) { if (ch->fgt->challenge == 10 && number_range (1, 5) == 2) { char buf[200]; switch (number_range(1,5)) { case 1: sprintf (buf, "($B$1Arena$N$7) $BBlood runs freely as %s and %s exchange blows.", NAME (ch), NAME (victim)); break; case 2: sprintf (buf, "($B$1Arena$N$7) $BThe two fighters circle, flailing at each other wildly."); break; case 3: sprintf (buf, "($B$1Arena$N$7) $BPieces of flesh fly every where as blows are exchanged."); break; case 4: sprintf (buf, "($B$1Arena$N$7) $B%s lets out a loud warcry before attacking!", NAME (ch)); break; case 5: sprintf (buf, "($B$1Arena$N$7) $BYou can almost hear the crunching of bones..."); break; } do_arenaecho (ch, buf, TRUE); } if (IS_MOB (ch) && ch->pIndexData && ch->pIndexData->spec) { if (ch->pIndexData->spec->tactics < 2 || !check_tactics (ch, victim)) { if (number_range (1, 101) < ch->pIndexData->spec->warrior_percent) { if (number_range(1,3) ==2) do_bash (ch, ""); else if (number_range(1,2) == 2) do_kick (ch, ""); else if (number_range(1,3) == 3) do_tackle (ch, ""); else if (number_range(1,2) == 2) do_flurry (ch, ""); else if (number_range(1,2) ==2) do_tackle (ch, ""); else if (number_range(1,3) == 3) do_flail (ch, ""); else do_kick(ch, ""); } else { if (number_range (1, 101) < ch->pIndexData->spec->cast_percent) { int iil; for (iil = 0; iil < 4; iil++) { if (number_range (1, 2) == 1 && ch->pIndexData->spec->cast_spells[iil] != 0) { SPELL_DATA *spl; if ((spl = skill_lookup (NULL,ch->pIndexData->spec->cast_spells[iil])) == NULL) continue; if (LEVEL (ch) < spl->spell_level/3) continue; if (IS_SET(ch->pIndexData->act3, ACT3_AREA_CASTER) && number_range (1,3) != 2) area_spell = TRUE; if (spl->spell_type == TAR_CHAR_DEFENSIVE || spl->spell_type == TAR_CHAR_SELF) { general_spell (spl, LEVEL (ch),ch,ch); } else general_spell (spl, LEVEL (ch), ch,victim); area_spell = FALSE; break; } } } } } } if(number_range(1,4) == 2 && victim && IS_PLAYER(victim) && IS_PLAYER(ch)) { int i; for (i = 0; i < 4; i ++) { CHAR_DATA *guarder; if ((guarder = victim->pcdata->guarded_by[i]) != NULL && IS_PLAYER(guarder) && (guarder->pcdata->guarding == victim) && (guarder->in_room == victim->in_room)) { if(check_skill(ch, gsn_guard)) { act("$n heroically steps in front of $N!", guarder, NULL, victim, TO_NOTVICT); act("You heroically step in front of $N", guarder, NULL, victim, TO_CHAR); act("$n heroically steps in front of you", guarder, NULL, victim, TO_VICT); check_fgt(ch); ch->fgt->fighting = guarder; break; } } } } if ((victim = FIGHTING(ch)) == NULL) { continue; } multi_hit (ch, victim, TYPE_UNDEFINED); if (FIGHTING (ch) && FIGHTING (FIGHTING (ch)) != ch && number_range (1, 2) == 2) continue; } if (posorg == POSITION_CASTING && victim->position != POSITION_CASTING) { send_to_char ("OUCH! You just lost your concentration!\n\r", victim); if (IS_PLAYER (victim)) victim->pcdata->tickcounts = 0; } } else { stop_fighting (ch, FALSE); } if ((victim = FIGHTING (ch)) == NULL) continue; else { if (ch->data_type == 50 || victim->data_type == 50 || !ch->in_room || !victim->in_room || ch->in_room != victim->in_room) { if (ch->fgt) { ch->fgt->fighting = NULL; ch->position = POSITION_STANDING; } if (victim->fgt) { victim->fgt->fighting = NULL; victim->position = POSITION_STANDING; } continue; } } for (rch = ch->in_room->people; rch != NULL; rch = rch_next) { rch_next = rch->next_in_room; if (FIGHTING(rch) != NULL || !IS_AWAKE(rch)) continue; if (IS_PLAYER (rch) && is_same_group (ch, rch) && IS_SET (rch->pcdata->act2, PLR_ASSIST) && IS_MOB (victim) && ((victim = FIGHTING(ch)) != NULL) && victim->position > POSITION_DEAD && rch->position == POSITION_STANDING) { act ("You join the fight!", rch, NULL, rch, TO_CHAR); act ("$n joins the fight!", rch, NULL, rch, TO_ROOM); multi_hit (rch, victim, TYPE_UNDEFINED); if((victim = FIGHTING(rch)) != NULL) set_fighting(rch,victim); } if (IS_MOB (rch) && !IS_HURT (rch, CHARM) && ((rch->pIndexData == ch->pIndexData) || (ch->society && rch->society == ch->society)) && LEVEL (rch) > 9 && (victim = FIGHTING(ch)) != NULL && can_see (rch, victim)) { check_fgt (rch); rch->fgt->fighting = victim; NEW_POSITION(rch, POSITION_FIGHTING); act ("$n CHARGES into battle!", rch, NULL, NULL, TO_ROOM); multi_hit (rch, victim, TYPE_UNDEFINED); } continue; } } return; } void do_circle (CHAR_DATA * ch, char *argy) { SINGLE_OBJECT *obj; int dt; SPELL_DATA *spl; CHAR_DATA *c; int i; DESCRIPTOR_DATA *d; bool hitit = FALSE; DEFINE_COMMAND ("circle", do_circle, POSITION_FIGHTING, 0, LOG_NORMAL, "This command allows you to circle behind an opponent (who isn't fighting you), and thrust a dagger in his/her/its back during combat.") check_fgt (ch); if ((spl = skill_lookup ("Circle", -1)) == NULL) { send_to_char ("Huh?\n\r", ch); return; } if (ch->fgt->ears > 9) { send_to_char ("You can't circle this soon after giving or recieving a bash.\n\r", ch); return; } if (!actually_doing && IS_MOB (ch)) return; if (ch->pcdata->tickcounts > 3) { send_to_char ("You are off-balance from your last maneuver; you can't circle at the moment.\n\r", ch); return; } if (ch->wait > 1 || FIGHTING (ch) == NULL || FIGHTING (FIGHTING (ch)) == NULL) return; if (actually_doing) check_char_fight_init (ch, FIGHTING(ch)); else { if (ch->position != POSITION_FIGHTING) return; if (IS_HURT(ch, FEAR) && number_range(1,5) != 3) { send_to_char("You are too afraid to attack!\n\r", ch); WAIT_STATE(ch, PULSE_VIOLENCE); return; } } if (!used_flash && FIGHTING (FIGHTING (ch)) == ch) { send_to_char ("You can't circle around behind the mob who is fighting you!\n\r", ch); return; } if (ch->pcdata->learned[gsn_circle] < 2) { send_to_char ("You do not know how to circle an opponent!\n\r", ch); return; } if (!actually_doing) { if ((obj = get_item_held (ch, ITEM_WEAPON)) == NULL) { send_to_char ("You need to wield a weapon.\n\r", ch); return; } dt = ((I_WEAPON *) obj->more)->attack_type; if (attack_table[dt].hit_type != TYPE_PIERCE || !IS_OBJ_STAT(obj, ITEM_PIERCE)) { send_to_char ("You need to wield a piercing weapon.\n\r", ch); return; } if (FIGHTING (ch)->position == POSITION_GROUNDFIGHTING) { send_to_char ("That person is entangled in mortal combat on the ground!!\n\r", ch); return; } if (!(IS_IN_MELEE (ch, FIGHTING (ch)))) { send_to_char ("You aren't on the front lines of that battle!\n\r", ch); return; } send_to_char ("You start to circle around your victim...\n\r", ch); ch->pcdata->tickcounts = spl->mana; NEW_POSITION(ch, POSITION_CIRCLE); return; } if (ch->position != POSITION_CIRCLE && !used_flash) return; NEW_POSITION(ch, POSITION_STANDING); if ((spl = skill_lookup ("Circle", -1)) == NULL) { send_to_char ("Huh?\n\r", ch); return; } if (FIGHTING (FIGHTING (ch)) == ch && !used_flash) { send_to_char ("You can't circle around behind the mob who is fighting you!\n\r", ch); return; } if ((obj = get_item_held (ch, ITEM_WEAPON)) == NULL) { send_to_char ("You need to wield a weapon.\n\r", ch); return; } dt = ((I_WEAPON *) obj->more)->attack_type; if (attack_table[dt].hit_type != TYPE_PIERCE || !IS_OBJ_STAT(obj, ITEM_PIERCE)) { send_to_char ("You need to wield a piercing weapon.\n\r", ch); return; } if (FIGHTING (ch)->position == POSITION_GROUNDFIGHTING) { send_to_char ("That person is entangled in mortal combat on the ground!!\n\r", ch); return; } for (d = descriptor_list; d != NULL; d = d->next) { if (!d->character || d->connected != CON_PLAYING) continue; c = d->character; if (FIGHTING (c) == FIGHTING (ch) && c->position == POSITION_CIRCLE && !used_flash) { act ("$B$4You bump into $N, who is also trying to circle at the same time!", ch, NULL, c, TO_CHAR); act ("$B$4$n bumps into $N, who are both trying to circle at the same time! What fools!", ch, NULL, c, TO_NOTVICT); act ("$B$4$n bumps into you as you both crowd behind the same mob, trying to circle!", ch, NULL, c, TO_VICT); NEW_POSITION(c, POSITION_FIGHTING); free_temp (c); SUBHIT(c,4); SUBHIT(ch,5); return; } } for (i = 0; i < MAX_HOLD; i++) { if (ch->hold[i] && FIGHTING(ch) && ch->hold[i]->pIndexData->item_type == ITEM_WEAPON && IS_OBJ_STAT(ch->hold[i], ITEM_PIERCE) && attack_table[((I_WEAPON *)ch->hold[i]->more)->attack_type].hit_type == TYPE_PIERCE && (IS_MOB(ch) || !IS_AWAKE(FIGHTING(ch)) || (i % 2 == 0 ? check_skill(ch, gsn_circle) : (number_range(1,4) == 2 && check_skill(ch, gsn_double_circle))))) { if (IS_PLAYER(FIGHTING(ch)) && number_range(1,12) == 3 && check_skill(FIGHTING(ch), gsn_awareness)) { act("$n just tried to circle you!", ch, NULL, FIGHTING(ch), TO_VICT); act("You try to stab $N, but $E notices.", ch, NULL, FIGHTING(ch), TO_CHAR); } else { hitit = TRUE; one_hit(ch, FIGHTING(ch), gsn_circle, ch->hold[i]); if (!FIGHTING(ch) || victim_is_dead) return; } } } if(!hitit) send_to_char ("You failed to circle your opponent.\n\r", ch); return; } void multi_hit (CHAR_DATA * ch, CHAR_DATA * victim, int dt) { int gmembers; bool second; int i; int times_through; CHAR_DATA *vch; SINGLE_OBJECT *wield1; SINGLE_OBJECT *wield2; second = FALSE; check_fgt (ch); check_fgt (victim); /* Not in same room */ if (!consid) { if (ch->in_room != victim->in_room) { ch->fgt->fighting=NULL; victim->fgt->fighting=NULL; ch->position=POSITION_STANDING; victim->position=POSITION_STANDING; return; } add_to_fighting_list (ch); add_to_fighting_list (victim); if (is_safe (ch, victim)) { return; } if ((IS_MOB (ch) && (ch->pIndexData->mobtype == MOB_DUMMY)) || ch->position == POSITION_SLEEPING || victim == NULL ) { return; } if (ch->position <= POSITION_STUNNED) return; if (victim->position == POSITION_DEAD) { stop_fighting (ch, TRUE); stop_fighting (victim, TRUE); ch->wait = 0; } if (IS_MOB (victim)) { if (IS_SET (victim->act, ACT_UNTOUCHABLE)) { send_to_char ("Your physical attacks don't seem to hurt this creature!\n\r", ch); return; } if ((victim->pIndexData->mobtype == MOB_GHOST) || IS_AFF(victim, ETHEREAL)) { bool can_hit_it = FALSE; for (i = 0; i < MAX_HOLD; i++) { if (ch->hold[i] && ch->hold[i]->pIndexData->item_type == ITEM_WEAPON && (IS_OBJ_STAT(ch->hold[i], ITEM_GLOW) || IS_OBJ_STAT(ch->hold[i], ITEM_HUM))) { can_hit_it = TRUE; break; } } if (!can_hit_it) { send_to_char ("Your attack goes right through your victim as if it was not there!\n\r", ch); return; } } } for (vch = victim->in_room->people; vch != NULL; vch = vch->next_in_room) { if (FIGHTING (vch) == victim) { if (!IS_IN_MELEE (vch, victim)) { for (gmembers = 0; gmembers < 4; gmembers++) { if (victim->fgt->attackers[gmembers] == NULL || victim->fgt->attackers[gmembers]->in_room != victim->in_room) { victim->fgt->attackers[gmembers] = vch; break; } } } } } if (pow.can_fight_self) { if (IS_PLAYER (ch) && ch->desc != NULL && FIGHTING (ch) == NULL) { write_to_descriptor2 (ch->desc, "\n\r", 2); ch->fgt->fighting = victim; } else { check_fgt (ch); ch->fgt->fighting = victim; } } if (FIGHTING (victim) == NULL) { ch->fgt->attackers[0] = victim; victim->fgt->attackers[0] = ch; victim->fgt->fighting = ch; } if (ch->fgt->combat_delay_count <= -5) { ch->fgt->combat_delay_count--; if (ch->fgt->combat_delay_count < -8) ch->fgt->combat_delay_count = -1; } if (ch->fgt->combat_delay_count > 0) { ch->fgt->combat_delay_count--; return; } if (ch->position != POSITION_BASHED && ch->fgt->combat_delay_count == 0) { ch->fgt->combat_delay_count = -1; ch->fgt->ears = 2; send_to_char ("You scramble to your feet!\n\r", ch); act ("$n stands up quickly, trying not to get whacked again!", ch, NULL, NULL, TO_ROOM); NEW_POSITION(ch, POSITION_FIGHTING); } if (IS_MOB (ch) && ch->position == POSITION_BASHED && ch->fgt->combat_delay_count < 1) { ch->fgt->combat_delay_count = -5; ch->fgt->ears = 2; send_to_char ("You scramble to your feet!\n\r", ch); act ("$n stands up, trying not to get bashed down again!", ch, NULL, NULL, TO_ROOM); NEW_POSITION(ch, POSITION_FIGHTING); } if (ch->position == POSITION_BASHED) { update_pos (ch); return; } if (ch->fgt->combat_delay_count < 1 && ch->position == POSITION_STANDING) { NEW_POSITION(ch, POSITION_FIGHTING); } if (number_range (1, 120) == 3 && RIDING (ch) == NULL && can_groundfight (ch) && can_groundfight (victim) && ch->hit < ch->max_hit/2) { if (number_range (1, 2) == 1 || FIGHTING (victim) != ch || !IS_SET (ch->pcdata->fight_ops, F_GROUND) || !IS_SET (victim->pcdata->fight_ops, F_GROUND) || LEVEL (ch) < 10 || LEVEL (victim) < 10 || victim->position == POSITION_GROUNDFIGHTING || ch->position == POSITION_GROUNDFIGHTING) { act ("You slip on a pool of blood that has formed on the ground here!\n\rYou hit your head hard as your face meets the ground!", ch, NULL, victim, TO_CHAR); act ("$n slips on a pool of blood and falls on $s face!", ch, NULL, victim, TO_ROOM); SUBHIT(ch,(7 + (UMIN (10, LEVEL (ch) / 7)))); WAIT_STATE (ch, PULSE_VIOLENCE); return; } else { act ("You slip on some blood and $N falls on top of you!", ch, NULL, victim, TO_CHAR); act ("$n slips on some blood and drags $N down too!", ch, NULL, victim, TO_NOTVICT); act ("$n slips on a pool of blood on the ground, but as $n\n\rgoes down, $n grabs you, taking you down too!", ch, NULL, victim, TO_VICT); act ("The fight is taken to the ground!", ch, NULL, victim, TO_ROOM); act ("The fight is taken to the ground!", ch, NULL, victim, TO_CHAR); NEW_POSITION(ch, POSITION_GROUNDFIGHTING); NEW_POSITION(victim, POSITION_GROUNDFIGHTING); WAIT_STATE (ch, PULSE_VIOLENCE); WAIT_STATE (victim, PULSE_VIOLENCE); return; } } if (ch == FIGHTING (victim) && !(IS_IN_MELEE (ch, victim))) { int kk; for (kk = 0; kk < 4; kk++) { if (victim->fgt->attackers[kk] == NULL) { victim->fgt->attackers[kk] = ch; break; } } } } times_through = (IS_MOB(ch) ? 1 : race_info[ch->pcdata->race].parts[3]); if (times_through == 0) return; for (i = 0; i < times_through; i++) { wield1 = ((ch->hold[2*i] != NULL && ch->hold[2*i]->pIndexData->item_type == ITEM_WEAPON) ? ch->hold[2*i] : NULL); wield2 = ((ch->hold[2*i+1] != NULL && ch->hold[2*i+1]->pIndexData->item_type == ITEM_WEAPON) ? ch->hold[2*i+1] : NULL); if (wield2 && !wield1) { wield1 = wield2; wield2 = NULL; } if (!consid && wield1 != NULL && !IS_OBJ_STAT(wield1, ITEM_POLEARM) && !IS_IN_MELEE (ch, victim)) { send_to_char ("\x1B[1;35m<-> (\x1B[32mYou are not within melee range\x1B[35m) <->\x1B[0;37m\n\r", ch); return; } one_hit (ch, victim, dt, wield1); /* Being affected by slow makes all of these extra attacks go poof */ if (!victim_is_dead && !IS_HURT(ch, SLOW)) { if (IS_AFF (ch, SPEED) && number_range(1,2) == 2) one_hit (ch, victim, dt, wield1); if (wpn_broke) { wpn_broke = FALSE; wield1 = NULL; } if (!victim_is_dead && (wield2 || IS_MOB(ch))) { if (check_skill(ch, gsn_dual_wield) && number_range(1,3) != 2) { one_hit (ch, victim, dt, wield2); if (wpn_broke) { wield2 = NULL; wpn_broke = FALSE; } } if (!victim_is_dead && check_skill(ch, gsn_dual_second) && number_range(1,2) == 2) { one_hit (ch, victim, dt, wield2); if (wpn_broke) { wield2 = NULL; wpn_broke = FALSE; } } if (!victim_is_dead && check_skill(ch, gsn_dual_third) && number_range(1,2) == 2) { one_hit (ch, victim, dt, wield2); if (wpn_broke) { wield2 = NULL; wpn_broke = FALSE; } } } if (!victim_is_dead && check_skill(ch, gsn_second_attack) && number_range(1,4) != 2) { one_hit (ch, victim, dt, wield1); if (wpn_broke) { wpn_broke = FALSE; wield1 = NULL; } } if (!victim_is_dead && check_skill(ch, gsn_third_attack) && number_range(1,3) != 1) { one_hit (ch, victim, dt, wield1); if (wpn_broke) { wpn_broke = FALSE; wield1 = NULL; } } if (!victim_is_dead && check_skill(ch, gsn_fourth_attack) && number_range(1,2) == 2) { one_hit (ch, victim, dt, wield1); if (wpn_broke) { wpn_broke = FALSE; wield1 = NULL; } } if (!victim_is_dead && check_skill(ch, gsn_fifth_attack) && number_range(1,2) == 1) { one_hit (ch, victim, dt, wield1); if (wpn_broke) { wpn_broke = FALSE; wield1 = NULL; } } } } if (!consid && (victim->position == POSITION_RESTING || victim->position == POSITION_SLEEPING || victim->position == POSITION_STANDING)) { set_fighting (victim, ch); } return; } /* This is the new check parry/dodge/shieldblock code which comes in BEFORE all the damage and crap are calculated. */ bool check_defense (CHAR_DATA * ch, CHAR_DATA * victim) { int chance; CHAR_DATA *fch; int i; int number = 0; if (victim->move <= 6) return FALSE; if (!IS_AWAKE (victim) || victim->position <= POSITION_STUNNED) return FALSE; if (!can_see(ch, victim)) { if(number_range(1,10) == 3 ) act ("You try to defend yourself, but you can't see your opponent!", victim, NULL, ch, TO_CHAR); return FALSE; } for (fch = ch->in_room->people; fch != NULL; fch = fch->next_in_room) { if (FIGHTING(fch) == victim) number++; } if (number < 1) number = 1; if (get_item_held(victim, ITEM_WEAPON) != NULL) { if (IS_MOB (victim)) chance = (LEVEL (victim)*3)/number; else { chance = (victim->pcdata->learned[gsn_parry]+ victim->pcdata->learned[gsn_riposte] + (5 * is_member(victim, GUILD_WARRIOR)) + (IS_AUGMENTED(victim, AUG_BODY_STR) ? 12 : 0)+ (IS_AUGMENTED(victim, AUG_ARM_STR) ? 12 : 0)+ (IS_AUGMENTED(victim, AUG_HAND_STR) ? 12 : 0)); for (i = 0; i < MAX_HOLD; i++) if (victim->hold[i] && victim->hold[i]->pIndexData->item_type == ITEM_WEAPON) chance += 25; chance /= number; } if (number_range (1, 1800) < UMIN(310, chance)) { if (number_range (1, 2) == 2) { act ("You skillfully parry $n's attack.", ch, NULL, victim, TO_VICT_SPAM); act ("$N skillfully parries your attack.", ch, NULL, victim, TO_CHAR_SPAM); act ("$N skillfully parries $n's attack.", ch, NULL, victim, TO_NOTVICT_SPAM); } else { act ("You forcefully deflect $n's blade, parrying the attack.", ch, NULL, victim, TO_VICT_SPAM); act ("$N forcefully deflects your blade, parrying the attack.", ch, NULL, victim, TO_CHAR_SPAM); act ("$N deflects $n's attack with his weapon.", ch, NULL, victim, TO_NOTVICT_SPAM); } if (IS_PLAYER(victim)) { check_skill(victim, gsn_parry); check_skill(victim, gsn_riposte); if (number_range(1,12) == 3 && number_percent() < victim->pcdata->learned[gsn_riposte]) { act ("$n lunges inside $N's defenses, scoring a quick strike!", victim, NULL, ch, TO_NOTVICT); act ("$n lunges inside your defenses, scoring a quick strike!", victim, NULL, ch, TO_VICT); act ("You lunge inside $N's defenses, scoring a quick strike!", victim, NULL, ch, TO_CHAR); } one_hit(victim, ch, TYPE_HIT, get_item_held(victim, ITEM_WEAPON)); } SUBMOVE(victim,1); return TRUE; } } /* Failed Parry, now check dodge. */ if (IS_MOB (victim)) chance = (LEVEL (victim) * 3/2) / (number); else { chance = (victim->pcdata->learned[gsn_dodge] + victim->pcdata->learned[gsn_enhanced_dodge] + (9*is_member(victim, GUILD_THIEF)) + (IS_AUGMENTED(victim, AUG_LEG_SPD) ? 30 : 0) + (IS_AUGMENTED(victim, AUG_FOOT_SPD) ? 30 : 0))/number; chance -= ((victim->pcdata->carry_weight/get_stat(victim, STR))); /* This takes into account the *10 from the new weight code and the desire to subtract 10 points for each multi of str carried...*/ } if (number_range (0, 1250) < UMIN(180, chance)) { if (victim->position != POSITION_BASHED) { if (number_range (1, 2) == 2) { act ("You step aside, dodging $n's attack.", ch, NULL, victim, TO_VICT_SPAM); act ("$N quickly steps aside, dodging your attack.", ch, NULL, victim, TO_CHAR_SPAM); act ("$N steps aside, dodging $n's attack.", ch, NULL, victim, TO_NOTVICT_SPAM); } else { if (number_range (1, 2) == 2) { act ("You duck right, dodging $n's attack.", ch, NULL, victim, TO_VICT_SPAM); act ("$N ducks right, dodging your attack.", ch, NULL, victim, TO_CHAR_SPAM); act ("$N ducks right, dodging $n's attack.", ch, NULL, victim, TO_NOTVICT_SPAM); } else { act ("You duck left, dodging $n's attack.", ch, NULL, victim, TO_VICT_SPAM); act ("$N ducks left, dodging your attack.", ch, NULL, victim, TO_CHAR_SPAM); act ("$N ducks left, dodging $n's attack.", ch, NULL, victim, TO_NOTVICT_SPAM); } } } else { act ("You roll out of the way of $n's attack.", ch, NULL, victim, TO_VICT_SPAM); act ("$N rolls out of the way of your attack.", ch, NULL, victim, TO_CHAR_SPAM); act ("$N rolls out of the way of $n's attack.", ch, NULL, victim, TO_NOTVICT_SPAM); } if (IS_PLAYER(victim)) { check_skill(victim, gsn_dodge); check_skill(victim, gsn_enhanced_dodge); } SUBMOVE(victim,1); return TRUE; } /* Failed dodge, now check shield block */ if (IS_PLAYER(victim) && IS_SET(victim->act, PLR_HAS_SHIELD)) { chance = (victim->pcdata->learned[gsn_shield_block] + victim->pcdata->learned[gsn_shieldbash] + (IS_AUGMENTED(victim, AUG_ARM_STR) ? 20 : 0)+ ( 5* is_member(victim, GUILD_BATTLEMASTER)) + (IS_AUGMENTED(victim, AUG_BODY_STR) ? 20 : 0))/number; if (number_range (1, 1000) < chance) { act ("You block $n's attack with your shield.", ch, NULL, victim, TO_VICT_SPAM); act ("$N blocks your attack with $S shield.", ch, NULL, victim, TO_CHAR_SPAM); act ("$N blocks $n's attack with $S shield.", ch, NULL, victim, TO_NOTVICT_SPAM); check_skill(victim, gsn_shield_block); if (number_range(1,150) < victim->pcdata->learned[gsn_shieldbash]) { act ("You slam into $N with your shield.", ch, NULL, victim, TO_CHAR_SPAM); act ("$N slams into you with $s shield.", ch, NULL, victim, TO_VICT_SPAM); act ("$N slams $S shield into $n's body.", ch, NULL, victim, TO_NOTVICT_SPAM); SUBHIT (ch, get_stat(victim, STR)/3); check_skill(victim, gsn_shieldbash); if (ch->hit < 1) ch->hit = 1; } return TRUE; } } if ((IS_MOB(victim) && LEVEL(victim) > IMM_LEVEL) || (IS_PLAYER(victim))) { int chance = 0; if (IS_PLAYER(victim)) { if(!IS_SET(victim->pcdata->act2, PLR_AUTOBLINK) || victim->pcdata->n_mana < 5) return FALSE; chance = UMAX(0, (get_stat(victim, INT) + get_stat(victim, WIS) + get_stat(victim, WIL) + get_stat(victim, DEX) - 42)); chance += 5 * is_member(victim, GUILD_SORCERER); chance *= UMAX(0, victim->pcdata->learned[gsn_blink]/8); } else { if (victim->pIndexData->spec != NULL) chance = LEVEL(victim)/2; } if (number_range(1,900) < UMIN(320, chance)) { act ("$B$6You blink out of the way of $n's attack.$R", ch, NULL, victim, TO_VICT_SPAM); act ("$B$6$N blinks out of the way of your attack.$R", ch, NULL, victim, TO_CHAR_SPAM); act ("$B$6$N blinks out of the way of $n's attack.$R", ch, NULL, victim, TO_NOTVICT_SPAM); if (IS_PLAYER(victim)) { victim->pcdata->n_mana--; if (number_range(1,20) == 3) check_skill(victim, gsn_blink); } return TRUE; } if (IS_AFF(victim, ETHEREAL)) { bool can_hit_it = FALSE; for (i = 0; i < MAX_HOLD; i++) { if (ch->hold[i] && ch->hold[i]->pIndexData->item_type == ITEM_WEAPON && (IS_OBJ_STAT(ch->hold[i], ITEM_GLOW) || IS_OBJ_STAT(ch->hold[i], ITEM_HUM))) { can_hit_it = TRUE; break; } } if (!can_hit_it) { act ("$n's attack passes right through you.", ch, NULL, victim, TO_VICT_SPAM); act ("Your attack passes right through $N.", ch, NULL, victim, TO_CHAR_SPAM); act ("$n's attack passes right through $N.", ch, NULL, victim, TO_NOTVICT_SPAM); return TRUE; } } } return FALSE; } int addoffense (CHAR_DATA * ch, SINGLE_OBJECT * obj) { if (IS_MOB (ch)) return 0; if (obj == NULL || obj->pIndexData->item_type != ITEM_WEAPON) return 0; if (IS_SET (obj->extra_flags, ITEM_POLEARM)) { check_skill(ch, gsn_polearm); return (-20+ch->pcdata->learned[gsn_polearm] / 7); } else if (IS_SET (obj->extra_flags, ITEM_PIERCE)) { check_skill(ch, gsn_pierce); return (ch->pcdata->learned[gsn_pierce] / 4); } else if (IS_SET (obj->extra_flags, ITEM_CONCUSSION)) { check_skill(ch, gsn_concussion); return (ch->pcdata->learned[gsn_concussion] / 5); } else if (IS_SET (obj->extra_flags, ITEM_WHIP)) { check_skill(ch, gsn_whip); return (ch->pcdata->learned[gsn_whip] / 4); } else if (IS_SET (obj->extra_flags, ITEM_HEAVY_SLASH)) { check_skill(ch, gsn_slashing); if (get_stat (ch, STR) < 11) return -3; if (get_stat (ch, STR) < 16) return 0; if (get_stat (ch, STR) < 18) return (ch->pcdata->learned[gsn_slashing] / 7); if (get_stat (ch, STR) < 21) return (ch->pcdata->learned[gsn_slashing] / 6); if (get_stat (ch, STR) < 24) return (ch->pcdata->learned[gsn_slashing] / 5); else return (ch->pcdata->learned[gsn_slashing] / 4); } else if (IS_SET (obj->extra_flags, ITEM_LIGHT_SLASH)) { check_skill(ch, gsn_slashing); return ((ch->pcdata->learned[gsn_slashing] / 4) + ((get_stat (ch, STR) - 5) / 2)); } else if (IS_SET (obj->extra_flags, ITEM_SLASHING)) { check_skill(ch, gsn_slashing); return (ch->pcdata->learned[gsn_slashing] / 5); } return 0; } int addoffense2 (CHAR_DATA * ch, SINGLE_OBJECT * obj) { if (IS_MOB (ch)) return 0; if (obj == NULL || obj->pIndexData->item_type != ITEM_WEAPON) return 0; if (IS_SET (obj->extra_flags, ITEM_POLEARM)) return (-20+ch->pcdata->learned[gsn_polearm] / 7); else if (IS_SET (obj->extra_flags, ITEM_PIERCE)) return (ch->pcdata->learned[gsn_pierce] / 4); else if (IS_SET (obj->extra_flags, ITEM_CONCUSSION)) return (ch->pcdata->learned[gsn_concussion] / 5); else if (IS_SET (obj->extra_flags, ITEM_WHIP)) return (ch->pcdata->learned[gsn_whip] / 4); else if (IS_SET (obj->extra_flags, ITEM_HEAVY_SLASH)) { if (get_stat (ch, STR) < 11) return -3; if (get_stat (ch, STR) < 16) return 0; if (get_stat (ch, STR) < 18) return (ch->pcdata->learned[gsn_slashing] / 7); if (get_stat (ch, STR) < 21) return (ch->pcdata->learned[gsn_slashing] / 6); if (get_stat (ch, STR) < 24) return (ch->pcdata->learned[gsn_slashing] / 5); else return (ch->pcdata->learned[gsn_slashing] / 4); } else if (IS_SET (obj->extra_flags, ITEM_LIGHT_SLASH)) return ((ch->pcdata->learned[gsn_slashing] / 4) + ((get_stat (ch, STR) - 5) / 2)); else if (IS_SET (obj->extra_flags, ITEM_SLASHING)) return (ch->pcdata->learned[gsn_slashing] / 5); return 0; } void one_hit (CHAR_DATA * ch, CHAR_DATA * victim, int dt, SINGLE_OBJECT * wield) { SINGLE_OBJECT *armor; int to_hit, i; int bonushit; int dam = 0; int iWear; int hit_pos = 1; bonushit = 0;; check_fgt (ch); check_fgt (victim); if (!consid) { if (ch->in_room != victim->in_room || victim->position == POSITION_DEAD) { ch->fgt->fighting=NULL; victim->fgt->fighting=NULL; ch->position=POSITION_STANDING; victim->position=POSITION_STANDING; return; } hit_pos = number_range (1, 4); if (ch && victim && IS_MOB (ch) && IS_PLAYER (victim) && (!HUNTING (ch) || (HUNTING (ch) && !is_number (HUNTING (ch))))) { if (strlen (NAME (victim)) < 16) { if (HUNTING (ch) != NULL) { free_string (ch->fgt->hunting); ch->fgt->hunting = NULL; } ch->fgt->hunting = str_dup (NAME (victim)); } } if (MOUNTED_BY (victim) == ch) { ch->fgt->riding = NULL; victim->fgt->mounted_by = NULL; } /* * Figure out the type of damage message. */ if (!FIGHTING(victim)) { check_fgt(victim); victim->fgt->fighting = ch; } if (victim->position == POSITION_GROUNDFIGHTING && number_range(1,3) == 1) { act ("$N is groundfighting and you can't find a line of attack.", ch, NULL, victim, TO_CHAR_SPAM); return; } if (IS_AFF(victim, ETHEREAL)) { bool can_hit_it = FALSE; for (i = 0; i < MAX_HOLD; i++) { if (ch->hold[i] && ch->hold[i]->pIndexData->item_type == ITEM_WEAPON && (IS_OBJ_STAT(ch->hold[i], ITEM_GLOW) || IS_OBJ_STAT(ch->hold[i], ITEM_HUM))) { can_hit_it = TRUE; break; } } if (!can_hit_it) { act ("$n's attack passes right through you.", ch, NULL, victim, TO_VICT_SPAM); act ("Your attack passes right through $N.", ch, NULL, victim, TO_CHAR_SPAM); act ("$n's attack passes right through $N.", ch, NULL, victim, TO_NOTVICT_SPAM); return; } } if (victim->aff[AFF] >= GAS) { int damm; int ii; int oldhit; int prot = 6 * IS_AFF (ch, MINDSHIELD) + 4 * IS_AUGMENTED (ch, AUG_MENTAL_ARMOR) + is_member (victim, GUILD_MYSTIC); char buff[SML_LENGTH]; /* NOTE NOTE NOTE IF YOU CHANGE affect_flags1 IN DEF.C and you remove some the flags before GAS or you remove a lot of the flags after it, be careful to watch out for this!!! */ for (ii = 21; affect_flags1[ii].flagname > 0; ii++) { if (IS_AFF(victim, affect_flags1[ii].flagname) && number_range(1,3)== 2 && !IS_PROT (ch, affect_flags1[ii].flagname)) { damm = number_range (1,40) - prot; if (damm > 1) { sprintf (buff, "$B$5$n is hit by your%sshield!$R", affect_flags1[ii].how_it_appears); act (buff, ch, NULL, victim, TO_VICT); sprintf (buff, "$B$3$n is hit by $N's%sshield!$R", affect_flags1[ii].how_it_appears); act (buff, ch, NULL, victim, TO_NOTVICT); sprintf (buff, "$B$3You are hit by $N's%sshield!$R", affect_flags1[ii].how_it_appears); act (buff, ch, NULL, victim, TO_CHAR); oldhit = ch->hit; damage (victim, ch, damm, 280); if (oldhit < damm) return; } } } } } if (dt == TYPE_UNDEFINED) { dt = TYPE_HIT; if (check_defense(ch, victim)) return; if (wield != NULL && wield->pIndexData->item_type == ITEM_WEAPON) { dt += ((I_WEAPON *)wield->more)->attack_type; } } if (wield && wield->pIndexData->item_type != ITEM_WEAPON) wield = NULL; else { if (IS_PLAYER (ch)) bonushit = addoffense (ch, wield); } to_hit = GET_HITROLL(ch) + (bonushit*4/3) + (IS_MOB(ch) ? ch->pIndexData->hitroll : (check_skill(ch, gsn_accuracy) * ch->pcdata->learned[gsn_accuracy]/5)); to_hit -= LEVEL(victim)/4 - get_stat (victim, DEX); if (IS_PLAYER(victim)) { to_hit -= ((!IS_SET (victim->pcdata->fight_ops, F_AGGRESSIVE) ? 8 : 0) + (!IS_SET (victim->pcdata->fight_ops, F_POWER) ? 8 : 0) + (IS_AUGMENTED(victim, AUG_LEG_SPD) ? 6 : 0) + (IS_AUGMENTED(victim, AUG_FOOT_SPD) ? 6 : 0)); } if (to_hit > 80) to_hit -= (to_hit-80)/2; if (number_percent() >= to_hit && number_range (0, 9) >= 3 && dt != gsn_backstab && dt != gsn_circle && IS_AWAKE (victim) && dt != gsn_impale) { ghit_pos = hit_pos; if (!consid) { damage (ch, victim, 0, dt); ghit_pos = 0; } return; } if (IS_MOB (ch)) { if (wield != NULL && wield->pIndexData->item_type == ITEM_WEAPON) dam = (dice (FIRSTDICE (wield), SECONDDICE (wield))); dam += number_range (LEVEL (ch) / 5, (LEVEL (ch)/2)); dam += ch->pIndexData->damroll; if (dam <= 0) dam = 1; } else { if (wield != NULL && wield->pIndexData->item_type == ITEM_WEAPON) { dam = dice (FIRSTDICE (wield), SECONDDICE (wield)); if (IS_OBJ_STAT(wield, ITEM_CONCUSSION)) dam += number_range(0,is_member(ch, GUILD_TINKER)/2); if (IS_OBJ_STAT(wield, ITEM_SLASHING) || IS_OBJ_STAT(wield, ITEM_HEAVY_SLASH) || IS_OBJ_STAT(wield, ITEM_LIGHT_SLASH)) dam += number_range(0,is_member(ch, GUILD_RANGER)/2); if (IS_OBJ_STAT(wield, ITEM_PIERCE)) dam += number_range(0,is_member(ch, GUILD_THIEF)/2); } else { if (dam == 0) dam = number_range(1, (1+LEVEL(ch)/10)); } } if (GET_DAMROLL(ch) > 0) dam += number_range(0, (GET_DAMROLL(ch)*2/5)); { int dif; int absorbed = 0; bool tinker = (is_member(ch, GUILD_TINKER ? TRUE : FALSE)); int b4 = 0; bool conc = FALSE; bool power = FALSE; if (IS_AUGMENTED(ch, AUG_BODY_STR)) dam += number_range(0,1); if (IS_AUGMENTED(ch, AUG_ARM_STR)) dam += number_range(0,1); if (IS_AUGMENTED(ch, AUG_HAND_STR)) dam += number_range(0,1); dam += number_range(0, is_member(ch, GUILD_WARRIOR)/2); dam += dam * ((check_skill(ch, gsn_enhanced_damage) * ch->pcdata->learned[gsn_enhanced_damage]/4) + (check_skill(ch, gsn_enhanced_damage_two) * ch->pcdata->learned[gsn_enhanced_damage_two]/5)) / 100; if (dam > 25) dam -= ((dam - 25)/2); if (wield && wield->pIndexData->item_type == ITEM_WEAPON) { if (IS_OBJ_STAT(wield, ITEM_POWER)) power = TRUE; if (IS_OBJ_STAT(wield, ITEM_CONCUSSION)) conc = TRUE; if (dt != gsn_backstab && dt != gsn_circle && IS_OBJ_STAT(wield, ITEM_PIERCE) && number_range(1,82) == 26 && IS_AUGMENTED(ch, AUG_HAND_SPD) && check_skill(ch, gsn_critical)) { dam += number_range(2,5); dam*=6; dam *= (race_info[ch->pcdata->race].backstab_percent + align_info[ch->pcdata->alignment].backstab_percent)/100; if (!consid) { act ("\x1b[1;33mCritical \x1b[1;31mHit!!!!", ch, NULL, NULL, TO_ROOM); act ("\x1b[1;33mCritical \x1b[1;31mHit!!!!", ch, NULL, NULL, TO_CHAR); } } } b4 = dam; dam = new_damage (victim, dam, hit_pos, dt); dif = b4 - dam; if (dif > 4 && check_skill (ch, gsn_penetration)) { dam += dif/5; if ((tinker && conc) || power) dam += dif/5; } if (dt != gsn_circle && dt != gsn_backstab) { if (IS_AUGMENTED(victim, AUG_LEG_ARMOR)) absorbed +=6; if (IS_AUGMENTED(victim, AUG_FOOT_ARMOR)) absorbed +=6; if (IS_AUGMENTED(victim, AUG_ARM_ARMOR)) absorbed +=6; if (IS_AUGMENTED(victim,AUG_HEAD_ARMOR)) absorbed +=6; if (IS_AUGMENTED(victim, AUG_BODY_ARMOR)) absorbed +=6; if (IS_PLAYER(victim)) { absorbed += (check_skill(victim, gsn_resilience) * victim->pcdata->learned[gsn_resilience]/5); } if (DIFF_ALIGN(ch, victim) && IS_AFF(victim, PROT_ALIGN)) absorbed += 19; if (IS_AFF (victim, SANCTUARY)) absorbed += 29; if (IS_AFF (victim, PROTECT)) absorbed += 38; if (IS_HURT (victim, OUTLINE)) absorbed -= LEVEL(ch); if (tinker && conc) absorbed -= absorbed/8; if (power) absorbed -= absorbed/7; absorbed += (number_range(0, absorbed/6)); if (absorbed > 90) absorbed = 90; dam = ((100-absorbed)*dam)/100; } } if (ch->in_room->sector_type == SECT_ASTRAL) dam/=2; if (consid) { consider_damage += dam; return; } if (wield && IS_OBJ_STAT(wield, ITEM_VAMPIRIC)) { if (number_range (1, 20) == 3) { act ("$4$n's $p$R$4 sticks to $B$0$N$R$4 briefly and sucks out a torrent of blood, sending the power $n's arm.", ch, wield, victim, TO_NOTVICT); act ("$4$n's $p$R$4 sticks to you briefly and sucks out a torrent of blood, sending the power up $s arm.", ch, wield, victim, TO_VICT); act ("$4Your $p$R$4 sticks to $N briefly and sucks out a torrent of blood, sending the power up your arm.", ch, wield, victim, TO_CHAR); } if (ch->hit < ((ch->max_hit * 5) /4)) ch->hit += dam/2; } if (!wield && IS_HURT (ch, VAMPIRIC)) { if (ch->hit > ch->max_hit *5/4) ch->hit += dam; if (number_range(1,20) == 3) { act ("You drain life from $N and feel MUCH better!", ch, NULL, victim, TO_CHAR); act ("$n drains life from you and looks MUCH better!", ch, NULL, victim, TO_VICT); act ("$n drains life from $N and looks MUCH better!", ch, NULL, victim, TO_NOTVICT); } } if (number_range(1,38) == 2 && ch->position != POSITION_BASHED && victim->position != POSITION_BASHED) { if (IS_AFF(ch, FLYING) && !IS_AFF(victim, FLYING)) { act ("$n swoops down and attacks $N!", ch, NULL, victim, TO_NOTVICT); act ("$n swoops down from the air and attacks you!", ch, NULL, victim, TO_VICT); act ("You swoop down from the air and attack $N!", ch, NULL, victim, TO_CHAR); dam += 2; if (number_range (1, 12) == 5) { if (number_range (1, 2) == 1) { act ("$N catches $n with an elbow while $e is approaching!", ch, NULL, victim, TO_NOTVICT); act ("You catch $n with an elbow as $e approaches!", ch, NULL, victim, TO_VICT); act ("$N smashes $S elbow into your face as you swoop down!", ch, NULL, victim, TO_CHAR); } else { act ("$N jumps out of the way and $n smashes into the ground!", ch, NULL, victim, TO_NOTVICT); act ("You jump out of the way and $n smashes into the ground!", ch, NULL, victim, TO_VICT); act ("$N steps out of the way and you smash into the ground!", ch, NULL, victim, TO_CHAR); } if (ch->hit > 7) SUBHIT(ch,7); return; } } else if (!IS_AFF(ch, FLYING) && IS_AFF(victim, FLYING)) { /*hitter not flying, victim flying */ act ("$N quickly flies out of the way, dodging your attack!", ch, NULL, victim, TO_CHAR); act ("$N flies out of $n's attack path.", ch, NULL, victim, TO_NOTVICT); act ("You fly out of the path of $n's attack.", ch, NULL, victim, TO_VICT); return; } else if (IS_AFF(ch,FLYING) && IS_AFF(victim, FLYING)) { /*both hitter and victim flying */ act ("$N and $n get tangled and smash into the ground!", ch, NULL, victim, TO_NOTVICT); act ("You smash into the ground as you struggle with $n!", ch, NULL, victim, TO_VICT); act ("You smash into the ground as you struggle with $N!", ch, NULL, victim, TO_CHAR); if (ch->hit > 10) { SUBHIT(ch,9); SUBHIT(victim,9); } return; } } if (!IS_AWAKE (victim)) dam *= 3; if (victim->position == POSITION_RESTING) dam = (dam * 3) / 2; if (dt == gsn_circle || dt == gsn_backstab) { int muu = 16 + (LEVEL (ch) / 8); if (dam < 4) dam = 4; if (check_skill(ch, gsn_critical) && number_range(1,30) == 7) dam = UMAX(30, dam*3/2); dam += is_member(ch, GUILD_THIEF); muu += 2*is_member(ch, GUILD_THIEF); if (IS_AUGMENTED(ch, AUG_HAND_SPD)) muu +=2; muu += (UMAX((get_curr_dex(ch)-27), 0)); dam = number_range(dam*muu/5,dam*muu/3); if(IS_PLAYER(ch)) dam = (dam*(race_info[ch->pcdata->race].backstab_percent + align_info[ch->pcdata->alignment].backstab_percent))/100; if(dt == gsn_circle) { if (dam > 300) dam = 260 + number_range(1,100); dam = dam*3/5; } } if (dt == gsn_impale) { int muu; if (dam < 5) dam = 5; muu = 2 + (LEVEL (ch) / 15); muu += is_member(ch, GUILD_BATTLEMASTER); dam += is_member(ch, GUILD_BATTLEMASTER); dam *= muu; dam /= 3; } if (dam <= 0) dam = 1; if (number_range (1, 5) == 1 && ch->move > 0) { SUBMOVE(ch,1); } ghit_pos = hit_pos; if (wield) { dam = dam * (UMIN(100,( 30+(((I_WEAPON*)wield->more)->damage_p))))/100; damage(ch, victim, dam, dt); } else { damage (ch, victim, dam, dt); } if (!consid) { if (FIGHTING (ch) == NULL || victim_is_dead) { check_fgt(ch); ch->fgt->fighting = NULL; NEW_POSITION(ch, POSITION_STANDING); return; } if (IS_PLAYER(ch) && number_range(1,30) == 3 && check_skill(ch, gsn_disarm)) { SINGLE_OBJECT *vwield; if (wield !=NULL && IS_OBJ_STAT(wield, ITEM_WHIP) && (((vwield=get_item_held(victim, ITEM_WEAPON)) != NULL) || ((vwield=get_item_held(victim, ITEM_GEM)) != NULL))) disarm (ch, victim); } if (wield !=NULL && (((I_WEAPON *) wield->more)->strength != 0) && (dam >= ((I_WEAPON *) wield->more)->strength)) if (number_range (1, 12) == 5) { --((I_WEAPON *) wield->more)->damage_p; if (((I_WEAPON *) wield->more)->damage_p == 1) { send_to_char ("--->ACK! Your weapon just broke!\n\r", ch); unequip_char (ch, wield); obj_from(wield); free_it (wield); wpn_broke = TRUE; } else if (number_range (1, 6) == 3) /*only display occasionally */ send_to_char ("Your weapon is damaged slightly by your attack!\n\r", ch); } ghit_pos = 0; if (dam >= 4 && number_range (1, 5) == 2 && (armor = get_eq_char (victim,(iWear = 1 << number_range(1, MAX_WEAR-1)), number_range(0,4))) != NULL && armor->pIndexData->item_type == ITEM_ARMOR && armor->wear_loc != WEAR_NONE && ((I_ARMOR *) armor->more)->max_condition) { int localle; char blah[500]; char *tmp; if (armor->pIndexData->short_descr[0] != '\0') { int slotnum; for (tmp = armor->pIndexData->short_descr; *tmp != '\0'; tmp++) { }; if (*(tmp - 1) == 's') sprintf (blah, "$p are damaged."); else sprintf (blah, "$p is damaged."); act (blah, victim, armor, NULL, TO_CHAR); localle = armor->wear_loc; slotnum = armor->wear_num; --((I_ARMOR *) armor->more)->condition_now; if (((I_ARMOR *) armor->more)->condition_now <= 0) { if (*tmp == 's') sprintf (blah, "The damage was so powerful, $p fall apart!"); else sprintf (blah, "The damage was so powerful, $p falls apart!"); act (blah, victim, armor, NULL, TO_CHAR); unequip_char (victim, armor); free_it (armor); return; } } if (IS_PLAYER(ch) && wield && IS_OBJ_STAT(wield, ITEM_CONCUSSION | ITEM_HEAVY_SLASH) && get_stat(ch, STR) > 28 && number_range(1,500) == 254 && check_skill(ch, gsn_destroy)) { SINGLE_OBJECT *obj; int objs_equipped = 0; int obj_destroyed = 0; for (obj = victim->carrying; (obj != NULL && obj->wear_loc != WEAR_NONE); obj = obj->next_content) objs_equipped++; if (objs_equipped > 0) { obj_destroyed = number_range(1, objs_equipped); } else return; objs_equipped = 0; for (obj = victim->carrying; (obj != NULL && obj->wear_loc != WEAR_NONE); obj = obj->next_content) { if (++objs_equipped == obj_destroyed) { act("$n's blow was so powerful, $N's $p was destroyed!", ch, obj, victim, TO_NOTVICT); act("$n's blow was so powerful, your $p was destroyed!", ch, obj, victim, TO_VICT); act("Your blow was so powerful, $N's $p was destroyed!", ch, obj, victim, TO_VICT); obj_from(obj); free_it(obj); break; } } } } } return; } bool can_trip (CHAR_DATA * ch) { if (number_range (1, 4) != 1) return FALSE; if (IS_PLAYER (ch)) return TRUE; if (ch->pIndexData->mobtype == MOB_HUMAN || ch->pIndexData->mobtype == MOB_DWARF || ch->pIndexData->mobtype == MOB_ELF || ch->pIndexData->mobtype == MOB_GIANT || ch->pIndexData->mobtype == MOB_DRAGON) return TRUE; return FALSE; } bool bashable (CHAR_DATA * ch) { if (IS_PLAYER (ch)) return TRUE; if (ch->pIndexData->mobtype == MOB_GHOST || IS_AFF(ch, ETHEREAL)) return FALSE; if (ch->pIndexData->mobtype == MOB_DRAGON) return FALSE; return TRUE; } int kickable (CHAR_DATA * ch) { if (IS_PLAYER (ch)) return 1; if (ch->pIndexData->mobtype == MOB_GHOST || IS_AFF(ch, ETHEREAL)) return 0; if (IS_AFF (ch, FLYING)) return 2; return 1; } bool pkill (CHAR_DATA * ch, CHAR_DATA * victim) { return TRUE; } /* * Inflict damage from a hit. */ void damage (CHAR_DATA * ch, CHAR_DATA * victim, int dam, int dt) { if (!ch || !victim) { return; } check_fgt (ch); check_fgt (victim); if (ch->in_room != victim->in_room) { if (dt > 300 && dt != gsn_shoot && dt != gsn_throw) { ch->fgt->fighting=NULL; victim->fgt->fighting=NULL; ch->position=POSITION_STANDING; victim->position=POSITION_STANDING; return; } else { if (IS_MOB(victim) && IS_SET(victim->act, ACT_SENTINEL)) { dam = 0; return; } } check_fgt (victim); if (!FIGHTING (victim)) { if (victim->fgt->hunting) free_string (victim->fgt->hunting); victim->fgt->hunting = str_dup (NAME (ch)); } } victim_is_dead = FALSE; if (victim->position == POSITION_DEAD) { ch->wait = 0; stop_fighting(ch,TRUE); return; } if (ch->in_room == victim->in_room) { add_to_fighting_list (ch); add_to_fighting_list (victim); if (!FIGHTING(ch)) set_fighting(ch,victim); if (!FIGHTING(victim)) set_fighting(victim,ch); if (FIGHTING (victim) == ch && FIGHTING (ch) != victim && !(victim->position == POSITION_GROUNDFIGHTING && ch->position == POSITION_GROUNDFIGHTING) && dt != gsn_kick && victim->position != POSITION_CASTING && victim->position != POSITION_BASHED && ch->position != POSITION_CASTING && ch->position != POSITION_BASHED) { NEW_POSITION(ch, POSITION_FIGHTING); NEW_POSITION(victim, POSITION_FIGHTING); if (ch!=victim || pow.can_fight_self) { ch->fgt->fighting = victim; } } if (ch->position == POSITION_GROUNDFIGHTING && victim->position != POSITION_GROUNDFIGHTING) { NEW_POSITION(ch, POSITION_FIGHTING); } update_pos (victim); } if (victim != ch) { if (is_safe (ch, victim)) { if (IS_MOB (ch)) return; act ("\x1B[1;37mYou hear a loud clash of thunder in the sky, sent forth by", ch, NULL, NULL, TO_CHAR); act ("the gods, and you decide not to attack.\x1B[0m", ch, NULL, NULL, TO_CHAR); act ("You hear massive clashes of thunder in the heavens above.", ch, NULL, NULL, TO_NOTVICT); return; } if(IS_PLAYER(ch)) { if (IS_MOB(victim) || !DIFF_ALIGN(ch, victim)) { if(ch->pcdata->no_quit_pk < MOB_QUIT_TIMER) ch->pcdata->no_quit_pk = MOB_QUIT_TIMER; } else { ch->pcdata->no_quit_pk = PK_QUIT_TIMER; victim->pcdata->no_quit_pk = PK_QUIT_TIMER; } } else { if (IS_PLAYER(victim) && victim->pcdata->no_quit_pk < MOB_QUIT_TIMER) victim->pcdata->no_quit_pk = MOB_QUIT_TIMER; } } { SINGLE_OBJECT *shield; int reduced; for (shield = victim->carrying; shield != NULL; shield = shield->next_content) { if(shield->pIndexData->item_type != ITEM_SHIELD) continue; if(worn_flags[shield->wear_loc].flagname != ITEM_FLOATING) break; reduced = UMIN(((I_SHIELD *)shield->more)->current_power, ((I_SHIELD *)shield->more)->max_power/7); reduced = UMIN(reduced, dam); dam -= reduced; ((I_SHIELD*)shield->more)->current_power -= reduced; if (dam <= 0) break; } } if (can_yell (victim) && victim->hit < 8 && victim->max_hit > 100 && ch->hit > 60 && dt > 300) { do_fatal (victim, ch, dt); } if (IS_PLAYER (ch) && dam > 2 && ch && victim && ch != victim) { int gn; gn = (dam * 3) + (LEVEL (victim) * 3) + ((LEVEL (ch) * LEVEL (ch)) / 8) + number_range (1, (LEVEL (victim) + LEVEL (ch))); gn/=7; if (IS_PLAYER(victim) && !DIFF_ALIGN(ch, victim)) gn = 0; gain_exp (ch, gn); ch->pcdata->voting_on += gn; } /* * More charm stuff. */ if (MASTER (victim) == ch) stop_follower (victim); if (IS_AFF (ch, HIDE)) { affect_strip (ch, gsn_hide); REMOVE_BIT (ch->aff[AFF], HIDE); act ("$n is revealed.", ch, NULL, NULL, TO_ROOM); } if (IS_AFF(ch, CHAMELEON)) { affect_strip (ch, gsn_chameleon); REMOVE_BIT (ch->aff[AFF], CHAMELEON); act ("$n comes back from the \x1b[1;32me\x1b[1;33mn\x1b[1;32mv\x1b[1;33mi\x1b[1;32mr\x1b[1;33mo\x1b[1;32mn\x1b[1;33mm\x1b[1;32me\x1b[1;33mn\x1b[1;32mt.", ch, NULL, NULL, TO_ROOM); } if (dt >= TYPE_HIT) { if ((IS_MOB (ch) && number_percent () < 20) && ch->move > 10) { if (can_trip (ch) && victim->position != POSITION_GROUNDFIGHTING && victim->position != POSITION_CASTING) { disarm (ch, victim); } } if ((IS_MOB (ch) && number_percent () < 8) && victim->position != POSITION_GROUNDFIGHTING && can_trip (ch) && victim->position != POSITION_CASTING && can_trip (victim) && victim->fgt->combat_delay_count < 0 && ch->move > 10) { if (number_range (0, 7) == 1) trip (ch, victim); else { act ("$n tries to trip you, but you quickly jump out of the way!", ch, NULL, victim, TO_VICT_SPAM); act ("You try to trip $N, but $N swiftly jumps out of the way!", ch, NULL, victim, TO_CHAR); act ("$n tries to trip $N, but $N swiftly jumps out of the way!", ch, NULL, victim, TO_NOTVICT_SPAM); } } if (dt > 999 && dt != gsn_circle && dt != gsn_backstab) { if (IS_AFF (victim, INVIS) && !IS_DET (ch, INVIS) && number_range (1, 14) == 3) { act ("You flail wildly around, trying to hit your invisible opponent...", ch, NULL, victim, TO_CHAR_SPAM); return; } } } dam_message (ch, victim, dam, dt, ghit_pos); SUBHIT(victim,dam); if (IS_PLAYER(victim) && victim->position == POSITION_CASTING) { if (!IS_AUGMENTED((victim), AUG_CONCENTRATION)) { if (dam > 4) { NEW_POSITION(victim, POSITION_FIGHTING); send_to_char ("OUCH! You just lost your concentration!\n\r", victim); victim->pcdata->tickcounts = 0; } } else { if (dt < 300) { if (dam > (10+LEVEL(victim)/2 + victim->pcdata->remort_times*5)) { NEW_POSITION(victim, POSITION_FIGHTING); send_to_char ("OUCH! You just lost your concentration!\n\r", victim); victim->pcdata->tickcounts = 0; } } else { if (dam > 5+LEVEL(victim)/12 + victim->pcdata->remort_times) { NEW_POSITION(victim, POSITION_FIGHTING); send_to_char ("OUCH! You just lost your concentration!\n\r", victim); victim->pcdata->tickcounts = 0; } } } } if (!IS_AWAKE (victim)) { stop_fighting (victim, FALSE); } if(ch->in_room == victim->in_room) { if (victim->position != POSITION_CASTING && victim->position != POSITION_BASHED && victim->position != POSITION_GROUNDFIGHTING && victim->position != POSITION_FIGHTING && victim->position != POSITION_CIRCLE && victim->position > POSITION_FIGHTING) { victim->position = POSITION_FIGHTING; if (FIGHTING(victim) == NULL) { check_fgt(victim); victim->fgt->fighting = ch; } } } if (has_killed (ch, victim, dt) || victim == ch) { victim_is_dead = TRUE; return; } if (dam > victim->max_hit / 5) send_to_char ("Ouch, that was *not* pleasant!\n\r", victim); if (victim->hit < victim->max_hit / 8) send_to_char ("You sure are BLEEDING!\n\r", victim); if (IS_PLAYER (victim) && victim->desc == NULL) { if (number_range (0, victim->wait) < 2) { do_flee (victim, ""); return; } } if (IS_MOB (victim) && dam > 0 && IS_SET (victim->act, ACT_WIMPY) && number_bits (1) == 0 && victim->hit < victim->max_hit / 6 && victim->hit > 2) { do_flee (victim, ""); return; } if (IS_PLAYER (victim) && dam > 0 && victim->hit < victim->pcdata->wimpy && victim->position != POSITION_BASHED && victim->position >= POSITION_SLEEPING && victim->hit > 0) { if (IS_HURT(victim, PARALYZE)) { send_to_char("You are DYING, but you CAN'T MOVE!!!\n\r", ch); return; } else do_flee (victim, ""); return; } return; } bool has_killed (CHAR_DATA *ch, CHAR_DATA *victim, int dt) { if (IS_PLAYER (victim) && LEVEL (victim) >= LEVEL_IMMORTAL && victim->hit < 1) { victim->hit = 1; return FALSE; } update_pos (victim); if (victim->position > POSITION_DEAD) { switch (victim->position) { case POSITION_MORTAL: act ("$n is mortally wounded, and will die soon if not aided.", victim, NULL, NULL, TO_ROOM); send_to_char ("You are mortally wounded, and will die soon if not aided.\n\r", victim); victim->wait = 10; break; case POSITION_INCAP: act ("$n is incapacitated and will suffer a slow, painful death if not aided.",victim, NULL, NULL, TO_ROOM); send_to_char ("You are incapacitated and will suffer a slow, painful death if not aided.\n\r",victim); victim->wait = 10; break; case POSITION_STUNNED: act ("$n is stunned, but will probably recover.", victim, NULL, NULL, TO_ROOM); send_to_char ("You are stunned, but will probably recover.\n\r", victim); victim->wait = 10; break; } return FALSE; } act ("$n has been killed!", victim, 0, 0, TO_ROOM); send_to_char ("You have been killed!\n\r\n\r", victim); victim->wait = 30; NEW_POSITION(ch, POSITION_STANDING); if (IS_PLAYER(victim)) { if (IN_BATTLE (victim)) { stop_fighting (victim, TRUE); NEW_POSITION(victim, POSITION_STANDING); NEW_POSITION(ch, POSITION_STANDING); MAXHIT(victim); victim->pcdata->no_quit_pk = 0; victim->pcdata->no_quit = 0; char_from_room (victim); char_to_room (victim, get_room_index (victim->pcdata->wasroom)); do_look (victim, ""); return TRUE; } if (CHALLENGE (victim) == ARENA_FIGHTING) { stop_fighting (victim, TRUE); NEW_POSITION(victim, POSITION_STANDING); NEW_POSITION(ch, POSITION_STANDING); ch->fgt->fighting = NULL; victim->fgt->fighting = NULL; MAXHIT(ch); MAXHIT(victim); victim->pcdata->no_quit_pk = 0; victim->pcdata->no_quit = 0; end_arena (ch, victim); return TRUE; } } group_gain (ch, victim); ch->wait = 0; if (IS_PLAYER (victim)) { int ii; char buf[STD_LENGTH]; victim->pcdata->deaths++; victim->pcdata->no_quit_pk = 0; reasonfd[0] = '\0'; if (strlen (NAME (ch)) < 30) strcpy (reasonfd, NAME (ch)); sprintf (log_buf, "%s killed by %s at %d", NAME (victim), NAME (ch), victim->in_room->vnum); log_string (log_buf); sprintf (log_buf, "%s just got killed by %s!", NAME (victim), NAME (ch)); ii = clan_number (victim); if (ii > 0) clan_notify (log_buf, ii); if (LEADER (victim) != NULL) group_notify (log_buf, victim); if (IS_PLAYER (ch)) { sprintf (log_buf, "%s just killed %s!", NAME (ch), NAME (victim)); ii = clan_number (ch); if (ii > 0) clan_notify (log_buf, ii); } sprintf (buf, "Ntfy> %s", log_buf); NOTIFY (buf, LEVEL_IMMORTAL, WIZ_NOTIFY_DEATH); if (IS_PLAYER (ch) && IS_PLAYER(victim) && DIFF_ALIGN(ch, victim)) { victim->pcdata->warpoints -= (1 + (LEVEL (victim) / 10)); if (victim->pcdata->warpoints < 0) victim->pcdata->warpoints = 0; } pc_death_penalty (ch, victim); } raw_kill (victim, (dt == 1003)); if (IS_PLAYER (ch) && IS_MOB (victim)) { int old_gold = 0; char buf[STD_LENGTH]; old_gold = tally_coins (ch); if (IS_SET (ch->pcdata->act2, PLR_AUTOLOOT)) do_get (ch, "all from corpse"); else if (IS_SET (ch->pcdata->act2, PLR_AUTOGOLD)) do_get (ch, "all.coins from corpse"); if (IS_SET (ch->pcdata->act2, PLR_AUTOSAC)) do_sacrifice (ch, "corpse"); if (IS_SET (ch->pcdata->act2, PLR_AUTOSPLIT) && tally_coins (ch) - old_gold > 1) { sprintf (buf, "%d", tally_coins (ch) - old_gold); do_split (ch, buf); } if (LEVEL (ch) < IMM_LEVEL) victim->pIndexData->area->lastkiller = ch->pcdata->online_spot; else victim->pIndexData->area->lastkiller = NULL; } ch->wait = 0; return TRUE; } bool is_safe (CHAR_DATA * ch, CHAR_DATA * victim) { CHAR_DATA *tch; if (!victim || !victim->in_room) return TRUE; if (ch->in_room && (ch->in_room->vnum < 110 && ch->in_room->vnum > 95)) return TRUE; for (tch = victim->in_room->people; tch != NULL; tch = tch->next_in_room) if (IS_PLAYER(tch) && LEVEL(tch) > IMM_LEVEL && IS_SET (tch->act, PLR_HOLYPEACE)) { if (FIGHTING (victim) != NULL) { victim->fgt->fighting = NULL; NEW_POSITION(victim, POSITION_STANDING); } if (FIGHTING (ch) != NULL) { ch->fgt->fighting = NULL; NEW_POSITION(ch, POSITION_STANDING); } send_to_char ("No fighting in the presence of Gods!\n\r", ch); return TRUE; } return FALSE; } void update_pos (CHAR_DATA * victim) { if (victim == NULL) return; if (victim->hit > 0) { if (victim->position <= POSITION_STUNNED && victim->position >= 0) { if (FIGHTING (victim) == NULL) NEW_POSITION(victim, POSITION_STANDING); } return; } if (IS_MOB (victim) || victim->hit <= -5) { NEW_POSITION(victim, POSITION_DEAD); return; } if (victim->hit <= -3) NEW_POSITION(victim, POSITION_MORTAL); else if (victim->hit <= -1) NEW_POSITION(victim, POSITION_INCAP); else NEW_POSITION(victim, POSITION_STUNNED); return; } /* * Start fights. */ void set_fighting (CHAR_DATA * ch, CHAR_DATA * victim) { check_fgt (ch); check_fgt (victim); if (ch == NULL || victim == NULL) { return; } if (ch==victim && !pow.can_fight_self) return; ch->fgt->fighting = victim; if (ch->position != POSITION_GROUNDFIGHTING && ch->position != POSITION_BASHED) NEW_POSITION(ch, POSITION_FIGHTING); add_to_fighting_list (ch); add_to_fighting_list (victim); if (IS_MOB (victim) && FIGHTING (victim) == NULL && (victim->society || victim->pIndexData->yeller_number) && number_range(1,3) == 2 && can_yell (victim)) { char buffr[500]; being_attacked_yell = TRUE; victim->fgt->fighting = ch; if (number_range (1, 2) == 1) sprintf (buffr, "Help! %s is attacking me!", NAME(ch)); else sprintf (buffr, "%s is trying to kill me! Send help!", NAME(ch)); do_yell (victim, buffr); being_attacked_yell = FALSE; } else if (FIGHTING(victim) == NULL) { victim->fgt->fighting = ch; } if (victim->position != POSITION_BASHED && victim->position != POSITION_GROUNDFIGHTING) NEW_POSITION(victim, POSITION_FIGHTING); return; } /* * Stop fights. */ void stop_fighting (CHAR_DATA * ch, bool fBoth) { CHAR_DATA *fch; CHAR_DATA *fch_next; if (FIGHTING(ch)==FIGHTING(FIGHTING(ch))) fBoth=TRUE; if (fBoth && FIGHTING (ch)) { NEW_POSITION(ch->fgt->fighting,POSITION_STANDING); if (FIGHTING (FIGHTING (ch))) { ch->fgt->fighting->fgt->fighting = NULL; } update_pos (FIGHTING (ch)); } for (fch = f_first; fch != NULL; fch = fch_next) { fch_next = fch->next_fighting; if (fch == ch || (fBoth && FIGHTING (fch) != NULL && FIGHTING (fch) == ch)) { fch->fgt->fighting = NULL; NEW_POSITION(fch, POSITION_STANDING); fch->fgt->combat_delay_count = -1; update_pos (fch); } } if (ch->fgt) { ch->fgt->fighting = NULL; } NEW_POSITION(ch, POSITION_STANDING); update_pos (ch); return; } bool IS_CORPSE_MOB (CHAR_DATA * ch) { if (IS_PLAYER (ch)) return TRUE; switch (ch->pIndexData->mobtype) { case MOB_GHOST: return FALSE; break; case MOB_STATUE: return FALSE; break; case MOB_PLANT: return FALSE; break; case MOB_FISH: return FALSE; break; } return TRUE; } void disarm (CHAR_DATA * ch, CHAR_DATA * victim) { int num = get_stat (ch, STR) - get_stat (victim, STR) + 3; SINGLE_OBJECT *obj; SINGLE_OBJECT *objc; if ((objc = get_item_held (ch, ITEM_WEAPON)) == NULL) return; if (((obj = get_item_held (victim, ITEM_WEAPON)) == NULL)) if (((obj = get_item_held (victim, ITEM_GEM)) == NULL)) return; if (ch->in_room && ch->in_room->vnum < 1000) return; if (IS_AUGMENTED(victim, AUG_HAND_STR)) num -= 5; if (IS_AUGMENTED(ch, AUG_HAND_STR)) num += 5; if (number_range(1,40) > num || number_range(1,6) != 3) { act ("$n tries to disarm you, but fails!", ch, NULL, victim,TO_VICT_SPAM + 1000); act ("You try to disarm $N, but fail!", ch, NULL, victim, TO_CHAR +1000); act ("$n tries to disarm $N, but fails!", ch, NULL, victim,TO_NOTVICT_SPAM + 1000); return; } if (IS_SET (obj->extra_flags, ITEM_NOREMOVE)) { act ("$B$n tries to disarm you, but fails!$R",ch, obj, victim, TO_VICT); act ("You try to disarm $N, but fail!",ch, obj, victim, TO_CHAR); return; } act ("$B$4$n disarms you and sends your $p flying!$R$7", ch,obj,victim,TO_VICT); act ("$B$4You have managed to disarm $N!$R$7", ch, NULL, victim, TO_CHAR); act ("$B$4$n disarms $N!$R$7", ch, NULL, victim, TO_NOTVICT); unequip_char (victim, obj); obj_from (obj); obj_to (obj, victim); return; } void do_bash (CHAR_DATA * ch, char *argy) { CHAR_DATA *victim; int chan = 0; bool notft = FALSE; int tmpi; char buf[STD_LENGTH]; DEFINE_COMMAND ("bash", do_bash, POSITION_FIGHTING, 0, LOG_NEVER, "This command allows you to bash an opponent to the ground.") check_fgt (ch); if (ch->wait > 2) return; ch->wait+= 5; if (ch->pcdata->learned[gsn_bash] < 10) { send_to_char("You don't know how to bash!\n\r", ch); WAIT_STATE(ch, 1*PULSE_VIOLENCE); return; } if (ch->fgt->ears > 9) { send_to_char ("You can't bash this soon again after giving or recieving a bash.\n\r", ch); WAIT_STATE(ch, 1*PULSE_VIOLENCE); return; } if (ch->in_room->sector_type == SECT_UNDERWATER) { send_to_char ("Bash someone underwater? I don't think so...\n\r", ch); return; } if ((FIGHTING (ch) == NULL || ch->position != POSITION_FIGHTING) && (argy == "" || argy[0] == '\0')) { send_to_char ("Bash whom?\n\r", ch); return; } if (FIGHTING (ch) == NULL) { notft = TRUE; if ((victim = get_char_room (ch, argy)) == NULL) { if (argy[0] == '\0') { send_to_char ("Bash who?\n\r", ch); return; } send_to_char ("They aren't here.\n\r", ch); return; } if (victim == ch) { send_to_char ("You really do look like an idiot!\n\r", ch); return; } } else victim = ch->fgt->fighting; if (RIDING (ch) != NULL) { send_to_char ("You can't bash someone when you are riding!\n\r", ch); return; } if (is_safe (ch, victim)) { return; } if (!(IS_IN_MELEE (ch, victim))) { send_to_char ("You aren't on the front lines of that battle!\n\r", ch); return; } if (FIGHTING(ch) == NULL && FIGHTING(victim) != NULL && !IS_IN_MELEE(ch, victim)) { send_to_char("You cannot get close enough to bash them!\n\r", ch); return; } if (!can_see (ch, victim)) { send_to_char ("How can you bash someone you can't see!?\n\r", ch); return; } if (ch->position == POSITION_GROUNDFIGHTING) { act ("You are wrestling on the ground! You can't bash $N!", ch, NULL, victim, TO_CHAR); return; } if (victim->position == POSITION_GROUNDFIGHTING) { send_to_char ("Your victim is groundfighting!\n\r", ch); WAIT_STATE(ch, 1*PULSE_VIOLENCE); return; } if (ch->position == POSITION_BASHED) { act ("You yourself are bashed.. how do you expect to bash $N?", ch, NULL, victim, TO_CHAR); return; } if (!bashable (victim)) { act ("You can't bash that kind of creature!", ch, NULL, victim, TO_CHAR); return; } check_fgt (victim); if (victim->fgt->combat_delay_count < -2) { act ("$N is alert from $S last bash to the ground. You nearly fall over!", ch, NULL, victim, TO_CHAR); WAIT_STATE (ch, 1 * PULSE_VIOLENCE); return; } if (victim->position == POSITION_BASHED || victim->fgt->ears > 2) { act ("$N has already been bashed to the ground!", ch, NULL, victim, TO_CHAR); WAIT_STATE(ch, 2*PULSE_VIOLENCE); return; } if (number_range (1, 11) == 3 && IS_AWAKE (victim) && IS_AFF (victim, FLYING) && !IS_AFF (ch, FLYING)) { /*basher is not flying, victim is */ act ("$N quickly flies out of the way of $n's bash!", ch, NULL, victim, TO_NOTVICT + 1000); act ("$N quickly flies out of the way of your bash!", ch, NULL, victim, TO_CHAR + 1000); act ("You quickly fly out of the way of $n's bash!", ch, NULL, victim, TO_VICT + 1000); WAIT_STATE (ch, 2 * PULSE_VIOLENCE); return; } check_char_fight_init (ch, victim); if (IS_HURT(ch, FEAR) && number_range(1,5) != 3) { send_to_char("You are too afraid to attack!\n\r", ch); WAIT_STATE(ch, PULSE_VIOLENCE); return; } if (IS_MOB (victim)) tmpi = 10; else tmpi = (15 + get_stat (victim, DEX) +(victim->pcdata->learned[gsn_dodge] / 5)); if (IS_MOB (ch)) chan = (LEVEL (ch) * 2); else chan = ((check_skill(ch, gsn_bash) * ch->pcdata->learned[gsn_bash]) + (get_stat (ch, STR) * 3)) -tmpi; if (IS_PLAYER (ch) && ch->pcdata->learned[gsn_bash] < 5) chan = 5; if (IS_AUGMENTED(victim, AUG_FOOT_SPD)) chan -= 10; if (IS_AUGMENTED(victim, AUG_LEG_SPD)) chan -= 10; if (IS_AUGMENTED(ch, AUG_BODY_STR)) chan += 10; if (IS_AUGMENTED(ch, AUG_LEG_STR)) chan += 10; if (IS_AUGMENTED(ch, AUG_ARM_STR)) chan += 10; if (IS_PLAYER(victim)) { chan -= (check_skill(victim, gsn_steadiness) *victim->pcdata->learned[gsn_steadiness]/3); } if (chan < 5) chan = 5; if (chan > 155) chan = number_range (150, 160); if (number_range (0, 215) > chan && IS_AWAKE (victim)) { act ("You miss the bash and almost fall on the ground!", ch, NULL, victim, TO_CHAR + 1000); act ("$n tries to bash you, but almost falls over instead!", ch, NULL, victim, TO_VICT + 1000); act ("$n misses a bash at $N and almost falls over!", ch, NULL, victim, TO_NOTVICT + 1000); if (notft) { WAIT_STATE (ch, (double) 4 * PULSE_VIOLENCE); } else WAIT_STATE (ch, (double) 3 * PULSE_VIOLENCE); if (FIGHTING (victim) == NULL) set_fighting (victim, ch); set_fighting (ch, victim); return; } if (RIDING (victim) != NULL) { sprintf (buf, "$B$2Your powerful bash sends $N flying off of %s!$R$7", PERS (RIDING (victim), ch)); act (buf, ch, NULL, victim, TO_CHAR); sprintf (buf, "$B$2$n's bash sends $N flying off of %s!$R$7", NAME (RIDING (victim))); act (buf, ch, NULL, victim, TO_NOTVICT); sprintf (buf, "$B$2You fly off of %s as $n bashes you!$R$7", PERS (RIDING (victim), victim)); act (buf, ch, NULL, victim, TO_VICT); check_fgt (victim->fgt->riding); victim->fgt->riding->fgt->mounted_by = NULL; victim->fgt->riding = NULL; } else if (RIDING (victim) == NULL) { if (number_range (1, 18) != 4 || !can_groundfight (victim) || LEVEL (victim) < 12 || !can_groundfight (ch) || LEVEL (ch) < 12 || !pow.bash_slip_to_tackle) { char buf[400]; act ("$B$2Your powerful bash sends $N sprawling onto the ground!$R$7", ch, NULL, victim, TO_CHAR + 1000); act ("$B$2$n sends $N sprawling backwards on to the ground with a powerful bash!$R$7", ch, NULL, victim, TO_NOTVICT + 1000); act ("$B$2$n sends you sprawling backwards on to the ground with a powerful bash!$R$7", ch, NULL, victim, TO_VICT + 1000); if (CHALLENGE (ch) == ARENA_FIGHTING && number_range(1,3) == 2) { sprintf (buf, "($B$1Arena$N$7) $B%s just sent %s flying with a bash!", NAME (ch), NAME (victim)); do_arenaecho (ch, buf, TRUE); } } else { char buf[500]; int i; act ("$B$5You bash $N, but trip and stumble! You are now groundfighting!$R$7", ch, NULL, victim, TO_CHAR); act ("$B$5$n bashes $N, but trips and falls! They begin fighting on the ground!$R$7", ch, NULL, victim, TO_NOTVICT); act ("$B$5$n bashes you, but trips and looses his balance and falls on top of you. You begin to ground-fight!!$R$7", ch, NULL, victim, TO_VICT); if (CHALLENGE (ch) == ARENA_FIGHTING && number_range(1,3) == 2) { i = number_range (1, 3); if (i == 1) sprintf (buf, "($B$1Arena$N$7) $B%s tries to bash %s but they both fall to the\n\r($B$1Arena$N$7) $Bground in a bloody tangle of elbows and teeth...", NAME (ch), NAME (victim)); if (i == 2) sprintf (buf, "($B$1Arena$N$7) $B%s falls on his face, trying to bash %s.\n\r($B$1Arena$N$7) $BThey both fall over and begin clawing at each other!", NAME (ch), NAME (victim)); if (i == 3) sprintf (buf, "($B$1Arena$N$7) $B%s tries to bash %s, but %s catches %s\n\r($B$1Arena$N$7) $Bwith an elbow and they both fall to the ground in a bloody mess!", NAME (ch), NAME (victim), NAME (victim), NAME (ch)); do_arenaecho (ch, buf, TRUE); } set_fighting (ch, victim); victim->fgt->fighting = ch; NEW_POSITION(victim, POSITION_GROUNDFIGHTING); NEW_POSITION(ch, POSITION_GROUNDFIGHTING); return; } } { SPELL_DATA *s; if ((s = skill_lookup (NULL, gsn_bash)) == NULL) { fprintf (stderr, "Bash not found!\n"); return; } victim->fgt->combat_delay_count = 4; if (victim->position != POSITION_FIGHTING) victim->fgt->fighting = ch; victim->position = POSITION_BASHED; set_fighting (ch, victim); if (check_skill(ch, gsn_smash)) { victim->fgt->ears = 11 + (s->casting_time); ch->fgt->ears = 9 + (s->casting_time * 2); } else { victim->fgt->ears = 10 + (s->casting_time); ch->fgt->ears = 10 + (s->casting_time *2); } if((IS_MOB(ch) && number_range(1,10) == 4) || check_skill(ch, gsn_smash)) { int damm = (number_range(1, LEVEL(ch)))*2/3; damage (ch, victim, damm, gsn_smash); } } return; } void trip (CHAR_DATA * ch, CHAR_DATA * victim) { if (ch->in_room->sector_type == SECT_UNDERWATER) { return; } if (RIDING (victim) != NULL) return; if ( IS_AFF (victim, FLYING) || IS_IMMORTAL (ch)) { act ("$n tries to trip you, but you float over it!", ch, NULL, victim, TO_VICT_SPAM); act ("You try to trip $N, but $N floats over it!", ch, NULL, victim, TO_CHAR); act ("$n tries to trip $N, but $N floats over it!", ch, NULL, victim, TO_NOTVICT_SPAM); return; } act ("$B$n trips you and you go down!$R", ch, NULL, victim, TO_VICT); act ("You trip $N and $E goes down!", ch, NULL, victim, TO_CHAR); act ("$n trips $N!", ch, NULL, victim, TO_NOTVICT); victim->fgt->combat_delay_count = UMAX (1, dice (1, 5 - get_stat (victim, DEX) / 6)); WAIT_STATE (ch, PULSE_VIOLENCE); WAIT_STATE (victim, PULSE_VIOLENCE); return; } void do_kill (CHAR_DATA * ch, char *argy) { char arg[SML_LENGTH]; CHAR_DATA *victim; CHAR_DATA *fch, *fch_next; DEFINE_COMMAND ("kill", do_kill, POSITION_FIGHTING, 0, LOG_NORMAL, "This command allows you to start combat or switch targets during combat.") check_fgt (ch); one_argy (argy, arg); if (ch->fgt->ears > 9) { send_to_char ("You are suffering from the ever-popular bash lag (tm), and therefore\n\rcannot attack another mob/player or use the kill command.\n\r", ch); return; } if (ch->wait > 2) return; if (arg[0] == '\0') { send_to_char ("Syntax: Kill <thing/person to kill>\n\r", ch); return; } if ((victim = get_char_room (ch, arg)) == NULL) { send_to_char ("Who or what is that?\n\r", ch); WAIT_STATE(ch, 1*PULSE_VIOLENCE); return; } if (victim == ch) { send_to_char ("You hit yourself.. moron!\n\r", ch); WAIT_STATE(ch, 10*PULSE_VIOLENCE); return; } if (!can_see (ch, victim)) { send_to_char ("Who or what is that?\n\r", ch); return; } if (is_safe (ch, victim)) { return; } check_char_fight_init (ch, victim); if (IS_HURT(ch, FEAR) && number_range(1,5) != 3) { send_to_char("You are too afraid to attack!\n\r", ch); WAIT_STATE(ch, PULSE_VIOLENCE); return; } if (IS_MOB (ch) && ch->pIndexData->spec &&ch->pIndexData->spec->tactics) { if (check_tactics (ch, victim)) return; } if (victim->position == POSITION_GROUNDFIGHTING) { set_fighting (ch, victim); return; } if (IS_HURT (ch, CHARM) && MASTER (ch) == victim) { act ("$N is your master!", ch, NULL, victim, TO_CHAR); return; } if (IS_MOB(victim)) for (fch = ch->in_room->people; fch != NULL; fch = fch_next) { fch_next = fch->next_in_room; if (IS_MOB (fch) && fch->pIndexData->guard && victim->pIndexData->vnum == fch->pIndexData->guard->guarding_mob) { do_say (fch, "You'll have to get by me first!"); multi_hit (fch, ch, TYPE_UNDEFINED); return; } } if (FIGHTING (ch) && victim == FIGHTING (ch)) { act ("You're already fighting $N!", ch, NULL, victim, TO_CHAR); return; } check_fgt (victim); if (ch->position == POSITION_FIGHTING && FIGHTING (ch) != victim) { if (!IS_AWAKE(victim)) { multi_hit (ch, victim, TYPE_UNDEFINED); return; } act ("Your new target is $N!", ch, NULL, victim, TO_CHAR); act ("$n turns and targets $N!", ch, NULL, victim, TO_ROOM); WAIT_STATE (ch, PULSE_VIOLENCE); set_fighting(ch,victim); } if ((IS_PLAYER (victim)) && IS_HURT (ch, CHARM)) { return; } if (ch->fgt->combat_delay_count >= 0) { ch->fgt->combat_delay_count = -1; } if (victim->fgt->combat_delay_count >= 0) { victim->fgt->combat_delay_count = -1; } WAIT_STATE (ch, 1 * PULSE_VIOLENCE); if (IS_MOB (ch) && IS_SET (ch->pIndexData->act4, ACT4_KILLGLADIATOR)) { do_say (ch, "You are not permitted to leave!!"); } set_fighting (ch, victim); if (victim->position != POSITION_FIGHTING && victim->position != POSITION_GROUNDFIGHTING && victim->position != POSITION_BASHED) victim->fgt->fighting = ch; multi_hit (ch, victim, TYPE_UNDEFINED); return; } void do_flurry (CHAR_DATA * ch, char *argy) { char arg[SML_LENGTH]; CHAR_DATA *victim; DEFINE_COMMAND ("flurry", do_flurry, POSITION_FIGHTING, 0, LOG_NORMAL, "This command allows you to flail around madly in a wild flurry. Anyone can do this (it uses moves).") if (!FIGHTING (ch)) { send_to_char ("You must be fighting to flurry.\n\r", ch); return; } one_argy (argy, arg); check_fgt(ch); if (ch->fgt->ears > 9) { send_to_char ("You can't flurry this soon after giving or recieving a bash.\n\r", ch); return; } if (ch->position == POSITION_GROUNDFIGHTING) { send_to_char ("You can't Flurry while groundfighting!\n\r", ch); return; } if (ch->position == POSITION_BASHED) { send_to_char ("You can't flurry when you have been bashed!\n\r", ch); return; } if (FIGHTING (ch) == NULL) { send_to_char ("You can't begin a fight with a flurry; you must be already fighting!\n\r", ch); return; } if (ch->move < pow.flurry_mps) { send_to_char ("You are too exhausted to flurry.\n\r", ch); return; } victim = ch->fgt->fighting; check_char_fight_init (ch, victim); if (IS_HURT(ch, FEAR) && number_range(1,5) != 3) { send_to_char("You are too afraid to attack!\n\r", ch); WAIT_STATE(ch, PULSE_VIOLENCE); return; } SUBMOVE(ch,pow.flurry_mps); WAIT_STATE (ch, 3 * PULSE_VIOLENCE); act ("You open up a wild flurry of multiple attacks!", ch, NULL, victim, TO_CHAR + 1000); act ("$n opens up in a wild flurry of multiple attacks!", ch, NULL, victim, TO_ROOM + 1000); multi_hit (ch, victim, TYPE_UNDEFINED); if (check_skill(ch, gsn_flurry) && (victim = FIGHTING(ch)) != NULL) multi_hit (ch, victim, TYPE_UNDEFINED); return; } void do_flash (CHAR_DATA * ch, char *argy) { char arg[SML_LENGTH]; CHAR_DATA *victim; I_TOOL *pow; char *argg; SINGLE_OBJECT *powder; DEFINE_COMMAND ("flash", do_flash, POSITION_FIGHTING, 0, LOG_NORMAL,"This command allows a thief to flash behind someone and circle them.") if (!FIGHTING (ch)) { send_to_char ("You must be fighting to flash.\n\r", ch); return; } argg = str_dup (argy); one_argy (argg, arg); if ((victim = FIGHTING(ch)) == NULL) { send_to_char("You must be fighting someone to flash behind them!\n\r", ch); return; } if (ch->fgt->ears > 9) { send_to_char ("You can't flash this soon after giving or recieving a bash.\n\r", ch); return; } if (ch->position == POSITION_GROUNDFIGHTING) { send_to_char ("You can't flash while groundfighting!\n\r", ch); return; } if (ch->position == POSITION_BASHED) { send_to_char ("You can't flash when you have been bashed!\n\r", ch); return; } if (FIGHTING (ch) == NULL) { send_to_char ("You can't begin a fight with a flash; you must be already fighting!\n\r", ch); return; } powder = get_item_held(ch, ITEM_TOOL); if (powder == NULL) { send_to_char("You must be holding flash powder to do this!\n\r",ch); return; } check_char_fight_init (ch, victim); if (IS_HURT(ch, FEAR) && number_range(1,5) != 3) { send_to_char("You are too afraid to attack!\n\r", ch); WAIT_STATE(ch, PULSE_VIOLENCE); return; } SUBMOVE(ch, 20); pow = (I_TOOL *) powder->more; if (use_tool (powder, TOOL_FLASH_POWDER)) { if (!check_skill(ch, gsn_flash)) { act ("You disappear in a bright $B$6FLASH$R$7, but reappear in the same spot.", ch, NULL, victim, TO_CHAR); act ("$n disappears in a bright $B$6FLASH$R$7, but reappears in the same spot.", ch, NULL, victim, TO_VICT); act ("$n disappears in a bright $B$6FLASH$R$7, but reappears in the same spot.", ch, NULL, victim, TO_NOTVICT); WAIT_STATE(ch, 1*PULSE_VIOLENCE); return; } else { act ("You disappear in a bright $B$6FLASH$R$7, and reappear right behind $N!", ch, NULL, victim, TO_CHAR); act ("$n disappears in a bright $B$6FLASH$R$7, and reappears behind YOU!", ch, NULL, victim, TO_VICT); act ("$n disappears in a bright $B$6FLASH$R$7, and reappears behind $N!", ch, NULL, victim, TO_NOTVICT); used_flash = TRUE; actually_doing = TRUE; do_circle(ch, argy); used_flash = FALSE; actually_doing = FALSE; WAIT_STATE(ch, 2*PULSE_VIOLENCE); return; } } else { send_to_char("You need flash powder to do this.\n\r", ch); return; } return; } void do_bs (CHAR_DATA * ch, char *argy) { DEFINE_COMMAND ("bs", do_bs, POSITION_STANDING, 0, LOG_NORMAL, "See backstab.") do_backstab (ch, argy); return; } void do_backstab (CHAR_DATA * ch, char *argy) { char arg[SML_LENGTH]; CHAR_DATA *victim; SINGLE_OBJECT *obj; int dt, i; SPELL_DATA *spl; DEFINE_COMMAND ("backstab", do_backstab, POSITION_STANDING, 0, LOG_NORMAL, "This command allows you to sneak behind an opponent and place a piercing weapon in his/her/its back.") if ((spl = skill_lookup ("Backstab", -1)) == NULL) { send_to_char ("Huh?\n\r", ch); return; } one_argy (argy, arg); if (arg[0] == '\0') { send_to_char ("Backstab whom?\n\r", ch); return; } if ((victim = get_char_room (ch, arg)) == NULL) { send_to_char ("They aren't here.\n\r", ch); return; } if (victim == ch) { send_to_char ("How can you sneak up on yourself?\n\r", ch); return; } if (is_safe (ch, victim)) { return; } if ((obj = get_item_held (ch, ITEM_WEAPON)) == NULL) { send_to_char ("You need to wield a weapon.\n\r", ch); return; } dt = ((I_WEAPON *) obj->more)->attack_type; if (attack_table[dt].hit_type != TYPE_PIERCE || !IS_OBJ_STAT(obj, ITEM_PIERCE)) { send_to_char ("You need to wield a piercing weapon as your primary weapon.\n\r", ch); return; } if (FIGHTING (victim) != NULL) { send_to_char ("You can't backstab a person who is already *fighting*.\n\r", ch); return; } if (IS_MOB (victim) && victim->pIndexData->guard && victim->pIndexData->guard->guarding_door != 0) { send_to_char ("But you can't get behind the mob to backstab; it's guarding an exit.\n\r", ch); return; } if (!actually_doing && IS_AWAKE (victim) && IS_PLAYER (ch)) { if (ch->pcdata->learned[gsn_backstab] < 3) { send_to_char ("You don't know how to backstab!\n\r", ch); return; } send_to_char ("You begin to stealthily move behind your target...\n\r", ch); if (IS_PLAYER (ch)) ch->pcdata->tickcounts = spl->mana; if (strlen (argy) > 140) return; check_temp (ch); strcpy (ch->pcdata->temp->temp_string, argy); NEW_POSITION(ch, POSITION_BACKSTAB); return; } if (IS_AFF (victim, FLYING) && !IS_AFF (ch, FLYING)) { /*victim is flying, char is not */ if (number_range (1, 4) > 1) { act ("You manage to jump up high enough to get your dagger to $S back...", ch, NULL, victim, TO_CHAR); } else { act ("You can't reach $N because $E is flying too high...", ch, NULL, victim, TO_CHAR); return; } } check_char_fight_init (ch, victim); if (IS_HURT(ch, FEAR) && number_range(1,5) != 3) { send_to_char("You are too afraid to attack!\n\r", ch); WAIT_STATE(ch, PULSE_VIOLENCE); return; } for (i = 0; i < MAX_HOLD; i++) { if (ch->hold[i] && ch->hold[i]->pIndexData->item_type == ITEM_WEAPON && IS_OBJ_STAT(ch->hold[i], ITEM_PIERCE) && attack_table[((I_WEAPON *)ch->hold[i]->more)->attack_type].hit_type == TYPE_PIERCE && (i == 0 || FIGHTING(ch) == victim) && (IS_MOB(ch) || !IS_AWAKE(victim) || (i % 2 == 0 ? (check_skill(ch, gsn_backstab)) : (number_range(1,4) == 3 && check_skill(ch, gsn_double_backstab))))) { if (IS_PLAYER(victim) && number_range(1,12) == 3 && check_skill(victim, gsn_awareness)) { act("$n just tried to stab you!", ch, NULL, victim, TO_VICT); act("You try to stab $N, but $E notices.", ch, NULL, victim, TO_CHAR); } else { one_hit(ch, victim, gsn_backstab, ch->hold[i]); if (victim_is_dead) return; } } } if (IS_PLAYER (ch)) ch->pcdata->tickcounts = spl->casting_time; return; } void do_flee (CHAR_DATA * ch, char *argy) { ROOM_DATA *room_one; ROOM_DATA *room_two; EXIT_DATA *pexit; int i; CHAR_DATA *victim; CHAR_DATA *fch; char buf[STD_LENGTH]; int attempt; bool double_flee = TRUE; bool door_open[6]; int num_open = 0; int num_chose = 0; int door = 0; DEFINE_COMMAND ("flee", do_flee, POSITION_GROUNDFIGHTING, 0, LOG_NORMAL, "This command allows you to flee from combat.") check_fgt (ch); if (!ch || !ch->in_room) return; if ((ch->in_room->vnum < 108 && ch->in_room->vnum > 97)|| ch->position <= POSITION_STUNNED) return; if (ch->fgt->ears > 9) { send_to_char ("You are too off balance from your last combat action to flee!\n\r", ch); return; } if (IS_PLAYER (ch) && ch->pcdata->tickcounts > 1) { send_to_char ("You fail to find a pause in combat in which to flee!\n\r", ch); return; } if (ch->wait > 1) { send_to_char ("You are too off-balance and cannot flee.\n\r", ch); return; } if (ch->position == POSITION_BASHED) { send_to_char ("You try to crawl away, but you are bashed to the ground!\n\rBetter stand up first...\n\r", ch); return; } if (ch->position == POSITION_GROUNDFIGHTING) { send_to_char ("You attempt to stand up...\n\r", ch); do_stand (ch, ""); return; } if((victim = FIGHTING(ch)) != NULL) { if (!victim->in_room || victim->in_room != ch->in_room) { ch->fgt->fighting = NULL; ch->position = POSITION_STANDING; if (victim->fgt) for (i = 0; i < 4; i++) if (victim->fgt->attackers[i] == ch) victim->fgt->attackers[i] = NULL; for (fch = ch->in_room->people; fch != NULL; fch = fch->next_in_room) { if (fch->fgt && fch->fgt->fighting == ch) { ch->fgt->fighting = fch; ch->position = POSITION_FIGHTING; break; } } if (ch->fgt->fighting == NULL) { send_to_char ("You don't have to flee if you aren't fighting!\n\r", ch); return; } } } else { bool attacked = FALSE; if (ch->position == POSITION_BASHED) { NEW_POSITION(ch, POSITION_STANDING); update_pos (ch); return; } for (fch = ch->in_room->people; fch != NULL; fch = fch->next_in_room) { if (fch->fgt && fch->fgt->fighting == ch) { attacked = TRUE; ch->fgt->fighting = fch; victim = fch; break; } } if (!attacked) { NEW_POSITION(ch, POSITION_STANDING); update_pos (ch); WAIT_STATE(ch, 3); send_to_char ("You don't have to flee if you're not fighting.\n\r", ch); return; } } if ((number_range (1, 100) < (pow.flee_chance - (IS_AUGMENTED(ch,AUG_FOOT_SPD) ? 5 : 0) - (IS_AUGMENTED(ch, AUG_LEG_SPD) ? 5 : 0) ))) { WAIT_STATE(ch, 5); send_to_char("You couldn't manage to flee from combat!\n\r",ch); return; } if (IS_MOB (ch)) { if (number_range (1, 2) == 2) { act ("$n tries to escape, but can't get away!", ch, NULL, ch, TO_ROOM); return; } if (victim->position == POSITION_DEAD) { stop_fighting (victim, TRUE); ch->wait = 0; return; } if (ch->position == POSITION_FIGHTING) NEW_POSITION(ch, POSITION_STANDING); } if (IS_PLAYER (ch) && rchars_in_group (ch) > 1) double_flee = FALSE; room_one = ch->in_room; num_open = 0; for (attempt = 0; attempt < 6; attempt++) { door_open[attempt] = FALSE; if ((pexit = room_one->exit[attempt]) != NULL && (ROOM_DATA *) pexit->to_room != NULL && (ROOM_DATA *) pexit->to_room != room_one && ((ROOM_DATA *) pexit->to_room)->sector_type != SECT_WATER_NOSWIM && (!pexit->d_info || !IS_SET (pexit->d_info->exit_info, EX_CLOSED))) { door_open[attempt] = TRUE; num_open++; } } if (num_open == 0) { act ("$N won't let you get away!", ch, NULL, FIGHTING (ch), TO_CHAR); return; } if (num_open >= 2) num_chose = number_range(1,num_open); else num_chose = 1; door = 0; for(i = 0; i < 6; i ++) { if (door_open[i] == TRUE) { door++; if (num_chose == door) { door = i; break; } } } if((pexit = ch->in_room->exit[door]) != NULL && pexit->to_room != NULL) room_two = (ROOM_DATA *) pexit->to_room; if (RIDING (ch) != NULL) { send_to_char ("You fall from your mount as you try to escape!\n\r", ch); check_fgt (ch->fgt->riding); ch->fgt->riding->fgt->mounted_by = NULL; ch->fgt->riding = NULL; } if (MOUNTED_BY (ch) != NULL) { send_to_char ("Your rider falls off as you try to escape!\n\r", ch); send_to_char ("Your mount bolts from under you!\n\r", MOUNTED_BY (ch)); check_fgt (ch->fgt->mounted_by); ch->fgt->mounted_by->fgt->riding = NULL; ch->fgt->mounted_by = NULL; } if(move_char (ch, door + 20)) { sprintf (buf, "\x1B[1;32m$N flees %s in panic!\x1B[0m\n\r", dir_name[door]); for (fch = room_one->people; fch != NULL; fch = fch->next_in_room) { if (fch->fgt) { if (fch->fgt->fighting == ch) { fch->fgt->fighting = NULL; fch->position = POSITION_STANDING; } for (i = 0; i < 4; i++) if (fch->fgt->attackers[i] == ch) fch->fgt->attackers[i] = NULL; } if (fch->next_in_room == NULL) { act(buf, fch, NULL, ch, TO_ROOM); act (buf, fch, NULL, ch, TO_CHAR); } } NEW_POSITION (ch, POSITION_STANDING); if(double_flee && IS_PLAYER(ch)) { room_two = ch->in_room; num_open = 0; door = 0; num_chose = 0; for (attempt = 0; attempt < 6; attempt++) { door_open[attempt] = FALSE; if ((pexit = room_two->exit[attempt]) != NULL && (ROOM_DATA *) pexit->to_room != NULL && (ROOM_DATA *) pexit->to_room != room_one && (ROOM_DATA *) pexit->to_room != room_two && ((ROOM_DATA *) pexit->to_room)->sector_type != SECT_WATER_NOSWIM && (!pexit->d_info || !IS_SET (pexit->d_info->exit_info, EX_CLOSED))) { door_open[attempt] = TRUE; num_open++; } } if (num_open > 0) { num_chose = number_range(1,num_open); for(i = 0; i < 6; i ++) { if (door_open[i]) { door++; if (num_chose == door) { door = i; break; } } } if (move_char (ch, door)) { for (fch = room_two->people; fch != NULL; fch = fch->next_in_room) { if (fch->fgt && fch->fgt->fighting == ch) { fch->fgt->fighting = NULL; fch->position = POSITION_STANDING; } if (fch->next_in_room == NULL) act(buf, fch, NULL, ch, TO_ROOM); } } } } if (IS_PLAYER (ch)) { send_to_char ("Run away! You flee head over heels!\n\r", ch); WAIT_STATE(ch, PULSE_VIOLENCE); gain_exp (ch, -10); } ch->position = POSITION_STANDING; if (ch->fgt) { ch->fgt->fighting = NULL; ch->fgt->combat_delay_count = -1; } return; } else { WAIT_STATE(ch, PULSE_VIOLENCE); act ("$N won't let you get away!", ch, NULL, FIGHTING (ch),TO_CHAR); return; } } void do_guard (CHAR_DATA * ch, char *argy) { char arg1[STD_LENGTH]; CHAR_DATA *victim; int i; DEFINE_COMMAND ("guard", do_guard, POSITION_FIGHTING, 0, LOG_NORMAL, "This command allows you to guard someone.") if (IS_MOB(ch)) return; argy = one_argy(argy, arg1); if (FIGHTING(ch) != NULL || ch->position != POSITION_STANDING) { send_to_char("You must be standing to guard someone!\n\r", ch); return; } if(arg1[0] == '\0' || arg1 == "") { send_to_char("Guard <name>\n\r", ch); return; } if ((victim = get_char_room(ch, arg1)) == NULL) { send_to_char("Guard <name>\n\r", ch); return; } if (IS_MOB(victim)) { send_to_char("You may only guard other players.\n\r", ch); return; } if (DIFF_ALIGN(ch,victim)) { send_to_char("You may not guard people of the opposite alignment.\n\r", ch); return; } if (ch->pcdata->learned[gsn_guard] < 50) { send_to_char("You are not experienced enough at guarding to attempt this!\n\r", ch); return; } if (victim->pcdata->guarding != NULL) { send_to_char("You cannot guard someone who is already guarding someone else.\n\r", ch); return; } for (i = 0; i < 4; i++) { if (ch->pcdata->guarded_by[i] != NULL) { send_to_char("You cannot guard someone if you are already being guarded.\n\r", ch); return; } } if(ch->pcdata->guarding != NULL) { send_to_char("You are already guarding someone else. Type Unguard first.\n\r", ch); return; } for (i = 0; i < 4; i ++) { if (victim->pcdata->guarded_by[i] == NULL) { ch->pcdata->guarding = victim; victim->pcdata->guarded_by[i] = ch; act("You are now guarding $N.", ch, NULL, victim, TO_CHAR); act("$n are now guarding you.", ch, NULL, victim, TO_VICT); act("$n is now guarding $N.", ch, NULL, victim, TO_NOTVICT); return; } } send_to_char("That person already has too many people guarding them.\n\r", ch); return; } void do_unguard (CHAR_DATA *ch, char *argy) { CHAR_DATA *victim; int i; DEFINE_COMMAND ("unguard", do_unguard, POSITION_FIGHTING, 0, LOG_NORMAL, "This command allows you to stop guarding someone.") if(IS_MOB(ch)) return; if(ch->pcdata->guarding == NULL) { send_to_char("You are not guarding anyone.\n\r", ch); return; } if (FIGHTING(ch) != NULL || ch->position != POSITION_STANDING) { send_to_char("You must be standing to unguard someone.\n\r", ch); return; } victim = (CHAR_DATA *) ch->pcdata->guarding; ch->pcdata->guarding = NULL; if (IS_MOB(victim)) return; for (i = 0; i < 4; i++) { if (victim->pcdata->guarded_by[i] == ch) { victim->pcdata->guarded_by[i] = NULL; act("You stop guarding $N.", ch, NULL, victim, TO_CHAR); act("$n stops guarding you.", ch, NULL, victim, TO_VICT); act("$n stops guarding $N.", ch, NULL, victim, TO_NOTVICT); return; } } return; } void do_rescue (CHAR_DATA * ch, char *argy) { char arg[SML_LENGTH]; CHAR_DATA *victim; CHAR_DATA *rch; int temp; int temp2; bool being_hit = FALSE; DEFINE_COMMAND ("rescue", do_rescue, POSITION_FIGHTING, 0, LOG_NORMAL, "This command allows you to rescue someone getting whacked. Success is based on your rescue skill.") one_argy (argy, arg); if (arg[0] == '\0') { send_to_char ("Who is that?\n\r", ch); return; } if ((victim = get_char_room (ch, arg)) == NULL) { send_to_char ("Who is that?\n\r", ch); return; } if (DIFF_ALIGN(ch, victim)) { send_to_char ("Why would you want to do that?\n\r", ch); return; } if (ch->position != POSITION_STANDING && ch->position != POSITION_FIGHTING) { send_to_char ("You must be fighting or standing to rescue someone.\n\r", ch); return; } if (victim == ch) { send_to_char ("You rescue yourself. That did a lot of good.\n\r", ch); return; } if (IS_PLAYER (ch) && IS_MOB (victim)) { send_to_char ("That person doesn't want your help!\n\r", ch); return; } if (FIGHTING (ch) == victim) { send_to_char ("You rescue yourself. That was useful.\n\r", ch); return; } for (rch = victim->in_room->people; rch != NULL; rch = rch->next_in_room) { if (FIGHTING (rch) == victim) { being_hit = TRUE; break; } } if (!being_hit) { send_to_char ("That person is not being hit right now.\n\r", ch); return; } if (victim->position != POSITION_FIGHTING) { send_to_char ("That person isn't in a normal fighting position.\n\r", ch); return; } if (rch->position != POSITION_FIGHTING) { send_to_char ("That person's opponent is not in a normal fighting position!\n\r", ch); return; } if (victim->position == POSITION_GROUNDFIGHTING) { send_to_char ("That person is groundfighting! You can't rescue!\n\r", ch); return; } if (victim->position == POSITION_GROUNDFIGHTING) { if (ch->position == POSITION_GROUNDFIGHTING) { send_to_char ("You are groundfighting! You can't rescue!\n\r", ch); return; } set_fighting (ch, FIGHTING (victim)); return; } WAIT_STATE (ch, 15); if (IS_PLAYER (ch) && !check_skill(ch, gsn_rescue)) { send_to_char ("You attempt the rescue but fail.\n\r", ch); return; } act ("You rescue $N!", ch, NULL, victim, TO_CHAR); act ("$n rescues you!", ch, NULL, victim, TO_VICT); act ("$n rescues $N!", ch, NULL, victim, TO_NOTVICT); check_fgt (rch); check_fgt (ch); check_fgt (victim); temp = victim->fgt->combat_delay_count; temp2 = rch->fgt->combat_delay_count; if (IS_PLAYER (ch)) { stop_fighting (rch, FALSE); stop_fighting (victim, FALSE); } { int jj = 0; for (jj = 0; jj < 4; jj++) if (rch->fgt->attackers[jj] == victim) rch->fgt->attackers[jj] = NULL; } check_fgt (rch); check_fgt (victim); check_char_fight_init (ch, rch); set_fighting (ch, rch); set_fighting (rch, ch); check_fgt (rch); check_fgt (victim); victim->fgt->combat_delay_count = temp; rch->fgt->combat_delay_count = temp2; WAIT_STATE (ch, 22); victim->fgt->combat_delay_count = temp; rch->fgt->combat_delay_count = temp2; return; } void do_kick (CHAR_DATA * ch, char *argy) { CHAR_DATA *victim; int ii, i, j; bool notft = FALSE; int dl = 0; char buf[500]; int damm; int num_times; DEFINE_COMMAND ("kick", do_kick, POSITION_FIGHTING, 0, LOG_NORMAL, "This command allows you to kick an opponent. Success is based on kicking skill, power is based on level.") check_fgt (ch); num_times = (IS_MOB(ch) ? 1 : race_info[ch->pcdata->race].parts[0]); if (num_times < 1) return; if (ch->wait > 2) return; if (ch->fgt->ears > 9) { send_to_char ("You can't kick this soon after a bash.\n\r", ch); return; } if (FIGHTING (ch) == NULL) { notft = TRUE; if (argy[0] == '\0' || argy == "") { send_to_char ("Who?\n\r", ch); return; } if ((victim = get_char_room (ch, argy)) == NULL) { send_to_char ("Who?\n\r", ch); return; } if (victim == ch) { send_to_char ("You kick yourself in the butt, but it doesn't hurt that much.\n\r", ch); return; } } else victim = ch->fgt->fighting; if (is_safe (ch, victim)) { return; } check_char_fight_init (ch, victim); if (IS_HURT(ch, FEAR) && number_range(1,5) != 3) { send_to_char("You are too afraid to attack!\n\r", ch); WAIT_STATE(ch, PULSE_VIOLENCE); return; } if (!(IS_IN_MELEE (ch, victim))) { send_to_char ("You aren't on the front lines of that battle!\n\r", ch); return; } if (ch->position == POSITION_BASHED) { send_to_char ("You try to kick, but from the ground you can't hit your opponent.\n\r", ch); return; } if (ch->position == POSITION_GROUNDFIGHTING) { send_to_char ("You can't kick when you are locked into mortal combat on the ground!\n\r", ch); return; } if (kickable (victim) == 0) { act ("You can't kick that type of creature!", ch, NULL, victim, TO_CHAR); return; } dl = 27; if (notft) dl = (PULSE_VIOLENCE); WAIT_STATE (ch, dl); if (kickable (victim) == 2) { act ("You try to kick $N, but $E flies out of the way!", ch, NULL, victim, TO_CHAR); return; } set_fighting (ch, victim); i = 0; for (j = 0; j < num_times; j++) { i++; if (number_range(1,5) == 2 && check_skill(ch, gsn_double_kick)) i++; } for (; i > 0; i--) { if (check_skill(ch, gsn_kick)) { if ((number_range(1,13) == 3) && (check_skill(victim, gsn_block) || (check_skill(victim, gsn_steadiness) && number_range(1,3) == 2))) { if (number_range(1,3) == 2) { act("$N blocks $s's kick and twists away.", ch, NULL,victim, TO_NOTVICT); act ("$N blocks your kick and twists away.", ch,NULL,victim, TO_CHAR); act ("You block $n's kick and twist away.", ch, NULL,victim, TO_VICT); } else if (number_range (1,2) == 2) { act("$N swiftly blocks $s's kick causing a momentary stumble.", ch, NULL,victim, TO_NOTVICT); act ("$N swiftly blocks your kick and causes you to stumble momentarily.", ch,NULL,victim, TO_CHAR); act ("You switftly block $n's kick and cause a momentary stumble.", ch, NULL,victim, TO_VICT); } else { act("$N blocks $s's foot with $S forearm.", ch, NULL,victim, TO_NOTVICT); act ("$N blocks your kick with $S forearm.", ch,NULL,victim, TO_CHAR); act ("You block $n's kick with your forearm.", ch, NULL,victim, TO_VICT); } continue; } damm = translate (damt.kick_dam, LEVEL (ch), ch); if (IS_AUGMENTED(ch, AUG_LEG_STR)) damm += number_range(1,3); if (IS_AUGMENTED(ch, AUG_FOOT_STR)) damm += number_range(1,4); damm += is_member(ch, GUILD_WARRIOR); if (ch->in_room != victim->in_room ) return; if (CHALLENGE (ch) == ARENA_FIGHTING && number_range(1,3) == 2) { i = number_range (1, 3); if (i == 1) sprintf (buf, "($B$1Arena$N$7) $B%s kicks %s in the ribs... snap crackle pop!", NAME (ch), NAME (victim)); if (i == 2) sprintf (buf, "($B$1Arena$N$7) $B%s kicks %s's knee; that's gotta hurt!", NAME (ch), NAME (victim)); if (i == 3) sprintf (buf, "($B$1Arena$N$7) $B%s's kick catches %s in the side of the head!", NAME (ch), NAME (victim)); do_arenaecho (ch, buf, TRUE); } if (can_yell (victim)) { if (damm < 5) { act ("\x1B[1;35mYour weak kick barely bruises $N's shin.\x1B[37;0m", ch, NULL, victim, TO_CHAR); act ("\x1B[1;37m$n's weak kick barely bruises $N's shin.\x1B[0m", ch, NULL, victim, TO_NOTVICT); act ("\x1B[1;36m$n's weak kick bruises your shin.\x1B[37;0m", ch, NULL, victim, TO_VICT); } else { ii = number_range (1, 5); if (ii == 1) { act ("\x1B[1;35mYour kick slams into $N's shin!\x1B[37;0m", ch, NULL, victim, TO_CHAR); act ("\x1B[1;37m$n's kick slams into $N's shin.\x1B[0m", ch, NULL, victim, TO_NOTVICT); act ("\x1B[1;36m$n's kick slams into your shin!\x1B[37;0m", ch, NULL, victim, TO_VICT); } else if (ii == 2) { act ("\x1B[1;35mYour kick smashes into $N's solar plexus!\x1B[37;0m", ch, NULL, victim, TO_CHAR); act ("\x1B[1;37m$n kicks $N directly in the solar plexus!\x1B[0m", ch, NULL, victim, TO_NOTVICT); act ("\x1B[1;36m$n kicks you in the solar plexus! Ouch!\x1B[37;0m", ch, NULL, victim, TO_VICT); } else if (ii == 3) { act ("\x1B[1;35mYour kick smashes into $N's knee!\x1B[37;0m", ch, NULL, victim, TO_CHAR); act ("\x1B[1;37m$n kicks $N's knee very hard!\x1B[0m", ch, NULL, victim, TO_NOTVICT); act ("\x1B[1;36m$n kicks your knee, and you nearly fall over...\x1B[37;0m", ch, NULL, victim, TO_VICT); } else if (ii == 4) { act ("\x1B[1;35mYou lift your leg high, and kick $N in the head!!\x1B[37;0m", ch, NULL, victim, TO_CHAR); act ("\x1B[1;37m$n kicks $N's right in the face! Ouch...\x1B[0m", ch, NULL, victim, TO_NOTVICT); act ("\x1B[1;36m$n kicks you in the face!\x1B[37;0m", ch, NULL, victim, TO_VICT); act ("\x1B[1;31mBlood spurts from $N's nose!\x1B[37;0m", ch, NULL, victim, TO_CHAR); act ("\x1B[1;31mBlood spurts from $N's nose!\x1B[37;0m", ch, NULL, victim, TO_NOTVICT); act ("\x1B[1;31mBlood pours forth from your injured nose!\x1B[37;0m", ch, NULL, victim, TO_VICT); } else if (ii == 5) { act ("\x1B[1;35mYour kick connects with $N's ribs!\x1B[37;0m", ch, NULL, victim, TO_CHAR); act ("\x1B[1;37m$n kicks $N in the ribs!\x1B[0m", ch, NULL, victim, TO_NOTVICT); act ("\x1B[1;36m$n kicks you in the ribs!! Ouch!\x1B[37;0m", ch, NULL, victim, TO_VICT); } } } else { act ("\x1B[1;35mWham! Your kick slams into $N!\x1B[37;0m", ch, NULL, victim, TO_CHAR); act ("\x1B[1;37m$n's kick slams into $N!\x1B[37;0m", ch, NULL, victim, TO_NOTVICT); act ("\x1B[1;37m$n's kick slams into you hard!\x1B[37;0m", ch, NULL, victim, TO_VICT); } damage (ch, victim, damm, gsn_kick); } else { set_fighting (ch, victim); if (FIGHTING (victim) == NULL) victim->fgt->fighting = ch; act ("You miss a kick at $N.", ch, NULL, victim, TO_CHAR + 1000); act ("$n misses a kick at $N.", ch, NULL, victim, TO_NOTVICT + 1000); act ("$n tries to kick you but misses.", ch, NULL, victim, TO_VICT + 1000); } } return; } void do_flail (CHAR_DATA * ch, char *argy) { CHAR_DATA *victim; int i; DEFINE_COMMAND ("flail", do_flail, POSITION_FIGHTING, 0, LOG_NORMAL,"You flail around hitting people as much as possible. This can only be used when you are afraid of dying, it is a last-ditch attempt to kill your opponent.") check_fgt(ch); if (FIGHTING(ch) == NULL) { send_to_char("You cannot flail unless you are fighting.\n\r", ch); return; } if (ch->fgt->ears > 9) { send_to_char ("You can't flail this soon after a bash.\n\r", ch); return; } if (ch->position != POSITION_FIGHTING) { send_to_char("You are not in the proper position to do this!\n\r",ch); WAIT_STATE(ch, 1*PULSE_VIOLENCE); SUBMOVE(ch, 20); return; } if (ch->move < 50) { send_to_char("You are too weak to flail!\n\r", ch); return; } if (ch->hit > ch->max_hit/2 && LEVEL(ch) < IMM_LEVEL) { send_to_char("You are not frantic enough to be able to use this skill! Try again when you are closer to DYING!\n\r", ch); WAIT_STATE(ch, 2*PULSE_VIOLENCE); return; } if (!check_skill(ch, gsn_flail)) { send_to_char("You try to flail around, and just end up falling on your butt!\n\r", ch); NEW_POSITION(ch, POSITION_BASHED); ch->fgt->ears = 11; return; } send_to_char("You flail around in a frenzy of death!\n\r", ch); SUBMOVE(ch, LEVEL(ch)); victim = FIGHTING(ch); for (i = 0; (i < 4 && ((victim = FIGHTING(ch)) != NULL)); i++) multi_hit(ch, victim, TYPE_UNDEFINED); WAIT_STATE(ch, 5*PULSE_VIOLENCE); return; } void do_impale (CHAR_DATA * ch, char *argy) { CHAR_DATA *victim; int i; DEFINE_COMMAND ("impale", do_impale, POSITION_FIGHTING, 0, LOG_NORMAL,"This command lets you impale an opponent with a polearm.") check_fgt (ch); if (ch->wait > 2) return; WAIT_STATE (ch, PULSE_VIOLENCE); if (ch->fgt->ears > 9) { send_to_char ("You can't impale someone this soon after a bash.\n\r", ch); return; } if (FIGHTING (ch) == NULL) { if (argy[0] == '\0' || argy == "") { send_to_char ("Who?\n\r", ch); WAIT_STATE(ch, 1*PULSE_VIOLENCE); return; } if ((victim = get_char_room (ch, argy)) == NULL) { send_to_char ("Who?\n\r", ch); WAIT_STATE(ch, PULSE_VIOLENCE); return; } } else victim = ch->fgt->fighting; if (victim == ch) { send_to_char("No.\n\r", ch); WAIT_STATE(ch, 30*PULSE_VIOLENCE); return; } if (ch->position == POSITION_BASHED) { send_to_char ("You try to impale your opponent, but just can't seem to get up.\n\r", ch); WAIT_STATE(ch, PULSE_VIOLENCE); return; } if (ch->position == POSITION_GROUNDFIGHTING) { send_to_char ("You can't impale someone while you are groundfighting!\n\r", ch); WAIT_STATE(ch, PULSE_VIOLENCE); return; } if (IS_HURT(ch, FEAR) && number_range(1,5) != 3) { send_to_char("You are too afraid to attack!\n\r", ch); WAIT_STATE(ch, PULSE_VIOLENCE); return; } for (i = 0; i < MAX_HOLD; i++) { if (ch->hold[i] && ch->hold[i]->pIndexData->item_type == ITEM_WEAPON && IS_OBJ_STAT(ch->hold[i], ITEM_POLEARM) && (check_skill(ch, gsn_impale))) { act("$R$7You lunge toward $N with $p.$R$7", ch, ch->hold[i], victim,TO_CHAR); act("$R$7$n lunges toward you with $s $p.$R$7", ch, ch->hold[i], victim,TO_VICT); act("$R$7$n lunges toward $N with $s $p.$R$7", ch, ch->hold[i],victim,TO_NOTVICT); one_hit (ch, victim, gsn_impale, ch->hold[i]); if (!FIGHTING(ch)) return; if (number_range(1,10) == 1 && !IS_OBJ_STAT(ch->hold[i], ITEM_POWER)) { if (((I_WEAPON *)ch->hold[i]->more)->damage_p > 10) ((I_WEAPON *)ch->hold[i]->more)->damage_p -= 5; else { send_to_char ("Your polearm just snapped under the stress.n\r",ch); unequip_char (ch, ch->hold[i]); obj_from(ch->hold[i]); free_it(ch->hold[i]); } } } } check_char_fight_init (ch, victim); WAIT_STATE(ch, 3* PULSE_VIOLENCE); return; } void do_disarm (CHAR_DATA * ch, char *argy) { CHAR_DATA *victim; SINGLE_OBJECT *obj; DEFINE_COMMAND ("disarm", do_disarm, POSITION_FIGHTING, 0, LOG_NORMAL, "This command allows you to disarm an opponent. Success is based on the disarm skill.") if (CHALLENGE (ch) == ARENA_FIGHTING) { send_to_char ("You cannot disarm in the arena.\n\r", ch); return; } if (ch->wait > 2) { send_to_char ("You are too off balance to disarm right now.\n\r", ch); return; } if (IS_PLAYER (ch) && ch->pcdata->tickcounts > 3) { send_to_char ("You are too off balance to disarm right now.\n\r", ch); return; } if (IN_BATTLE (ch) == TRUE) { send_to_char ("You cannot disarm while in the battleground.\n\r", ch); return; } if (get_item_held (ch, ITEM_WEAPON) == NULL) { send_to_char ("You must wield a weapon to disarm.\n\r", ch); return; } if ((victim = FIGHTING (ch)) == NULL) { send_to_char ("You aren't fighting anybody or anything.\n\r", ch); return; } if ((obj = get_item_held (victim, ITEM_WEAPON)) == NULL && (obj = get_item_held (victim, ITEM_GEM)) == NULL) { send_to_char ("Your opponent is not wielding an item.\n\r", ch); return; } WAIT_STATE(ch, 3*PULSE_VIOLENCE); if (number_range(1,3) > 1 && check_skill(ch, gsn_disarm)) disarm (ch, victim); else send_to_char ("You tried to disarm your opponent, but failed.\n\r",ch); return; } void do_sla (CHAR_DATA * ch, char *argy) { DEFINE_COMMAND ("sla", do_sla, POSITION_DEAD, MAX_LEVEL, LOG_NORMAL, "This is so you don't try to slap someone and slay em instead!") send_to_char ("Slay? Slam? Sleep? What do you mean?\n\r", ch); return; } void do_slay (CHAR_DATA * ch, char *argy) { CHAR_DATA *victim; char arg[SML_LENGTH]; DEFINE_COMMAND ("slay", do_slay, POSITION_DEAD, MAX_LEVEL, LOG_ALWAYS, "This command slays a mob or player.") if (IS_MOB (ch)) return; one_argy (argy, arg); if (arg[0] == '\0') { send_to_char ("Who is that?\n\r", ch); return; } if ((victim = get_char_room (ch, arg)) == NULL) { send_to_char ("Who is that?\n\r", ch); return; } if (ch == victim) { send_to_char ("You aren't allowed to slay yourself. Go see a psychiatrist.\n\r", ch); return; } if (IS_PLAYER (victim) && LEVEL (ch) < MAX_LEVEL) { send_to_char ("You shouldn't be slaying other players.\n\r", ch); return; } act ("You grab $S head and you squeeze hard... until $N's skull explodes into a bloody mess!", ch, NULL, victim, TO_CHAR); act ("$n grabs your head and squeezes hard... until your eyes pop out! Everything goes dark...", ch, NULL, victim, TO_VICT); act ("$n grabs ahold of $N's head and squeezes hard. Pretty soon $N's entire head and skull are just bloody pieces of flesh-and-brain-chunks on the ground.", ch, NULL, victim, TO_NOTVICT); raw_kill (victim, FALSE); return; } bool hit_suck_disarm (CHAR_DATA * ch, CHAR_DATA * victim, int hit, int dam) { SINGLE_OBJECT *obj; if (number_range (1, 100) >= LEVEL (ch) && (obj = get_item_held (victim, ITEM_WEAPON)) != NULL && hand_empty (ch) != WEAR_NONE) { unequip_char (victim, obj); obj->wear_loc = hand_empty (ch); obj_from (obj); obj_to (obj, ch); act ("Your weapon sucks $N's weapon right out of $S hand!", ch, NULL, victim, TO_CHAR); act ("$n's weapon sucks your weapon right out of your hand!", ch, NULL, victim, TO_VICT); act ("$n's magical weapon sucks $N's weapon right out of $S hand!", ch, NULL, victim, TO_NOTVICT); return TRUE; } return FALSE; } bool check_skill (CHAR_DATA * ch, int gsn) { char buf[SML_LENGTH]; SPELL_DATA *spell; if (IS_MOB (ch)) { if (number_percent() < UMIN (90, LEVEL(ch))) return TRUE; else return FALSE; } /* You must have at least 15 pct learned in the skill. You must have a spell that is a real spell. You must get a number_percent which is no greater than your pct learned. */ if (ch->pcdata->learned[gsn] < 30 || (spell = skill_lookup (NULL, gsn)) == NULL || number_percent() > ch->pcdata->learned[gsn]) return FALSE; if (!ch->in_room || ch->in_room->vnum < 1000 || ch->pcdata->learned[gsn] >= 100 || consid /* || IS_SET(ch->in_room->area->area_flags, AREA_HOMELAND) */) return TRUE; /* gsn 500-549 are the gsn's that are checked EACH combat hit. Therefore they have a MUCH smaller chance of actually getting raised. The other things are checked very rarely and as such can just be gotten more often. Also, if you are in pkill, you have an 8x as good chance of getting an improve. */ if ((gsn >499 && gsn < 549 && number_range(1,30) != 14) || (ch->pcdata->no_quit_pk < (PK_QUIT_TIMER - 1) && number_range(1,8) != 3)) return TRUE; /* After all that, we now have a chance to improve. The chance is taking a random number from 1-10000 and seeing if its less than learned * (100-learned). Yes, this is a logistic map. Yes it is easy to get improves in the middle, but it's hard a heck to get improves at the high or low ends. */ if (number_range(1,10000) < ((100- ch->pcdata->learned[gsn])*ch->pcdata->learned[gsn])) return TRUE; sprintf (buf, "\x1B[1;37m**** [You have become better at %s!] ****\x1B[0m\n\r", spell->spell_name); send_to_char (buf, ch); ch->pcdata->learned[gsn]++; return TRUE; } void disengage (CHAR_DATA * ch, char *argy) { DEFINE_COMMAND ("disengage", disengage, POSITION_FIGHTING, 0, LOG_NORMAL, "Allows you to disengage from battle if someone is not directly hitting you.") if (FIGHTING (ch) == NULL) { send_to_char ("You aren't fighting anything or anyone!\n\r", ch); return; } if (ch->fgt && ch->fgt->fighting && ch->fgt->fighting->fgt && ch->fgt->fighting->fgt->fighting == ch) { send_to_char ("Your opponent is attacking YOU! You can't disengage!\n\r", ch); return; } if (ch->fgt) { ch->fgt->fighting = NULL; } ch->position = POSITION_STANDING; WAIT_STATE (ch, 4 * PULSE_VIOLENCE); return; } void do_load (CHAR_DATA *ch, char *argy) { SINGLE_OBJECT *bow; SINGLE_OBJECT *arrow; SINGLE_OBJECT *obj; SINGLE_OBJECT *siege; char arg1[SML_LENGTH]; char arg2[SML_LENGTH]; int i; DEFINE_COMMAND ("load", do_load, POSITION_FIGHTING, 0, LOG_NORMAL, "Allows you to load a missile weapon.") if (IS_MOB(ch)) return; argy = one_argy (argy, arg1); argy = one_argy (argy, arg2); if (FIGHTING(ch) != NULL) { send_to_char("You cannot load a weapon while engaged in mortal combat!\n\r", ch); return; } if (ch->position != POSITION_STANDING) { send_to_char("You cannot load a weapon unless you are standing.\n\r", ch); return; } if ((arrow = get_obj_inv (ch, arg1)) != NULL) { if (arrow->pIndexData->item_type != ITEM_AMMO) { send_to_char ("That isnt ammo.\n\r", ch); return; } if (arg2[0] != '\0') { if ((siege = get_obj_here (ch, arg2, SEARCH_ROOM_FIRST)) == NULL) { send_to_char ("You don't see that here to load.\n\r", ch); return; } else if (siege->in_room) { if (siege->pIndexData->item_type != ITEM_SIEGE) { send_to_char ("That is not a siege weapon.\n\r", ch); return; } if (((I_SIEGE *)siege->more)->type != SIEGE_CATAPULT && ((I_SIEGE *)siege->more)->type != SIEGE_BALLISTA) { send_to_char ("This kind of siege engine does not take ammo!\n\r", ch); return; } if (siege->contains) { send_to_char ("That is already loaded and ready to go.\n\r", ch); return; } if (((I_SIEGE *)siege->more)->ammo_type != ((I_AMMO *)arrow->more)->ammo_type) { send_to_char ("That is the wrong kind of siege engine for that ammo.\n\r", ch); return; } obj_from (arrow); obj_to (arrow, siege); act ("$n loads $p into $P.", ch, arrow, siege, TO_ROOM); act ("You load $p into $P.", ch, arrow, siege, TO_CHAR); return; } } for (i = 0; i < MAX_HOLD; i++) { if ((bow = ch->hold[i]) != NULL && bow->pIndexData->item_type == ITEM_MISSILE && bow->contains == NULL && ((I_AMMO *)arrow->more)->ammo_type == ((I_MISSILE*)bow->more)->ammo_type) { act ("You load $p into $P", ch, arrow, bow, TO_CHAR); act ("$n loads $p into $P", ch, arrow, bow, TO_ROOM); obj_from (arrow); obj_to (arrow, bow); return; } } send_to_char ("You can't seem to load that anywhere.\n\r", ch); return; } for (i = 0; i < MAX_HOLD; i++) { if ((bow = ch->hold[i]) != NULL && bow->pIndexData->item_type == ITEM_MISSILE) { if (bow->contains != NULL) { send_to_char("Your weapon is already loaded.\n\r", ch); continue; } arrow = NULL; for(obj = ch->carrying; obj != NULL; obj = obj->next_content) { if (obj->pIndexData->item_type == ITEM_AMMO && (((I_AMMO *)obj->more)->ammo_type == ((I_MISSILE *)bow->more)->ammo_type)) { arrow = obj; break; } } if (arrow == NULL) { send_to_char("You don't have any missiles of the proper type to load into your weapon.\n\r", ch); continue; } obj_from(arrow); obj_to(arrow, bow); act ("You load $p into $P", ch, arrow, bow, TO_CHAR); act ("$n loads $p into $P", ch, arrow, bow, TO_ROOM); WAIT_STATE (ch, PULSE_VIOLENCE); } return; } send_to_char ("Syntax: for missile weapons, load, or load <ammo>. For siege engines, load <ammo> <siege engine>.\n\r", ch); return; } bool check_tactics (CHAR_DATA *ch, CHAR_DATA *victim) { int i, choice, num, flag; int total_tactics = 0; if (!victim || number_range(1,2) != 2 || IS_PLAYER (ch) || !ch->pIndexData->spec) return FALSE; for (i = 0; tactics_flags[i].flagname > 0; i++) { if (IS_SET (ch->pIndexData->spec->tactics, tactics_flags[i].flagname)) total_tactics++; } if (total_tactics < 1) return FALSE; num = 0; choice = number_range (1, total_tactics); for (i = 0; tactics_flags[i].flagname > 0; i++) { if (IS_SET (ch->pIndexData->spec->tactics, tactics_flags[i].flagname)) num++; if (num == choice) { flag = tactics_flags[i].flagname; break; } } actually_doing = TRUE; if (flag == TACTICS_BACKSTAB) do_backstab (ch, NAME (victim)); else if (flag == TACTICS_CIRCLE) do_circle (ch, "noarg"); else if (flag == TACTICS_KICK) do_kick (ch, NAME(victim)); else if (flag == TACTICS_BASH) do_bash (ch, NAME (victim)); else if (flag == TACTICS_TACKLE) do_tackle (ch, NAME(victim)); else if (flag == TACTICS_FLAIL) do_flail (ch, NAME(victim)); else if (flag == TACTICS_FLURRY) do_flurry (ch, NAME(victim)); else if (flag == TACTICS_DISARM) do_disarm (ch, NAME (victim)); else if (flag == TACTICS_HEAL) { do_cast (ch, "heal"); } else if (flag == TACTICS_BASHCAST) { SPELL_DATA *spl; int i; do_bash (ch, NAME (victim)); for (i = 0; i < 4; i++) { if (ch->pIndexData->spec->cast_spells[i] != 0 && (spl = skill_lookup (NULL,ch->pIndexData->spec->cast_spells[i])) != NULL && spl->spell_type == TAR_CHAR_OFFENSIVE) { if (number_percent () < ch->pIndexData->spec->area_percent) area_spell = TRUE; else area_spell = FALSE; general_spell (spl, LEVEL (ch), ch, victim); break; } } } actually_doing = FALSE; return TRUE; } void do_unload (CHAR_DATA *ch, char *argy) { SINGLE_OBJECT *bow; SINGLE_OBJECT *arrow; DEFINE_COMMAND ("unload", do_unload, POSITION_FIGHTING, 0, LOG_NORMAL, "Allows you to unload a missile weapon.") if (IS_MOB(ch)) return; if (FIGHTING(ch) != NULL) { send_to_char("You cannot unload a weapon while engaged in mortal combat!\n\r", ch); return; } if (ch->position != POSITION_STANDING) { send_to_char("You cannot unload a weapon unless you are standing.\n\r", ch); return; } if ((bow = get_obj_here (ch, argy, SEARCH_ROOM_FIRST)) == NULL) { send_to_char ("You must specify a weapon held or a siege engine in the room to unload.\n\r", ch); return; } if ((arrow = bow->contains) == NULL) { if (bow->pIndexData->item_type == ITEM_SIEGE) send_to_char ("That siege engine is not loaded.\n\r", ch); else send_to_char("That missile weapon is not loaded.\n\r", ch); return; } else { obj_from(arrow); obj_to(arrow, ch); send_to_char("You unload your weapon.\n\r", ch); return; } return; } void do_shoot (CHAR_DATA *ch, char *argy) { SINGLE_OBJECT *bow; SINGLE_OBJECT *arrow; CHAR_DATA *victim; int range = 0; int dam = 0; int to_hit; int mult; int i, j; DEFINE_COMMAND ("shoot", do_shoot, POSITION_FIGHTING, 0, LOG_NORMAL, "Allows you to shoot a loadded missile weapon.") check_fgt (ch); if (!actually_doing && IS_MOB(ch)) return; if (ch->fgt->ears > 9) { send_to_char ("You can't shoot this soon after a bash.\n\r", ch); return; } if ((bow = get_item_held(ch, ITEM_MISSILE)) == NULL) { send_to_char("You must be holding a ranged weapon to shoot it.\n\r", ch); return; } if ((arrow = bow->contains) == NULL) { send_to_char("Your missile weapon is not loaded.\n\r", ch); return; } if (arrow->pIndexData->item_type != ITEM_AMMO) { send_to_char("Your bow was loaded with something other than ammunition.\n\r", ch); obj_from(arrow); free_it(arrow); return; } if (((I_AMMO *)arrow->more)->shots_left < 1) { obj_from(arrow); free_it(arrow); send_to_char("Your missile weapon is not loaded.\n\r", ch); return; } if (((I_AMMO *) arrow->more)->ammo_type != ((I_MISSILE *) bow->more)->ammo_type) { obj_from(arrow); free_it(arrow); send_to_char( "The missile weapon had the wrong kind of ammo.\n\r", ch); return; } range = ((I_MISSILE *)bow->more)->range; if ((victim = get_char_room_near (ch, ch->in_room, range, argy)) == NULL) { send_to_char("You don't see that person here to shoot.\n\r", ch); return; } if (!actually_doing) { if (FIGHTING(ch) != NULL) { send_to_char("You cannot shoot a weapon while engaged in mortal combat!\n\r", ch); return; } if (ch->position != POSITION_STANDING) { send_to_char("You cannot shoot a weapon unless you are standing.\n\r", ch); return; } check_temp(ch); strcpy(ch->pcdata->temp->temp_string, argy); ch->pcdata->tickcounts = 5 + ((I_MISSILE *)bow->more)->aiming_time; NEW_POSITION(ch, POSITION_SHOOTING); return; } if (ch->position != POSITION_SHOOTING) { send_to_char("You cannot shoot a weapon unless you are in a shooting position.\n\r", ch); return; } for (i = 0; i < MAX_HOLD; i++) { if ((bow = ch->hold[i]) != NULL && bow->pIndexData->item_type == ITEM_MISSILE && (arrow = bow->contains) != NULL) { if (arrow->pIndexData->item_type != ITEM_AMMO) { send_to_char("Your missile weapon was loaded with something other than ammunition.\n\r", ch); obj_from(arrow); free_it(arrow); continue; } if (((I_AMMO *)arrow->more)->shots_left < 1) { obj_from(arrow); free_it(arrow); send_to_char("Your missile weapon is not loaded.\n\r", ch); continue; } if (((I_AMMO *) arrow->more)->ammo_type != ((I_MISSILE *) bow->more)->ammo_type) { obj_from(arrow); free_it(arrow); send_to_char( "The missile weapon had the wrong kind of ammo.\n\r", ch); continue; } range = ((I_MISSILE *)bow->more)->range; if ((victim = get_char_room_near (ch, ch->in_room, range, argy)) == NULL) { send_to_char("You don't see that person here to shoot.\n\r", ch); WAIT_STATE(ch, PULSE_VIOLENCE); return; } to_hit = GET_HITROLL(ch); check_char_fight_init (ch, victim); for (j = 0; j < (UMAX(1, ((I_MISSILE *)bow->more)->shots_per_use)) && ((arrow = bow->contains) != NULL); j++) { if (!check_skill(ch, gsn_shoot)) { act ("You shoot your $p at $N , but it misses!", ch,arrow, victim, TO_CHAR); act ("$n lets loose with $p, but it misses.", ch,arrow,NULL, TO_ROOM); act("$p whizzes by your head.", victim, arrow, NULL,TO_CHAR); act("$p whizzes by $n's head.", victim, arrow,NULL,TO_ROOM); if (--((I_AMMO *)arrow->more)->shots_left < 1) { obj_from(arrow); free_it(arrow); break; } } else { mult = ((I_MISSILE *)bow->more)->aiming_time/4 +1; mult += number_range(0,2); dam = (dice (((I_AMMO *)arrow->more)->firstdice, ((I_AMMO *)arrow->more)->seconddice)); if (dam < 3) dam = 3; dam = dam*mult; if (IS_MOB(victim) && IS_SET(victim->act, ACT_SENTINEL)) dam = 0; act("You let loose with your $p and strike $N", ch, arrow,victim,TO_CHAR); act("$n lets loose with $s $p and strikes $N", ch, arrow,victim,TO_ROOM); damage (ch, victim, dam, gsn_shoot); if (--((I_AMMO *)arrow->more)->shots_left < 1) { obj_from(arrow); free_it(arrow); break; } if (victim_is_dead) break; } } } } WAIT_STATE(ch, PULSE_VIOLENCE); NEW_POSITION(ch, POSITION_STANDING); return; } void do_fire (CHAR_DATA *ch, char *argy) { SINGLE_OBJECT *siege = NULL; SINGLE_OBJECT *ammo; CHAR_DATA *rch; CHAR_DATA *rchn; EXIT_DATA *pexit; ROOM_DATA *to_room; ROOM_DATA *curr_room; int type = 0; char arg1[SML_LENGTH]; char arg[SML_LENGTH]; char buf1[SML_LENGTH]; /* Sailing through room msg */ char buf2[SML_LENGTH]; /* Ending room msg */ char buf[SML_LENGTH]; /* Start room msg and message where wall breaks.*/ char buf3[SML_LENGTH]; /* Message where wall breaks */ EXIT_DATA *rev_exit = NULL; int range = 0; int door = MAX_DIR; int i; int firstdie = 0; int seconddie = 0; DEFINE_COMMAND ("fire", do_fire, POSITION_FIGHTING, 0, LOG_NORMAL, "Allows you to shoot ammo from a siege engine a certain range in a certain direction.") if (IS_MOB(ch)) return; check_fgt (ch); strcpy (arg, argy); buf[0] = '\0'; buf1[0] = '\0'; buf2[0] = '\0'; buf3[0] = '\0'; if (ch->fgt->ears > 9) { send_to_char ("You cannot fire any siege engines this soon after a bash.\n\r", ch); return; } if (FIGHTING(ch) != NULL) { send_to_char("You cannot fire a siege engine while engaged in mortal combat!\n\r", ch); return; } argy = one_argy (argy, arg1); for (siege = ch->in_room->contents; siege != NULL; siege = siege->next_content) { if (is_name (arg1, siege->pIndexData->name) && siege->pIndexData->item_type == ITEM_SIEGE && ((type = ((I_SIEGE *)siege->more)->type) == SIEGE_CATAPULT || type == SIEGE_BALLISTA) && siege->contains && siege->contains->pIndexData->item_type == ITEM_AMMO) break; } if (siege == NULL) { send_to_char ("Syntax: Fire <siege engine> <direction> <range>\n\r", ch); return; } argy = one_argy (argy, arg1); if ((door = get_direction_number (arg1)) >= 4) { send_to_char ("The direction must be north, south, east, or west.\n\r", ch); return; } argy = one_argy (argy, arg1); if (!is_number (arg1) || ((range = atoi(arg1)) > ((I_SIEGE *)siege->more)->range) || range < 1) { sprintf (buf, "Range must be a number from 1 to %d.\n\r", ((I_SIEGE *)siege->more)->range); send_to_char (buf, ch); return; } if ((ammo = siege->contains) == NULL) { send_to_char ("The siege engine is not loaded.\n\r", ch); return; } if (ammo->pIndexData->item_type != ITEM_AMMO) { send_to_char("Your siege engine was loaded with something other than ammunition.\n\r", ch); obj_from(ammo); free_it(ammo); return; } if (((I_AMMO *) ammo->more)->ammo_type != ((I_SIEGE *) siege->more)->ammo_type) { obj_from(ammo); free_it(ammo); send_to_char( "The siege engine had the wrong kind of ammo.\n\r", ch); return; } if (!actually_doing) { if (ch->position != POSITION_STANDING) { send_to_char("You cannot fire a siege engine unless you are standing.\n\r", ch); return; } check_temp(ch); strcpy(ch->pcdata->temp->temp_string, arg); ch->pcdata->tickcounts = 5 + ((I_SIEGE *)siege->more)->firing_time; NEW_POSITION(ch, POSITION_FIRING); return; } if (!check_skill (ch, gsn_fire)) { send_to_char ("You mess up the mechanism and cause the siege engine to fail to work.\n\r", ch); obj_from (ammo); free_it (ammo); return; } firstdie = UMAX (1, ((I_AMMO *)ammo->more)->firstdice); seconddie = UMAX (1, ((I_AMMO *)ammo->more)->seconddice); if (type != SIEGE_CATAPULT && type != SIEGE_BALLISTA) { send_to_char ("You can only fire catapults and ballistae at the moment.\n\r", ch); return; } sprintf (buf, "You release $p and $P goes flying off to to the %s!", dir_name[door]); act (buf, ch, siege, ammo, TO_CHAR); sprintf (buf, "$n releases $p and $P goes flying off to to the %s!", dir_name[door]); act (buf, ch, siege, ammo, TO_ROOM); sprintf (buf, "%s comes sailing in from the %s and leaves to the %s!\n\r", OOSTR (ammo, short_descr), dir_name[rev_dir[door]], dir_name[door]); curr_room = ch->in_room; if (type == SIEGE_BALLISTA) { sprintf (buf1, "You get impaled by the force of $p, and are flung %s!", dir_name[door]); sprintf (buf2, "$n gets impaled by the force of $p, and gets flung %s!", dir_name[door]); } for (i = 0; i < range; i++) { if ((pexit = curr_room->exit[door]) != NULL && (to_room = pexit->to_room) != NULL && (!pexit->d_info || !IS_SET (pexit->d_info->exit_info, EX_ISDOOR | EX_CLOSED | EX_ISWALL))) { /* If the ammo does not stop, we show all the people in that room that the ammo sails on through. */ if (curr_room != ch->in_room) { for (rch = curr_room->people; rch != NULL; rch = rchn) { rchn = rch->next_in_room; send_to_char (buf, rch); if (type == SIEGE_BALLISTA && number_range(1,2) == 2) { act (buf1, rch, ammo, NULL, TO_CHAR); act (buf2, rch, ammo, NULL, TO_ROOM); rch->hit -= dice (firstdie, seconddie) - number_range(1,10); if (rch->hit < 0) { act ("$n just got killed by $p!", rch, ammo, NULL, TO_ROOM); act ("You just got killed by $p!", rch, ammo, NULL, TO_CHAR); raw_kill (rch, FALSE); } else { move_char (rch, door + 30); } } } } curr_room = to_room; } else break; } /* At the final room, send the "it crashes into the room" message */ if (curr_room == ch->in_room) { sprintf (buf, "%s does not manage to leave the general vicinity, but instead smashes everything in sight!\n\r", OOSTR (ammo, short_descr)); } else { sprintf (buf, "%s comes sailing in from the %s and crashes down to earth!\n\r", OOSTR (ammo, short_descr), dir_name[rev_dir[door]]); } if (curr_room->people) { rch = curr_room->people; act (buf, rch, ammo, NULL, TO_ROOM); act (buf, rch, ammo, NULL, TO_CHAR); } if (type == SIEGE_BALLISTA) { for (rch = curr_room->people; rch != NULL; rch = rch = rchn) { rchn = rch->next_in_room; send_to_char (buf, rch); if (type == SIEGE_BALLISTA && number_range(1,5) == 2) { act (buf1, rch, ammo, NULL, TO_CHAR); act (buf2, rch, ammo, NULL, TO_ROOM); rch->hit -= dice (firstdie, seconddie) - number_range(1,10); if (rch->hit < 0) { act ("$n just got killed by $p!", rch, ammo, NULL, TO_ROOM); act ("You just got killed by $p!", rch, ammo, NULL, TO_CHAR); raw_kill (rch, FALSE); } else if (IS_PLAYER (rch) && !IS_SET(rch->act, ACT_SENTINEL)) { move_char (rch, door + (FIGHTING (rch) ? 20 : 0)); } } } } else if (type == SIEGE_CATAPULT) { if ((pexit = curr_room->exit[door]) != NULL && pexit->d_info) { if (IS_SET (pexit->d_info->exit_info, EX_ISWALL)) { pexit->d_info->str -= UMAX(1,dice (firstdie, seconddie)/10); if (pexit->to_room && (rev_exit = pexit->to_room->exit[rev_dir[door]]) != NULL) { if (rev_exit->d_info && IS_SET (rev_exit->d_info->exit_info, EX_ISWALL)) { rev_exit->d_info->str -= UMAX(1,dice (firstdie, seconddie)/10); } } if (pexit->d_info->str < 1 || (rev_exit && rev_exit->d_info && rev_exit->d_info->str < 1)) { REMOVE_BIT (pexit->d_info->exit_info, EX_ISDOOR | EX_CLOSED | EX_ISWALL | EX_HIDDEN); if (rev_exit && rev_exit->d_info) { REMOVE_BIT (rev_exit->d_info->exit_info, EX_ISWALL | EX_ISDOOR | EX_CLOSED | EX_HIDDEN); } sprintf (buf1, "The %s wall breaks and crumbles into nothingness!\n\r", dir_name[door]); sprintf (buf3, "The %s wall breaks and crumbles into nothingness!\n\r", dir_name[rev_dir[door]]); } } else if (IS_SET (pexit->d_info->exit_info, EX_ISDOOR | EX_CLOSED)) { sprintf (buf1, "The %s to the %s is smashed into nothingness by the force of the %s!\n\r", (pexit->d_info->keyword[0] != '\0' ? pexit->d_info->keyword : "door"), dir_name[door], OOSTR(ammo, short_descr)); sprintf (buf3, "The %s to the %s is smashed into nothingness by the force of the %s!\n\r", (pexit->d_info->keyword[0] != '\0' ? pexit->d_info->keyword : "door"), dir_name[rev_dir[door]], OOSTR(ammo,short_descr)); REMOVE_BIT (pexit->d_info->exit_info,EX_ISDOOR | EX_CLOSED | EX_HIDDEN); pexit->d_info->str = 0; if (pexit->to_room && (rev_exit = pexit->to_room->exit[rev_dir[door]]) != NULL && rev_exit->d_info) { REMOVE_BIT (rev_exit->d_info->exit_info, EX_ISDOOR | EX_CLOSED | EX_HIDDEN); rev_exit->d_info->str = 0; } } } for (rch = curr_room->people; rch != NULL; rch = rchn) { rchn = rch->next_in_room; if (buf[0] != '\0') send_to_char (buf1, rch); act ("$p smashes into $n!", rch, ammo, NULL, TO_ROOM); act ("$p smashes into you!", rch, ammo, NULL, TO_CHAR); rch->hit -= (number_range(1,30) + dice (firstdie, seconddie)); if (rch->hit < 0) { act ("$n was killed by $p!", rch, ammo, NULL, TO_ROOM); act ("You were just killed by $p!", rch, ammo, NULL, TO_CHAR); raw_kill (rch, FALSE); } for (rch = to_room->people; rch != NULL; rch = rch->next_in_room) { if (IS_MOB (rch) && DIFF_ALIGN (rch, ch) && !being_attacked_yell && IS_SET (rch->pIndexData->act4, ACT4_KILL_OPP)) { being_attacked_yell = TRUE; check_fgt (rch); rch->fgt->fighting = ch; sprintf (buf, "Help!, %s is raiding us, come to my assistance!\n\r", NAME (ch)); do_yell (rch, buf); rch->fgt->fighting = NULL; being_attacked_yell = FALSE; } send_to_char (buf3, rch); } } if ((pexit = curr_room->exit[door]) != NULL && (to_room = pexit->to_room) != NULL && buf3[0] != '\0') { being_attacked_yell = FALSE; for (rch = to_room->people; rch != NULL; rch = rch->next_in_room) { if (IS_MOB (rch) && DIFF_ALIGN (rch, ch) && !being_attacked_yell && IS_SET (rch->pIndexData->act4, ACT4_KILL_OPP)) { being_attacked_yell = TRUE; sprintf (buf, "Help!, %s is raiding us, come to my assistance!\n\r", NAME (ch)); do_yell (rch, buf); check_fgt (rch); if (rch->fgt->hunting) free_string (rch->fgt->hunting); rch->fgt->hunting = str_dup (NAME (ch)); } send_to_char (buf3, rch); } } } being_attacked_yell = FALSE; obj_from (ammo); obj_to (ammo, curr_room); WAIT_STATE(ch, PULSE_VIOLENCE); NEW_POSITION(ch, POSITION_STANDING); return; } void do_throw (CHAR_DATA *ch, char *argy) { SINGLE_OBJECT *thrown; int range; int dam; int mult; CHAR_DATA *victim; char arg1[SML_LENGTH]; char arg2[SML_LENGTH]; int to_hit; int i; DEFINE_COMMAND ("throw", do_throw, POSITION_FIGHTING, 0, LOG_NORMAL, "Allows you to throw a held weapon (axe or piercer).") argy = one_argy(argy, arg1); argy = one_argy(argy, arg2); if (ch->fgt->ears > 9) { send_to_char ("You can't throw this soon after a bash.\n\r", ch); return; } for (i = 0; i < MAX_HOLD; i++) { range = 0; if ((thrown = ch->hold[i]) == NULL || thrown->pIndexData->item_type != ITEM_WEAPON) continue; if (IS_OBJ_STAT(thrown, ITEM_PIERCE)) range = 2; if (is_name("axe", thrown->pIndexData->name)) range = 1; if (arg2[0] != '\0' && !is_name(arg1, thrown->pIndexData->name)) continue; if (range == 0) continue; if ((victim = get_char_room_near (ch, ch->in_room, range, arg2)) == NULL) { continue; } to_hit = GET_HITROLL(ch); check_char_fight_init (ch, victim); if (!check_skill(ch, gsn_throw)) { act("You heave your $p toward $N, but miss.", ch, thrown, victim, TO_CHAR); act ("$n throws the $p, but it misses.", ch, thrown, NULL, TO_ROOM); act("A $p flies by your head.", victim, thrown, NULL, TO_CHAR); act("A $p flies by $n's head.", victim, thrown, NULL, TO_ROOM); obj_from(thrown); if (number_range(1,8) == 4) free_it(thrown); else obj_to(thrown, victim->in_room); WAIT_STATE(ch, PULSE_VIOLENCE); continue; } mult = (3-range)+number_range(0,2); dam = (dice (((I_WEAPON *) thrown->more)->firstdice, ((I_WEAPON*) thrown->more)->seconddice)); if (dam < 2) dam = 2; dam += 2*thrown->pIndexData->made_of; dam *= mult; if (IS_MOB(victim) && IS_SET(victim->act, ACT_SENTINEL)) dam = 0; act("You throw your $p and strike $N", ch, thrown, victim, TO_CHAR); act("$n throws $s $p and strikes $N", ch, thrown, victim, TO_ROOM); damage (ch, victim, dam, gsn_throw); obj_from(thrown); if (number_range(1,8) == 4) free_it(thrown); else obj_to (thrown, victim); } WAIT_STATE(ch, 30); return; }