/*************************************************************************** * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. * * * * Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * * * In order to use any part of this Merc Diku Mud, you must comply with * * both the original Diku license in 'license.doc' as well the Merc * * license in 'license.txt'. In particular, you may not remove either of * * these copyright notices. * * * * Much time and thought has gone into this software and you are * * benefitting. We hope that you share your changes too. What goes * * around, comes around. * ***************************************************************************/ /*************************************************************************** * ROM 2.4 is copyright 1993-1995 Russ Taylor * * ROM has been brought to you by the ROM consortium * * Russ Taylor (rtaylor@pacinfo.com) * * Gabrielle Taylor (gtaylor@pacinfo.com) * * Brian Moore (rom@rom.efn.org) * * By using this code, you have agreed to follow the terms of the * * ROM license, in the file 'rom.license' * ***************************************************************************/ /*************************************************************************** * ROT 2.0 is copyright 1996-1999 by Russ Walsh * * By using this code, you have agreed to follow the terms of the * * ROT license, in the file 'rot.license' * ***************************************************************************/ #if defined(macintosh) #include <types.h> #else #include <sys/types.h> #endif #include <stdio.h> #include <string.h> #include <time.h> #include <stdlib.h> #include <ctype.h> #include "merc.h" #include "tables.h" #include "interp.h" float cpo_stat, vpo_stat; //actual pay-off ratio for arena const int vam_str[] = { 6, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5 }; /* * Local functions. */ void check_assist args ( ( CHAR_DATA * ch, CHAR_DATA * victim ) ); bool check_dodge args ( ( CHAR_DATA * ch, CHAR_DATA * victim ) ); bool check_parry args ( ( CHAR_DATA * ch, CHAR_DATA * victim ) ); bool check_shield_block args ( ( CHAR_DATA * ch, CHAR_DATA * victim ) ); void dam_message args ( ( CHAR_DATA * ch, CHAR_DATA * victim, int dam, int dt, bool immune ) ); void death_cry args ( ( CHAR_DATA * ch, CHAR_DATA * killer ) ); void group_gain args ( ( CHAR_DATA * ch, CHAR_DATA * victim ) ); int xp_compute args ( ( CHAR_DATA * gch, CHAR_DATA * victim, int total_levels ) ); bool can_bypass args ( ( CHAR_DATA * ch, CHAR_DATA * victim ) ); int dambonus args ( ( CHAR_DATA * ch, CHAR_DATA * victim, int dam, int stance ) ); void special_move args ( ( CHAR_DATA * ch, CHAR_DATA * victim ) ); bool can_counter args ( ( CHAR_DATA * ch ) ); bool is_safe args ( ( CHAR_DATA * ch, CHAR_DATA * victim ) ); bool is_safe_mock args ( ( CHAR_DATA * ch, CHAR_DATA * victim ) ); bool is_voodood args ( ( CHAR_DATA * ch, CHAR_DATA * victim ) ); void make_corpse args ( ( CHAR_DATA * ch, CHAR_DATA * killer ) ); void one_hit args ( ( CHAR_DATA * ch, CHAR_DATA * victim, int dt, bool secondary ) ); void one_hit_mock args ( ( CHAR_DATA * ch, CHAR_DATA * victim, int dt, bool secondary ) ); void mob_hit args ( ( CHAR_DATA * ch, CHAR_DATA * victim, int dt ) ); void raw_kill args ( ( CHAR_DATA * victim, CHAR_DATA * killer ) ); void set_fighting args ( ( CHAR_DATA * ch, CHAR_DATA * victim ) ); void disarm args ( ( CHAR_DATA * ch, CHAR_DATA * victim ) ); bool check_fade args ( ( CHAR_DATA *ch, CHAR_DATA *victim ) ); void check_arena args((CHAR_DATA * ch, CHAR_DATA * victim)); /* * Control the fights going on. * Called periodically by update_handler. */ void violence_update(void) { CHAR_DATA *ch; CHAR_DATA *ch_next; CHAR_DATA *victim; for (ch = char_list; ch != NULL; ch = ch->next) { ch_next = ch->next; if ((victim = ch->fighting) == NULL || ch->in_room == NULL) continue; if (IS_AWAKE(ch) && ch->in_room == victim->in_room) multi_hit(ch, victim, TYPE_UNDEFINED); else stop_fighting(ch, FALSE); if ((victim = ch->fighting) == NULL) continue; /* * Fun for the whole family! */ check_assist(ch, victim); if ( IS_NPC( ch ) ) { if ( HAS_TRIGGER( ch, TRIG_FIGHT ) ) mp_percent_trigger( ch, victim, NULL, NULL, TRIG_FIGHT ); if ( HAS_TRIGGER( ch, TRIG_HPCNT ) ) mp_hprct_trigger( ch, victim ); } } return; } /* for auto assisting */ void check_assist(CHAR_DATA * ch, CHAR_DATA * victim) { CHAR_DATA *rch, *rch_next; for (rch = ch->in_room->people; rch != NULL; rch = rch_next) { rch_next = rch->next_in_room; if (IS_AWAKE(rch) && rch->fighting == NULL) { /* quick check for ASSIST_PLAYER */ if (!IS_NPC(ch) && IS_NPC(rch) && IS_SET(rch->off_flags, ASSIST_PLAYERS) && rch->level + 6 > victim->level) { do_emote(rch, "{Rscreams and attacks!{x"); multi_hit(rch, victim, TYPE_UNDEFINED); continue; } /* PCs next */ if (!IS_NPC(ch) || IS_AFFECTED(ch, AFF_CHARM)) { if (!IS_NPC(rch) && !IS_NPC(victim) && (!is_pkill(rch) || !is_pkill(victim)) && !IS_SET(victim->act, PLR_TWIT)) continue; if (((!IS_NPC(rch) && IS_SET(rch->act, PLR_AUTOASSIST)) || IS_AFFECTED(rch, AFF_CHARM)) && is_same_group(ch, rch) && !is_safe(rch, victim)) multi_hit(rch, victim, TYPE_UNDEFINED); continue; } /* now check the NPC cases */ if (IS_NPC(ch) && !IS_AFFECTED(ch, AFF_CHARM)) { if ((IS_NPC(rch) && IS_SET(rch->off_flags, ASSIST_ALL)) || (IS_NPC(rch) && rch->group && rch->group == ch->group) || (IS_NPC(rch) && rch->race == ch->race && IS_SET(rch->off_flags, ASSIST_RACE)) || (IS_NPC(rch) && IS_SET(rch->off_flags, ASSIST_ALIGN) && ((IS_GOOD(rch) && IS_GOOD(ch)) || (IS_EVIL(rch) && IS_EVIL(ch)) || (IS_NEUTRAL(rch) && IS_NEUTRAL(ch)))) || (rch->pIndexData == ch->pIndexData && IS_SET(rch->off_flags, ASSIST_VNUM))) { CHAR_DATA *vch; CHAR_DATA *target; int number; if (number_bits(1) == 0) continue; target = NULL; number = 0; for (vch = ch->in_room->people; vch; vch = vch->next) { if (can_see(rch, vch) && is_same_group(vch, victim) && number_range(0, number) == 0) { target = vch; number++; } } if (target != NULL) { do_emote(rch, "{Rscreams and attacks!{x"); multi_hit(rch, target, TYPE_UNDEFINED); } } } } } } /* * Do one group of attacks. */ void multi_hit(CHAR_DATA * ch, CHAR_DATA * victim, int dt) { int chance; int count = 1; // DB /* decrement the wait */ if (ch->desc == NULL) ch->wait = UMAX(0, ch->wait - PULSE_VIOLENCE); if (ch->desc == NULL) ch->daze = UMAX(0, ch->daze - PULSE_VIOLENCE); /* no attacks for stunnies -- just a check */ if (ch->position < POS_RESTING) return; if (ch->shadow) { ch->shadowing->shadowed = FALSE; ch->shadowing->shadower = NULL; ch->shadowing = NULL; ch->shadow = FALSE; } if (ch->stunned) { ch->stunned--; if (!ch->stunned) { send_to_char("You regain your equilibrium.\n\r", ch); act("$n regains $s equilibrium.", ch, NULL, NULL, TO_ROOM); } return; } if (IS_NPC(ch)) { mob_hit(ch, victim, dt); return; } one_hit(ch, victim, dt, FALSE); if (get_eq_char(ch, WEAR_SECONDARY)) { chance = (get_skill(ch, gsn_dual_wield) / 3) * 2; chance += 33; if (number_percent() < chance) { one_hit(ch, victim, dt, TRUE); if (get_skill(ch, gsn_dual_wield) != 0 && (!IS_NPC(ch) && ch->level >= skill_table [gsn_dual_wield]. skill_level[ch-> class])) { check_improve(ch, gsn_dual_wield, TRUE, 1); } else if (!IS_NPC(ch) && (ch->pcdata->tier == 2)) { if (get_skill(ch, gsn_dual_wield) != 0 && (!IS_NPC(ch) && ch->level >= skill_table [gsn_dual_wield]. skill_level[ch-> clasb])) { check_improve(ch, gsn_dual_wield, TRUE, 1); } } } if (ch->fighting != victim) return; } if (ch->fighting != victim) return; if (IS_AFFECTED(ch, AFF_HASTE)) one_hit(ch, victim, dt, FALSE); if (IS_STANCE(ch, STANCE_SERPENT) && number_percent() > ch->stance[STANCE_SERPENT] * 0.5) count += 1; else if (IS_STANCE(ch, STANCE_MANTIS) && number_percent() > ch->stance[STANCE_MANTIS] * 0.5) count += 1; else if (IS_STANCE(ch, STANCE_TIGER) && number_percent() > ch->stance[STANCE_TIGER] * 0.5) count += 3; if (ch->fighting != victim || dt == gsn_backstab || dt == gsn_circle) return; chance = get_skill(ch, gsn_second_attack) / 2; if (IS_AFFECTED(ch, AFF_SLOW)) chance /= 2; if (number_percent() < chance) { one_hit(ch, victim, dt, FALSE); check_improve(ch, gsn_second_attack, TRUE, 5); if (ch->fighting != victim) return; } else { return; } chance = get_skill(ch, gsn_third_attack) / 2; if (IS_AFFECTED(ch, AFF_SLOW)) chance /= 2; if (number_percent() < chance) { one_hit(ch, victim, dt, FALSE); check_improve(ch, gsn_third_attack, TRUE, 6); if (ch->fighting != victim) return; } else { return; } chance = get_skill(ch, gsn_fourth_attack) / 2; if (IS_AFFECTED(ch, AFF_SLOW)) chance /= 3; if (number_percent() < chance) { one_hit(ch, victim, dt, FALSE); check_improve(ch, gsn_fourth_attack, TRUE, 6); if (ch->fighting != victim) return; } else { return; } chance = get_skill(ch, gsn_fifth_attack) / 2; if (IS_AFFECTED(ch, AFF_SLOW)) chance = 0; if (ch->stance[0] > 0 && number_percent() == 1) { int stance = ch->stance[0]; if (ch->stance[stance] >= 200) { special_move(ch, victim); return; } } if (number_percent() < chance) { one_hit(ch, victim, dt, FALSE); check_improve(ch, gsn_fifth_attack, TRUE, 6); if (ch->fighting != victim) return; } return; } /* procedure for all mobile attacks */ void mob_hit(CHAR_DATA * ch, CHAR_DATA * victim, int dt) { int chance, number; CHAR_DATA *vch, *vch_next; one_hit(ch, victim, dt, FALSE); if (ch->fighting != victim) return; if (ch->stunned) return; /* Area attack -- BALLS nasty! */ if (IS_SET(ch->off_flags, OFF_AREA_ATTACK)) { for (vch = ch->in_room->people; vch != NULL; vch = vch_next) { vch_next = vch->next; if ((vch != victim && vch->fighting == ch)) one_hit(ch, vch, dt, FALSE); } } if (ch->fighting != victim) return; if (get_eq_char(ch, WEAR_SECONDARY)) { chance = (get_skill(ch, gsn_dual_wield) / 3) * 2; chance += 33; if (number_percent() < chance) { one_hit(ch, victim, dt, TRUE); } if (ch->fighting != victim) return; } if (IS_AFFECTED(ch, AFF_HASTE) || (IS_SET(ch->off_flags, OFF_FAST) && !IS_AFFECTED(ch, AFF_SLOW))) one_hit(ch, victim, dt, FALSE); if (ch->fighting != victim || dt == gsn_backstab || dt == gsn_circle) return; chance = get_skill(ch, gsn_second_attack) / 2; if (IS_AFFECTED(ch, AFF_SLOW) && !IS_SET(ch->off_flags, OFF_FAST)) chance /= 2; if (number_percent() < chance) { one_hit(ch, victim, dt, FALSE); if (ch->fighting != victim) return; chance = get_skill(ch, gsn_third_attack) / 2; if (IS_AFFECTED(ch, AFF_SLOW) && !IS_SET(ch->off_flags, OFF_FAST)) chance /= 2; if (number_percent() < chance) { one_hit(ch, victim, dt, FALSE); if (ch->fighting != victim) return; chance = get_skill(ch, gsn_fourth_attack) / 2; if (IS_AFFECTED(ch, AFF_SLOW) && !IS_SET(ch->off_flags, OFF_FAST)) chance /= 3; if (number_percent() < chance) { one_hit(ch, victim, dt, FALSE); if (ch->fighting != victim) return; chance = get_skill(ch, gsn_fifth_attack) / 2; if (IS_AFFECTED(ch, AFF_SLOW) && !IS_SET(ch->off_flags, OFF_FAST)) chance = 0; if (number_percent() < chance) { one_hit(ch, victim, dt, FALSE); if (ch->fighting != victim) return; } } } } /* oh boy! Fun stuff! */ if (ch->wait > 0) return; number = number_range(0, 2); if (number == 1 && IS_SET(ch->act, ACT_MAGE)) { /* { mob_cast_mage(ch,victim); return; } */ ; } if (number == 2 && IS_SET(ch->act, ACT_CLERIC)) { /* { mob_cast_cleric(ch,victim); return; } */ ; } /* now for the skills */ number = number_range(0, 8); switch (number) { case (0): if (IS_SET(ch->off_flags, OFF_BASH)) do_bash(ch, ""); break; case (1): if (IS_SET(ch->off_flags, OFF_BERSERK) && !IS_AFFECTED(ch, AFF_BERSERK)) do_berserk(ch, ""); break; case (2): if (IS_SET(ch->off_flags, OFF_DISARM) || (get_weapon_sn(ch) != gsn_hand_to_hand && (IS_SET(ch->act, ACT_WARRIOR) || IS_SET(ch->act, ACT_VAMPIRE) || IS_SET(ch->act, ACT_THIEF)))) do_disarm(ch, ""); break; case (3): if (IS_SET(ch->off_flags, OFF_KICK)) do_kick(ch, ""); break; case (4): if (IS_SET(ch->off_flags, OFF_KICK_DIRT)) do_dirt(ch, ""); break; case (5): if (IS_SET(ch->off_flags, OFF_TAIL)) { do_tail(ch,""); } break; case (6): if (IS_SET(ch->off_flags, OFF_TRIP)) do_trip(ch, ""); break; case (7): if (IS_SET(ch->off_flags, OFF_CRUSH)) { do_crush(ch,""); } break; case (8): if (IS_SET(ch->off_flags, OFF_BACKSTAB)) { do_backstab(ch, ""); } } } /* * Hit one guy once. */ void one_hit(CHAR_DATA * ch, CHAR_DATA * victim, int dt, bool secondary) { OBJ_DATA *wield; int victim_ac; int thac0; int thac0_00; int thac0_32; int dam; int stance; int diceroll; int sn, skill; int dam_type; bool result; sn = -1; /* just in case */ if (victim == ch || ch == NULL || victim == NULL) return; /* * Can't beat a dead char! * Guard against weird room-leavings. */ if (victim->position == POS_DEAD || ch->in_room != victim->in_room || victim->spirit) return; /* * Figure out the type of damage message. * if secondary == true, use the second weapon. */ if (!secondary) wield = get_eq_char(ch, WEAR_WIELD); else wield = get_eq_char(ch, WEAR_SECONDARY); if (dt == TYPE_UNDEFINED) { dt = TYPE_HIT; if (wield != NULL && wield->item_type == ITEM_WEAPON) dt += wield->value[3]; else dt += ch->dam_type; } if (dt < TYPE_HIT) if (wield != NULL) dam_type = attack_table[wield->value[3]].damage; else dam_type = attack_table[ch->dam_type].damage; else dam_type = attack_table[dt - TYPE_HIT].damage; if (dam_type == -1) dam_type = DAM_BASH; /* get the weapon skill */ sn = get_weapon_sn(ch); skill = 20 + get_weapon_skill(ch, sn); /* * Calculate to-hit-armor-class-0 versus armor. */ if (IS_NPC(ch)) { thac0_00 = 20; thac0_32 = -4; /* as good as a thief */ if (IS_SET(ch->act, ACT_VAMPIRE)) thac0_32 = -30; else if (IS_SET(ch->act, ACT_DRUID)) thac0_32 = 0; else if (IS_SET(ch->act, ACT_RANGER)) thac0_32 = -4; else if (IS_SET(ch->act, ACT_WARRIOR)) thac0_32 = -10; else if (IS_SET(ch->act, ACT_THIEF)) thac0_32 = -4; else if (IS_SET(ch->act, ACT_CLERIC)) thac0_32 = 2; else if (IS_SET(ch->act, ACT_MAGE)) thac0_32 = 6; } else { thac0_00 = class_table[ch->class].thac0_00; thac0_32 = class_table[ch->class].thac0_32; if (ch->pcdata->tier == 2) { thac0_00 = UMIN(class_table[ch->class].thac0_00, class_table[ch->clasb].thac0_00); thac0_32 = UMIN(class_table[ch->class].thac0_32, class_table[ch->clasb].thac0_32); } } thac0 = interpolate(ch->level, thac0_00, thac0_32); if (thac0 < 0) thac0 = thac0 / 2; if (thac0 < -5) thac0 = -5 + (thac0 + 5) / 2; thac0 -= GET_HITROLL(ch) * skill / 100; thac0 += 5 * (100 - skill) / 100; if (dt == gsn_backstab) thac0 -= 10 * (100 - get_skill(ch, gsn_backstab)); switch (dam_type) { case (DAM_PIERCE): victim_ac = GET_AC(victim, AC_PIERCE) / 10; break; case (DAM_BASH): victim_ac = GET_AC(victim, AC_BASH) / 10; break; case (DAM_SLASH): victim_ac = GET_AC(victim, AC_SLASH) / 10; break; default: victim_ac = GET_AC(victim, AC_EXOTIC) / 10; break; }; if (((!strcmp(class_table[victim->class].name, "vampire")) || (!strcmp(class_table[victim->class].name, "lich"))) && (IS_OUTSIDE(victim)) && (vam_str[time_info.hour] != 0)) { if ((time_info.hour > 6) && (time_info.hour < 18)) { victim_ac += (victim_ac * (vam_str[time_info.hour] / 100)); } else { victim_ac -= (victim_ac * (vam_str[time_info.hour] / 100)); } } else if (!IS_NPC(victim) && (victim->pcdata->tier == 2)) { if ((!strcmp(class_table[victim->clasb].name, "vampire")) && (IS_OUTSIDE(victim)) && (vam_str[time_info.hour] != 0)) { if ((time_info.hour > 6) && (time_info.hour < 18)) { victim_ac += (victim_ac * (vam_str[time_info.hour] / 100)); } else { victim_ac -= (victim_ac * (vam_str[time_info.hour] / 100)); } } } if (victim_ac < -15) victim_ac = (victim_ac + 15) / 5 - 15; if (!can_see(ch, victim)) victim_ac -= 4; if (victim->position < POS_FIGHTING) victim_ac += 4; if (victim->position < POS_RESTING) victim_ac += 6; /* * The moment of excitement! */ while ((diceroll = number_bits(5)) >= 20); if (diceroll == 0 || (diceroll != 19 && diceroll < thac0 - victim_ac)) { /* Miss. */ damage(ch, victim, 0, dt, dam_type, TRUE); tail_chain(); return; } /* * Hit. * Calc damage. */ if (IS_NPC(ch) && (!ch->pIndexData->new_format || wield == NULL)) if (!ch->pIndexData->new_format) { dam = number_range(ch->level / 2, ch->level * 3 / 2); if (wield != NULL) dam += dam / 2; if (global_damq){ dam = dam*2; } } else dam = dice(ch->damage[DICE_NUMBER], ch->damage[DICE_TYPE]); else { if (sn != -1) check_improve(ch, sn, TRUE, 5); if (wield != NULL) { if (wield->clan) { float adlev, inclev; int cntr; adlev = 8; inclev = .01; for (cntr = 0; cntr <= ch->level; cntr++) { adlev += .57; adlev += inclev; inclev += .005; } cntr = (int) adlev; dam = dice(cntr / 3, 3) * skill / 100; if (global_damq){ dam = dam*2; } } else { if (wield->pIndexData->new_format) dam = dice(wield->value[1], wield->value[2]) * skill / 100; else dam = number_range(wield->value[1] * skill / 100, wield->value[2] * skill / 100); if (global_damq){ dam = dam*2; } } if (get_eq_char(ch, WEAR_SHIELD) == NULL) /* no shield = more */ dam = dam * 11 / 10; if (global_damq){ dam = dam*2; } /* sharpness! */ if (IS_WEAPON_STAT(wield, WEAPON_SHARP)) { int percent; if ((percent = number_percent()) <= (skill / 8)) dam = 2 * dam + (dam * 2 * percent / 100); if (global_damq){ dam = dam*2; } } } else dam = number_range(1 + 4 * skill / 100, 2 * ch->level / 3 * skill / 100); if (global_damq){ dam = dam*2; } } /* * Bonuses. */ if (((!strcmp(class_table[ch->class].name, "vampire")) || (!strcmp(class_table[ch->class].name, "lich"))) && (IS_OUTSIDE(ch)) && (vam_str[time_info.hour] != 0)) { if ((time_info.hour > 6) && (time_info.hour < 18)) { dam -= (dam * (vam_str[time_info.hour] / 100)); if (global_damq){ dam = dam*2; } } else { dam += (dam * (vam_str[time_info.hour] / 100)); if (global_damq){ dam = dam*2; } } } else if (!IS_NPC(ch) && (ch->pcdata->tier == 2)) { if ((!strcmp(class_table[ch->clasb].name, "vampire")) && (IS_OUTSIDE(ch)) && (vam_str[time_info.hour] != 0)) { if ((time_info.hour > 6) && (time_info.hour < 18)) { dam -= (dam * (vam_str[time_info.hour] / 100)); } else { dam += (dam * (vam_str[time_info.hour] / 100)); } } if (global_damq){ dam = dam*2; } } if (get_skill(ch, gsn_enhanced_damage) > 0) { diceroll = number_percent(); if (diceroll <= get_skill(ch, gsn_enhanced_damage)) { check_improve(ch, gsn_enhanced_damage, TRUE, 6); if (str_cmp(class_table[ch->class].name, "gladiator")) dam += 2 * (dam * diceroll / 300); else dam += 2 * (dam * diceroll / 200); } if (global_damq){ dam = dam*2; } } if (!IS_AWAKE(victim)) dam *= 2; else if (victim->position < POS_FIGHTING) dam = dam * 3 / 2; if (dt == gsn_backstab && wield != NULL) { if (wield->value[0] != 2) dam *= 2 + (ch->level / 10); else dam *= 2 + (ch->level / 8); } if (dt == gsn_circle && wield != NULL) { if (wield->value[0] != 2) dam *= 1.5 + (ch->level / 15); else dam *= 1.5 + (ch->level / 12); } dam += GET_DAMROLL(ch) * UMIN(100, skill) / 100; if (global_damq){ dam = dam*2; } if (dam <= 0) dam = 1; result = damage(ch, victim, dam, dt, dam_type, TRUE); /* but do we have a funky weapon? */ if (result && wield != NULL) { int dam; if (ch->fighting == victim && IS_WEAPON_STAT(wield, WEAPON_POISON)) { int level; AFFECT_DATA *poison, af; if ((poison = affect_find(wield->affected, gsn_poison)) == NULL) level = wield->level; else level = poison->level; if (!saves_spell(level / 2, victim, DAM_POISON)) { send_to_char ("{cYou feel {ypoison{c coursing through your veins.\n{x", victim); act("$n is {ypoisoned{x by the venom on $p.", victim, wield, NULL, TO_ROOM); af.where = TO_AFFECTS; af.type = gsn_poison; af.level = level * 3 / 4; af.duration = level / 2; af.location = APPLY_STR; af.modifier = -1; af.bitvector = AFF_POISON; affect_join(victim, &af); } /* weaken the poison if it's temporary */ if (poison != NULL) { poison->level = UMAX(0, poison->level - 2); poison->duration = UMAX(0, poison->duration - 1); if (poison->level == 0 || poison->duration == 0) act("The {ypoison{x on $p has worn off.", ch, wield, NULL, TO_CHAR); } } if (ch->fighting == victim && IS_WEAPON_STAT(wield, WEAPON_VAMPIRIC)) { dam = number_range(1, wield->level / 5 + 1); act("$p draws life from $n.{x", victim, wield, NULL, TO_ROOM); act("You feel $p drawing your life away.{x", victim, wield, NULL, TO_CHAR); damage(ch, victim, dam, 0, DAM_NEGATIVE, FALSE); ch->alignment = UMAX(-1000, ch->alignment - 1); if (ch->pet != NULL) ch->pet->alignment = ch->alignment; ch->hit += dam / 2; } if (ch->fighting == victim && IS_WEAPON_STAT(wield, WEAPON_FLAMING)) { dam = number_range(1, wield->level / 4 + 1); act("$n is {rburned by $p.{x", victim, wield, NULL, TO_ROOM); act("$p {rsears your flesh.{x", victim, wield, NULL, TO_CHAR); fire_effect((void *) victim, wield->level / 2, dam, TARGET_CHAR); damage(ch, victim, dam, 0, DAM_FIRE, FALSE); } if (ch->fighting == victim && IS_WEAPON_STAT(wield, WEAPON_FROST)) { dam = number_range(1, wield->level / 6 + 2); act("$p {cfreezes $n.{x", victim, wield, NULL, TO_ROOM); act("The {Ccold touch of $p surrounds you with {Cice.{x", victim, wield, NULL, TO_CHAR); cold_effect(victim, wield->level / 2, dam, TARGET_CHAR); damage(ch, victim, dam, 0, DAM_COLD, FALSE); } if (ch->fighting == victim && IS_WEAPON_STAT(wield, WEAPON_SHOCKING)) { dam = number_range(1, wield->level / 5 + 2); act("$n is struck by {Ylightning from $p.{x", victim, wield, NULL, TO_ROOM); act("You are {Yshocked by $p.{x", victim, wield, NULL, TO_CHAR); shock_effect(victim, wield->level / 2, dam, TARGET_CHAR); damage(ch, victim, dam, 0, DAM_LIGHTNING, FALSE); } if (global_damq){ dam = dam*2; } } if (ch->fighting == victim); { if (result) { if (IS_SHIELDED(victim, SHD_ICE)) { if (!IS_SHIELDED(ch, SHD_ICE)) { dt = skill_lookup("iceshield"); dam = number_range(5, 15); damage(victim, ch, dam, dt, DAM_COLD, TRUE); } } if (IS_SHIELDED(victim, SHD_FIRE)) { if (!IS_SHIELDED(ch, SHD_FIRE)) { dt = skill_lookup("fireshield"); dam = number_range(10, 20); damage(victim, ch, dam, dt, DAM_FIRE, TRUE); } } if (!IS_NPC(ch)) { stance = ch->stance[0]; if (IS_STANCE(ch, STANCE_NORMAL)) dam *= 1.75; else dam = dambonus(ch, victim, dam, stance); dambonus(ch, victim, dam, stance); improve_stance(ch); } if (IS_NPC(ch)) { stance = ch->stance[0]; if (IS_STANCE(ch, STANCE_NORMAL)) dam *= 1.95; else dam = dambonus(ch, victim, dam, stance); dambonus(ch, victim, dam, stance); improve_stance(ch); improve_stance(ch); } if (IS_SHIELDED(victim, SHD_SHOCK)) { if (!IS_SHIELDED(ch, SHD_SHOCK)) { dt = skill_lookup("shockshield"); dam = number_range(15, 25); damage(victim, ch, dam, dt, DAM_LIGHTNING, TRUE); } } } if (global_damq){ dam = dam*2; } } tail_chain(); return; } /* * Mock hit one guy once. */ void one_hit_mock(CHAR_DATA * ch, CHAR_DATA * victim, int dt, bool secondary) { OBJ_DATA *wield; int victim_ac; int thac0; int thac0_00; int thac0_32; int dam; int diceroll; int sn, skill; int dam_type; bool result; sn = -1; /* just in case */ if (ch == NULL || victim == NULL) return; /* * Can't beat a dead char! * Guard against weird room-leavings. */ if (victim->position == POS_DEAD || ch->in_room != victim->in_room) return; /* * Figure out the type of damage message. * if secondary == true, use the second weapon. */ if (!secondary) wield = get_eq_char(ch, WEAR_WIELD); else wield = get_eq_char(ch, WEAR_SECONDARY); if (dt == TYPE_UNDEFINED) { dt = TYPE_HIT; if (wield != NULL && wield->item_type == ITEM_WEAPON) dt += wield->value[3]; else dt += ch->dam_type; } if (dt < TYPE_HIT) if (wield != NULL) dam_type = attack_table[wield->value[3]].damage; else dam_type = attack_table[ch->dam_type].damage; else dam_type = attack_table[dt - TYPE_HIT].damage; if (dam_type == -1) dam_type = DAM_BASH; /* get the weapon skill */ sn = get_weapon_sn(ch); skill = 20 + get_weapon_skill(ch, sn); /* * Calculate to-hit-armor-class-0 versus armor. */ if (IS_NPC(ch)) { thac0_00 = 20; thac0_32 = -4; /* as good as a thief */ if (IS_SET(ch->act, ACT_VAMPIRE)) thac0_32 = -30; else if (IS_SET(ch->act, ACT_DRUID)) thac0_32 = 0; else if (IS_SET(ch->act, ACT_RANGER)) thac0_32 = -4; else if (IS_SET(ch->act, ACT_WARRIOR)) thac0_32 = -10; else if (IS_SET(ch->act, ACT_THIEF)) thac0_32 = -4; else if (IS_SET(ch->act, ACT_CLERIC)) thac0_32 = 2; else if (IS_SET(ch->act, ACT_MAGE)) thac0_32 = 6; } else { thac0_00 = class_table[ch->class].thac0_00; thac0_32 = class_table[ch->class].thac0_32; if (ch->pcdata->tier == 2) { thac0_00 = UMIN(class_table[ch->class].thac0_00, class_table[ch->clasb].thac0_00); thac0_32 = UMIN(class_table[ch->class].thac0_32, class_table[ch->clasb].thac0_32); } } thac0 = interpolate(ch->level, thac0_00, thac0_32); if (thac0 < 0) thac0 = thac0 / 2; if (thac0 < -5) thac0 = -5 + (thac0 + 5) / 2; thac0 -= GET_HITROLL(ch) * skill / 100; thac0 += 5 * (100 - skill) / 100; if (dt == gsn_backstab) thac0 -= 10 * (100 - get_skill(ch, gsn_backstab)); switch (dam_type) { case (DAM_PIERCE): victim_ac = GET_AC(victim, AC_PIERCE) / 10; break; case (DAM_BASH): victim_ac = GET_AC(victim, AC_BASH) / 10; break; case (DAM_SLASH): victim_ac = GET_AC(victim, AC_SLASH) / 10; break; default: victim_ac = GET_AC(victim, AC_EXOTIC) / 10; break; }; if (victim_ac < -15) victim_ac = (victim_ac + 15) / 5 - 15; if (!can_see(ch, victim)) victim_ac -= 4; if (victim->position < POS_FIGHTING) victim_ac += 4; if (victim->position < POS_RESTING) victim_ac += 6; /* * The moment of excitement! */ while ((diceroll = number_bits(5)) >= 20); if (diceroll == 0 || (diceroll != 19 && diceroll < thac0 - victim_ac)) { /* Miss. */ damage_mock(ch, victim, 0, dt, dam_type, TRUE); tail_chain(); return; } /* * Hit. * Calc damage. */ if (IS_NPC(ch) && (!ch->pIndexData->new_format || wield == NULL)) if (!ch->pIndexData->new_format) { dam = number_range(ch->level / 2, ch->level * 3 / 2); if (wield != NULL) dam += dam / 2; } else dam = dice(ch->damage[DICE_NUMBER], ch->damage[DICE_TYPE]); else { if (sn != -1) check_improve(ch, sn, TRUE, 5); if (wield != NULL) { if (wield->clan) { float adlev, inclev; int cntr; adlev = 8; inclev = .01; for (cntr = 0; cntr <= ch->level; cntr++) { adlev += .57; adlev += inclev; inclev += .005; } cntr = (int) adlev; dam = dice(cntr / 3, 3) * skill / 100; } else { if (wield->pIndexData->new_format) dam = dice(wield->value[1], wield->value[2]) * skill / 100; else dam = number_range(wield->value[1] * skill / 100, wield->value[2] * skill / 100); } if (get_eq_char(ch, WEAR_SHIELD) == NULL) /* no shield = more */ dam = dam * 11 / 10; /* sharpness! */ if (IS_WEAPON_STAT(wield, WEAPON_SHARP)) { int percent; if ((percent = number_percent()) <= (skill / 8)) dam = 2 * dam + (dam * 2 * percent / 100); } } else dam = number_range(1 + 4 * skill / 100, 2 * ch->level / 3 * skill / 100); } /* * Bonuses. */ if (get_skill(ch, gsn_enhanced_damage) > 0) { diceroll = number_percent(); if (diceroll <= get_skill(ch, gsn_enhanced_damage)) { check_improve(ch, gsn_enhanced_damage, TRUE, 6); if (str_cmp(class_table[ch->class].name, "gladiator")) dam += 2 * (dam * diceroll / 300); else dam += 2 * (dam * diceroll / 200); } } if (!IS_AWAKE(victim)) dam *= 2; else if (victim->position < POS_FIGHTING) dam = dam * 3 / 2; if (dt == gsn_backstab && wield != NULL) { if (wield->value[0] != 2) dam *= 2 + (ch->level / 10); else dam *= 2 + (ch->level / 8); } if (dt == gsn_circle && wield != NULL) { if (wield->value[0] != 2) dam *= 1.5 + (ch->level / 15); else dam *= 1.5 + (ch->level / 12); } dam += GET_DAMROLL(ch) * UMIN(100, skill) / 100; if (dam <= 0) dam = 1; result = damage_mock(ch, victim, dam, dt, dam_type, TRUE); tail_chain(); return; } /* * Inflict damage from a hit. */ bool damage(CHAR_DATA * ch, CHAR_DATA * victim, int dam, int dt, int dam_type, bool show) { OBJ_DATA *corpse; bool immune; int stance; if (victim->position == POS_DEAD) return FALSE; if (ch->spirit || victim->spirit) return FALSE; /* * Stop up any residual loopholes. */ if (IS_NPC(ch)) { stance = ch->stance[0]; if (IS_STANCE(ch, STANCE_NORMAL)) dam *= 1.75; else dam = dambonus(ch, victim, dam, stance); dambonus(ch, victim, dam, stance); improve_stance(ch); } if (!IS_NPC(ch)) { stance = ch->stance[0]; if (IS_STANCE(ch, STANCE_NORMAL)) dam *= 1.95; else dam = dambonus(ch, victim, dam, stance); dambonus(ch, victim, dam, stance); improve_stance(ch); } /* if (dam > 25000 && dt >= TYPE_HIT && !IS_IMMORTAL(ch)) { bug("Damage: %d: more than 25000 points!", dam); dam = 5200; if (!IS_IMMORTAL(ch)) { OBJ_DATA *obj; obj = get_eq_char(ch, WEAR_WIELD); send_to_char("Damage more than 25000 points!", ch); // send_to_char("{cYou {z{Breally{x{c shouldn't cheat.{x\n\r", ch); if (obj != NULL) extract_obj(obj); obj = get_eq_char(ch, WEAR_SECONDARY); if (obj != NULL) extract_obj(obj); } } */ /* damage reduction */ if (dam > 35) dam = (dam - 35) / 2 + 35; if (dam > 80) dam = (dam - 80) / 2 + 80; if (victim != ch) { /* * Certain attacks are forbidden. * Most other attacks are returned. */ if (is_safe(ch, victim)) return FALSE; if (ch->spirit || victim->spirit) return FALSE; if (victim->position > POS_STUNNED) { if ( victim->fighting == NULL ) { set_fighting( victim, ch ); if ( IS_NPC( victim ) && HAS_TRIGGER( victim, TRIG_KILL ) ) mp_percent_trigger( victim, ch, NULL, NULL, TRIG_KILL ); } if (victim->timer <= 4) victim->position = POS_FIGHTING; } if (victim->position > POS_STUNNED) { if (ch->fighting == NULL) set_fighting(ch, victim); } /* * More charm stuff. */ if (victim->master == ch) stop_follower(victim); } /* * Inviso attacks ... not. */ if (IS_SHIELDED(ch, SHD_INVISIBLE)) { affect_strip(ch, gsn_invis); affect_strip(ch, gsn_mass_invis); REMOVE_BIT(ch->shielded_by, SHD_INVISIBLE); act("$n fades into existence.", ch, NULL, NULL, TO_ROOM); } /* * Damage modifiers. */ if (dam > 1 && !IS_NPC(victim) && victim->pcdata->condition[COND_DRUNK] > 10) dam = 9 * dam / 10; if (dam > 1 && IS_SHIELDED(victim, SHD_SANCTUARY)) dam /= 2; if (dam > 1 && ((IS_SHIELDED(victim, SHD_PROTECT_EVIL) && IS_EVIL(ch)) || (IS_SHIELDED(victim, SHD_PROTECT_GOOD) && IS_GOOD(ch)))) dam -= dam / 4; immune = FALSE; /* * Check for parry, and dodge. */ if (dt >= TYPE_HIT && ch != victim) { if (check_parry(ch, victim)) return FALSE; if (check_dodge(ch, victim)) return FALSE; if (check_shield_block(ch, victim)) return FALSE; if ( check_fade( ch, victim )) return FALSE; if (IS_STANCE(victim, STANCE_CRANE) && victim->stance[STANCE_CRANE] > 100 && !can_counter(ch) && !can_bypass(ch, victim)) return FALSE; if (IS_STANCE(victim, STANCE_MANTIS) && victim->stance[STANCE_MANTIS] > 100 && !can_counter(ch) && !can_bypass(ch, victim)) return FALSE; if (IS_STANCE(victim, STANCE_MONGOOSE) && victim->stance[STANCE_MONGOOSE] > 100 && !can_counter(ch) && !can_bypass(ch, victim)) return FALSE; if (IS_STANCE(victim, STANCE_SWALLOW) && victim->stance[STANCE_SWALLOW] > 100 && !can_counter(ch) && !can_bypass(ch, victim)) return FALSE; } switch (check_immune(victim, dam_type)) { case (IS_IMMUNE): immune = TRUE; dam = 0; break; case (IS_RESISTANT): dam -= dam / 3; break; case (IS_VULNERABLE): dam += dam / 2; break; } if (ch->spirit || victim->spirit) return FALSE; if (show) dam_message(ch, victim, dam, dt, immune); if (dam == 0) return FALSE; /* * Hurt the victim. * Inform the victim of his new state. */ victim->hit -= dam; if (!IS_NPC(victim) && victim->level >= LEVEL_IMMORTAL && victim->hit < 1) victim->hit = 1; update_pos(victim); if (dt == gsn_feed && !victim->spirit) { ch->hit = UMIN(ch->hit + ((dam / 4) * 3), ch->max_hit); update_pos(ch); } switch (victim->position) { case POS_MORTAL: act("{c$n is mortally wounded, and will die soon, if not aided.{x", victim, NULL, NULL, TO_ROOM); send_to_char ("{cYou are mortally wounded, and will die soon, if not aided.{x\n\r", victim); break; case POS_INCAP: act("{c$n is incapacitated and will slowly die, if not aided.{x", victim, NULL, NULL, TO_ROOM); send_to_char ("{cYou are incapacitated and will slowly {z{Rdie{x{c, if not aided.{x\n\r", victim); break; case POS_STUNNED: act("{c$n is stunned, but will probably recover.{x", victim, NULL, NULL, TO_ROOM); send_to_char("{cYou are stunned, but will probably recover.{x\n\r", victim); break; case POS_DEAD: if ((IS_NPC(victim)) && (victim->die_descr[0] != '\0')) { act("{c$n $T{x", victim, 0, victim->die_descr, TO_ROOM); } else { act("{c$n is {CDEAD!!{x", victim, 0, 0, TO_ROOM); } send_to_char("{cYou have been {RKILLED!!{x\n\r\n\r", victim); break; default: if (dam > victim->max_hit / 4) send_to_char("{cThat really did {RHURT!{x\n\r", victim); if (victim->hit < victim->max_hit / 4) send_to_char("{cYou sure are {z{RBLEEDING!{x\n\r", victim); break; } /* * Sleep spells and extremely wounded folks. */ if (!IS_AWAKE(victim)) stop_fighting(victim, FALSE); /* * Payoff for killing things. */ if (victim->position == POS_DEAD) { group_gain(ch, victim); if (!IS_NPC(victim)) { sprintf(log_buf, "%s killed by %s at %d", victim->name, (IS_NPC(ch) ? ch->short_descr : ch->name), ch->in_room->vnum); log_string(log_buf); /* * Dying penalty: * 5/6 way back to previous level. */ if (victim->exp > exp_per_level(victim, victim->pcdata->points) * victim->level) if (!IS_SET(victim->act, PLR_LQUEST)) gain_exp(victim, (5 * (exp_per_level (victim, victim->pcdata->points) * victim->level - victim->exp) / 6) + 50); } sprintf(log_buf, "%s got toasted by %s at %s [room %d]", (IS_NPC(victim) ? victim->short_descr : victim->name), (IS_NPC(ch) ? ch->short_descr : ch->name), ch->in_room->name, ch->in_room->vnum); if (IS_NPC(victim)) wiznet(log_buf, NULL, NULL, WIZ_MOBDEATHS, 0, 0); else wiznet(log_buf, NULL, NULL, WIZ_DEATHS, 0, 0); /* * Death trigger */ if ( IS_NPC( victim ) && HAS_TRIGGER( victim, TRIG_DEATH) ) { victim->position = POS_STANDING; mp_percent_trigger( victim, ch, NULL, NULL, TRIG_DEATH ); } raw_kill(victim, ch); /* dump the flags */ if (IS_SET(victim->exbit1_flags, RECRUIT)) { REMOVE_BIT(victim->exbit1_flags, RECRUIT); } if (IS_SET(victim->exbit1_flags, PK_KILLER)) { REMOVE_BIT(victim->exbit1_flags, PK_KILLER); SET_BIT(ch->exbit1_flags, PK_LAWFUL); } if (ch != victim && !IS_NPC(ch) && (!is_same_clan(ch, victim) || clan_table[victim->clan]. independent)) { if (IS_SET(victim->act, PLR_TWIT)) REMOVE_BIT(victim->act, PLR_TWIT); } if (!IS_NPC(ch) && !IS_NPC(victim) && IS_SET(ch->in_room->room_flags, ROOM_ARENA) && IS_SET(victim->in_room->room_flags, ROOM_ARENA)) { check_arena(ch, victim); return TRUE; } /* RT new auto commands */ if (!IS_NPC(ch) && IS_NPC(victim)) { OBJ_DATA *coins; corpse = get_obj_list(ch, "corpse", ch->in_room->contents); if (IS_SET(ch->act, PLR_AUTOLOOT) && corpse && corpse->contains) /* exists and not empty */ do_get(ch, "all corpse"); if (IS_SET(ch->act, PLR_AUTOGOLD) && corpse && corpse->contains && /* exists and not empty */ !IS_SET(ch->act, PLR_AUTOLOOT)) if ((coins = get_obj_list(ch, "gcash", corpse->contains)) != NULL) do_get(ch, "all.gcash corpse"); if (IS_SET(ch->act, PLR_AUTOSAC)) { if (IS_SET(ch->act, PLR_AUTOLOOT) && corpse && corpse->contains) return TRUE; /* leave if corpse has treasure */ else do_sacrifice(ch, "corpse"); } } return TRUE; } if (victim == ch) return TRUE; /* * Take care of link dead people. */ if (!IS_NPC(victim) && victim->desc == NULL) { if (number_range(0, victim->wait) == 0) { do_recall(victim, ""); return TRUE; } } /* * Wimp out? */ if (IS_NPC(victim) && dam > 0 && victim->wait < PULSE_VIOLENCE / 2) { if ((IS_SET(victim->act, ACT_WIMPY) && number_bits(2) == 0 && victim->hit < victim->max_hit / 5) || (IS_AFFECTED(victim, AFF_CHARM) && victim->master != NULL && victim->master->in_room != victim->in_room)) do_flee(victim, ""); } if (!IS_NPC(victim) && victim->hit > 0 && victim->hit <= victim->wimpy && victim->wait < PULSE_VIOLENCE / 2) do_flee(victim, ""); tail_chain(); return TRUE; } /* * Show damage from a mock hit. */ bool damage_mock(CHAR_DATA * ch, CHAR_DATA * victim, int dam, int dt, int dam_type, bool show) { long immdam; bool immune; char buf1[256], buf2[256], buf3[256]; const char *attack; if (victim->position == POS_DEAD) return FALSE; if (dam > 35) dam = (dam - 35) / 2 + 35; if (dam > 80) dam = (dam - 80) / 2 + 80; if (is_safe_mock(ch, victim)) return FALSE; /* * Damage modifiers. */ if (dam > 1 && !IS_NPC(victim) && victim->pcdata->condition[COND_DRUNK] > 10) dam = 9 * dam / 10; if (dam > 1 && IS_SHIELDED(victim, SHD_SANCTUARY)) dam /= 2; if (dam > 1 && ((IS_SHIELDED(victim, SHD_PROTECT_EVIL) && IS_EVIL(ch)) || (IS_SHIELDED(victim, SHD_PROTECT_GOOD) && IS_GOOD(ch)))) dam -= dam / 4; immune = FALSE; switch (check_immune(victim, dam_type)) { case (IS_IMMUNE): immune = TRUE; dam = 0; break; case (IS_RESISTANT): dam -= dam / 3; break; case (IS_VULNERABLE): dam += dam / 2; break; } if (dt >= 0 && dt < MAX_SKILL) attack = skill_table[dt].noun_damage; else if (dt >= TYPE_HIT && dt <= TYPE_HIT + MAX_DAMAGE_MESSAGE) attack = attack_table[dt - TYPE_HIT].noun; else { bug("Dam_message: bad dt %d.", dt); dt = TYPE_HIT; attack = attack_table[0].name; } immdam = 0; if (ch->level == MAX_LEVEL) { immdam = dam * 63; } if (ch == victim) { sprintf(buf1, "{y$n's {gmock {B%s{g would have done {R%d hp{g damage to {y$mself{g.{x", attack, dam); sprintf(buf2, "{yYour {gmock {B%s{g would have done {R%d hp{g damage to {yyourself{g.{x", attack, dam); act(buf1, ch, NULL, NULL, TO_ROOM); act(buf2, ch, NULL, NULL, TO_CHAR); } else if (ch->level < MAX_LEVEL) { sprintf(buf1, "{y$n's {gmock {B%s{g would have done {R%d hp{g damage to {y$N{g.{x", attack, dam); sprintf(buf2, "{yYour {gmock {B%s{g would have done {R%d hp{g damage to {y$N{g.{x", attack, dam); sprintf(buf3, "{y$n's {gmock {B%s{g would have done {R%d hp{g damage to {yyou{g.{x", attack, dam); act(buf1, ch, NULL, victim, TO_NOTVICT); act(buf2, ch, NULL, victim, TO_CHAR); act(buf3, ch, NULL, victim, TO_VICT); } else { sprintf(buf1, "{y$n's {gmock {B%s{g would have done {R%lu hp{g damage to {y$N{g.{x", attack, immdam); sprintf(buf2, "{yYour {gmock {B%s{g would have done {R%lu hp{g damage to {y$N{g.{x", attack, immdam); sprintf(buf3, "{y$n's {gmock {B%s{g would have done {R%lu hp{g damage to {yyou{g.{x", attack, immdam); act(buf1, ch, NULL, victim, TO_NOTVICT); act(buf2, ch, NULL, victim, TO_CHAR); act(buf3, ch, NULL, victim, TO_VICT); } tail_chain(); return TRUE; } bool is_safe(CHAR_DATA * ch, CHAR_DATA * victim) { if (victim->in_room == NULL || ch->in_room == NULL) return TRUE; if (victim->fighting == ch || victim == ch) return FALSE; if (!IS_NPC(ch) && IS_IMMORTAL(ch)) return FALSE; if (ch->spirit) { send_to_char("You need a body for that!\n\r", ch); return TRUE; } if (victim->spirit) { send_to_char("Spirits are difficult to harm.\n\r", ch); return TRUE; } /* killing mobiles */ if (IS_NPC(victim)) { /* safe room? */ if (IS_SET(victim->in_room->room_flags, ROOM_SAFE)) { send_to_char("Not in this room.\n\r", ch); return TRUE; } if (IS_SET(victim->exbit1_flags, RECRUIT) || IS_SET(victim->exbit1_flags, PK_VETERAN) || IS_SET(victim->exbit1_flags, PK_LAWFUL) || IS_SET(victim->exbit1_flags, PK_KILLER) || IS_SET(victim->exbit1_flags, PK_KILLER2)) { return FALSE; } if (IS_SET(victim->in_room->room_flags, ROOM_ARENA)) return FALSE; if (IS_SET(victim->in_room->room_flags, ROOM_ARENA)) return FALSE; if (!IS_NPC(ch) && IS_SET(victim->in_room->room_flags, ROOM_CLAN_ENT)) { send_to_char("Not in this room.\n\r", ch); return TRUE; } if (victim->pIndexData->pShop != NULL) { send_to_char("The shopkeeper wouldn't like that.\n\r", ch); return TRUE; } /* no killing healers, trainers, etc */ if (IS_SET(victim->act, ACT_TRAIN) || IS_SET(victim->act, ACT_PRACTICE) || IS_SET(victim->act, ACT_IS_HEALER) || IS_SET(victim->act, ACT_IS_BANKER) || IS_SET(victim->act, ACT_IS_SATAN) || IS_SET(victim->act, ACT_IS_PRIEST)) { act("I don't think $g would approve.", ch, NULL, NULL, TO_CHAR); return TRUE; } if (!IS_NPC(ch)) { /* no pets */ if (IS_SET(victim->act, ACT_PET)) { act("But $N looks so cute and cuddly...", ch, NULL, victim, TO_CHAR); return TRUE; } /* no charmed creatures unless owner */ if (IS_AFFECTED(victim, AFF_CHARM) && ch != victim->master) { send_to_char("You don't own that monster.\n\r", ch); return TRUE; } } } /* killing players */ else { /* NPC doing the killing */ if (IS_NPC(ch)) { /* safe room check */ if (IS_SET(victim->in_room->room_flags, ROOM_SAFE)) { send_to_char("Not in this room.\n\r", ch); return TRUE; } /* charmed mobs and pets cannot attack players while owned */ if (IS_AFFECTED(ch, AFF_CHARM) && ch->master != NULL && ch->master->fighting != victim) { send_to_char("Players are your friends!\n\r", ch); return TRUE; } } /* player doing the killing */ else { if (IS_SET(victim->in_room->room_flags, ROOM_ARENA)) return FALSE; if (IS_SET(victim->act, PLR_TWIT)) return FALSE; if (((victim->level > 19) || ((victim->class >= MCLT_1) && (victim->level > 14))) && (is_voodood(ch, victim))) return FALSE; if (IS_SET(victim->in_room->room_flags, ROOM_SAFE)) { send_to_char("Not in this room.\n\r", ch); return TRUE; } if (ch->on_gquest) { send_to_char("Not while you are on a quest.\n\r", ch); return TRUE; } if (victim->on_gquest) { send_to_char("They are on a quest, leave them alone.\n\r", ch); return TRUE; } if (!is_clan(ch)) { send_to_char ("Join a clan if you want to fight players.\n\r", ch); return TRUE; } if (!is_pkill(ch)) { send_to_char ("Your clan does not allow player fighting.\n\r", ch); return TRUE; } if (!is_clan(victim)) { send_to_char ("They aren't in a clan, leave them alone.\n\r", ch); return TRUE; } if (!is_pkill(victim)) { send_to_char ("They are in a no pkill clan, leave them alone.\n\r", ch); return TRUE; } if (is_same_clan(ch, victim)) { send_to_char("You can't fight your own clan members.\n\r", ch); return TRUE; } if (((ch->pcdata->tier == 2) && (victim->pcdata->tier == 2)) || ((ch->pcdata->tier == 1) && (victim->pcdata->tier == 1)) || ((ch->pcdata->tier == 0) && (victim->pcdata->tier == 0))) { if (ch->level > victim->level + 10) { send_to_char("Pick on someone your own size.\n\r", ch); return TRUE; } if (ch->level < victim->level - 20) { send_to_char ("If you wish to die, there are less painful methods.\n\r", ch); return TRUE; } } if ((ch->pcdata->tier == 2) && (victim->pcdata->tier == 0)) { send_to_char("Pick on someone your own size.\n\r", ch); return TRUE; } if ((ch->pcdata->tier == 0) && (victim->pcdata->tier == 2)) { send_to_char ("If you wish to die, there are less painful methods.\n\r", ch); return TRUE; } if (((ch->pcdata->tier == 1) && (victim->pcdata->tier == 0)) || ((ch->pcdata->tier == 2) && (victim->pcdata->tier == 1))) { if (ch->level < (victim->level - 30)) { send_to_char ("If you wish to die, there are less painful methods.\n\r", ch); return TRUE; } if (ch->level > victim->level) { send_to_char("Pick on someone your own size.\n\r", ch); return TRUE; } } if (((ch->pcdata->tier == 0) && (victim->pcdata->tier == 1)) || ((ch->pcdata->tier == 1) && (victim->pcdata->tier == 2))) { if (ch->level < (victim->level - 10)) { send_to_char ("If you wish to die, there are less painful methods.\n\r", ch); return TRUE; } if (ch->level > (victim->level + 20)) { send_to_char("Pick on someone your own size.\n\r", ch); return TRUE; } } } } return FALSE; } bool is_safe_mock(CHAR_DATA * ch, CHAR_DATA * victim) { if (victim->in_room == NULL || ch->in_room == NULL) return TRUE; if (!IS_NPC(ch) && IS_IMMORTAL(ch)) return FALSE; if (ch->spirit) { send_to_char("You need a body for that!\n\r", ch); return TRUE; } if (victim->spirit) { send_to_char("Spirits are difficult to harm.\n\r", ch); return TRUE; } if (IS_SET(victim->in_room->room_flags, ROOM_SAFE)) { send_to_char("Not in this room.\n\r", ch); return TRUE; } if (IS_NPC(victim)) { send_to_char("{RYou can only use this on a player.{x\n\r", ch); return TRUE; } return FALSE; } /*=======================================================================* * function: do_challenge * * purpose: sends initial arena match query * * written by: Doug Araya (whiplash@tft.nacs.net) 6-10-96 * *=======================================================================*/ // DB void do_challenge(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; char buf[MSL]; DESCRIPTOR_DATA *d; /* == First make all invalid checks == */ if (IS_NPC(ch)) return; if ((ch->in_room->vnum == ROOM_VNUM_CORNER) && (!IS_IMMORTAL(ch))) { send_to_char ("Just keep your nose in the corner like a good little player.\n\r", ch); return; } if (arena == FIGHT_START) { send_to_char ("Sorry, some one else has already started a challenge, please try later.\n\r", ch); return; } if (arena == FIGHT_BUSY) { send_to_char ("Sorry, there is a fight in progress, please wait a few moments.\n\r", ch); return; } if (arena == FIGHT_LOCK) { send_to_char("Sorry, the arena is currently locked from use.\n\r", ch); return; } if (IS_SET(ch->exbit1_flags, EXBIT1_CHALLENGED)) { send_to_char ("You have already been challenged, either ACCEPT or DECLINE first.\n\r", ch); return; } if (ch->hit < ch->max_hit) { send_to_char("You must be fully healed to fight in the arena.\n\r", ch); return; } if (IS_AFFECTED(ch, SHD_INVISIBLE) || IS_AFFECTED(ch, AFF_SNEAK) || IS_AFFECTED(ch, AFF_HIDE)) { send_to_char ("You can't challenge while invis, sneaking, or hidden.\n\r", ch); return; } if (argument[0] == '\0') { send_to_char("You must specify whom you wish to challenge.\n\r", ch); return; } if ((victim = get_char_world(ch, argument)) == NULL) { send_to_char("They are not playing.\n\r", ch); return; } if ((victim->in_room->vnum == ROOM_VNUM_CORNER)) { send_to_char("They are in the corner, leave them alone.\n\r", ch); return; } /* if( IS_IMMORTAL(ch) ) { send_to_char("Immortals are not allowed to battle in the arena.\n\r",ch); return; } */ if (IS_NPC(victim) || victim == ch) { send_to_char("You cannot challenge NPC's, or yourself.\n\r", ch); return; } if (IS_AFFECTED(victim, AFF_BLIND)) { send_to_char("That person is blind right now.\n\r", ch); return; } if (IS_SET(victim->exbit1_flags, EXBIT1_CHALLENGER)) { send_to_char("They have already challenged someone else.\n\r", ch); return; } if (victim->fighting != NULL) { send_to_char("That person is engaged in battle right now.\n\r", ch); return; } if (victim->hit < victim->max_hit) { send_to_char ("That player is not healthy enough to fight right now.\n\r", ch); return; } if (IS_SET(victim->comm, COMM_AFK)) { send_to_char ("That player is AFK at the moment, try them later.\n\r", ch); return; } if (victim->desc == NULL) { send_to_char ("That player is linkdead at the moment, try them later.\n\r", ch); return; } if (IS_SET(ch->comm, COMM_NOARENA)) { send_to_char ("Why should you be allowed to challenge if no one can challenge you?\n\r", ch); return; } if (IS_SET(victim->comm, COMM_NOARENA)) { send_to_char("That player is blocking all challenges.\n\r", ch); return; } if (victim->level <= 10) { send_to_char("That player is just a newbie!\n\r", ch); return; } if (ch->level > (victim->level + 50)) { send_to_char("That player would be no challenge at all!\r", ch); return; } if (ch->level < (victim->level - 50)) { act("{bThey laugh at you mercilessly!{x\r.", ch, NULL, victim, TO_VICT); return; } /* == Now for the challenge == */ ch->challenged = victim; SET_BIT(ch->exbit1_flags, EXBIT1_CHALLENGER); victim->challenger = ch; SET_BIT(victim->exbit1_flags, EXBIT1_CHALLENGED); arena = FIGHT_START; send_to_char("Challenge has been sent\n\r", ch); act("{b$n{x has {ychallenged{x you to a {rdeath match{x.", ch, NULL, victim, TO_VICT); sprintf(buf, "{W^{x{gArena{x{W^{x {R%s{x has {rchallenged{x {B%s{x to a duel.\n\r", ch->name, victim->name); for (d = descriptor_list; d; d = d->next) { if (d->connected == CON_PLAYING && (d->character != victim && d->character != ch) && !IS_SET(d->character->comm, COMM_NOARENA)) { send_to_char(buf, d->character); } } sprintf(buf, "type: {gACCEPT{x {b%s{x to meet the challenge.\n\r", ch->name); send_to_char(buf, victim); sprintf(buf, "type: {gDECLINE{x {b%s{x to chicken out.\n\r", ch->name); send_to_char(buf, victim); return; } /*=======================================================================* * function: do_accept * * purpose: to accept the arena match, and move the players to the arena * * written by: Doug Araya (whiplash@tft.nacs.net) 6-10-96 * *=======================================================================*/ void do_accept(CHAR_DATA * ch, char *argument) { float vafl, vdfl, cafl, cdfl, vpd, vpk, cpd, cpk; float clvl, vlvl, cw, vw, clo, vlo; // the preceding variables before this point can be redefined to use less space. // all variables following need to be set at what they are. float cha_stat, vha_stat; //base odds from arena wins float chl_stat, vhl_stat; //base odds from level diff float chpk_stat, vhpk_stat; //base odds from pk/pd ratio float cht_stat, vht_stat; //Average odds of winning based // off previous statistics DESCRIPTOR_DATA *d; CHAR_DATA *victim; char buf1[MSL]; char buf2[MSL]; char buf3[MSL]; int char_room; int vict_room; char_room = number_range(27001, 27032); vict_room = number_range(27001, 27032); if (IS_NPC(ch)) return; if (!IS_SET(ch->exbit1_flags, EXBIT1_CHALLENGED)) { send_to_char("You have not been challenged.\n\r", ch); return; } if (arena == FIGHT_BUSY) { send_to_char ("Sorry, there is a fight in progress, please wait a few moments.\n\r", ch); return; } if (arena == FIGHT_LOCK) { send_to_char("Sorry, the arena is currently locked from use.\n\r", ch); return; } if (argument[0] == '\0') { send_to_char ("You must specify whose challenge you wish to accept.\n\r", ch); return; } if ((victim = get_char_world(ch, argument)) == NULL) { send_to_char("They aren't logged in!\n\r", ch); return; } if (victim == ch) { send_to_char("You haven't challenged yourself!\n\r", ch); return; } if (!IS_SET(victim->exbit1_flags, EXBIT1_CHALLENGER) || victim != ch->challenger) { send_to_char("That player hasn't challenged you!\n\r", ch); return; } send_to_char("You have accepted the challenge!\n\r", ch); act("$n accepts your challenge!", ch, NULL, victim, TO_VICT); cw = ch->pcdata->awins; vw = victim->pcdata->awins; clo = ch->pcdata->alosses; vlo = victim->pcdata->alosses; clvl = ch->level; vlvl = victim->level; vafl = victim->pcdata->aflee; vdfl = victim->pcdata->dflee; cafl = ch->pcdata->aflee; cdfl = ch->pcdata->dflee; vpd = victim->pcdata->pdeath; vpk = victim->pcdata->pkills; cpd = ch->pcdata->pdeath; cpk = ch->pcdata->pkills; /* flee record is currently not taken into account */ /* until a fair adjustment can be decided using it. * vafl = victim->pcdata->aflee; vdfl = victim->pcdata->dflee; cafl = ch->pcdata->aflee; cdfl = ch->pcdata->dflee; * can add later */ /* This sets base odds of winning to 1. Needed to maintain accurate ratio's */ /* and to also keep this function from having 'division by zero' errors */ if (cw == 0) { cw = 1; } if (clo == 0) { clo = 1; } if (cpd == 0) { cpd = 1; } if (cpk == 0) { cpk = 1; } if (vw == 0) { vw = 1; } if (vlo == 0) { vlo = 1; } if (vpd == 0) { vpd = 1; } if (vpk == 0) { vpk = 1; } /* Sample odds from a test fight are commented in to the right Please take a look at these and notice how much of an extreme in odds you get by having each base stat use both peoples stats */ /* Base odds from previous arena wins/loss ratio */ cha_stat = ((cw / clo) / (vw / vlo)); /* (1/4) / (100/10) = 0.025 */ vha_stat = ((vw / vlo) / (cw / clo)); /* (100/10) / (1/4) = 40.00 */ /* Base odds from pk/pdeath ratio */ chpk_stat = ((cpk / cpd) / (vpk / vpd)); /* (1/5) / (2/20) = 2.0 */ vhpk_stat = ((vpk / vpd) / (cpk / cpd)); /* (2/20) / (1/5) = 0.5 */ /* Base odds from level differences */ chl_stat = ((clvl / vlvl)); // 20/40 = 0.5 vhl_stat = ((vlvl / clvl)); // 40/20 = 2.0 /* Calculate winning odds = AVG of other ratio's */ /* Does NOT always equal payoff ratio */ cht_stat = ((cha_stat + chpk_stat + chl_stat) / 3); // 2.0 + 0.5 + .025 = 2.25/3 = .750 vht_stat = ((vha_stat + vhpk_stat + vhl_stat) / 3); // 0.5 + 2.0 + 40.0 = 42.5/3 = 14.x /* Enforce payoff ratio limits Max payoff is 300% profit Min payoff is 20% profit */ if (cha_stat > 3) { cha_stat = 3; } if (chl_stat > 3) { chl_stat = 3; } if (chpk_stat > 3) { chpk_stat = 3; } if (vha_stat > 3) { vha_stat = 3; } if (vhl_stat > 3) { vhl_stat = 3; } if (vhpk_stat > 3) { vhpk_stat = 3; } if (cha_stat < .2) { cha_stat = .2; } if (chl_stat < .2) { chl_stat = .2; } if (chpk_stat < .2) { chpk_stat = .2; } if (vha_stat < .2) { vha_stat = .2; } if (vhl_stat < .2) { vhl_stat = .2; } if (vhpk_stat < .2) { vhpk_stat = .2; } /* the aditional +1 is set here to make sure the original bet is also returned with the profits */ /*bet is not deducted in the first place, so +1 removed */ cpo_stat = ((cha_stat + chpk_stat + chl_stat) / 3); vpo_stat = ((vha_stat + vhpk_stat + vhl_stat) / 3); if (cpo_stat > 10) { cpo_stat = 10; } if (vpo_stat > 10) { vpo_stat = 10; } sprintf(buf1, "^{gArena{x^ {b%s{x {m({y%d {gwins{m) ({y%d {rlosses{m){x Payoff odds %f\n\r", victim->name, victim->pcdata->awins, victim->pcdata->alosses, vht_stat); sprintf(buf2, "^{gArena{x^ {b%s{x {m({y%d {gwins{m) ({y%d {rlosses{m){x Payoff odds %f\n\r", ch->name, ch->pcdata->awins, ch->pcdata->alosses, cht_stat); strcpy(buf3, "{x^{gArena{x^ To wager on the fight, type: {gbet{x ({yamount{x) ({bplayer name{x)\n\r"); for (d = descriptor_list; d; d = d->next) { if (d->connected == CON_PLAYING && (d->character != victim && d->character != ch) && !IS_SET(d->character->comm, COMM_NOARENA)) { send_to_char(buf1, d->character); send_to_char(buf2, d->character); send_to_char(buf3, d->character); d->character->gladiator = NULL; } } /* == now move them both to an arena for the fun == */ send_to_char("You make your way into the arena.\n\r", ch); char_from_room(ch); char_to_room(ch, get_room_index(char_room)); do_look(ch, "auto"); SET_BIT(ch->comm, COMM_NOCHANNELS); SET_BIT(ch->act, PLR_NORESTORE); send_to_char("You make your way to the arena.\n\r", victim); char_from_room(victim); char_to_room(victim, get_room_index(vict_room)); do_look(victim, "auto"); SET_BIT(victim->comm, COMM_NOCHANNELS); SET_BIT(victim->act, PLR_NORESTORE); arena = FIGHT_BUSY; return; } /*=======================================================================* if( !IS_SET(fighter->in_room->room_flags,ROOM_ARENA) ) * function: do_decline * * purpose: to chicken out from a sent arena challenge * * written by: Doug Araya (whiplash@tft.nacs.net) 6-10-96 * *=======================================================================*/ void do_decline(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; char buf[MSL]; DESCRIPTOR_DATA *d; /*== make all invalid checks == */ if (IS_NPC(ch)) return; if (!IS_SET(ch->exbit1_flags, EXBIT1_CHALLENGED)) { send_to_char ("You have niether given a challenge or been challenged.\n\r", ch); return; } if (argument[0] == '\0') { send_to_char ("You must specify whose challenge you wish to decline.\n\r", ch); return; } if ((victim = get_char_world(ch, argument)) == NULL) { send_to_char("They aren't logged in!\n\r", ch); return; } if (!IS_SET(victim->exbit1_flags, EXBIT1_CHALLENGER) || victim != ch->challenger) { send_to_char("That player hasn't challenged you.\n\r", ch); return; } /*== now actually decline == */ victim->challenged = NULL; REMOVE_BIT(victim->exbit1_flags, EXBIT1_CHALLENGER); ch->challenger = NULL; REMOVE_BIT(ch->exbit1_flags, EXBIT1_CHALLENGED); arena = FIGHT_OPEN; send_to_char("Challenge declined!\n\r", ch); act("$n has withdrawn from the challenge.", ch, NULL, victim, TO_VICT); sprintf(buf, "^{gArena{x^ {b%s{x {bhas withdrawn from the challenge{x.\n\r", ch->name); for (d = descriptor_list; d; d = d->next) { if (d->connected == CON_PLAYING && (d->character != victim && d->character != ch) && !IS_SET(d->character->comm, COMM_NOARENA)) { send_to_char(buf, d->character); } } return; } void do_dismiss(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; char buf[MSL]; DESCRIPTOR_DATA *d; /*== make all invalid checks == */ if (IS_NPC(ch)) return; if (!IS_SET(ch->exbit1_flags, EXBIT1_CHALLENGER)) { send_to_char ("You have niether given a challenge or been challenged.\n\r", ch); return; } if (argument[0] == '\0') { send_to_char ("You must specify whose challenge you wish to decline.\n\r", ch); return; } if ((victim = get_char_world(ch, argument)) == NULL) { send_to_char("They aren't logged in!\n\r", ch); return; } if (!IS_SET(victim->exbit1_flags, EXBIT1_CHALLENGER) || victim != ch->challenger) { send_to_char("That player hasn't challenged you.\n\r", ch); return; } /*== now actually decline == */ victim->challenged = NULL; REMOVE_BIT(victim->exbit1_flags, EXBIT1_CHALLENGER); ch->challenger = NULL; REMOVE_BIT(ch->exbit1_flags, EXBIT1_CHALLENGED); arena = FIGHT_OPEN; send_to_char("Challenge declined!\n\r", ch); act("$n has withdrawn from the challenge.", ch, NULL, victim, TO_VICT); sprintf(buf, "^{gArena{x^ {b%s{x {bhas withdrawn from the challenge{x.\n\r", ch->name); for (d = descriptor_list; d; d = d->next) { if (d->connected == CON_PLAYING && (d->character != victim && d->character != ch) && !IS_SET(d->character->comm, COMM_NOARENA)) { send_to_char(buf, d->character); } } return; } void do_arec(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; char buf[MSL]; DESCRIPTOR_DATA *d; /* == First make all invalid checks == */ if (IS_NPC(ch)) { send_to_char("Arec will not recover mobs in the arena!\n\r", ch); return; } if (argument[0] == '\0') { send_to_char ("Syntax: Arec <player-name> to recover somebody stuck in the Arena.\n\r", ch); return; } if ((victim = get_char_world(ch, argument)) == NULL) { send_to_char("They are not playing.\n\r", ch); return; } /* == Removing the flags == */ stop_fighting(victim, TRUE); char_from_room(victim); victim->hit = victim->max_hit; victim->mana = victim->max_mana; victim->move = victim->max_move; update_pos(victim); do_look(victim, "auto"); char_to_room(victim, get_room_index(ROOM_VNUM_AWINNER)); if (IS_SET(ch->exbit1_flags, EXBIT1_CHALLENGER)) REMOVE_BIT(ch->exbit1_flags, EXBIT1_CHALLENGER); if (IS_SET(victim->exbit1_flags, EXBIT1_CHALLENGER)) REMOVE_BIT(victim->exbit1_flags, EXBIT1_CHALLENGER); if (IS_SET(victim->exbit1_flags, EXBIT1_CHALLENGED)) REMOVE_BIT(victim->exbit1_flags, EXBIT1_CHALLENGED); if (IS_SET(ch->exbit1_flags, EXBIT1_CHALLENGED)) REMOVE_BIT(ch->exbit1_flags, EXBIT1_CHALLENGED); victim->challenger = NULL; victim->challenged = NULL; REMOVE_BIT(victim->comm, COMM_NOCHANNELS); REMOVE_BIT(victim->act, PLR_NORESTORE); arena = FIGHT_OPEN; for (d = descriptor_list; d; d = d->next) { if (d->connected == CON_PLAYING && (d->character != victim && d->character != ch)) { send_to_char(buf, d->character); } } send_to_char("Player recovered from the arena.\n\r", ch); return; } /*======================================================================* * function: do_bet * * purpose: to allow players to wager on the outcome of arena battles * * written by: Doug Araya (whiplash@tft.nacs.net) 6-10-96 * *======================================================================*/ void do_bet(CHAR_DATA * ch, char *argument) { char arg[MIL]; char buf[MSL]; CHAR_DATA *fighter; int wager; argument = one_argument(argument, arg); if (argument[0] == '\0' || !is_number(arg)) { send_to_char("Syntax: BET [amount] [player]\n\r", ch); return; } if (ch->gladiator != NULL) { send_to_char("You have already placed a bet on this fight.\n\r", ch); return; } /*== disable the actual fighters from betting ==*/ if (IS_SET(ch->exbit1_flags, EXBIT1_CHALLENGER) || IS_SET(ch->exbit1_flags, EXBIT1_CHALLENGED)) { send_to_char("You can't bet on this battle.\n\r", ch); return; } fighter = get_char_world(ch, argument); /*== make sure the choice is valid ==*/ if (fighter == NULL) { send_to_char("That player is not logged in.\n\r", ch); return; } if (IS_NPC(ch)) { send_to_char("Why bet on a mob? They aren't fighting...\n\r", ch); return; } if (!IS_SET(fighter->in_room->room_flags, ROOM_ARENA)) { send_to_char("That player is not in the arena.\n\r", ch); return; } /*== do away with the negative number trickery ==*/ if (!str_prefix("-", arg)) { send_to_char("Error: Invalid argument!\n\r", ch); return; } wager = atoi(arg); if (wager > 10001 || wager < 1) { send_to_char("Wager range is between 1 and 10000\n\r", ch); return; } /*== make sure they have the cash ==*/ if (wager > ch->gold + (ch->platinum * 100)) { send_to_char("You don't have that much gold to wager!\n\r", ch); return; } /*== now set the info ==*/ ch->gladiator = fighter; ch->pcdata->plr_wager = wager; sprintf(buf, "You have placed a {y%d{x gold wager on {b%s{x\n\r", wager, fighter->name); send_to_char(buf, ch); return; } bool is_voodood(CHAR_DATA * ch, CHAR_DATA * victim) { OBJ_DATA *object; bool found; if (ch->level > HERO) return FALSE; found = FALSE; for (object = victim->carrying; object != NULL; object = object->next_content) { if (object->pIndexData->vnum == OBJ_VNUM_VOODOO) { char arg[MIL]; one_argument(object->name, arg); if (!str_cmp(arg, ch->name)) { return TRUE; } } } return FALSE; } bool is_safe_spell(CHAR_DATA * ch, CHAR_DATA * victim, bool area) { if (victim->in_room == NULL || ch->in_room == NULL) return TRUE; if (victim == ch && area) return TRUE; if (victim->fighting == ch || victim == ch) return FALSE; if (!IS_NPC(ch) && IS_IMMORTAL(ch)) return FALSE; if (ch->spirit) return TRUE; if (victim->spirit) return TRUE; /* killing mobiles */ if (IS_NPC(victim)) { /* safe room? */ if (IS_SET(victim->in_room->room_flags, ROOM_SAFE)) return TRUE; if (!IS_NPC(ch) && IS_SET(victim->in_room->room_flags, ROOM_CLAN_ENT)) return TRUE; if (victim->pIndexData->pShop != NULL) return TRUE; /* no killing healers, trainers, etc */ if (IS_SET(victim->act, ACT_TRAIN) || IS_SET(victim->act, ACT_PRACTICE) || IS_SET(victim->act, ACT_IS_HEALER) || IS_SET(victim->act, ACT_IS_BANKER) || IS_SET(victim->act, ACT_IS_SATAN) || IS_SET(victim->act, ACT_IS_PRIEST)) return TRUE; if (!IS_NPC(ch)) { /* no pets */ if (IS_SET(victim->act, ACT_PET)) return TRUE; /* no charmed creatures unless owner */ if (IS_AFFECTED(victim, AFF_CHARM) && (area || ch != victim->master)) return TRUE; /* legal kill? -- cannot hit mob fighting non-group member */ if (victim->fighting != NULL && !is_same_group(ch, victim->fighting)) return TRUE; } else { /* area effect spells do not hit other mobs */ if (area && !is_same_group(victim, ch->fighting)) return TRUE; } } /* killing players */ else { if (area && IS_IMMORTAL(victim) && victim->level > LEVEL_IMMORTAL) return TRUE; /* NPC doing the killing */ if (IS_NPC(ch)) { /* charmed mobs and pets cannot attack players while owned */ if (((IS_AFFECTED(ch, AFF_CHARM)) & (ch->master != NULL)) && (ch->master->fighting != victim)) return TRUE; /* safe room? */ if (IS_SET(victim->in_room->room_flags, ROOM_SAFE)) return TRUE; /* legal kill? -- mobs only hit players grouped with opponent */ if (ch->fighting != NULL && !is_same_group(ch->fighting, victim)) return TRUE; } /* player doing the killing */ else { if (IS_SET(victim->in_room->room_flags, ROOM_ARENA)) return FALSE; if (IS_SET(victim->act, PLR_TWIT)) return FALSE; if (((victim->level > 19) || ((victim->class >= MCLT_1) && (victim->level > 14))) && (is_voodood(ch, victim))) return FALSE; if (!is_clan(ch)) return TRUE; if (!is_pkill(ch)) return TRUE; if (IS_SET(victim->in_room->room_flags, ROOM_SAFE)) return TRUE; if (ch->on_gquest) return TRUE; if (victim->on_gquest) return TRUE; if (!is_clan(victim)) return TRUE; if (!is_pkill(victim)) return TRUE; if (is_same_clan(ch, victim)) return TRUE; if (((ch->pcdata->tier == 2) && (victim->pcdata->tier == 2)) || ((ch->pcdata->tier == 1) && (victim->pcdata->tier == 1)) || ((ch->pcdata->tier == 0) && (victim->pcdata->tier == 0))) { if (ch->level > victim->level + 10) { return TRUE; } if (ch->level < victim->level - 20) { return TRUE; } } if ((ch->pcdata->tier == 2) && (victim->pcdata->tier == 0)) { return TRUE; } if ((ch->pcdata->tier == 0) && (victim->pcdata->tier == 2)) { return TRUE; } if (((ch->pcdata->tier == 1) && (victim->pcdata->tier == 0)) || ((ch->pcdata->tier == 2) && (victim->pcdata->tier == 1))) { if (ch->level < (victim->level - 30)) { return TRUE; } if (ch->level > victim->level) { return TRUE; } } if (((ch->pcdata->tier == 0) && (victim->pcdata->tier == 1)) || ((ch->pcdata->tier == 1) && (victim->pcdata->tier == 2))) { if (ch->level < (victim->level - 10)) { return TRUE; } if (ch->level > (victim->level + 20)) { return TRUE; } } } } return FALSE; } /* * Check for parry. */ bool check_parry(CHAR_DATA * ch, CHAR_DATA * victim) { int chance; int bill; if (!IS_AWAKE(victim)) return FALSE; chance = get_skill(victim, gsn_parry) / 2; if (get_eq_char(victim, WEAR_WIELD) == NULL) { if (IS_NPC(victim)) chance /= 2; else return FALSE; } if (victim->stunned) return FALSE; if (!can_see(ch, victim)) chance /= 2; if (number_percent() >= chance + victim->level - ch->level) return FALSE; if (IS_STANCE(victim, STANCE_CRANE) && victim->stance[STANCE_CRANE] > 0 && !can_counter(ch) && !can_bypass(ch, victim)) chance += (victim->stance[STANCE_CRANE] * 0.25); else if (IS_STANCE(victim, STANCE_MANTIS) && victim->stance[STANCE_MANTIS] > 0 && !can_counter(ch) && !can_bypass(ch, victim)) chance += (victim->stance[STANCE_MANTIS] * 0.25); /* fuk */ bill = number_range(1, 24); if (bill == 1) { act("With cat like speed you parry $n's attack.", ch, NULL, victim, TO_VICT); act("With cat like speed $N parries your attack.", ch, NULL, victim, TO_CHAR); act("With cat like speed $n parries $N's attack.", ch, NULL, victim, TO_NOTVICT); check_improve(victim, gsn_parry, TRUE, 6); } else if (bill == 2) { act("You move your weapon up parrying $n's attack.", ch, NULL, victim, TO_VICT); act("$N moves $s weapon up parrying your blow.", ch, NULL, victim, TO_CHAR); act("$n moves $s weapon up parrying $N's blow.", ch, NULL, victim, TO_NOTVICT); check_improve(victim, gsn_parry, TRUE, 6); } else if (bill == 3) { act("You move your weapon to the side parrying $n's blow.", ch, NULL, victim, TO_VICT); act("$N moves $s weapon to the side parrying your blow.", ch, NULL, victim, TO_CHAR); act("$n moves $s weapon to the side parring $N's blow.", ch, NULL, victim, TO_NOTVICT); check_improve(victim, gsn_parry, TRUE, 6); } else if (bill == 4) { act("You deftly move your weapon between $n's attack.", ch, NULL, victim, TO_VICT); act("$N deftly moves $s weapon between your attack", ch, NULL, victim, TO_CHAR); act("$n deftly moves $s weapon between $N's attack.", ch, NULL, victim, TO_NOTVICT); } else if (bill == 5) { act("You spin your weapon in a defensive move parrying $n's blow.", ch, get_eq_char(ch, WEAR_WIELD), victim, TO_VICT); act("$N spins $s weapon in a defensive move parrying your blow.", ch, get_eq_char(ch, WEAR_WIELD), victim, TO_CHAR); act("$n spins $s weapon in a defensive move parrying $N's blow.", ch, get_eq_char(ch, WEAR_WIELD), victim, TO_NOTVICT); check_improve(victim, gsn_parry, TRUE, 6); } else if (bill == 6) { act("With a bone-jarring skill you parry $n's blow.", ch, NULL, victim, TO_VICT); act("With a bone-jarring skill $N parries your blow.", ch, NULL, victim, TO_CHAR); act("With a bone-jarring skill $n parries $N's blow.", ch, NULL, victim, TO_NOTVICT); check_improve(victim, gsn_parry, TRUE, 6); } else if (bill == 7) { act("You swiftly parry $n's attack.", ch, NULL, victim, TO_VICT); act("$N swiftly parries your attack.", ch, NULL, victim, TO_CHAR); act("$n swiftly parries $N's attack.", ch, NULL, victim, TO_NOTVICT); check_improve(victim, gsn_parry, TRUE, 6); } else if (bill == 8) { act("Moving like a panther you parry $n's attack.", ch, NULL, victim, TO_VICT); act("$N moves like a panther parrying your attack.", ch, NULL, victim, TO_CHAR); act("$n moves like a panther parrying $N's attack.", ch, NULL, victim, TO_NOTVICT); check_improve(victim, gsn_parry, TRUE, 6); } return TRUE; } /* * Check for shield block. */ bool check_shield_block(CHAR_DATA * ch, CHAR_DATA * victim) { int chance; if (!IS_AWAKE(victim)) return FALSE; chance = get_skill(victim, gsn_shield_block) / 5 + 3; if (get_eq_char(victim, WEAR_SHIELD) == NULL) return FALSE; if (number_percent() >= chance + victim->level - ch->level) return FALSE; if (victim->stunned) return FALSE; act("You block $n's attack with your shield.{x", ch, NULL, victim, TO_VICT); act("{h$N blocks your attack with a shield.{x", ch, NULL, victim, TO_CHAR); check_improve(victim, gsn_shield_block, TRUE, 6); return TRUE; } /* * Check for dodge. */ bool check_dodge(CHAR_DATA * ch, CHAR_DATA * victim) { int chance; int bill; if (!IS_AWAKE(victim)) return FALSE; chance = get_skill(victim, gsn_dodge) / 2; if (!can_see(victim, ch)) chance /= 2; if (number_percent() >= chance + victim->level - ch->level) return FALSE; if (victim->stunned) return FALSE; if (IS_STANCE(victim, STANCE_MONGOOSE) && victim->stance[STANCE_MONGOOSE] > 0 && !can_counter(ch) && !can_bypass(ch, victim)) (chance += victim->stance[STANCE_MONGOOSE] * 0.25); if (IS_STANCE(victim, STANCE_SWALLOW) && victim->stance[STANCE_SWALLOW] > 0 && !can_counter(ch) && !can_bypass(ch, victim)) (chance += victim->stance[STANCE_SWALLOW] * 0.25); bill = number_range(1, 27); if (bill == 1) { act("You feint to the right dodging $n's blow.", ch, NULL, victim, TO_VICT); act("$N feints to the right dodging your blow.", ch, NULL, victim, TO_CHAR); act("$n feints to the right dodging $N's blow.", ch, NULL, victim, TO_NOTVICT); check_improve(victim, gsn_dodge, TRUE, 6); } else if (bill == 2) { act("You quickly duck dodging $n's attack.", ch, NULL, victim, TO_VICT); act("$N ducks quickly dodging your attack.", ch, NULL, victim, TO_CHAR); act("$n ducks quickly dodging $N's attack.", ch, NULL, victim, TO_NOTVICT); check_improve(victim, gsn_dodge, TRUE, 6); } else if (bill == 3) { act("You roll to the ground dodging $n's blow.", ch, NULL, victim, TO_VICT); act("$N rolls to the ground dodging your blow.", ch, NULL, victim, TO_CHAR); act("$n rolls to the ground dodging $N's blow.", ch, NULL, victim, TO_NOTVICT); act("$n leaps back up!", ch, NULL, victim, TO_NOTVICT); act("You leap back up!", ch, NULL, victim, TO_VICT); act("$N leaps back up!", ch, NULL, victim, TO_CHAR); check_improve(victim, gsn_dodge, TRUE, 6); } else if (bill == 4) { act("You dodge $n's useless attack.", ch, NULL, victim, TO_VICT); act("$N dodges your useless attack.", ch, NULL, victim, TO_CHAR); act("$n dodges $N's useless attack.", ch, NULL, victim, TO_NOTVICT); check_improve(victim, gsn_dodge, TRUE, 6); } else if (bill == 5) { act("You bob and weave dodging $n's blow.", ch, NULL, victim, TO_VICT); act("$N bobs and weaves dodging your blow.", ch, NULL, victim, TO_CHAR); act("$n bobs and weaves dodging $N's blow.", ch, NULL, victim, TO_NOTVICT); check_improve(victim, gsn_dodge, TRUE, 6); } else if (bill == 6) { act("You roll with the blow dodging $n's attack.", ch, NULL, victim, TO_VICT); act("$N rolls with the blow dodging your attack.", ch, NULL, victim, TO_CHAR); act("$n rolls with the blow dodging $N's attack.", ch, NULL, victim, TO_NOTVICT); } else if (bill == 7) { act("You twist right dodging $n.", ch, NULL, victim, TO_VICT); act("$N twists right dodging your blow.", ch, NULL, victim, TO_CHAR); act("$n twists right dodging $N's blow.", ch, NULL, victim, TO_NOTVICT); check_improve(victim, gsn_dodge, TRUE, 6); } else if (bill == 8) { act("You twist left dodging $n.", ch, NULL, victim, TO_VICT); act("$N twists left dodging your blow.", ch, NULL, victim, TO_CHAR); act("$n twists left dodging $N's blow.", ch, NULL, victim, TO_NOTVICT); check_improve(victim, gsn_dodge, TRUE, 6); } else if (bill == 9) { act("You roll to the ground dodging $n's blow.", ch, NULL, victim, TO_VICT); act("$N rolls to the ground dodging your blow.", ch, NULL, victim, TO_CHAR); act("$n rolls to the ground dodging $N's blow.", ch, NULL, victim, TO_NOTVICT); act("$n deftly springs to their feet!", ch, NULL, victim, TO_NOTVICT); act("deftly... you spring to your feet!", ch, NULL, victim, TO_VICT); act("$N deftly springs to their feet!", ch, NULL, victim, TO_CHAR); check_improve(victim, gsn_dodge, TRUE, 6); } return TRUE; } /* * Set position of a victim. */ void update_pos(CHAR_DATA * victim) { if (victim->hit > 0) { if (victim->position <= POS_STUNNED) victim->position = POS_STANDING; return; } if (IS_NPC(victim) && victim->hit < 1) { victim->position = POS_DEAD; return; } if (victim->hit <= -11) { if (IS_SET(victim->exbit1_flags, RECRUIT) && (victim->pcdata->pdeath >= 5 || victim->pcdata->pkills >= 5)) { send_to_char("Your skill at PK has improved.\n\r", victim); REMOVE_BIT(victim->exbit1_flags, RECRUIT); SET_BIT(victim->exbit1_flags, PK_VETERAN); } victim->position = POS_DEAD; victim->spirit = 1; return; } if (victim->hit <= -6) victim->position = POS_MORTAL; else if (victim->hit <= -3) victim->position = POS_INCAP; else victim->position = POS_STUNNED; return; } /* * Start fights. */ void set_fighting(CHAR_DATA * ch, CHAR_DATA * victim) { if (ch->fighting != NULL) { bug("Set_fighting: already fighting", 0); return; } if (IS_AFFECTED(ch, AFF_SLEEP)) affect_strip(ch, gsn_sleep); if (ch->shadow) { ch->shadowing->shadowed = FALSE; ch->shadowing->shadower = NULL; ch->shadowing = NULL; ch->shadow = FALSE; } ch->fighting = victim; ch->position = POS_FIGHTING; ch->stunned = 0; return; } /* * Stop fights. */ void stop_fighting(CHAR_DATA * ch, bool fBoth) { CHAR_DATA *fch; char buf[MSL]; for (fch = char_list; fch != NULL; fch = fch->next) { if (fch == ch || (fBoth && fch->fighting == ch)) { fch->fighting = NULL; fch->position = IS_NPC(fch) ? fch->default_pos : POS_STANDING; fch->stunned = 0; update_pos(fch); if (IS_SET(fch->comm, COMM_STORE)) if (fch->tells) { sprintf(buf, "You have {R%d{x tells waiting.\n\r", fch->tells); send_to_char(buf, fch); send_to_char("Type 'replay' to see tells.\n\r", fch); } if (IS_SET(ch->exbit1_flags, RECRUIT) && (ch->pcdata->pdeath >= 5 || ch->pcdata->pkills >= 5)) { send_to_char("Your skill at PK has improved.\n\r", ch); REMOVE_BIT(ch->exbit1_flags, RECRUIT); SET_BIT(ch->exbit1_flags, PK_VETERAN); } } } return; } /* * Make a corpse out of a character. */ void make_corpse(CHAR_DATA * ch, CHAR_DATA * killer) { char buf[MSL]; OBJ_DATA *corpse; OBJ_DATA *obj; OBJ_DATA *obj_next; char *name; int gold, silver, platinum; int wearloc; if (IS_NPC(ch)) { if (IS_SET(ch->act, ACT_NO_BODY)) { if (IS_SET(ch->act, ACT_NB_DROP)) { for (obj = ch->carrying; obj != NULL; obj = obj_next) { obj_next = obj->next_content; obj_from_char(obj); if (!IS_NPC(killer) && killer->pcdata->is_aquest) { obj->got_from = ch->pIndexData->vnum; } else { obj->got_from = 0; } if (obj->item_type == ITEM_POTION) obj->timer = number_range(500, 1000); if (obj->item_type == ITEM_SCROLL) obj->timer = number_range(1000, 2500); if (IS_SET(obj->extra_flags, ITEM_ROT_DEATH)) { obj->timer = number_range(5, 10); REMOVE_BIT(obj->extra_flags, ITEM_ROT_DEATH); } REMOVE_BIT(obj->extra_flags, ITEM_VIS_DEATH); if (IS_SET(obj->extra_flags, ITEM_INVENTORY)) extract_obj(obj); act("$p falls to the floor.", ch, obj, NULL, TO_ROOM); obj_to_room(obj, ch->in_room); } } return; } name = ch->short_descr; corpse = create_object(get_obj_index(OBJ_VNUM_CORPSE_NPC), 0); corpse->timer = number_range(3, 6); if (ch->silver > 0 || ch->gold > 0 || ch->platinum > 0) { obj_to_obj(create_money(ch->platinum, ch->gold, ch->silver), corpse); ch->platinum = 0; ch->gold = 0; ch->silver = 0; } corpse->cost = 0; } else { name = ch->name; corpse = create_object(get_obj_index(OBJ_VNUM_CORPSE_PC), 0); corpse->timer = number_range(25, 40); REMOVE_BIT(ch->act, PLR_CANLOOT); if (!is_clan(ch)) { corpse->owner = str_dup(ch->name); corpse->killer = NULL; } else { corpse->owner = str_dup(ch->name); corpse->killer = str_dup(killer->name); if (ch->platinum > 1 || ch->gold > 1 || ch->silver > 1) { silver = number_range(0, ch->silver / 3); gold = number_range(0, ch->gold / 3); platinum = number_range(0, ch->platinum / 3); obj_to_obj(create_money ((ch->platinum / 2) - platinum, (ch->gold / 2) - gold, (ch->silver / 2) - silver), corpse); ch->platinum -= ch->platinum / 2; ch->gold -= ch->gold / 2; ch->silver -= ch->silver / 2; obj_to_room(create_money(platinum, gold, silver), ch->in_room); act("Some money spills across the floor.", ch, NULL, NULL, TO_ROOM); act("Some of your money spills across the floor.", ch, NULL, NULL, TO_CHAR); } } corpse->cost = 0; } corpse->level = ch->level; sprintf(buf, corpse->short_descr, name); free_string(corpse->short_descr); corpse->short_descr = str_dup(buf); sprintf(buf, corpse->description, name); free_string(corpse->description); corpse->description = str_dup(buf); if (!IS_NPC(ch) && !IS_NPC(killer)) { wearloc = number_range(0, MAX_WEAR - 1); if ((obj = get_eq_char(ch, wearloc)) != NULL) { if ((obj->wear_loc != WEAR_FLOAT) && (obj->item_type != ITEM_PASSBOOK) && (!obj->clan) && (!obj->quest)) { obj_from_char(obj); obj_to_room(obj, ch->in_room); act("$p falls to the floor.", ch, obj, NULL, TO_ROOM); act("$p falls to the floor.", ch, obj, NULL, TO_CHAR); } } wearloc = number_range(0, MAX_WEAR - 1); if ((obj = get_eq_char(ch, wearloc)) != NULL) { if ((obj->wear_loc != WEAR_FLOAT) && (obj->item_type != ITEM_PASSBOOK) && (!obj->clan) && (!obj->quest)) { obj_from_char(obj); obj_to_room(obj, ch->in_room); act("$p falls to the floor.", ch, obj, NULL, TO_ROOM); act("$p falls to the floor.", ch, obj, NULL, TO_CHAR); } } wearloc = number_range(0, MAX_WEAR - 1); if ((obj = get_eq_char(ch, wearloc)) != NULL) { if ((obj->wear_loc != WEAR_FLOAT) && (obj->item_type != ITEM_PASSBOOK) && (!obj->clan) && (!obj->quest)) { obj_from_char(obj); obj_to_room(obj, ch->in_room); act("$p falls to the floor.", ch, obj, NULL, TO_ROOM); act("$p falls to the floor.", ch, obj, NULL, TO_CHAR); } } } for (obj = ch->carrying; obj != NULL; obj = obj_next) { bool floating = FALSE; obj_next = obj->next_content; if (IS_OBJ_STAT(obj, ITEM_LQUEST)) continue; if (obj->pIndexData->vnum == OBJ_VNUM_QPOUCH) continue; if (obj->wear_loc == WEAR_FLOAT) floating = TRUE; obj_from_char(obj); if (IS_NPC(ch) && !IS_NPC(killer) && killer->pcdata->is_aquest) { obj->got_from = ch->pIndexData->vnum; } else { obj->got_from = 0; } if (obj->item_type == ITEM_POTION) obj->timer = number_range(500, 1000); if (obj->item_type == ITEM_SCROLL) obj->timer = number_range(1000, 2500); if (IS_SET(obj->extra_flags, ITEM_ROT_DEATH) && !floating) { obj->timer = number_range(5, 10); REMOVE_BIT(obj->extra_flags, ITEM_ROT_DEATH); } REMOVE_BIT(obj->extra_flags, ITEM_VIS_DEATH); if (obj->item_type == ITEM_PASSBOOK) { change_banklist(ch, FALSE, obj->value[0], obj->value[1], 0, obj->name); extract_obj(obj); } else if (IS_SET(obj->extra_flags, ITEM_INVENTORY)) { extract_obj(obj); } else if (floating) { if (IS_OBJ_STAT(obj, ITEM_ROT_DEATH)) { /* get rid of it! */ if (obj->contains != NULL) { OBJ_DATA *in, *in_next; act("$p evaporates,scattering its contents.", ch, obj, NULL, TO_ROOM); for (in = obj->contains; in != NULL; in = in_next) { in_next = in->next_content; obj_from_obj(in); obj_to_room(in, ch->in_room); } } else act("$p evaporates.", ch, obj, NULL, TO_ROOM); extract_obj(obj); } else { act("$p falls to the floor.", ch, obj, NULL, TO_ROOM); obj_to_room(obj, ch->in_room); } } else obj_to_obj(obj, corpse); } if (!IS_NPC(ch)) { act("$p vanishes in a bright flash.", ch, corpse, NULL, TO_ROOM); act("Your corpse vanishes in a bright flash.", ch, corpse, NULL, TO_CHAR); if (ch->level < 10 && ch->pcdata->tier < 1 ) obj_to_room(corpse, get_room_index(ROOM_VNUM_MORGUE_SCHOOL)); else obj_to_room(corpse, get_room_index(home_table[ch->home].morgue)); } else { obj_to_room(corpse, ch->in_room); } return; } /* * Improved Death_cry contributed by Diavolo. * PK Token modifications added by D. A. C. */ void death_cry(CHAR_DATA * ch, CHAR_DATA * killer) { ROOM_INDEX_DATA *was_in_room; char buf[MSL]; OBJ_DATA *token2, *token3, *token4, *token5, *token6; // CHAR_DATA *victim; char *msg; int door; int vnum; vnum = 0; msg = "You hear $n's death cry."; if (!IS_SET(ch->act, ACT_NO_BODY)) { switch (number_bits(4)) { case 0: msg = "$n hits the ground ... DEAD."; vnum = OBJ_VNUM_BLOOD; break; case 1: msg = "$n splatters blood on your armor."; vnum = OBJ_VNUM_BLOOD; break; case 2: if (IS_SET(ch->parts, PART_GUTS)) { msg = "$n spills $s guts all over the floor."; vnum = OBJ_VNUM_GUTS; } break; case 3: if (IS_SET(ch->parts, PART_HEAD)) { msg = "$n's severed head plops on the ground."; vnum = OBJ_VNUM_SEVERED_HEAD; } break; case 4: if (IS_SET(ch->parts, PART_HEART)) { msg = "$n's heart is torn from $s chest."; vnum = OBJ_VNUM_TORN_HEART; } break; case 5: if (IS_SET(ch->parts, PART_ARMS)) { msg = "$n's arm is sliced from $s dead body."; vnum = OBJ_VNUM_SLICED_ARM; } break; case 6: if (IS_SET(ch->parts, PART_LEGS)) { msg = "$n's leg is sliced from $s dead body."; vnum = OBJ_VNUM_SLICED_LEG; } break; case 7: if (IS_SET(ch->parts, PART_BRAINS)) { msg = "$n's head is shattered, and $s brains splash all over you."; vnum = OBJ_VNUM_BRAINS; } break; case 8: msg = "$n hits the ground ... DEAD."; vnum = OBJ_VNUM_BLOOD; break; case 9: msg = "$n hits the ground ... DEAD."; vnum = OBJ_VNUM_BLOOD; } } else if (ch->level > 19) { switch (number_bits(4)) { case 0: msg = "$n hits the ground ... DEAD."; vnum = OBJ_VNUM_BLOOD; break; case 1: msg = "$n splatters blood on your armor."; vnum = OBJ_VNUM_BLOOD; break; case 2: if (IS_SET(ch->parts, PART_GUTS)) { msg = "$n spills $s guts all over the floor."; vnum = OBJ_VNUM_GUTS; } break; case 3: if (IS_SET(ch->parts, PART_HEAD)) { msg = "$n's severed head plops on the ground."; vnum = OBJ_VNUM_SEVERED_HEAD; } break; case 4: if (IS_SET(ch->parts, PART_HEART)) { msg = "$n's heart is torn from $s chest."; vnum = OBJ_VNUM_TORN_HEART; } break; case 5: if (IS_SET(ch->parts, PART_ARMS)) { msg = "$n's arm is sliced from $s dead body."; vnum = OBJ_VNUM_SLICED_ARM; } break; case 6: if (IS_SET(ch->parts, PART_LEGS)) { msg = "$n's leg is sliced from $s dead body."; vnum = OBJ_VNUM_SLICED_LEG; } break; case 7: if (IS_SET(ch->parts, PART_BRAINS)) { msg = "$n's head is shattered, and $s brains splash all over you."; vnum = OBJ_VNUM_BRAINS; } break; case 8: msg = "$n hits the ground ... DEAD."; vnum = OBJ_VNUM_BLOOD; break; case 9: msg = "$n hits the ground ... DEAD."; vnum = OBJ_VNUM_BLOOD; break; case 10: if (IS_SET(ch->parts, PART_HEAD)) { msg = "$n's severed head plops on the ground."; vnum = OBJ_VNUM_SEVERED_HEAD; } break; case 11: if (IS_SET(ch->parts, PART_HEART)) { msg = "$n's heart is torn from $s chest."; vnum = OBJ_VNUM_TORN_HEART; } break; case 12: if (IS_SET(ch->parts, PART_ARMS)) { msg = "$n's arm is sliced from $s dead body."; vnum = OBJ_VNUM_SLICED_ARM; } break; case 13: if (IS_SET(ch->parts, PART_LEGS)) { msg = "$n's leg is sliced from $s dead body."; vnum = OBJ_VNUM_SLICED_LEG; } break; case 14: if (IS_SET(ch->parts, PART_BRAINS)) { msg = "$n's head is shattered, and $s brains splash all over you."; vnum = OBJ_VNUM_BRAINS; } } } act(msg, ch, NULL, NULL, TO_ROOM); if ((vnum == 0) && !IS_SET(ch->act, ACT_NO_BODY) && (!IS_SET(ch->in_room->room_flags, ROOM_ARENA))) { switch (number_bits(4)) { case 0: if (killer == ch) // This part here is where I want it to return if its a self kill return; if ( !IS_NPC( ch ) ) { vnum = OVPKT1; } else { ; // vnum = vnum; } break; case 1: if (killer == ch) return; token2 = get_eq_char(killer, WEAR_HOLD); token4 = create_object(get_obj_index(OVPKT4), 0); if (!IS_NPC(ch) && token2 != NULL && token2->pIndexData->vnum == OVPKT2) { sprintf(buf, token4->short_descr, killer->name, ch->name); free_string(token4->short_descr); token4->short_descr = str_dup(buf); sprintf(buf, token4->description, killer->name, ch->name); free_string(token4->description); token4->description = str_dup(buf); sprintf(buf, token4->name, killer->name, ch->name); free_string(token4->name); token4->name = str_dup(buf); obj_from_char(token2); extract_obj(token2); obj_to_char(token4, killer); DAZE_STATE(killer, 17 + (5 * PULSE_VIOLENCE)); } else if ( !IS_NPC( ch ) ) { vnum = OVPKT1; } else { vnum = OBJ_VNUM_BLOOD; } break; case 2: if (killer == ch) return; if ( !IS_NPC( ch ) ) { vnum = OVPKT1; } else { vnum = OBJ_VNUM_BLOOD; } break; case 3: if (killer == ch) return; token2 = get_eq_char(killer, WEAR_HOLD); token4 = create_object(get_obj_index(OVPKT4), 0); if (!IS_NPC(ch) && token2 != NULL && token2->pIndexData->vnum == OVPKT2) { sprintf(buf, token4->short_descr, killer->name, ch->name); free_string(token4->short_descr); token4->short_descr = str_dup(buf); sprintf(buf, token4->description, killer->name, ch->name); free_string(token4->description); token4->description = str_dup(buf); sprintf(buf, token4->name, killer->name, ch->name); free_string(token4->name); token4->name = str_dup(buf); obj_from_char(token2); extract_obj(token2); obj_to_char(token4, killer); DAZE_STATE(killer, 17 + (5 * PULSE_VIOLENCE)); } else if ( !IS_NPC( ch ) ) { vnum = OVPKT2; } else { vnum = OBJ_VNUM_BLOOD; } break; case 4: if (killer == ch) return; token2 = get_eq_char(killer, WEAR_HOLD); token4 = get_eq_char(killer, WEAR_NECK_1); token5 = create_object(get_obj_index(OVPKT5), 0); if (!IS_NPC(ch) && token2 != NULL && token2->pIndexData->vnum == OVPKT2 && token4 != NULL && token4->pIndexData->vnum == OVPKT4) { obj_from_char(token2); extract_obj(token2); obj_to_char(token5, killer); DAZE_STATE(killer, 24 + (5 * PULSE_VIOLENCE)); } else if ( !IS_NPC( ch ) ) { vnum = OVPKT1; } else { vnum = OBJ_VNUM_BLOOD; } break; case 5: if (killer == ch) return; if ( !IS_NPC( ch ) ) { vnum = OVPKT1; } else { vnum = OBJ_VNUM_BLOOD; } break; case 6: if (killer == ch) return; token2 = get_eq_char(killer, WEAR_HOLD); token4 = get_eq_char(killer, WEAR_NECK_1); token5 = create_object(get_obj_index(OVPKT5), 0); if (!IS_NPC(ch) && token2 != NULL && token2->pIndexData->vnum == OVPKT2 && token4 != NULL && token4->pIndexData->vnum == OVPKT4) { obj_from_char(token2); extract_obj(token2); obj_to_char(token5, killer); DAZE_STATE(killer, 24 + (5 * PULSE_VIOLENCE)); } else if ( !IS_NPC( ch ) ) { vnum = OVPKT2; } else { vnum = OBJ_VNUM_BLOOD; } break; case 7: if (killer == ch) return; if ( !IS_NPC( ch ) ) { vnum = OVPKT2; } else { vnum = OBJ_VNUM_BLOOD; } break; case 8: if (killer == ch) return; token2 = get_eq_char(killer, WEAR_HOLD); token4 = get_eq_char(killer, WEAR_NECK_1); token5 = create_object(get_obj_index(OVPKT5), 0); if (!IS_NPC(ch) && token2 != NULL && token2->pIndexData->vnum == OVPKT2 && token4 != NULL && token4->pIndexData->vnum == OVPKT4) { obj_from_char(token2); extract_obj(token2); obj_to_char(token5, killer); DAZE_STATE(killer, 24 + (5 * PULSE_VIOLENCE)); } else if ( !IS_NPC( ch ) ) { vnum = OVPKT2; } else { vnum = OBJ_VNUM_BLOOD; } break; case 9: if (killer == ch) return; token2 = get_eq_char(killer, WEAR_HOLD); token3 = create_object(get_obj_index(OVPKT3), 0); if (!IS_NPC(ch) && token2 != NULL && token2->pIndexData->vnum == OVPKT2) { obj_from_char(token2); extract_obj(token2); obj_to_char(token3, killer); do_wear(killer, "token"); DAZE_STATE(killer, 12 + (5 * PULSE_VIOLENCE)); } else { vnum = OBJ_VNUM_BLOOD; } break; case 10: if (killer == ch) return; token2 = get_eq_char(killer, WEAR_HOLD); token4 = create_object(get_obj_index(OVPKT4), 0); if (!IS_NPC(ch) && token2 != NULL && token2->pIndexData->vnum == OVPKT2) { sprintf(buf, token4->short_descr, killer->name, ch->name); free_string(token4->short_descr); token4->short_descr = str_dup(buf); sprintf(buf, token4->description, killer->name, ch->name); free_string(token4->description); token4->description = str_dup(buf); sprintf(buf, token4->name, killer->name, ch->name); free_string(token4->name); token4->name = str_dup(buf); obj_from_char(token2); extract_obj(token2); obj_to_char(token4, killer); DAZE_STATE(killer, 17 + (5 * PULSE_VIOLENCE)); } else if ( !IS_NPC( ch ) ) { vnum = OVPKT2; } else { vnum = OBJ_VNUM_BLOOD; } break; case 11: if (killer == ch) return; token2 = get_eq_char(killer, WEAR_HOLD); token4 = get_eq_char(killer, WEAR_NECK_1); token5 = create_object(get_obj_index(OVPKT5), 0); if (!IS_NPC(ch) && token2 != NULL && token2->pIndexData->vnum == OVPKT2 && token4 != NULL && token4->pIndexData->vnum == OVPKT4) { obj_from_char(token2); extract_obj(token2); obj_to_char(token5, killer); DAZE_STATE(killer, 24 + (5 * PULSE_VIOLENCE)); } else if ( !IS_NPC( ch ) ) { vnum = OVPKT2; } else { vnum = OBJ_VNUM_BLOOD; } break; case 12: if (killer == ch) return; token2 = get_eq_char(killer, WEAR_HOLD); token4 = get_eq_char(killer, WEAR_NECK_1); token5 = get_eq_char(killer, WEAR_BODY); token6 = create_object(get_obj_index(OVPKT6), 0); if (!IS_NPC(ch) && token2 != NULL && token2->pIndexData->vnum == OVPKT2 && token4 != NULL && token4->pIndexData->vnum == OVPKT4 && token5 != NULL && token5->pIndexData->vnum == OVPKT5) { obj_from_char(token2); extract_obj(token2); obj_to_char(token6, killer); DAZE_STATE(killer, 32 + (5 * PULSE_VIOLENCE)); } else if ( !IS_NPC( ch ) ) { vnum = OVPKT2; } else { vnum = OBJ_VNUM_BLOOD; } break; } } if (vnum != 0) { char buf[MSL]; OBJ_DATA *obj; char *name; name = IS_NPC(ch) ? ch->short_descr : ch->name; obj = create_object(get_obj_index(vnum), 0); obj->timer = number_range(4, 7); if (!IS_NPC(ch)) { obj->timer = number_range(12, 18); } if (vnum == OBJ_VNUM_BLOOD) { obj->timer = number_range(1, 4); } if (IS_NPC(killer) && vnum == OVPKT1 ) { obj->timer = number_range(1, 4); } if (IS_NPC(killer) && vnum == OVPKT2 ) { obj->timer = number_range(1, 4); } if (!IS_NPC(killer) && vnum == OVPKT1 ) { obj->timer = number_range(100, 200); } if (!IS_NPC(killer) && vnum == OVPKT2 ) { obj->timer = number_range(100, 200); } if (vnum == OVPKT3) { obj->timer = number_range(50, 100 * PULSE_VIOLENCE); } sprintf(buf, obj->short_descr, name); free_string(obj->short_descr); obj->short_descr = str_dup(buf); sprintf(buf, obj->description, name); free_string(obj->description); obj->description = str_dup(buf); sprintf(buf, obj->name, name); free_string(obj->name); obj->name = str_dup(buf); if (obj->item_type == ITEM_FOOD) { if (IS_SET(ch->form, FORM_POISON)) obj->value[3] = 1; else if (!IS_SET(ch->form, FORM_EDIBLE)) obj->item_type = ITEM_TRASH; } if (IS_NPC(ch)) { obj->value[4] = 0; } else { obj->value[4] = 1; } obj_to_room(obj, ch->in_room); } if (IS_NPC(ch)) msg = "You hear something's death cry."; else msg = "You hear someone's death cry."; was_in_room = ch->in_room; for (door = 0; door <= 5; door++) { EXIT_DATA *pexit; if ((pexit = was_in_room->exit[door]) != NULL && pexit->u1.to_room != NULL && pexit->u1.to_room != was_in_room) { ch->in_room = pexit->u1.to_room; act(msg, ch, NULL, NULL, TO_ROOM); } } ch->in_room = was_in_room; return; } void raw_kill(CHAR_DATA * victim, CHAR_DATA * killer) { int i; death_cry( victim, killer ); stop_fighting(victim, TRUE); /*do not make corps if character is in arena*/ if (!IS_SET(victim->in_room->room_flags, ROOM_ARENA)) { make_corpse(victim, killer); } if (IS_NPC(victim) && !IS_NPC(killer)) { if ((killer->can_aquest == 2) && (victim->pIndexData->vnum == killer->pcdata->quest_mob)) { bool found = FALSE; OBJ_DATA *object; int level_vnum; level_vnum = ((killer->level / 10) + 56); for (object = killer->carrying; object != NULL; object = object->next_content) { if (IS_OBJ_STAT(object, ITEM_LQUEST) && (object->pIndexData->vnum == level_vnum)) found = TRUE; } if (!found) { char buf[MIL]; OBJ_DATA *obj; OBJ_DATA *obj_next; OBJ_DATA *pouch; sprintf(buf, "You quickly pick up the %s.\n\r", killer->pcdata->lquest_obj); send_to_char(buf, killer); object = create_object(get_obj_index(level_vnum), 0); sprintf(buf, "%s", killer->pcdata->lquest_obj); free_string(object->short_descr); object->short_descr = str_dup(buf); free_string(object->description); object->description = str_dup(buf); // DB free_string(object->name); object->name = str_dup(buf); buf[0] = '\0'; SET_BIT(object->extra_flags, ITEM_LQUEST); for (obj = killer->carrying; obj != NULL; obj = obj_next) { obj_next = obj->next_content; if (obj->pIndexData->vnum == OBJ_VNUM_QPOUCH) { obj_to_obj(object, obj); break; } else { pouch = create_object(get_obj_index(OBJ_VNUM_QPOUCH), 0); obj_to_char(pouch, killer); send_to_char ("Your quest pouch returns to you.{x\n\r", killer); obj_to_obj(object, pouch); break; } } } } } if (IS_NPC(victim)) { victim->pIndexData->killed++; kill_table[URANGE(0, victim->level, MAX_LEVEL - 1)].killed++; extract_char(victim, TRUE); if ( !IS_SET(victim->form,FORM_UNDEAD)) check_spirit(victim, killer); return; } do_mod_favor(victim, 4); if (killer->race == victim->race) do_mod_favor(killer, 9); /*do no give pkills, etc, for arena*/ if (!IS_SET(victim->in_room->room_flags, ROOM_ARENA)) { if (!IS_NPC(killer)) { if (strcmp(killer->pcdata->socket, victim->pcdata->socket)) { do_mod_favor(killer, 5); killer->pcdata->pkills++; } victim->pcdata->pdeath++; if (!is_banklist(victim)) { int bank; bank = number_range(0, MAX_BANKS - 1); if ((number_range(1, 100) < 50) && victim->balance[bank]) { char buf[MSL]; int amount; int pwd; OBJ_DATA *pbook; EXTRA_DESCR_DATA *ed; amount = (number_range(1, 75) / 100) * victim->balance[bank]; pwd = number_range(1, 20000); pbook = create_object(get_obj_index(OBJ_VNUM_PASSBOOK), 0); sprintf(buf, "%s %s", capitalize(victim->name), pbook->name); free_string(pbook->name); pbook->name = str_dup(buf); sprintf(buf, "The passbook is covered with strange magical symbols that prevent your eyes\n\rfrom focusing on the inscriptions. Only the word {B%s{x is legible.\n\r", capitalize(victim->name)); ed = alloc_perm(sizeof(*ed)); ed->keyword = str_dup("passbook"); ed->description = str_dup(buf); ed->next = pbook->extra_descr; pbook->extra_descr = ed; pbook->value[0] = bank; pbook->value[1] = pwd; pbook->value[2] = amount; obj_to_char(pbook, killer); send_to_char ("{RA passbook appears in your inventory!{x\n\r", killer); change_banklist(killer, TRUE, bank, amount, pwd, victim->name); } } } extract_char(victim, FALSE); while (victim->affected) affect_remove(victim, victim->affected); victim->affected_by = race_table[victim->race].aff; victim->shielded_by = race_table[victim->race].shd; for (i = 0; i < 4; i++) victim->armor[i] = 100; victim->position = POS_STANDING; victim->hit = UMAX(1, victim->hit); victim->mana = UMAX(1, victim->mana); victim->move = UMAX(1, victim->move); return; } } void group_gain(CHAR_DATA * ch, CHAR_DATA * victim) { char buf[MSL]; CHAR_DATA *gch; CHAR_DATA *lch; int xp; int members; int group_levels; /* * Monsters don't get kill xp's or alignment changes. * P-killing doesn't help either. * Dying of mortal wounds or poison doesn't give xp to anyone! */ if (victim == ch) return; members = 0; group_levels = 0; for (gch = ch->in_room->people; gch != NULL; gch = gch->next_in_room) { if (is_same_group(gch, ch)) { members++; group_levels += IS_NPC(gch) ? gch->level / 2 : gch->level; } } if (members == 0) { bug("Group_gain: members.", members); members = 1; group_levels = ch->level; } lch = (ch->leader != NULL) ? ch->leader : ch; for (gch = ch->in_room->people; gch != NULL; gch = gch->next_in_room) { OBJ_DATA *obj; OBJ_DATA *obj_next; if (!is_same_group(gch, ch) || IS_NPC(gch)) continue; /* Taken out, add it back if you want it if ( gch->level - lch->level >= 5 ) { send_to_char( "You are too high for this group.\n\r", gch ); continue; } if ( gch->level - lch->level <= -5 ) { send_to_char( "You are too low for this group.\n\r", gch ); continue; } */ xp = xp_compute(gch, victim, group_levels); if (global_xpq){ xp = xp*2; } if (!IS_NPC(ch) && IS_SET(ch->act, PLR_LQUEST)) xp = 0; sprintf(buf, "{BYou receive {W%d{B experience points.{x\n\r", xp); send_to_char(buf, gch); gain_exp(gch, xp); for (obj = ch->carrying; obj != NULL; obj = obj_next) { obj_next = obj->next_content; if (obj->wear_loc == WEAR_NONE) continue; if ((IS_OBJ_STAT(obj, ITEM_ANTI_EVIL) && IS_EVIL(ch)) || (IS_OBJ_STAT(obj, ITEM_ANTI_GOOD) && IS_GOOD(ch)) || (IS_OBJ_STAT(obj, ITEM_ANTI_NEUTRAL) && IS_NEUTRAL(ch))) { act("{cYou are {Wzapped{c by $p.{x", ch, obj, NULL, TO_CHAR); act("$n is {Wzapped{x by $p.", ch, obj, NULL, TO_ROOM); obj_from_char(obj); obj_to_room(obj, ch->in_room); } } if (IS_SET(ch->exbit1_flags, PLR_QUESTOR) && IS_NPC(victim)) { if (ch->questmob == victim->pIndexData->vnum) { send_to_char ("You have almost completed your ADVENTURE!\n\r", ch); send_to_char ("Return to the questmaster before your time runs out!\n\r", ch); ch->questmob = -1; } } } return; } /* * Compute xp for a kill. * Also adjust alignment of killer. * Edit this function to change xp computations. */ int xp_compute(CHAR_DATA * gch, CHAR_DATA * victim, int total_levels) { int xp, base_exp; int align, level_range; int change; int time_per_level; level_range = victim->level - gch->level; if (!IS_NPC(gch)) { // if (gch->class >= MCLT_1) // level_range -= 4; if (gch->pcdata->tier == 3) { level_range -= 4; } if (gch->pcdata->tier == 2) { level_range -= 3; } if (gch->pcdata->tier == 1) { level_range -= 2; } if (gch->pcdata->tier == 0) { level_range -= 1; } } /* compute the base exp */ switch (level_range) { default: base_exp = 0; break; case -9: base_exp = 1; break; case -8: base_exp = 3; break; case -7: base_exp = 8; break; case -6: base_exp = 14; break; case -5: base_exp = 22; break; case -4: base_exp = 35; break; case -3: base_exp = 49; break; case -2: base_exp = 61; break; case -1: base_exp = 77; break; case 0: base_exp = 95; break; case 1: base_exp = 115; break; case 2: base_exp = 135; break; case 3: base_exp = 157; break; case 4: base_exp = 181; break; } if (level_range > 4) base_exp = 181 + 29 * (level_range - 4); /* do alignment computations */ align = victim->alignment - gch->alignment; if (IS_SET(victim->act, ACT_NOALIGN)) { /* no change */ } else if (align > 500) { /* monster is more good than slayer */ change = (align - 500) * base_exp / 500 * gch->level / total_levels; change = UMAX(1, change); gch->alignment = UMAX(-1000, gch->alignment - change); if (gch->pet != NULL) gch->pet->alignment = gch->alignment; } else if (align < -500) { /* monster is more evil than slayer */ change = (-1 * align - 500) * base_exp / 500 * gch->level / total_levels; change = UMAX(1, change); gch->alignment = UMIN(1000, gch->alignment + change); if (gch->pet != NULL) gch->pet->alignment = gch->alignment; } else { /* improve this someday */ change = gch->alignment * base_exp / 500 * gch->level / total_levels; gch->alignment -= change; if (gch->pet != NULL) gch->pet->alignment = gch->alignment; } /* calculate exp multiplier */ if (IS_SET(victim->act, ACT_NOALIGN)) xp = base_exp; else if (gch->alignment > 500) { if (victim->alignment <= -750) xp = (base_exp * 4) / 3; else if (victim->alignment <= -500 && victim->alignment > -750) xp = (base_exp * 5) / 4; else if (victim->alignment <= -250 && victim->alignment > -500) xp = (base_exp * 6) / 5; else if (victim->alignment <= 250 && victim->alignment > -250) xp = (base_exp * 7) / 6; else if (victim->alignment <= 500 && victim->alignment > 250) xp = (base_exp * 8) / 7; else xp = base_exp; } else if (gch->alignment < -500) { if (victim->alignment >= 750) xp = (base_exp * 4) / 3; else if (victim->alignment >= 500 && victim->alignment < 750) xp = (base_exp * 5) / 4; else if (victim->alignment >= 250 && victim->alignment < 500) xp = (base_exp * 6) / 5; else if (victim->alignment >= -250 && victim->alignment < 250) xp = (base_exp * 7) / 6; else if (victim->alignment >= -500 && victim->alignment < -250) xp = (base_exp * 8) / 7; else if (victim->alignment > 500) xp = (base_exp * 11) / 10; else if (victim->alignment < -750) xp = base_exp / 2; else if (victim->alignment < -500) xp = (base_exp * 3) / 4; else if (victim->alignment < -250) xp = (base_exp * 9) / 10; else xp = base_exp; } else if (gch->alignment > 200) { /* a little good */ if (victim->alignment < -500) xp = (base_exp * 6) / 5; else if (victim->alignment > 750) xp = base_exp / 2; else if (victim->alignment > 0) xp = (base_exp * 3) / 4; else xp = base_exp; } else if (gch->alignment < -200) { /* a little bad */ if (victim->alignment > 500) xp = (base_exp * 6) / 5; else if (victim->alignment < -750) xp = base_exp / 2; else if (victim->alignment < 0) xp = (base_exp * 3) / 4; else xp = base_exp; } else { /* neutral */ if (victim->alignment > 500 || victim->alignment < -500) xp = (base_exp * 4) / 3; else if (victim->alignment < 200 && victim->alignment > -200) xp = base_exp / 2; else xp = base_exp; } /* more exp at the low levels */ if (gch->level < 11) xp = 15 * xp / (gch->level + 4); /* less at high */ if (gch->level > 60) xp = 15 * xp / (gch->level - 25); /* reduce for playing time */ { /* compute quarter-hours per level */ time_per_level = 4 * (gch->played + (int) (current_time - gch->logon)) / 3600 / gch->level; time_per_level = URANGE(2, time_per_level, 12); if (gch->level < 25) /* make it a curve */ time_per_level = UMAX(time_per_level, (25 - gch->level)); /* * xp = xp * time_per_level / 12; */ } /* xp = xp*.75; */ /* randomize the rewards */ xp = number_range(xp * 3 / 4, xp * 5 / 4); /* adjust for grouping */ xp = xp * gch->level / (UMAX(1, total_levels - 1)); if (!IS_NPC(gch) && !IS_NPC(victim)) if (xp > 1) xp = xp / 2; return xp; } void dam_message(CHAR_DATA * ch, CHAR_DATA * victim, int dam, int dt, bool immune) { char buf1[256], buf2[256], buf3[256]; const char *vs; const char *vp; const char *attack; char punct; if (ch == NULL || victim == NULL) return; if (dam == 0) { vs = "miss"; vp = "misses"; } else if (dam <= 4) { vs = "scratch"; vp = "scratches"; } else if (dam <= 8) { vs = "graze"; vp = "grazes"; } else if (dam <= 12) { vs = "hit"; vp = "hits"; } else if (dam <= 16) { vs = "injure"; vp = "injures"; } else if (dam <= 20) { vs = "wound"; vp = "wounds"; } else if (dam <= 24) { vs = "maul"; vp = "mauls"; } else if (dam <= 28) { vs = "decimate"; vp = "decimates"; } else if (dam <= 32) { vs = "devastate"; vp = "devastates"; } else if (dam <= 36) { vs = "maim"; vp = "maims"; } else if (dam <= 40) { vs = "MUTILATE"; vp = "MUTILATES"; } else if (dam <= 44) { vs = "DISEMBOWEL"; vp = "DISEMBOWELS"; } else if (dam <= 48) { vs = "DISMEMBER"; vp = "DISMEMBERS"; } else if (dam <= 52) { vs = "MASSACRE"; vp = "MASSACRES"; } else if (dam <= 56) { vs = "MANGLE"; vp = "MANGLES"; } else if (dam <= 60) { vs = "*** DEMOLISH ***"; vp = "*** DEMOLISHES ***"; } else if (dam <= 75) { vs = "*** DEVASTATE ***"; vp = "*** DEVASTATES ***"; } else if (dam <= 100) { vs = "=== OBLITERATE ==="; vp = "=== OBLITERATES ==="; } else if (dam <= 125) { vs = ">>> ANNIHILATE <<<"; vp = ">>> ANNIHILATES <<<"; } else if (dam <= 150) { vs = "<<< ERADICATE >>>"; vp = "<<< ERADICATES >>>"; } else { vs = "do UNSPEAKABLE things to"; vp = "does UNSPEAKABLE things to"; } punct = (dam <= 24) ? '.' : '!'; if (dt == TYPE_HIT) { if (ch == victim) { sprintf(buf1, "$n %s $melf%c{x", vp, punct); sprintf(buf2, "{hYou %s {hyourself%c{x", vs, punct); } else { sprintf(buf1, "{k$n %s {k$N%c {R[{k%d{R]{x", vp, punct, dam); sprintf(buf2, "{hYou %s {h$N%c {R[{h%d{R]{x", vs, punct, dam); sprintf(buf3, "{i$n %s {iyou%c {R[{i%d{R]{x", vp, punct, dam); } } else { if (dt >= 0 && dt < MAX_SKILL) attack = skill_table[dt].noun_damage; else if (dt >= TYPE_HIT && dt < TYPE_HIT + MAX_DAMAGE_MESSAGE) attack = attack_table[dt - TYPE_HIT].noun; else { bug("Dam_message: bad dt %d.", dt); dt = TYPE_HIT; attack = attack_table[0].name; } if (immune) { if (ch == victim) { sprintf(buf1, "$n is unaffected by $s own %s.{x", attack); sprintf(buf2, "{hLuckily, you are immune to that.{x"); } else { sprintf(buf1, "$N is unaffected by $n's %s!{x", attack); sprintf(buf2, "{h$N is unaffected by your %s!{x", attack); sprintf(buf3, "$n's %s is powerless against you.{x", attack); } } else { if (ch == victim) { sprintf(buf1, "$n's %s %s $m%c{x", attack, vp, punct); sprintf(buf2, "{hYour %s %s you%c{x", attack, vp, punct); } else { sprintf(buf1, "$n's %s %s $N%c {R[%d{R]{x", attack, vp, punct, dam); sprintf(buf2, "{hYour %s %s {h$N%c {R[{h%d{R]{x", attack, vp, punct, dam); sprintf(buf3, "$n's %s %s you%c {R[%d{R]{x", attack, vp, punct, dam); } } } if (ch == victim) { act(buf1, ch, NULL, NULL, TO_ROOM); act(buf2, ch, NULL, NULL, TO_CHAR); } else { act(buf1, ch, NULL, victim, TO_NOTVICT); act(buf2, ch, NULL, victim, TO_CHAR); act(buf3, ch, NULL, victim, TO_VICT); } return; } void do_surrender( CHAR_DATA *ch, char *argument ) { CHAR_DATA *mob; if ( (mob = ch->fighting) == NULL ) { send_to_char( "But you're not fighting!\n\r", ch ); return; } act( "You surrender to $N!", ch, NULL, mob, TO_CHAR ); act( "$n surrenders to you!", ch, NULL, mob, TO_VICT ); act( "$n tries to surrender to $N!", ch, NULL, mob, TO_NOTVICT ); stop_fighting( ch, TRUE ); if ( !IS_NPC( ch ) && IS_NPC( mob ) && ( !HAS_TRIGGER( mob, TRIG_SURR ) || !mp_percent_trigger( mob, ch, NULL, NULL, TRIG_SURR ) ) ) { act( "$N seems to ignore your cowardly act!", ch, NULL, mob, TO_CHAR ); multi_hit( mob, ch, TYPE_UNDEFINED ); } } /* * Disarm a creature. * Caller must check for successful attack. */ void disarm(CHAR_DATA * ch, CHAR_DATA * victim) { OBJ_DATA *obj; if ((obj = get_eq_char(victim, WEAR_WIELD)) == NULL) return; if (ch->shadow) { ch->shadowing->shadowed = FALSE; ch->shadowing->shadower = NULL; ch->shadowing = NULL; ch->shadow = FALSE; } if (IS_OBJ_STAT(obj, ITEM_NOREMOVE)) { act("{j$S weapon won't budge!{x", ch, NULL, victim, TO_CHAR); act("{j$n tries to disarm you, but your weapon won't budge!{x", ch, NULL, victim, TO_VICT); act("$n tries to disarm $N, but fails.{x", ch, NULL, victim, TO_NOTVICT); return; } act("{j$n DISARMS you and sends your weapon flying!{x", ch, NULL, victim, TO_VICT); act("{jYou disarm $N!{x", ch, NULL, victim, TO_CHAR); act("$n disarms $N!{x", ch, NULL, victim, TO_NOTVICT); obj_from_char(obj); if (IS_OBJ_STAT(obj, ITEM_NODROP) || IS_OBJ_STAT(obj, ITEM_INVENTORY)) obj_to_char(obj, victim); else { obj_to_room(obj, victim->in_room); if (IS_NPC(victim) && victim->wait == 0 && can_see_obj(victim, obj)) get_obj(victim, obj, NULL); } return; } void do_berserk(CHAR_DATA * ch, char *argument) { int chance, hp_percent; if ((chance = get_skill(ch, gsn_berserk)) == 0 || (IS_NPC(ch) && !IS_SET(ch->off_flags, OFF_BERSERK)) || (!IS_NPC(ch) && ch->level < skill_table[gsn_berserk].skill_level[ch->class])) { if (IS_NPC(ch)) { send_to_char ("{hYou turn {rred{h in the face, but nothing happens.{x\n\r", ch); return; } if (ch->pcdata->tier != 2) { send_to_char ("{hYou turn {rred{h in the face, but nothing happens.{x\n\r", ch); return; } else if (chance == 0 || (IS_NPC(ch) && !IS_SET(ch->off_flags, OFF_BERSERK)) || (!IS_NPC(ch) && ch->level < skill_table[gsn_berserk].skill_level[ch->clasb])) { send_to_char ("{hYou turn {rred{h in the face, but nothing happens.{x\n\r", ch); return; } } if (IS_AFFECTED(ch, AFF_BERSERK) || is_affected(ch, gsn_berserk) || is_affected(ch, skill_lookup("frenzy"))) { send_to_char("{hYou get a little madder.{x\n\r", ch); return; } if (IS_AFFECTED(ch, AFF_CALM)) { send_to_char("{hYou're feeling to mellow to berserk.{x\n\r", ch); return; } if (ch->mana < 50) { send_to_char("{hYou can't get up enough energy.{x\n\r", ch); return; } /* modifiers */ /* fighting */ if (ch->position == POS_FIGHTING) chance += 10; /* damage -- below 50% of hp helps, above hurts */ hp_percent = 100 * ch->hit / ch->max_hit; chance += 25 - hp_percent / 2; if (number_percent() < chance) { AFFECT_DATA af; WAIT_STATE(ch, PULSE_VIOLENCE); ch->mana -= 50; ch->move /= 2; /* heal a little damage */ ch->hit += ch->level * 2; ch->hit = UMIN(ch->hit, ch->max_hit); if (ch->shadow) { ch->shadowing->shadowed = FALSE; ch->shadowing->shadower = NULL; ch->shadowing = NULL; ch->shadow = FALSE; } send_to_char ("{hYour pulse races as you are consumed by {rrage!{x\n\r", ch); act("$n gets a {cw{gi{rl{yd look in $s eyes.{x", ch, NULL, NULL, TO_ROOM); check_improve(ch, gsn_berserk, TRUE, 2); af.where = TO_AFFECTS; af.type = gsn_berserk; af.level = ch->level; af.duration = number_fuzzy(ch->level / 8); af.modifier = UMAX(1, ch->level / 5); af.bitvector = AFF_BERSERK; af.location = APPLY_HITROLL; affect_to_char(ch, &af); af.location = APPLY_DAMROLL; affect_to_char(ch, &af); af.modifier = UMAX(10, 10 * (ch->level / 5)); af.location = APPLY_AC; affect_to_char(ch, &af); } else { WAIT_STATE(ch, 3 * PULSE_VIOLENCE); ch->mana -= 25; ch->move /= 2; send_to_char("{hYour pulse speeds up, but nothing happens.{x\n\r", ch); check_improve(ch, gsn_berserk, FALSE, 2); } } void do_voodoo(CHAR_DATA * ch, char *argument) { char arg[MIL]; OBJ_DATA *doll; if (IS_NPC(ch)) return; doll = get_eq_char(ch, WEAR_HOLD); if (doll == NULL || (doll->pIndexData->vnum != OBJ_VNUM_VOODOO)) { send_to_char("You are not holding a voodoo doll.\n\r", ch); return; } one_argument(argument, arg); if (arg[0] == '\0') { send_to_char("Syntax: voodoo <action>\n\r", ch); send_to_char("Actions: pin trip throw\n\r", ch); return; } if (!str_cmp(arg, "pin")) { do_vdpi(ch, doll->name); return; } if (!str_cmp(arg, "trip")) { do_vdtr(ch, doll->name); return; } if (!str_cmp(arg, "throw")) { do_vdth(ch, doll->name); return; } do_voodoo(ch, ""); } void do_vdpi(CHAR_DATA * ch, char *argument) { char arg1[MIL]; DESCRIPTOR_DATA *d; AFFECT_DATA af; bool found = FALSE; argument = one_argument(argument, arg1); for (d = descriptor_list; d != NULL; d = d->next) { CHAR_DATA *wch; if (d->connected != CON_PLAYING || !can_see(ch, d->character)) continue; wch = (d->original != NULL) ? d->original : d->character; if (!can_see(ch, wch)) continue; if (!str_cmp(arg1, wch->name) && !found) { if (IS_NPC(wch)) continue; if (IS_IMMORTAL(wch) && (wch->level > ch->level)) { send_to_char("That's not a good idea.\n\r", ch); return; } if ((wch->level < 20) && !IS_IMMORTAL(ch)) { send_to_char("They are a little too young for that.\n\r", ch); return; } if (IS_SHIELDED(wch, SHD_PROTECT_VOODOO)) { send_to_char ("They are still realing from a previous voodoo.\n\r", ch); return; } found = TRUE; if (ch->shadow) { ch->shadowing->shadowed = FALSE; ch->shadowing->shadower = NULL; ch->shadowing = NULL; ch->shadow = FALSE; } send_to_char("You stick a pin into your voodoo doll.\n\r", ch); act("$n sticks a pin into a voodoo doll.", ch, NULL, NULL, TO_ROOM); send_to_char ("{RYou double over with a sudden pain in your gut!{x\n\r", wch); act("$n suddenly doubles over with a look of extreme pain!", wch, NULL, NULL, TO_ROOM); af.where = TO_SHIELDS; af.type = skill_lookup("protection voodoo"); af.level = wch->level; af.duration = 1; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = SHD_PROTECT_VOODOO; affect_to_char(wch, &af); return; } } send_to_char("Your victim doesn't seem to be in the realm.\n\r", ch); return; } void do_vdtr(CHAR_DATA * ch, char *argument) { char arg1[MIL]; DESCRIPTOR_DATA *d; AFFECT_DATA af; bool found = FALSE; argument = one_argument(argument, arg1); for (d = descriptor_list; d != NULL; d = d->next) { CHAR_DATA *wch; if (d->connected != CON_PLAYING || !can_see(ch, d->character)) continue; wch = (d->original != NULL) ? d->original : d->character; if (!can_see(ch, wch)) continue; if (!str_cmp(arg1, wch->name) && !found) { if (IS_NPC(wch)) continue; if (IS_IMMORTAL(wch) && (wch->level > ch->level)) { send_to_char("That's not a good idea.\n\r", ch); return; } if ((wch->level < 20) && !IS_IMMORTAL(ch)) { send_to_char("They are a little too young for that.\n\r", ch); return; } if (IS_SHIELDED(wch, SHD_PROTECT_VOODOO)) { send_to_char ("They are still realing from a previous voodoo.\n\r", ch); return; } found = TRUE; if (ch->shadow) { ch->shadowing->shadowed = FALSE; ch->shadowing->shadower = NULL; ch->shadowing = NULL; ch->shadow = FALSE; } send_to_char ("You slam your voodoo doll against the ground.\n\r", ch); act("$n slams a voodoo doll against the ground.", ch, NULL, NULL, TO_ROOM); send_to_char("{RYour feet slide out from under you!{x\n\r", wch); send_to_char("{RYou hit the ground face first!{x\n\r", wch); act ("$n trips over $s own feet, and does a nose dive into the ground!", wch, NULL, NULL, TO_ROOM); af.where = TO_SHIELDS; af.type = skill_lookup("protection voodoo"); af.level = wch->level; af.duration = 1; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = SHD_PROTECT_VOODOO; affect_to_char(wch, &af); return; } } send_to_char("Your victim doesn't seem to be in the realm.\n\r", ch); return; } void do_vdth(CHAR_DATA * ch, char *argument) { char arg1[MIL]; char buf[MSL]; DESCRIPTOR_DATA *d; AFFECT_DATA af; ROOM_INDEX_DATA *was_in; ROOM_INDEX_DATA *now_in; bool found = FALSE; int attempt; argument = one_argument(argument, arg1); for (d = descriptor_list; d != NULL; d = d->next) { CHAR_DATA *wch; if (d->connected != CON_PLAYING || !can_see(ch, d->character)) continue; wch = (d->original != NULL) ? d->original : d->character; if (!can_see(ch, wch)) continue; if (!str_cmp(arg1, wch->name) && !found) { if (IS_NPC(wch)) continue; if (IS_IMMORTAL(wch) && (wch->level > ch->level)) { send_to_char("That's not a good idea.\n\r", ch); return; } if ((wch->level < 20) && !IS_IMMORTAL(ch)) { send_to_char("They are a little too young for that.\n\r", ch); return; } if (IS_SHIELDED(wch, SHD_PROTECT_VOODOO)) { send_to_char ("They are still reeling from a previous voodoo.\n\r", ch); return; } found = TRUE; if (ch->shadow) { ch->shadowing->shadowed = FALSE; ch->shadowing->shadower = NULL; ch->shadowing = NULL; ch->shadow = FALSE; } send_to_char("You toss your voodoo doll into the air.\n\r", ch); act("$n tosses a voodoo doll into the air.", ch, NULL, NULL, TO_ROOM); af.where = TO_SHIELDS; af.type = skill_lookup("protection voodoo"); af.level = wch->level; af.duration = 1; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = SHD_PROTECT_VOODOO; affect_to_char(wch, &af); if ((wch->fighting != NULL) || (number_percent() < 25)) { send_to_char ("{RA sudden gust of wind throws you through the air!{x\n\r", wch); send_to_char ("{RYou slam face first into the nearest wall!{x\n\r", wch); act ("A sudden gust of wind picks up $n and throws $m into a wall!", wch, NULL, NULL, TO_ROOM); return; } wch->position = POS_STANDING; was_in = wch->in_room; for (attempt = 0; attempt < 6; attempt++) { EXIT_DATA *pexit; int door; door = number_door(); if ((pexit = was_in->exit[door]) == 0 || pexit->u1.to_room == NULL || IS_SET(pexit->exit_info, EX_CLOSED) || (IS_NPC(wch) && IS_SET(pexit->u1.to_room->room_flags, ROOM_NO_MOB))) continue; move_char(wch, door, FALSE, TRUE); if ((now_in = wch->in_room) == was_in) continue; wch->in_room = was_in; sprintf(buf, "A sudden gust of wind picks up $n and throws $m to the %s.", dir_name[door]); act(buf, wch, NULL, NULL, TO_ROOM); send_to_char ("{RA sudden gust of wind throws you through the air!{x\n\r", wch); wch->in_room = now_in; act ("$n sails into the room and slams face first into a wall!", wch, NULL, NULL, TO_ROOM); do_look(wch, "auto"); send_to_char ("{RYou slam face first into the nearest wall!{x\n\r", wch); return; } send_to_char ("{RA sudden gust of wind throws you through the air!{x\n\r", wch); send_to_char ("{RYou slam face first into the nearest wall!{x\n\r", wch); act ("A sudden gust of wind picks up $n and throws $m into a wall!", wch, NULL, NULL, TO_ROOM); return; } } send_to_char("Your victim doesn't seem to be in the realm.\n\r", ch); return; } void do_bash(CHAR_DATA * ch, char *argument) { char arg[MIL]; CHAR_DATA *victim; int chance; one_argument(argument, arg); if ((chance = get_skill(ch, gsn_bash)) == 0 || (IS_NPC(ch) && !IS_SET(ch->off_flags, OFF_BASH))) { send_to_char("Bashing? What's that?\n\r", ch); return; } if (!IS_NPC(ch)) { if (ch->pcdata->tier != 2) { if (ch->level < skill_table[gsn_bash].skill_level[ch->class]) { send_to_char("Bashing? What's that?\n\r", ch); return; } } else if ((ch->level < skill_table[gsn_bash].skill_level[ch->class]) && (ch->level < skill_table[gsn_bash].skill_level[ch->clasb])) { send_to_char("Bashing? What's that?\n\r", ch); return; } } if (arg[0] == '\0') { victim = ch->fighting; if (victim == NULL) { send_to_char("But you aren't fighting anyone!\n\r", ch); return; } } else if ((victim = get_char_room(ch, arg)) == NULL) { send_to_char("They aren't here.\n\r", ch); return; } if (victim->position < POS_FIGHTING) { act("You'll have to let $M get back up first.", ch, NULL, victim, TO_CHAR); return; } if (victim == ch) { send_to_char("You try to bash your brains out, but fail.\n\r", ch); return; } if (is_safe(ch, victim)) return; if (IS_NPC(victim) && victim->fighting != NULL && !is_same_group(ch, victim->fighting)) { send_to_char("Kill stealing is not permitted.\n\r", ch); return; } if (IS_AFFECTED(ch, AFF_CHARM) && ch->master == victim) { act("But $N is your friend!", ch, NULL, victim, TO_CHAR); return; } if (ch->stunned) { send_to_char("You're still a little woozy.\n\r", ch); return; } if (!can_see(ch, victim)) { send_to_char ("You get a running start, and slam right into a wall.\n\r", ch); return; } if (ch->shadow) { ch->shadowing->shadowed = FALSE; ch->shadowing->shadower = NULL; ch->shadowing = NULL; ch->shadow = FALSE; } if ((ch->fighting == NULL) && (!IS_NPC(ch)) && (!IS_NPC(victim))) { ch->attacker = TRUE; victim->attacker = FALSE; } /* modifiers */ /* size and weight */ chance += ch->carry_weight / 250; chance -= victim->carry_weight / 200; if (ch->size < victim->size) chance += (ch->size - victim->size) * 15; else chance += (ch->size - victim->size) * 10; /* stats */ chance += get_curr_stat(ch, STAT_STR); chance -= (get_curr_stat(victim, STAT_DEX) * 4) / 3; chance -= GET_AC(victim, AC_BASH) / 25; /* speed */ if (IS_SET(ch->off_flags, OFF_FAST) || IS_AFFECTED(ch, AFF_HASTE)) chance += 10; if (IS_SET(victim->off_flags, OFF_FAST) || IS_AFFECTED(victim, AFF_HASTE)) chance -= 30; /* level */ chance += (ch->level - victim->level); if (!IS_NPC(victim) && chance < get_skill(victim, gsn_dodge)) { /* act("$n tries to bash you, but you dodge it.{x",ch,NULL,victim,TO_VICT); act("{h$N dodges your bash, you fall flat on your face.{x",ch,NULL,victim,TO_CHAR); WAIT_STATE(ch,skill_table[gsn_bash].beats); return; */ chance -= 3 * (get_skill(victim, gsn_dodge) - chance); } /* now the attack */ if (number_percent() < chance) { int dam; dam = number_range(2, 2 + 2 * ch->size + chance / 20); act("$n sends you sprawling with a powerful bash!{x", ch, NULL, victim, TO_VICT); act("{hYou slam into $N, and send $M flying!{x", ch, NULL, victim, TO_CHAR); act("$n sends $N sprawling with a powerful bash.{x", ch, NULL, victim, TO_NOTVICT); check_improve(ch, gsn_bash, TRUE, 1); DAZE_STATE(victim, 3 * PULSE_VIOLENCE); WAIT_STATE(ch, skill_table[gsn_bash].beats); victim->position = POS_RESTING; damage(ch, victim, dam, gsn_bash, DAM_BASH, TRUE); chance = (get_skill(ch, gsn_stun) / 5); if (number_percent() < chance) { chance = (get_skill(ch, gsn_stun) / 5); if (number_percent() < chance) { victim->stunned = 2; } else { victim->stunned = 1; } act("You are stunned, and have trouble getting back up!{x", ch, NULL, victim, TO_VICT); act("{h$N is stunned by your bash!{x", ch, NULL, victim, TO_CHAR); act("$N is having trouble getting back up.{x", ch, NULL, victim, TO_NOTVICT); check_improve(ch, gsn_stun, TRUE, 1); } } else { damage(ch, victim, 0, gsn_bash, DAM_BASH, FALSE); act("{hYou fall flat on your face!{x", ch, NULL, victim, TO_CHAR); act("$n falls flat on $s face.{x", ch, NULL, victim, TO_NOTVICT); act("You evade $n's bash, causing $m to fall flat on $s face.{x", ch, NULL, victim, TO_VICT); check_improve(ch, gsn_bash, FALSE, 1); ch->position = POS_RESTING; WAIT_STATE(ch, skill_table[gsn_bash].beats * 3 / 2); } } void do_dirt(CHAR_DATA * ch, char *argument) { char arg[MIL]; CHAR_DATA *victim; int chance; one_argument(argument, arg); if ((chance = get_skill(ch, gsn_dirt)) == 0 || (IS_NPC(ch) && !IS_SET(ch->off_flags, OFF_KICK_DIRT))) { send_to_char("{hYou get your feet dirty.{x\n\r", ch); return; } if (!IS_NPC(ch)) { if (ch->pcdata->tier != 2) { if (ch->level < skill_table[gsn_dirt].skill_level[ch->class]) { send_to_char("{hYou get your feet dirty.{x\n\r", ch); return; } } else if ((ch->level < skill_table[gsn_dirt].skill_level[ch->class]) && (ch->level < skill_table[gsn_dirt].skill_level[ch->clasb])) { send_to_char("{hYou get your feet dirty.{x\n\r", ch); return; } } if (arg[0] == '\0') { victim = ch->fighting; if (victim == NULL) { send_to_char("But you aren't in combat!\n\r", ch); return; } } else if ((victim = get_char_room(ch, arg)) == NULL) { send_to_char("They aren't here.\n\r", ch); return; } if (IS_AFFECTED(victim, AFF_BLIND)) { act("{h$E's already been blinded.{x", ch, NULL, victim, TO_CHAR); return; } if (victim == ch) { send_to_char("Very funny.\n\r", ch); return; } if (is_safe(ch, victim)) return; if (IS_NPC(victim) && victim->fighting != NULL && !is_same_group(ch, victim->fighting)) { send_to_char("Kill stealing is not permitted.\n\r", ch); return; } if (IS_AFFECTED(ch, AFF_CHARM) && ch->master == victim) { act("But $N is such a good friend!", ch, NULL, victim, TO_CHAR); return; } if (ch->stunned) { send_to_char("You're still a little woozy.\n\r", ch); return; } if (IS_SET(victim->exbit1_flags, RECRUIT) || IS_SET(victim->exbit1_flags, PK_VETERAN) || IS_SET(victim->exbit1_flags, PK_LAWFUL) || IS_SET(victim->exbit1_flags, PK_KILLER) || IS_SET(victim->exbit1_flags, PK_KILLER) || IS_SET(ch->exbit1_flags, RECRUIT) || IS_SET(ch->exbit1_flags, PK_VETERAN) || IS_SET(ch->exbit1_flags, PK_LAWFUL) || IS_SET(ch->exbit1_flags, PK_KILLER) ) { if (victim->fighting != NULL && IS_SET(ch->exbit1_flags, PK_LAWFUL) && !IS_NPC(victim)) { send_to_char("So thats the way you like to play.\n\r", ch); REMOVE_BIT(ch->exbit1_flags, PK_LAWFUL); SET_BIT(ch->exbit1_flags, PK_KILLER); } else if (victim->fighting != NULL && IS_SET(ch->exbit1_flags, PK_KILLER) && !IS_NPC(victim)) { send_to_char("You really deserve this.\n\r", ch); REMOVE_BIT(ch->exbit1_flags, PK_KILLER); SET_BIT(ch->exbit1_flags, PK_KILLER2); } // send_to_char("Have mercy on them.\n\r", ch); } if ((ch->fighting == NULL) && (!IS_NPC(ch)) && (!IS_NPC(victim))) { ch->attacker = TRUE; victim->attacker = FALSE; } /* modifiers */ /* dexterity */ chance += get_curr_stat(ch, STAT_DEX); chance -= 2 * get_curr_stat(victim, STAT_DEX); /* speed */ if (IS_SET(ch->off_flags, OFF_FAST) || IS_AFFECTED(ch, AFF_HASTE)) chance += 10; if (IS_SET(victim->off_flags, OFF_FAST) || IS_AFFECTED(victim, AFF_HASTE)) chance -= 25; /* level */ chance += (ch->level - victim->level) * 2; /* sloppy hack to prevent false zeroes */ if (chance % 5 == 0) chance += 1; /* terrain */ switch (ch->in_room->sector_type) { case (SECT_INSIDE): chance -= 20; break; case (SECT_CITY): chance -= 10; break; case (SECT_FIELD): chance += 5; break; case (SECT_FOREST): break; case (SECT_HILLS): break; case (SECT_MOUNTAIN): chance -= 10; break; case (SECT_WATER_SWIM): chance = 0; break; case (SECT_WATER_NOSWIM): chance = 0; break; case (SECT_AIR): chance = 0; break; case (SECT_DESERT): chance += 10; break; } if (chance == 0) { send_to_char("{hThere isn't any dirt to kick.{x\n\r", ch); return; } if (ch->shadow) { ch->shadowing->shadowed = FALSE; ch->shadowing->shadower = NULL; ch->shadowing = NULL; ch->shadow = FALSE; } /* now the attack */ if (number_percent() < chance) { AFFECT_DATA af; int dam; dam = number_range(2, 5); act("$n is blinded by the dirt in $s eyes!{x", victim, NULL, NULL, TO_ROOM); act("$n kicks dirt in your eyes!{x", ch, NULL, victim, TO_VICT); damage(ch, victim, dam, gsn_dirt, DAM_NONE, TRUE); send_to_char("{DYou can't see a thing!{x\n\r", victim); check_improve(ch, gsn_dirt, TRUE, 2); WAIT_STATE(ch, skill_table[gsn_dirt].beats); af.where = TO_AFFECTS; af.type = gsn_dirt; af.level = ch->level; af.duration = 0; af.location = APPLY_HITROLL; af.modifier = -4; af.bitvector = AFF_BLIND; affect_to_char(victim, &af); } else { damage(ch, victim, 0, gsn_dirt, DAM_NONE, TRUE); check_improve(ch, gsn_dirt, FALSE, 2); WAIT_STATE(ch, skill_table[gsn_dirt].beats); } } void do_gouge(CHAR_DATA * ch, char *argument) { char arg[MIL]; CHAR_DATA *victim; int chance; one_argument(argument, arg); if ((chance = get_skill(ch, gsn_gouge)) == 0) { send_to_char("Gouge? What's that?\n\r", ch); return; } if (!IS_NPC(ch)) { if (ch->pcdata->tier != 2) { if (ch->level < skill_table[gsn_gouge].skill_level[ch->class]) { send_to_char("Gouge? What's that?\n\r", ch); return; } } else if ((ch->level < skill_table[gsn_gouge].skill_level[ch->class]) && (ch->level < skill_table[gsn_gouge].skill_level[ch->clasb])) { send_to_char("Gouge? What's that?\n\r", ch); return; } } if (arg[0] == '\0') { victim = ch->fighting; if (victim == NULL) { send_to_char("But you aren't in combat!\n\r", ch); return; } } else if ((victim = get_char_room(ch, arg)) == NULL) { send_to_char("They aren't here.\n\r", ch); return; } if (IS_AFFECTED(victim, AFF_BLIND)) { act("{h$E's already been blinded.{x", ch, NULL, victim, TO_CHAR); return; } if (victim == ch) { send_to_char("Very funny.\n\r", ch); return; } if (is_safe(ch, victim)) return; if (IS_NPC(victim) && victim->fighting != NULL && !is_same_group(ch, victim->fighting)) { send_to_char("Kill stealing is not permitted.\n\r", ch); return; } if (IS_AFFECTED(ch, AFF_CHARM) && ch->master == victim) { act("But $N is such a good friend!", ch, NULL, victim, TO_CHAR); return; } if (ch->stunned) { send_to_char("You're still a little woozy.\n\r", ch); return; } if (ch->shadow) { ch->shadowing->shadowed = FALSE; ch->shadowing->shadower = NULL; ch->shadowing = NULL; ch->shadow = FALSE; } if ((ch->fighting == NULL) && (!IS_NPC(ch)) && (!IS_NPC(victim))) { ch->attacker = TRUE; victim->attacker = FALSE; } /* modifiers */ /* dexterity */ chance += get_curr_stat(ch, STAT_DEX); chance -= 2 * get_curr_stat(victim, STAT_DEX); /* speed */ if (IS_SET(ch->off_flags, OFF_FAST) || IS_AFFECTED(ch, AFF_HASTE)) chance += 10; if (IS_SET(victim->off_flags, OFF_FAST) || IS_AFFECTED(victim, AFF_HASTE)) chance -= 25; /* level */ chance += (ch->level - victim->level) * 2; /* sloppy hack to prevent false zeroes */ if (chance % 5 == 0) chance += 1; /* now the attack */ if (number_percent() < chance) { AFFECT_DATA af; int dam; dam = number_range(2, 8); act("$n is blinded by a poke in the eyes!{x", victim, NULL, NULL, TO_ROOM); act("$n gouges at your eyes!{x", ch, NULL, victim, TO_VICT); damage(ch, victim, dam, gsn_gouge, DAM_NONE, TRUE); send_to_char("{DYou see nothing but stars!{x\n\r", victim); check_improve(ch, gsn_gouge, TRUE, 2); WAIT_STATE(ch, skill_table[gsn_gouge].beats); af.where = TO_AFFECTS; af.type = gsn_gouge; af.level = ch->level; af.duration = 0; af.location = APPLY_HITROLL; af.modifier = -4; af.bitvector = AFF_BLIND; affect_to_char(victim, &af); } else { damage(ch, victim, 0, gsn_gouge, DAM_NONE, TRUE); check_improve(ch, gsn_gouge, FALSE, 2); WAIT_STATE(ch, skill_table[gsn_gouge].beats); } } void do_trip(CHAR_DATA * ch, char *argument) { char arg[MIL]; CHAR_DATA *victim; int chance; one_argument(argument, arg); if ((chance = get_skill(ch, gsn_trip)) == 0 || (IS_NPC(ch) && !IS_SET(ch->off_flags, OFF_TRIP))) { send_to_char("Tripping? What's that?\n\r", ch); return; } if (!IS_NPC(ch)) { if (ch->pcdata->tier != 2) { if (ch->level < skill_table[gsn_trip].skill_level[ch->class]) { send_to_char("Tripping? What's that?\n\r", ch); return; } } else if ((ch->level < skill_table[gsn_trip].skill_level[ch->class]) && (ch->level < skill_table[gsn_trip].skill_level[ch->clasb])) { send_to_char("Tripping? What's that?\n\r", ch); return; } } if (arg[0] == '\0') { victim = ch->fighting; if (victim == NULL) { send_to_char("But you aren't fighting anyone!\n\r", ch); return; } } else if ((victim = get_char_room(ch, arg)) == NULL) { send_to_char("They aren't here.\n\r", ch); return; } if (is_safe(ch, victim)) return; if (IS_NPC(victim) && victim->fighting != NULL && !is_same_group(ch, victim->fighting)) { send_to_char("Kill stealing is not permitted.\n\r", ch); return; } if (ch->stunned) { send_to_char("You're still a little woozy.\n\r", ch); return; } if (IS_AFFECTED(victim, AFF_FLYING)) { act("{h$S feet aren't on the ground.{x", ch, NULL, victim, TO_CHAR); return; } if (victim->position < POS_FIGHTING) { act("{h$N is already down.{c", ch, NULL, victim, TO_CHAR); return; } if (IS_AFFECTED(ch, AFF_CHARM) && ch->master == victim) { act("$N is your beloved master.", ch, NULL, victim, TO_CHAR); return; } if (ch->shadow) { ch->shadowing->shadowed = FALSE; ch->shadowing->shadower = NULL; ch->shadowing = NULL; ch->shadow = FALSE; } if (victim == ch) { send_to_char("{hYou fall flat on your face!{x\n\r", ch); WAIT_STATE(ch, 2 * skill_table[gsn_trip].beats); act("$n trips over $s own feet!{x", ch, NULL, NULL, TO_ROOM); return; } if ((ch->fighting == NULL) && (!IS_NPC(ch)) && (!IS_NPC(victim))) { ch->attacker = TRUE; victim->attacker = FALSE; } /* modifiers */ /* size */ if (ch->size < victim->size) chance += (ch->size - victim->size) * 10; /* bigger = harder to trip */ /* dex */ chance += get_curr_stat(ch, STAT_DEX); chance -= get_curr_stat(victim, STAT_DEX) * 3 / 2; /* speed */ if (IS_SET(ch->off_flags, OFF_FAST) || IS_AFFECTED(ch, AFF_HASTE)) chance += 10; if (IS_SET(victim->off_flags, OFF_FAST) || IS_AFFECTED(victim, AFF_HASTE)) chance -= 20; /* level */ chance += (ch->level - victim->level) * 2; /* now the attack */ if (number_percent() < chance) { int dam; dam = number_range(2, 2 + 2 * victim->size); act("$n trips you and you go down!{x", ch, NULL, victim, TO_VICT); act("{hYou trip $N and $N goes down!{x", ch, NULL, victim, TO_CHAR); act("$n trips $N, sending $M to the ground.{x", ch, NULL, victim, TO_NOTVICT); check_improve(ch, gsn_trip, TRUE, 1); DAZE_STATE(victim, 2 * PULSE_VIOLENCE); WAIT_STATE(ch, skill_table[gsn_trip].beats); victim->position = POS_RESTING; damage(ch, victim, dam, gsn_trip, DAM_BASH, TRUE); } else { damage(ch, victim, 0, gsn_trip, DAM_BASH, TRUE); WAIT_STATE(ch, skill_table[gsn_trip].beats * 2 / 3); check_improve(ch, gsn_trip, FALSE, 1); } } void do_kill(CHAR_DATA * ch, char *argument) { char arg[MIL]; CHAR_DATA *victim; one_argument(argument, arg); if (arg[0] == '\0') { send_to_char("Kill 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("{hYou hit yourself. {z{COuch!{x\n\r", ch); multi_hit(ch, ch, TYPE_UNDEFINED); return; } if (is_safe(ch, victim)) return; if (!IS_NPC(victim)) { /* if ( !IS_SET(victim->act, PLR_TWIT) ) { send_to_char( "You must MURDER a player.\n\r", ch ); return; } */ } if (victim->fighting != NULL && !is_same_group(ch, victim->fighting)) { send_to_char("Kill stealing is not permitted.\n\r", ch); return; } if (IS_AFFECTED(ch, AFF_CHARM) && ch->master == victim) { act("$N is your beloved master.", ch, NULL, victim, TO_CHAR); return; } if (ch->position == POS_FIGHTING) { send_to_char("You do the best you can!\n\r", ch); return; } if (ch->shadow) { ch->shadowing->shadowed = FALSE; ch->shadowing->shadower = NULL; ch->shadowing = NULL; ch->shadow = FALSE; } /* Autostancing - Loki */ if (IS_SET(victim->extra, dd)) { if (victim->stance[11] == STANCE_SERPENT) do_stance(victim, "serpent"); else if (victim->stance[11] == STANCE_CRANE) do_stance(victim, "crane"); else if (victim->stance[11] == STANCE_CRAB) do_stance(victim, "crab"); else if (victim->stance[11] == STANCE_MONGOOSE) do_stance(victim, "mongoose"); else if (victim->stance[11] == STANCE_BULL) do_stance(victim, "bull"); else if (victim->stance[11] == STANCE_MANTIS) do_stance(victim, "mantis"); else if (victim->stance[11] == STANCE_DRAGON) do_stance(victim, "dragon"); else if (victim->stance[11] == STANCE_TIGER) do_stance(victim, "tiger"); else if (victim->stance[11] == STANCE_MONKEY) do_stance(victim, "monkey"); else if (victim->stance[11] == STANCE_SWALLOW) do_stance(victim, "swallow"); } /* Autostancing - Loki */ if (IS_SET(ch->extra, dd)) { if (ch->stance[11] == STANCE_SERPENT) do_stance(ch, "serpent"); else if (ch->stance[11] == STANCE_CRANE) do_stance(ch, "crane"); else if (ch->stance[11] == STANCE_CRAB) do_stance(ch, "crab"); else if (ch->stance[11] == STANCE_MONGOOSE) do_stance(ch, "mongoose"); else if (ch->stance[11] == STANCE_BULL) do_stance(ch, "bull"); else if (ch->stance[11] == STANCE_MANTIS) do_stance(ch, "mantis"); else if (ch->stance[11] == STANCE_DRAGON) do_stance(ch, "dragon"); else if (ch->stance[11] == STANCE_TIGER) do_stance(ch, "tiger"); else if (ch->stance[11] == STANCE_MONKEY) do_stance(ch, "monkey"); else if (ch->stance[11] == STANCE_SWALLOW) do_stance(ch, "swallow"); } if ((ch->fighting == NULL) && (!IS_NPC(ch)) && (!IS_NPC(victim))) { ch->attacker = TRUE; victim->attacker = FALSE; } WAIT_STATE(ch, 1 * PULSE_VIOLENCE); multi_hit(ch, victim, TYPE_UNDEFINED); return; } void do_mock(CHAR_DATA * ch, char *argument) { char arg[MIL]; CHAR_DATA *victim; one_argument(argument, arg); if (arg[0] == '\0') { send_to_char("Mock hit 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 (is_safe_mock(ch, victim)) return; if (victim->fighting != NULL) { send_to_char("{gThis player is busy at the moment.{x\n\r", ch); return; } if (ch->position == POS_FIGHTING) { send_to_char("{gYou've already got your hands full!{x\n\r", ch); return; } if (ch->shadow) { ch->shadowing->shadowed = FALSE; ch->shadowing->shadower = NULL; ch->shadowing = NULL; ch->shadow = FALSE; } one_hit_mock(ch, victim, TYPE_UNDEFINED, FALSE); return; } void do_murde(CHAR_DATA * ch, char *argument) { send_to_char("If you want to {RMURDER{x, spell it out.\n\r", ch); return; } void do_murder(CHAR_DATA * ch, char *argument) { char buf[MSL]; char arg[MIL]; CHAR_DATA *victim; one_argument(argument, arg); if (arg[0] == '\0') { send_to_char("Murder whom?\n\r", ch); return; } if (IS_NPC(ch)) return; if (IS_AFFECTED(ch, AFF_CHARM)) 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("Suicide is a mortal sin.\n\r", ch); return; } if (is_safe(ch, victim)) return; if (IS_NPC(victim) && victim->fighting != NULL && !is_same_group(ch, victim->fighting)) { send_to_char("Kill stealing is not permitted.\n\r", ch); return; } if (IS_AFFECTED(ch, AFF_CHARM) && ch->master == victim) { act("$N is your beloved master.", ch, NULL, victim, TO_CHAR); return; } if (ch->position == POS_FIGHTING) { send_to_char("You do the best you can!\n\r", ch); return; } if (ch->shadow) { ch->shadowing->shadowed = FALSE; ch->shadowing->shadower = NULL; ch->shadowing = NULL; ch->shadow = FALSE; } if (IS_SET(victim->exbit1_flags, RECRUIT) || IS_SET(victim->exbit1_flags, PK_VETERAN) || IS_SET(victim->exbit1_flags, PK_LAWFUL) || IS_SET(victim->exbit1_flags, PK_KILLER) || IS_SET(ch->exbit1_flags, RECRUIT) || IS_SET(ch->exbit1_flags, PK_VETERAN) || IS_SET(ch->exbit1_flags, PK_LAWFUL) || IS_SET(ch->exbit1_flags, PK_KILLER) ) { if (victim->fighting != NULL && IS_SET(ch->exbit1_flags, PK_LAWFUL)) { send_to_char("So thats the way you like to play.\n\r", ch); REMOVE_BIT(ch->exbit1_flags, PK_LAWFUL); SET_BIT(ch->exbit1_flags, PK_KILLER); } else if (victim->fighting != NULL && IS_SET(ch->exbit1_flags, PK_KILLER)) { send_to_char("You really deserve this.\n\r", ch); REMOVE_BIT(ch->exbit1_flags, PK_KILLER); SET_BIT(ch->exbit1_flags, PK_KILLER2); } // send_to_char("Have mercy on them.\n\r", ch); } /* Autostancing - Loki */ if (IS_SET(victim->extra, dd)) { if (victim->stance[11] == STANCE_SERPENT) do_stance(victim, "serpent"); else if (victim->stance[11] == STANCE_CRANE) do_stance(victim, "crane"); else if (victim->stance[11] == STANCE_CRAB) do_stance(victim, "crab"); else if (victim->stance[11] == STANCE_MONGOOSE) do_stance(victim, "mongoose"); else if (victim->stance[11] == STANCE_BULL) do_stance(victim, "bull"); else if (victim->stance[11] == STANCE_MANTIS) do_stance(victim, "mantis"); else if (victim->stance[11] == STANCE_DRAGON) do_stance(victim, "dragon"); else if (victim->stance[11] == STANCE_TIGER) do_stance(victim, "tiger"); else if (victim->stance[11] == STANCE_MONKEY) do_stance(victim, "monkey"); else if (victim->stance[11] == STANCE_SWALLOW) do_stance(victim, "swallow"); } /* Autostancing - Loki */ if (IS_SET(ch->extra, dd)) { if (ch->stance[11] == STANCE_SERPENT) do_stance(ch, "serpent"); else if (ch->stance[11] == STANCE_CRANE) do_stance(ch, "crane"); else if (ch->stance[11] == STANCE_CRAB) do_stance(ch, "crab"); else if (ch->stance[11] == STANCE_MONGOOSE) do_stance(ch, "mongoose"); else if (ch->stance[11] == STANCE_BULL) do_stance(ch, "bull"); else if (ch->stance[11] == STANCE_MANTIS) do_stance(ch, "mantis"); else if (ch->stance[11] == STANCE_DRAGON) do_stance(ch, "dragon"); else if (ch->stance[11] == STANCE_TIGER) do_stance(ch, "tiger"); else if (ch->stance[11] == STANCE_MONKEY) do_stance(ch, "monkey"); else if (ch->stance[11] == STANCE_SWALLOW) do_stance(ch, "swallow"); } if ((ch->fighting == NULL) && (!IS_NPC(ch)) && (!IS_NPC(victim))) { ch->attacker = TRUE; victim->attacker = FALSE; } WAIT_STATE(ch, 1 * PULSE_VIOLENCE); if (IS_NPC(ch)) sprintf(buf, "Help! I am being attacked by %s!", ch->short_descr); else sprintf(buf, "Help! I am being attacked by %s!", ch->name); do_yell(victim, buf); multi_hit(ch, victim, TYPE_UNDEFINED); return; } void do_backstab(CHAR_DATA * ch, char *argument) { char arg[MIL]; CHAR_DATA *victim; OBJ_DATA *obj; one_argument(argument, arg); if (arg[0] == '\0') { send_to_char("Backstab whom?\n\r", ch); return; } if (ch->fighting != NULL) { send_to_char("{hYou're facing the wrong end.{x\n\r", ch); return; } else 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 (IS_NPC(victim) && victim->fighting != NULL && !is_same_group(ch, victim->fighting)) { send_to_char("Kill stealing is not permitted.\n\r", ch); return; } if ((obj = get_eq_char(ch, WEAR_WIELD)) == NULL) { send_to_char ("{hYou need to wield a primary weapon to backstab.{x\n\r", ch); return; } if (victim->hit < victim->max_hit / 3) { act("$N is hurt and suspicious ... you can't sneak up.", ch, NULL, victim, TO_CHAR); return; } if (ch->shadow) { ch->shadowing->shadowed = FALSE; ch->shadowing->shadower = NULL; ch->shadowing = NULL; ch->shadow = FALSE; } if (IS_SET(victim->exbit1_flags, RECRUIT) || IS_SET(victim->exbit1_flags, PK_VETERAN) || IS_SET(victim->exbit1_flags, PK_LAWFUL) || IS_SET(victim->exbit1_flags, PK_KILLER) || IS_SET(ch->exbit1_flags, RECRUIT) || IS_SET(ch->exbit1_flags, PK_VETERAN) || IS_SET(ch->exbit1_flags, PK_LAWFUL) || IS_SET(ch->exbit1_flags, PK_KILLER) ) { if (victim->fighting != NULL && IS_SET(ch->exbit1_flags, PK_LAWFUL)) { send_to_char("So thats the way you like to play.\n\r", ch); REMOVE_BIT(ch->exbit1_flags, PK_LAWFUL); SET_BIT(ch->exbit1_flags, PK_KILLER); } else if (victim->fighting != NULL && IS_SET(ch->exbit1_flags, PK_KILLER)) { send_to_char("You really deserve this.\n\r", ch); REMOVE_BIT(ch->exbit1_flags, PK_KILLER); SET_BIT(ch->exbit1_flags, PK_KILLER2); } // send_to_char("Have mercy on them.\n\r", ch); } /* Autostancing - Loki */ if (IS_SET(victim->extra, dd)) { if (victim->stance[11] == STANCE_SERPENT) do_stance(victim, "serpent"); else if (victim->stance[11] == STANCE_CRANE) do_stance(victim, "crane"); else if (victim->stance[11] == STANCE_CRAB) do_stance(victim, "crab"); else if (victim->stance[11] == STANCE_MONGOOSE) do_stance(victim, "mongoose"); else if (victim->stance[11] == STANCE_BULL) do_stance(victim, "bull"); else if (victim->stance[11] == STANCE_MANTIS) do_stance(victim, "mantis"); else if (victim->stance[11] == STANCE_DRAGON) do_stance(victim, "dragon"); else if (victim->stance[11] == STANCE_TIGER) do_stance(victim, "tiger"); else if (victim->stance[11] == STANCE_MONKEY) do_stance(victim, "monkey"); else if (victim->stance[11] == STANCE_SWALLOW) do_stance(victim, "swallow"); } /* Autostancing - Loki */ if (IS_SET(ch->extra, dd)) { if (ch->stance[11] == STANCE_SERPENT) do_stance(ch, "serpent"); else if (ch->stance[11] == STANCE_CRANE) do_stance(ch, "crane"); else if (ch->stance[11] == STANCE_CRAB) do_stance(ch, "crab"); else if (ch->stance[11] == STANCE_MONGOOSE) do_stance(ch, "mongoose"); else if (ch->stance[11] == STANCE_BULL) do_stance(ch, "bull"); else if (ch->stance[11] == STANCE_MANTIS) do_stance(ch, "mantis"); else if (ch->stance[11] == STANCE_DRAGON) do_stance(ch, "dragon"); else if (ch->stance[11] == STANCE_TIGER) do_stance(ch, "tiger"); else if (ch->stance[11] == STANCE_MONKEY) do_stance(ch, "monkey"); else if (ch->stance[11] == STANCE_SWALLOW) do_stance(ch, "swallow"); } if ((ch->fighting == NULL) && (!IS_NPC(ch)) && (!IS_NPC(victim))) { ch->attacker = TRUE; victim->attacker = FALSE; } if (get_skill(ch, gsn_backstab) == 0 && !IS_AWAKE(victim)) { WAIT_STATE(ch, skill_table[gsn_backstab].beats); multi_hit(ch, victim, gsn_backstab); if (!IS_NPC(ch)) do_mod_favor(ch, 1); return; } if (ch->shadow && (ch->shadowing == victim)) { WAIT_STATE(ch, skill_table[gsn_backstab].beats); multi_hit(ch, victim, gsn_backstab); if (!IS_NPC(ch)) do_mod_favor(ch, 1); return; } WAIT_STATE(ch, skill_table[gsn_backstab].beats); if (number_percent() < get_skill(ch, gsn_backstab) || (get_skill(ch, gsn_backstab) >= 1 && !IS_AWAKE(victim))) { check_improve(ch, gsn_backstab, TRUE, 1); multi_hit(ch, victim, gsn_backstab); if (!IS_NPC(ch)) do_mod_favor(ch, 1); } else { check_improve(ch, gsn_backstab, FALSE, 1); damage(ch, victim, 0, gsn_backstab, DAM_NONE, TRUE); } return; } void do_circle(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; OBJ_DATA *obj; int chance; if ((chance = get_skill(ch, gsn_circle)) == 0) { send_to_char("Circle? What's that?\n\r", ch); return; } if (!IS_NPC(ch)) { if (ch->pcdata->tier != 2) { if (ch->level < skill_table[gsn_circle].skill_level[ch->class]) { send_to_char("Circle? What's that?\n\r", ch); return; } } else if ( (ch->level < skill_table[gsn_circle].skill_level[ch->class]) && (ch->level < skill_table[gsn_circle].skill_level[ch->clasb])) { send_to_char("Circle? What's that?\n\r", ch); return; } } if ((victim = ch->fighting) == NULL) { send_to_char("You aren't fighting anyone.\n\r", ch); return; } if ((obj = get_eq_char(ch, WEAR_WIELD)) == NULL) { send_to_char("You need to wield a primary weapon to circle.\n\r", ch); return; } if (victim->hit < victim->max_hit / 6) { act("$N is hurt and suspicious ... you can't sneak around.", ch, NULL, victim, TO_CHAR); return; } if (ch->stunned) { send_to_char("You're still a little woozy.\n\r", ch); return; } if (!can_see(ch, victim)) { send_to_char("You stumble blindly into a wall.\n\r", ch); return; } WAIT_STATE(ch, skill_table[gsn_circle].beats); if (number_percent() < get_skill(ch, gsn_circle) || (get_skill(ch, gsn_circle) >= 2 && !IS_AWAKE(victim))) { check_improve(ch, gsn_circle, TRUE, 1); act("$n circles around behind you.{x", ch, NULL, victim, TO_VICT); act("{hYou circle around $N.{x", ch, NULL, victim, TO_CHAR); act("$n circles around behind $N.{x", ch, NULL, victim, TO_NOTVICT); multi_hit(ch, victim, gsn_circle); if (!IS_NPC(ch)) do_mod_favor(ch, 1); } else { check_improve(ch, gsn_circle, FALSE, 1); act("$n tries to circle around you.{x", ch, NULL, victim, TO_VICT); act("{h$N circles with you.{x", ch, NULL, victim, TO_CHAR); act("$n tries to circle around $N.{x", ch, NULL, victim, TO_NOTVICT); damage(ch, victim, 0, gsn_circle, DAM_NONE, TRUE); } return; } void do_feed(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; int chance; if ((chance = get_skill(ch, gsn_feed)) == 0) { send_to_char("Feed? What's that?\n\r", ch); return; } if (!IS_NPC(ch)) { if (ch->pcdata->tier != 2) { if (ch->level < skill_table[gsn_feed].skill_level[ch->class]) { send_to_char("Feed? What's that?\n\r", ch); return; } } else if ((ch->level < skill_table[gsn_feed].skill_level[ch->class]) && (ch->level < skill_table[gsn_feed].skill_level[ch->clasb])) { send_to_char("Feed? What's that?\n\r", ch); return; } } if ((victim = ch->fighting) == NULL) { send_to_char("You aren't fighting anyone.\n\r", ch); return; } if (victim->hit < victim->max_hit / 6) { act("$N is hurt and suspicious ... you can't get close enough.", ch, NULL, victim, TO_CHAR); return; } if (ch->stunned) { send_to_char("You're still a little woozy.\n\r", ch); return; } WAIT_STATE(ch, skill_table[gsn_feed].beats); if (number_percent() < get_skill(ch, gsn_feed) / 3 || (get_skill(ch, gsn_feed) >= 2 && !IS_AWAKE(victim))) { int dam; dam = number_range((((ch->level / 2) + (victim->level / 2)) / 2.5), (((ch->level / 2) + (victim->level / 2)) / 2.5) * 2.5); check_improve(ch, gsn_feed, TRUE, 1); act("$n bites you.{x", ch, NULL, victim, TO_VICT); act("{hYou bite $N.{x", ch, NULL, victim, TO_CHAR); act("$n bites $N.{x", ch, NULL, victim, TO_NOTVICT); damage(ch, victim, dam, gsn_feed, DAM_NEGATIVE, TRUE); } else { check_improve(ch, gsn_feed, FALSE, 1); act("$n tries to bite you, but hits only air.{x", ch, NULL, victim, TO_VICT); act("{hYou chomp a mouthfull of air.{x", ch, NULL, victim, TO_CHAR); act("$n tries to bite $N.{x", ch, NULL, victim, TO_NOTVICT); damage(ch, victim, 0, gsn_feed, DAM_NEGATIVE, TRUE); } return; } void do_flee(CHAR_DATA * ch, char *argument) { ROOM_INDEX_DATA *was_in; ROOM_INDEX_DATA *now_in; CHAR_DATA *victim; int attempt; if ((victim = ch->fighting) == NULL) { if (ch->position == POS_FIGHTING) ch->position = POS_STANDING; send_to_char("You aren't fighting anyone.\n\r", ch); return; } was_in = ch->in_room; for (attempt = 0; attempt < 6; attempt++) { EXIT_DATA *pexit; int door; int gdoor; door = number_door(); if (((pexit = was_in->exit[door + 6]) != NULL) && (ch->alignment < 0)) gdoor = door + 6; else gdoor = door; if (((pexit = was_in->exit[gdoor]) == NULL) || (IS_SET(ch->in_room->room_flags, ROOM_CLAN_ENT))) { OBJ_DATA *portal; portal = get_obj_exit(dir_name[door], was_in->contents); if (portal == NULL) { continue; } } else if ((pexit = was_in->exit[gdoor]) == 0 || pexit->u1.to_room == NULL || IS_SET(pexit->exit_info, EX_CLOSED) || number_range(0, ch->daze) != 0 || (IS_NPC(ch) && IS_SET(pexit-> u1. to_room-> room_flags, ROOM_NO_MOB))) continue; move_char(ch, door, FALSE, FALSE); if ((now_in = ch->in_room) == was_in) { continue; } ch->in_room = was_in; act("$n has {Yfled{x!", ch, NULL, NULL, TO_ROOM); if (!IS_NPC(ch)) { if (!IS_NPC(victim)) { if (ch->attacker == FALSE) ch->pcdata->dflee++; else ch->pcdata->aflee++; } send_to_char("{BYou {Yflee{B from combat!{x\n\r", ch); if (((ch->class == 2) || (ch->class == (MCLT_1) + 1)) && (number_percent() < 3 * (ch->level / 2))) { if (IS_NPC(victim) || ch->attacker == FALSE) { send_to_char("You {Ysnuck away{x safely.\n\r", ch); } else { send_to_char ("You feel something singe your butt on the way out.\n\r", ch); act ("$n is nearly {Yzapped{x in the butt by a lightning bolt from above!", ch, NULL, NULL, TO_ROOM); ch->hit -= (ch->hit / 8); } } else { if (!IS_NPC(victim) && ch->attacker == TRUE) { send_to_char ("The {RWrath of Thoth {YZAPS{x your butt on the way out!\n\r", ch); act ("$n is {Yzapped{x in the butt by a lightning bolt from above!", ch, NULL, NULL, TO_ROOM); ch->hit -= (ch->hit / 4); } if (!IS_NPC(ch) && !IS_SET(ch->act, PLR_LQUEST)) { send_to_char("You lost 10 exp.\n\r", ch); gain_exp(ch, -10); } } } ch->in_room = now_in; stop_fighting(ch, TRUE); do_mod_favor(ch, 2); return; } send_to_char("{z{CPANIC!{x{B You couldn't escape!{x\n\r", ch); return; } void do_rescue(CHAR_DATA * ch, char *argument) { char arg[MIL]; CHAR_DATA *victim; CHAR_DATA *fch; one_argument(argument, arg); if (arg[0] == '\0') { send_to_char("Rescue 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("What about {Yfleeing{x instead?\n\r", ch); return; } if (!IS_NPC(ch) && IS_NPC(victim)) { send_to_char("Doesn't need your help!\n\r", ch); return; } if (ch->fighting == victim) { send_to_char("Too late.\n\r", ch); return; } if ((fch = victim->fighting) == NULL) { send_to_char("That person is not fighting right now.\n\r", ch); return; } if (IS_NPC(fch) && !is_same_group(ch, victim)) { send_to_char("Kill stealing is not permitted.\n\r", ch); return; } if (ch->spirit) { send_to_char("That's tough to do without flesh.\n\r", ch); return; } WAIT_STATE(ch, skill_table[gsn_rescue].beats); if (number_percent() > get_skill(ch, gsn_rescue)) { send_to_char("You fail the rescue.\n\r", ch); check_improve(ch, gsn_rescue, FALSE, 1); return; } if (ch->shadow) { ch->shadowing->shadowed = FALSE; ch->shadowing->shadower = NULL; ch->shadowing = NULL; ch->shadow = FALSE; } act("{yYou rescue $N!{x", ch, NULL, victim, TO_CHAR); act("{y$n rescues you!{x", ch, NULL, victim, TO_VICT); act("{y$n rescues $N!{x", ch, NULL, victim, TO_NOTVICT); do_mod_favor(ch, 6); check_improve(ch, gsn_rescue, TRUE, 1); stop_fighting(fch, FALSE); stop_fighting(victim, FALSE); set_fighting(ch, fch); set_fighting(fch, ch); return; } void do_stance(CHAR_DATA * ch, char *argument) { char arg[MIL]; int selection; argument = one_argument(argument, arg); if (arg[0] == '\0') { if (ch->stance[0] == -1) { ch->stance[0] = 0; send_to_char("You drop into a street fighting stance.\n\r", ch); act("$n drops into a street fighting stance.", ch, NULL, NULL, TO_ROOM);} else { ch->stance[0] = -1; send_to_char("You relax from your street fighting stance.\n\r", ch); act("$n relaxes from $s street fighting stance.", ch, NULL, NULL, TO_ROOM); } return; } if (!str_cmp(arg, "none")) { selection = STANCE_NONE; send_to_char("You drop into a boxing fighting stance.\n\r", ch); act("$n drops into a boxing fighting stance.", ch, NULL, NULL, TO_ROOM);} else if (!str_cmp(arg, "serpent")) { selection = STANCE_SERPENT; send_to_char("You take up the serpent fighting stance.\n\r", ch); act("$n takes up the serpent fighting stance.", ch, NULL, NULL, TO_ROOM);} else if (!str_cmp(arg, "crane")) { selection = STANCE_CRANE; send_to_char("You take up the crane fighting stance.\n\r", ch); act("$n takes up the crane fighting stance.", ch, NULL, NULL, TO_ROOM);} else if (!str_cmp(arg, "crab")) { selection = STANCE_CRAB; send_to_char("You take up the crab fighting stance.\n\r", ch); act("$n takes up the crab fighting stance. ", ch, NULL, NULL, TO_ROOM);} else if (!str_cmp(arg, "mongoose")) { selection = STANCE_MONGOOSE; send_to_char("You take up the mongoose fighting stance.\n\r", ch); act("$n takes up the mongoose fighting stance. ", ch, NULL, NULL, TO_ROOM);} else if (!str_cmp(arg, "bull")) { selection = STANCE_BULL; send_to_char("You take up the bull fighting stance.\n\r", ch); act("$n takes up the bull fighting stance. ", ch, NULL, NULL, TO_ROOM);} else { if (!str_cmp(arg, "mantis") && ch->stance[STANCE_CRANE] >= 200 && ch->stance[STANCE_SERPENT] >= 200) { selection = STANCE_MANTIS; send_to_char("You take up the mantis fighting stance.\n\r", ch); act("$n takes up the mantis fighting stance.", ch, NULL, NULL, TO_ROOM); } else if (!str_cmp(arg, "dragon") && ch->stance[STANCE_BULL] >= 200 && ch->stance[STANCE_CRAB] >= 200) { selection = STANCE_DRAGON; send_to_char("You take up the dragon fighting stance.\n\r", ch); act("$n takes up the dragon fighting stance.", ch, NULL, NULL, TO_ROOM); } else if (!str_cmp(arg, "tiger") && ch->stance[STANCE_BULL] >= 200 && ch->stance[STANCE_SERPENT] >= 200) { selection = STANCE_TIGER; send_to_char("You take up the tiger fighting stance.\n\r", ch); act("$n takes up the tiger fighting stance.", ch, NULL, NULL, TO_ROOM); } else if (!str_cmp(arg, "monkey") && ch->stance[STANCE_CRANE] >= 200 && ch->stance[STANCE_MONGOOSE] >= 200) { selection = STANCE_MONKEY; send_to_char("You take up the monkey fighting stance.\n\r", ch); act("$n takes up the monkey fighting stance.", ch, NULL, NULL, TO_ROOM); } else if (!str_cmp(arg, "swallow") && ch->stance[STANCE_CRAB] >= 200 && ch->stance[STANCE_MONGOOSE] >= 200) { selection = STANCE_SWALLOW; send_to_char("You take up the swallow fighting stance.\n\r", ch); act("$n takes up the swallow fighting stance.", ch, NULL, NULL, TO_ROOM); } else { send_to_char("Syntax is: stance <stance>.\n\r", ch); send_to_char ("Stance being one of: None, Serpent, Crane, Crab, Mongoose, Bull.\n\r", ch); return; } } ch->stance[0] = selection; return; } void do_autostance(CHAR_DATA * ch, char *argument) { char arg[MIL]; int selection; one_argument(argument, arg); if (IS_NPC(ch)) return; if (!str_cmp(arg, "none")) { selection = STANCE_NONE; send_to_char("You're autostance has been removed.\n\r", ch); REMOVE_BIT(ch->extra, dd); } else if (!str_cmp(arg, "serpent")) { selection = STANCE_SERPENT; send_to_char("Serpent stance set.\n\r", ch); } else if (!str_cmp(arg, "crane")) { selection = STANCE_CRANE; send_to_char("Crane stance set.\n\r", ch); } else if (!str_cmp(arg, "crab")) { selection = STANCE_CRAB; send_to_char("Crab stance set.\n\r", ch); } else if (!str_cmp(arg, "mongoose")) { selection = STANCE_MONGOOSE; send_to_char("Mongoose stance set.\n\r", ch); } else if (!str_cmp(arg, "bull")) { selection = STANCE_BULL; send_to_char("Bull stance set.\n\r", ch); } else { if (!str_cmp(arg, "mantis") && ch->stance[STANCE_CRANE] >= 200 && ch->stance[STANCE_SERPENT] >= 200) { selection = STANCE_MANTIS; send_to_char("Mantis stance set.\n\r", ch); } else if (!str_cmp(arg, "dragon") && ch->stance[STANCE_BULL] >= 200 && ch->stance[STANCE_CRAB] >= 200) { selection = STANCE_DRAGON; send_to_char("Dragon stance set.\n\r", ch); } else if (!str_cmp(arg, "tiger") && ch->stance[STANCE_BULL] >= 200 && ch->stance[STANCE_SERPENT] >= 200) { selection = STANCE_TIGER; send_to_char("Tiger stance set.\n\r", ch); } else if (!str_cmp(arg, "monkey") && ch->stance[STANCE_CRANE] >= 200 && ch->stance[STANCE_MONGOOSE] >= 200) { selection = STANCE_MONKEY; send_to_char("Monkey stance set.\n\r", ch); } else if (!str_cmp(arg, "swallow") && ch->stance[STANCE_CRAB] >= 200 && ch->stance[STANCE_MONGOOSE] >= 200) { selection = STANCE_SWALLOW; send_to_char("Swallow stance set.\n\r", ch); } else { send_to_char("Syntax is: autostance <stance>.\n\r", ch); send_to_char ("Autotance being one of: None, Serpent, Crane, Crab, Mongoose, Bull.\n\r", ch); send_to_char ("If you know them, they are: Mantis, Dragon, Tiger, Monkey, Swallow.\n\r", ch); return; } } ch->stance[11] = selection; SET_BIT(ch->extra, dd); return; } int dambonus(CHAR_DATA * ch, CHAR_DATA * victim, int dam, int stance) { if (dam < 1) return 0; if (stance < 1) return dam; if (!IS_NPC(ch) && !can_counter(victim)) { if (IS_STANCE(ch, STANCE_MONKEY)) { int mindam = dam * 0.25; dam *= (ch->stance[STANCE_MONKEY] + 1) / 200; if (dam < mindam) dam = mindam; } else if (IS_STANCE(ch, STANCE_BULL) && ch->stance[STANCE_BULL] > 100) dam += dam * (ch->stance[STANCE_BULL] / 100); else if (IS_STANCE(ch, STANCE_DRAGON) && ch->stance[STANCE_DRAGON] > 100) dam += dam * (ch->stance[STANCE_DRAGON] / 100); else if (IS_STANCE(ch, STANCE_TIGER) && ch->stance[STANCE_TIGER] > 100) dam += dam * (ch->stance[STANCE_TIGER] / 100); else if (ch->stance[0] > 0 && ch->stance[stance] < 100) dam *= 0.5; } if (!IS_NPC(victim) && !can_counter(ch)) { if (IS_STANCE(victim, STANCE_CRAB) && victim->stance[STANCE_CRAB] > 100) dam /= victim->stance[STANCE_CRAB] / 100; else if (IS_STANCE(victim, STANCE_DRAGON) && victim->stance[STANCE_DRAGON] > 100) dam /= victim->stance[STANCE_DRAGON] / 100; else if (IS_STANCE(victim, STANCE_SWALLOW) && victim->stance[STANCE_SWALLOW] > 100) dam /= victim->stance[STANCE_SWALLOW] / 100; } return dam; } bool can_counter(CHAR_DATA * ch) { if (IS_STANCE(ch, STANCE_MONKEY)) return TRUE; return FALSE; } bool can_bypass(CHAR_DATA * ch, CHAR_DATA * victim) { if (IS_STANCE(ch, STANCE_SERPENT)) return TRUE; else if (IS_STANCE(ch, STANCE_MANTIS)) return TRUE; else if (IS_STANCE(ch, STANCE_TIGER)) return TRUE; return FALSE; } void improve_stance(CHAR_DATA * ch) { char buf[MIL]; char bufskill[25]; char stancename[10]; int dice1; int dice2; int stance; dice1 = number_percent(); dice2 = number_percent(); stance = ch->stance[0]; if (stance < 1 || stance > 10) return; if (ch->stance[stance] >= 200) { ch->stance[stance] = 200; return; } if ((dice1 > ch->stance[stance] && dice2 > ch->stance[stance]) || (dice1 == 100 || dice2 == 100)) ch->stance[stance] += 1; else return; if (stance == ch->stance[stance]) return; if (ch->stance[stance] == 1) sprintf(bufskill, "an apprentice of"); else if (ch->stance[stance] == 26) sprintf(bufskill, "a trainee of"); else if (ch->stance[stance] == 51) sprintf(bufskill, "a student of"); else if (ch->stance[stance] == 76) sprintf(bufskill, "fairly experienced in"); else if (ch->stance[stance] == 101) sprintf(bufskill, "well trained in"); else if (ch->stance[stance] == 126) sprintf(bufskill, "highly skilled in"); else if (ch->stance[stance] == 151) sprintf(bufskill, "an expert of"); else if (ch->stance[stance] == 176) sprintf(bufskill, "a master of"); else if (ch->stance[stance] == 200) sprintf(bufskill, "a grand master of"); else return; if (stance == STANCE_SERPENT) sprintf(stancename, "serpent"); else if (stance == STANCE_CRANE) sprintf(stancename, "crane"); else if (stance == STANCE_CRAB) sprintf(stancename, "crab"); else if (stance == STANCE_MONGOOSE) sprintf(stancename, "mongoose"); else if (stance == STANCE_BULL) sprintf(stancename, "bull"); else if (stance == STANCE_MANTIS) sprintf(stancename, "mantis"); else if (stance == STANCE_DRAGON) sprintf(stancename, "dragon"); else if (stance == STANCE_TIGER) sprintf(stancename, "tiger"); else if (stance == STANCE_MONKEY) sprintf(stancename, "monkey"); else if (stance == STANCE_SWALLOW) sprintf(stancename, "swallow"); else return; sprintf(buf, "You are now %s the %s stance.\n\r", bufskill, stancename); send_to_char(buf, ch); return; } void special_move(CHAR_DATA * ch, CHAR_DATA * victim) { int dam = number_range(20, 40); if (dam < 20) dam = 20; switch (number_range(1, 7)) { default: return; case 1: act ("You pull your hands into your waist then snap them into $N's stomach.", ch, NULL, victim, TO_CHAR); act ("$n pulls $s hands into $s waist then snaps them into your stomach.", ch, NULL, victim, TO_VICT); act ("$n pulls $s hands into $s waist then snaps them into $N's stomach.", ch, NULL, victim, TO_NOTVICT); if (victim == NULL || victim->position == POS_DEAD) return; act ("You double over in agony, and fall to the ground gasping for breath.", victim, NULL, NULL, TO_CHAR); act ("$n doubles over in agony, and falls to the ground gasping for breath.", victim, NULL, NULL, TO_ROOM); stop_fighting(victim, TRUE); victim->position = POS_STUNNED; break; case 2: act("You spin in a low circle, catching $N behind $S ankle.", ch, NULL, victim, TO_CHAR); act("$n spins in a low circle, catching you behind your ankle.", ch, NULL, victim, TO_VICT); act("$n spins in a low circle, catching $N behind $S ankle.", ch, NULL, victim, TO_NOTVICT); if (victim == NULL || victim->position == POS_DEAD) return; act("You crash to the ground, stunned.", victim, NULL, NULL, TO_CHAR); act("$n crashes to the ground, stunned.", victim, NULL, NULL, TO_ROOM); stop_fighting(victim, TRUE); victim->position = POS_STUNNED; break; case 3: act("You roll between $N's legs and flip to your feet.", ch, NULL, victim, TO_CHAR); act("$n rolls between your legs and flips to $s feet.", ch, NULL, victim, TO_VICT); act("$n rolls between $N's legs and flips to $s feet.", ch, NULL, victim, TO_NOTVICT); act ("You spin around and smash your elbow into the back of $N's head.", ch, NULL, victim, TO_CHAR); act ("$n spins around and smashes $s elbow into the back of your head.", ch, NULL, victim, TO_VICT); act ("$n spins around and smashes $s elbow into the back of $N's head.", ch, NULL, victim, TO_NOTVICT); if (victim == NULL || victim->position == POS_DEAD) return; act("You fall to the ground, stunned.", victim, NULL, NULL, TO_CHAR); act("$n falls to the ground, stunned.", victim, NULL, NULL, TO_ROOM); stop_fighting(victim, TRUE); victim->position = POS_STUNNED; break; case 4: act("You somersault over $N's head and land lightly on your toes.", ch, NULL, victim, TO_CHAR); act("$n somersaults over your head and lands lightly on $s toes.", ch, NULL, victim, TO_VICT); act("$n somersaults over $N's head and lands lightly on $s toes.", ch, NULL, victim, TO_NOTVICT); act ("You roll back onto your shoulders and kick both feet into $N's back.", ch, NULL, victim, TO_CHAR); act ("$n rolls back onto $s shoulders and kicks both feet into your back.", ch, NULL, victim, TO_VICT); act ("$n rolls back onto $s shoulders and kicks both feet into $N's back.", ch, NULL, victim, TO_NOTVICT); act("You fall to the ground, stunned.", victim, NULL, NULL, TO_CHAR); act("$n falls to the ground, stunned.", victim, NULL, NULL, TO_ROOM); act("You flip back up to your feet.", ch, NULL, NULL, TO_CHAR); act("$n flips back up to $s feet.", ch, NULL, NULL, TO_ROOM); stop_fighting(victim, TRUE); victim->position = POS_STUNNED; break; case 5: act("You grab $N by the waist and hoist $M above your head.", ch, NULL, victim, TO_CHAR); act("$n grabs $N by the waist and hoists $M above $s head.", ch, NULL, victim, TO_NOTVICT); act("$n grabs you by the waist and hoists you above $s head.", ch, NULL, victim, TO_VICT); if (victim == NULL || victim->position == POS_DEAD) return; act("You crash to the ground, stunned.", victim, NULL, NULL, TO_CHAR); act("$n crashes to the ground, stunned.", victim, NULL, NULL, TO_ROOM); stop_fighting(victim, TRUE); victim->position = POS_STUNNED; break; case 6: act("You grab $N by the head and slam $S face into your knee.", ch, NULL, victim, TO_CHAR); act("$n grabs you by the head and slams your face into $s knee.", ch, NULL, victim, TO_VICT); act("$n grabs $N by the head and slams $S face into $s knee.", ch, NULL, victim, TO_NOTVICT); if (victim == NULL || victim->position == POS_DEAD) return; act("You crash to the ground, stunned.", victim, NULL, NULL, TO_CHAR); act("$n crashes to the ground, stunned.", victim, NULL, NULL, TO_ROOM); act("You flip back up to your feet.", ch, NULL, NULL, TO_CHAR); act("$n flips back up to $s feet.", ch, NULL, NULL, TO_ROOM); stop_fighting(victim, TRUE); victim->position = POS_STUNNED; break; case 7: act ("You duck under $N's attack and pound your fist into $S stomach.", ch, NULL, victim, TO_CHAR); act ("$n ducks under your attack and pounds $s fist into your stomach.", ch, NULL, victim, TO_VICT); act ("$n ducks under $N's attack and pounds $s fist into $N's stomach.", ch, NULL, victim, TO_NOTVICT); if (victim == NULL || victim->position == POS_DEAD) return; act("You double over in agony.", victim, NULL, NULL, TO_CHAR); act("$n doubles over in agony.", victim, NULL, NULL, TO_ROOM); if (victim == NULL || victim->position == POS_DEAD) return; stop_fighting(victim, TRUE); victim->position = POS_STUNNED; break; } return; } void do_left_hook(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; int dam; if (!IS_NPC(ch) && ch->level < skill_table[gsn_left_hook].skill_level[ch-> class]) {send_to_char("You better leave that to the experts.\n\r", ch); return; } if ((victim = ch->fighting) == NULL) { send_to_char("You aren't fighting anyone.\n\r", ch); return; } if (ch->stunned) { send_to_char("You're still a little woozy.\n\r", ch); return; } dam = number_range(3, ch->level * 2); WAIT_STATE(ch, skill_table[gsn_left_hook].beats); if (get_skill(ch, gsn_left_hook) > number_percent()) { damage(ch, victim, number_range(dam, (ch->level * 2.2)), gsn_left_hook, DAM_BASH, TRUE); SET_BIT(victim->position, POS_STUNNED); check_improve(ch, gsn_left_hook, TRUE, 1); } else { damage(ch, victim, 0, gsn_left_hook, DAM_BASH, TRUE); check_improve(ch, gsn_left_hook, FALSE, 1); } return; } void do_kidney_punch(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; int dam; if (!IS_NPC(ch) && ch->level < skill_table[gsn_kidney_punch].skill_level[ch-> class]) {send_to_char("You better leave that to the experts.\n\r", ch); return; } if ((victim = ch->fighting) == NULL) { send_to_char("You aren't fighting anyone.\n\r", ch); return; } if (ch->stunned) { send_to_char("You're still a little woozy.\n\r", ch); return; } dam = number_range(3, ch->level * 1.9); WAIT_STATE(ch, skill_table[gsn_kidney_punch].beats); if (get_skill(ch, gsn_kidney_punch) > number_percent()) { damage(ch, victim, number_range(dam, (ch->level * 2.1)), gsn_kidney_punch, DAM_BASH, TRUE); SET_BIT(victim->position, POS_STUNNED); check_improve(ch, gsn_kidney_punch, TRUE, 1); } else { damage(ch, victim, 0, gsn_kidney_punch, DAM_BASH, TRUE); check_improve(ch, gsn_kidney_punch, FALSE, 1); } return; } void do_right_cross(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; int dam; if (!IS_NPC(ch) && ch->level < skill_table[gsn_right_cross].skill_level[ch-> class]) {send_to_char("You better leave that to the experts.\n\r", ch); return; } if ((victim = ch->fighting) == NULL) { send_to_char("You aren't fighting anyone.\n\r", ch); return; } if (ch->stunned) { send_to_char("You're still a little woozy.\n\r", ch); return; } dam = number_range(2, ch->level * 2.1); WAIT_STATE(ch, skill_table[gsn_right_cross].beats); if (get_skill(ch, gsn_right_cross) > number_percent()) { damage(ch, victim, number_range(dam, (ch->level * 2.3)), gsn_right_cross, DAM_BASH, TRUE); check_improve(ch, gsn_right_cross, TRUE, 1); } else { damage(ch, victim, 0, gsn_right_cross, DAM_BASH, TRUE); check_improve(ch, gsn_right_cross, FALSE, 1); } return; } void do_critical_strike(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; int dam; if (!IS_NPC(ch) && ch->level < skill_table[gsn_critical_strike].skill_level[ch-> class]) {send_to_char("You better leave that to the experts.\n\r", ch); return; } if ((victim = ch->fighting) == NULL) { send_to_char("You aren't fighting anyone.\n\r", ch); return; } if (ch->stunned) { send_to_char("You're still a little woozy.\n\r", ch); return; } dam = number_range(12, ch->level * 2.5); WAIT_STATE(ch, skill_table[gsn_critical_strike].beats); if (get_skill(ch, gsn_critical_strike) > number_percent()) { damage(ch, victim, number_range(dam, (ch->level * 3.7)), gsn_critical_strike, DAM_BASH, TRUE); SET_BIT(victim->position, POS_MORTAL); check_improve(ch, gsn_critical_strike, TRUE, 1); } else { damage(ch, victim, 0, gsn_critical_strike, DAM_BASH, TRUE); check_improve(ch, gsn_critical_strike, FALSE, 1); } return; } void do_jab(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; int dam; if (!IS_NPC(ch) && ch->level < skill_table[gsn_jab].skill_level[ch-> class]) {send_to_char("You better leave that to the experts.\n\r", ch); return; } if ((victim = ch->fighting) == NULL) { send_to_char("You aren't fighting anyone.\n\r", ch); return; } if (ch->stunned) { send_to_char("You're still a little woozy.\n\r", ch); return; } dam = number_range(3, ch->level * 1); WAIT_STATE(ch, skill_table[gsn_jab].beats); if (get_skill(ch, gsn_jab) > number_percent()) { damage(ch, victim, number_range(dam, (ch->level * 1.2)), gsn_jab, DAM_BASH, TRUE); check_improve(ch, gsn_jab, TRUE, 1); } else { damage(ch, victim, 0, gsn_jab, DAM_BASH, TRUE); check_improve(ch, gsn_jab, FALSE, 1); } return; } void do_uppercut(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; int dam; if (!IS_NPC(ch) && ch->level < skill_table[gsn_uppercut].skill_level[ch-> class]) {send_to_char("You better leave that to the experts.\n\r", ch); return; } if ((victim = ch->fighting) == NULL) { send_to_char("You aren't fighting anyone.\n\r", ch); return; } if (ch->stunned) { send_to_char("You're still a little woozy.\n\r", ch); return; } dam = number_range(3, ch->level * 2.3); WAIT_STATE(ch, skill_table[gsn_uppercut].beats); if (get_skill(ch, gsn_uppercut) > number_percent()) { damage(ch, victim, number_range(dam, (ch->level * 2.5)), gsn_uppercut, DAM_BASH, TRUE); SET_BIT(victim->position, POS_STUNNED); check_improve(ch, gsn_uppercut, TRUE, 1); } else { damage(ch, victim, 0, gsn_uppercut, DAM_BASH, TRUE); check_improve(ch, gsn_uppercut, FALSE, 1); } return; } void check_arena(CHAR_DATA * ch, CHAR_DATA * victim) { DESCRIPTOR_DATA *d; /* needed for Arena bet checking */ char buf[MSL]; static int payoff; sprintf(buf, "^{gArena{x^ {b%s{x has {rdefeated{x {b%s{x!\n\r", ch->name, victim->name); for (d = descriptor_list; d; d = d->next) { if (d->connected == CON_PLAYING && (d->character != victim && d->character != ch) && !IS_SET(d->character->comm, COMM_NOARENA)) { send_to_char(buf, d->character); } } ch->pcdata->awins += 1; victim->pcdata->alosses += 1; for (d = descriptor_list; d; d = d->next) { if (d->connected == CON_PLAYING) { if (d->character->gladiator == ch) { if (IS_SET(ch->exbit1_flags, EXBIT1_CHALLENGER)) { float odd1 = cpo_stat; payoff = d->character->pcdata->plr_wager * (odd1); } if (IS_SET(ch->exbit1_flags, EXBIT1_CHALLENGED)) { float odd2 = vpo_stat; payoff = d->character->pcdata->plr_wager * (odd2); } /*Since there is no ratio for a loss (you lose what you bet) this second part may be fubbing things up - going to comment it out for now* *if (IS_SET(victim->exbit1_flags, EXBIT1_CHALLENGER)) { float odd1=cpo_stat; payoff = d->character->pcdata->plr_wager * ( odd1 ); } if (IS_SET(victim->exbit1_flags, EXBIT1_CHALLENGED)) { float odd2=vpo_stat; payoff = d->character->pcdata->plr_wager * ( odd2 ); }*/ sprintf(buf, "You {gwon{x! Your wager: {y%d{x, payoff: {y%d{x\n\r", d->character->pcdata->plr_wager, payoff); send_to_char(buf, d->character); d->character->gold += payoff; /* reset the betting info */ d->character->gladiator = NULL; d->character->pcdata->plr_wager = 0; payoff = 0; } if (d->character->gladiator != ch && d->character->pcdata->plr_wager >= 1) { int tmp = 0; sprintf(buf, "You {rlost{x! Your wager: {y%d{x\n\r", d->character->pcdata->plr_wager); send_to_char(buf, d->character); if (d->character->pcdata->plr_wager > d->character->gold) { tmp = d->character->pcdata->plr_wager / 100; d->character->pcdata->plr_wager -= (tmp * 100); } if (tmp > 0) d->character->platinum -= tmp; d->character->gold -= d->character->pcdata->plr_wager; /* reset the betting info */ d->character->gladiator = NULL; d->character->pcdata->plr_wager = 0; } } } /* now move both fighters out of arena and back to the regular "world" be sure to define ROOM_VNUM_AWINNER and ROOM_VNUM_ALOSER */ stop_fighting(victim, TRUE); char_from_room(victim); char_to_room(victim, get_room_index(ROOM_VNUM_ALOSER)); victim->hit = victim->max_hit; victim->mana = victim->max_mana; // affect_strip(victim,gsn_plague); // affect_strip(victim,gsn_poison); // affect_strip(victim,gsn_blindness); // affect_strip(victim,gsn_sleep); // affect_strip(victim,gsn_curse); victim->move = victim->max_move; update_pos(victim); do_look(victim, "auto"); stop_fighting(ch, TRUE); char_from_room(ch); char_to_room(ch, get_room_index(ROOM_VNUM_AWINNER)); ch->hit = ch->max_hit; ch->mana = ch->max_mana; // affect_strip(ch,gsn_plague); // affect_strip(ch,gsn_poison); // affect_strip(ch,gsn_blindness); //affect_strip(ch,gsn_sleep); // affect_strip(ch,gsn_curse); ch->move = ch->max_move; update_pos(ch); do_look(ch, "auto"); if (IS_SET(ch->exbit1_flags, EXBIT1_CHALLENGER)) REMOVE_BIT(ch->exbit1_flags, EXBIT1_CHALLENGER); if (IS_SET(victim->exbit1_flags, EXBIT1_CHALLENGER)) REMOVE_BIT(victim->exbit1_flags, EXBIT1_CHALLENGER); if (IS_SET(victim->exbit1_flags, EXBIT1_CHALLENGED)) REMOVE_BIT(victim->exbit1_flags, EXBIT1_CHALLENGED); if (IS_SET(ch->exbit1_flags, EXBIT1_CHALLENGED)) REMOVE_BIT(ch->exbit1_flags, EXBIT1_CHALLENGED); ch->challenger = NULL; ch->challenged = NULL; victim->challenger = NULL; victim->challenged = NULL; REMOVE_BIT(ch->comm, COMM_NOCHANNELS); REMOVE_BIT(ch->act, PLR_NORESTORE); REMOVE_BIT(victim->comm, COMM_NOCHANNELS); REMOVE_BIT(victim->act, PLR_NORESTORE); send_to_char("You have been restored.\n\r", ch); send_to_char("You have been restored.\n\r", victim); arena = FIGHT_OPEN; /* clear the arena */ return; } void do_kick(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; if (!IS_NPC(ch)) { if ((ch->pcdata->tier != 2) && (ch->level < skill_table[gsn_kick].skill_level[ch->class])) { send_to_char ("You better leave the martial arts to fighters.\n\r", ch); return; } if ((ch->pcdata->tier == 2) && (ch->level < skill_table[gsn_kick].skill_level[ch->class]) && (ch->level < skill_table[gsn_kick].skill_level[ch->clasb])) { send_to_char ("You better leave the martial arts to fighters.\n\r", ch); return; } } if (IS_NPC(ch) && !IS_SET(ch->off_flags, OFF_KICK)) return; if ((victim = ch->fighting) == NULL) { send_to_char("You aren't fighting anyone.\n\r", ch); return; } if (ch->stunned) { send_to_char("You're still a little woozy.\n\r", ch); return; } WAIT_STATE(ch, skill_table[gsn_kick].beats); if (get_skill(ch, gsn_kick) > number_percent()) { int dam; dam = number_range(1, ch->level); dam = number_range(dam, (ch->level * 1.5)); damage(ch, victim, dam, gsn_kick, DAM_BASH, TRUE); check_improve(ch, gsn_kick, TRUE, 1); } else { damage(ch, victim, 0, gsn_kick, DAM_BASH, TRUE); check_improve(ch, gsn_kick, FALSE, 1); } return; } void do_disarm(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; OBJ_DATA *obj; int chance, hth, ch_weapon, vict_weapon, ch_vict_weapon; hth = 0; if ((chance = get_skill(ch, gsn_disarm)) == 0) { send_to_char("You don't know how to disarm opponents.\n\r", ch); return; } if (get_eq_char(ch, WEAR_WIELD) == NULL && ((hth = get_skill(ch, gsn_hand_to_hand)) == 0 || (IS_NPC(ch) && !IS_SET(ch->off_flags, OFF_DISARM)))) { send_to_char("You must wield a weapon to disarm.\n\r", ch); return; } if ((victim = ch->fighting) == NULL) { send_to_char("You aren't fighting anyone.\n\r", ch); return; } if (ch->stunned) { send_to_char("You're still a little woozy.\n\r", ch); return; } if ((obj = get_eq_char(victim, WEAR_WIELD)) == NULL) { send_to_char("{hYour opponent is not wielding a weapon.{x\n\r", ch); return; } /* find weapon skills */ ch_weapon = get_weapon_skill(ch, get_weapon_sn(ch)); vict_weapon = get_weapon_skill(victim, get_weapon_sn(victim)); ch_vict_weapon = get_weapon_skill(ch, get_weapon_sn(victim)); /* modifiers */ /* skill */ if (get_eq_char(ch, WEAR_WIELD) == NULL) chance = chance * hth / 150; else chance = chance * ch_weapon / 100; chance += (ch_vict_weapon / 2 - vict_weapon) / 2; /* dex vs. strength */ chance += get_curr_stat(ch, STAT_DEX); chance -= 2 * get_curr_stat(victim, STAT_STR); /* level */ chance += (ch->level - victim->level) * 2; chance /= 2; /* and now the attack */ if (number_percent() < chance) { if (((chance = get_skill(victim, gsn_grip)) == 0) || (!IS_NPC(victim) && victim->level < skill_table[gsn_grip].skill_level[victim->class])) { if (chance == 0 || IS_NPC(victim)) { WAIT_STATE(ch, skill_table[gsn_disarm].beats); disarm(ch, victim); check_improve(ch, gsn_disarm, TRUE, 1); return; } if ((victim->pcdata->tier != 2) && (victim->level < skill_table[gsn_grip].skill_level[victim->class])) { WAIT_STATE(ch, skill_table[gsn_disarm].beats); disarm(ch, victim); check_improve(ch, gsn_disarm, TRUE, 1); return; } if ((victim->pcdata->tier == 2) && (victim->level < skill_table[gsn_grip].skill_level[victim->class]) && (victim->level < skill_table[gsn_grip].skill_level[victim->clasb])) { WAIT_STATE(ch, skill_table[gsn_disarm].beats); disarm(ch, victim); check_improve(ch, gsn_disarm, TRUE, 1); return; } } if (number_percent() > (chance / 5) * 4) { WAIT_STATE(ch, skill_table[gsn_disarm].beats); disarm(ch, victim); check_improve(ch, gsn_disarm, TRUE, 1); check_improve(victim, gsn_grip, FALSE, 1); return; } check_improve(victim, gsn_grip, TRUE, 1); } WAIT_STATE(ch, skill_table[gsn_disarm].beats); act("{hYou fail to disarm $N.{x", ch, NULL, victim, TO_CHAR); act("$n tries to disarm you, but fails.{x", ch, NULL, victim, TO_VICT); act("$n tries to disarm $N, but fails.{x", ch, NULL, victim, TO_NOTVICT); check_improve(ch, gsn_disarm, FALSE, 1); return; } void do_sla(CHAR_DATA * ch, char *argument) { send_to_char("If you want to {RSLAY{x, spell it out.\n\r", ch); return; } void do_slay(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; char arg[MIL]; one_argument(argument, arg); if (arg[0] == '\0') { send_to_char("Slay 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 (ch == victim) { send_to_char("Suicide is a mortal sin.\n\r", ch); return; } if (!IS_NPC(victim) && victim->level >= get_trust(ch)) { send_to_char("{hYou failed.{c\n\r", ch); return; } if (ch->shadow) { ch->shadowing->shadowed = FALSE; ch->shadowing->shadower = NULL; ch->shadowing = NULL; ch->shadow = FALSE; } if (IS_NPC(victim) || get_trust(ch) >= CREATOR) { act("{hYou slay $M in cold blood!{x", ch, NULL, victim, TO_CHAR); act("$n slays you in cold blood!{x", ch, NULL, victim, TO_VICT); act("$n slays $N in cold blood!{x", ch, NULL, victim, TO_NOTVICT); raw_kill(victim, ch); } else { act("$N wields a sword called '{z{RGodSlayer'!{x", ch, NULL, victim, TO_CHAR); act("{hYou wield a sword called '{z{RGodSlayer{h'!{x", ch, NULL, victim, TO_VICT); act("$N wields a sword called '{z{RGodSlayer'!{x", ch, NULL, victim, TO_NOTVICT); act("$N's slice takes off your left arm!{x", ch, NULL, victim, TO_CHAR); act("{hYour slice takes off $n's left arm!{x", ch, NULL, victim, TO_VICT); act("$N's slice takes off $n's left arm!{x", ch, NULL, victim, TO_NOTVICT); act("$N's slice takes off your right arm!{x", ch, NULL, victim, TO_CHAR); act("{hYour slice takes off $n's right arm!{x", ch, NULL, victim, TO_VICT); act("$N's slice takes off $n's right arm!{x", ch, NULL, victim, TO_NOTVICT); act("$N's slice cuts off both of your legs!{x", ch, NULL, victim, TO_CHAR); act("{hYour slice cuts off both of $n's legs!{x", ch, NULL, victim, TO_VICT); act("$N's slice cuts off both of $n's legs!{x", ch, NULL, victim, TO_NOTVICT); act("$N's slice beheads you!{x", ch, NULL, victim, TO_CHAR); act("{hYour slice beheads $n!{x", ch, NULL, victim, TO_VICT); act("$N's slice beheads $n!{x", ch, NULL, victim, TO_NOTVICT); act("You are DEAD!!!{x", ch, NULL, victim, TO_CHAR); act("{h$n is DEAD!!!{x", ch, NULL, victim, TO_VICT); act("$n is DEAD!!!{x", ch, NULL, victim, TO_NOTVICT); act("A sword called '{z{RGodSlayer{x' vanishes.", ch, NULL, victim, TO_VICT); act("A sword called '{z{RGodSlayer{x' vanishes.", ch, NULL, victim, TO_NOTVICT); raw_kill(ch, victim); } return; } void do_crush( CHAR_DATA *ch, char *argument ) { CHAR_DATA *victim; if ( !IS_NPC(ch) && ch->level < skill_table[gsn_tail].skill_level[ch->class] ) { send_to_char( "Since when did you grow a tail?\n\r", ch ); return; } if (IS_NPC(ch) && !IS_SET(ch->off_flags,OFF_TAIL)) return; if ( ( victim = ch->fighting ) == NULL ) { send_to_char( "You aren't fighting anyone.\n\r", ch ); return; } WAIT_STATE( ch, skill_table[gsn_tail].beats ); if ( get_skill(ch,gsn_tail) > number_percent()) { damage(ch,victim,number_range( 1, ch->level ), gsn_tail,DAM_SLASH,TRUE); check_improve(ch,gsn_tail,TRUE,1); } else { damage( ch, victim, 0, gsn_tail,DAM_SLASH,TRUE); check_improve(ch,gsn_tail,FALSE,1); } // check_killer(ch,victim); return; } bool check_fade( CHAR_DATA *ch, CHAR_DATA *victim ) { int chance; if ( !IS_AWAKE(victim) ) return FALSE; chance = get_skill(victim,gsn_fade) / 2; if (!can_see(victim,ch)) chance /= 3; if ( number_percent( ) >= chance + victim->level - ch->level ) return FALSE; act( "Your body fades from existence and avoids $n's attack.", ch, NULL, victim, TO_VICT ); act( "$N's body fades from existence to avoid your attack.", ch, NULL, victim, TO_CHAR ); return TRUE; } void do_tail( CHAR_DATA *ch, char *argument ) { CHAR_DATA *victim; if ( !IS_NPC(ch) && ch->level < skill_table[gsn_tail].skill_level[ch->class] ) { send_to_char( "Since when did you grow a tail?\n\r", ch ); return; } if (IS_NPC(ch) && !IS_SET(ch->off_flags,OFF_TAIL)) return; if ( ( victim = ch->fighting ) == NULL ) { send_to_char( "You aren't fighting anyone.\n\r", ch ); return; } WAIT_STATE( ch, skill_table[gsn_tail].beats ); if ( get_skill(ch,gsn_tail) > number_percent()) { damage(ch,victim,number_range( 1, ch->level ), gsn_tail,DAM_SLASH,TRUE); check_improve(ch,gsn_tail,TRUE,1); } else { damage( ch, victim, 0, gsn_tail,DAM_SLASH,TRUE); check_improve(ch,gsn_tail,FALSE,1); } // check_killer(ch,victim); return; }