#if defined(macintosh) #include <types.h> #else #include <sys/types.h> #endif #include <stdio.h> #include <string.h> #include <time.h> #include "merc.h" #include "interp.h" #include "tables.h" /* Holds all Defensive skills/commands like * dodge/parry/shield block, etc */ void cmd_combatconfig (CHAR_DATA * ch, char *argument) { char arg[MSL]; char buf[MSL]; /* No NPC, thats a BAD NPC! */ if (IS_NPC (ch)) return; argument = one_argument (argument, arg); if (arg[0] == '\0') { stc ( " Current combat configuration options:\n", ch); stc ( " Option Status\n", ch); stc ( "---------------------\n", ch); sprintf(buf, " Parry %s\n", (IS_SET (ch->new_config, CONFIG_PARRY)) ? "{YOn{x" : "{ROff{x"); stc(buf, ch); sprintf(buf, " Dodge %s\n", (IS_SET (ch->new_config, CONFIG_DODGE)) ? "{YOn{x" : "{ROff{x"); stc(buf, ch); sprintf(buf, " Shield Block %s\n", (IS_SET (ch->new_config, CONFIG_SHIELDBLOCK)) ? "{YOn{x" : "{ROff{x"); stc(buf, ch); sprintf(buf, " Roll %s\n", (IS_SET (ch->new_config, CONFIG_ROLL)) ? "{YOn{x" : "{ROff{x"); stc(buf, ch); sprintf(buf, " Leap %s\n", (IS_SET (ch->new_config, CONFIG_LEAP)) ? "{YOn{x" : "{ROff{x"); stc(buf, ch); stc("\n", ch); return; } if (!str_prefix(arg, "parry")) { if (IS_SET (ch->new_config, CONFIG_PARRY)) { REMOVE_BIT(ch->new_config, CONFIG_PARRY); stc("You will no longer parry incomming attacks.\n", ch); } else { SET_BIT(ch->new_config, CONFIG_PARRY); stc("You will now attempt to parry incomming attacks.\n", ch); } return; } if (!str_prefix(arg, "dodge")) { if (IS_SET (ch->new_config, CONFIG_DODGE)) { REMOVE_BIT(ch->new_config, CONFIG_DODGE); stc("You will no longer dodge incomming attacks.\n", ch); } else { SET_BIT(ch->new_config, CONFIG_DODGE); stc("You will now attempt to dodge incomming attacks.\n", ch); } return; } if (!str_prefix(arg, "shieldblock")) { if (IS_SET (ch->new_config, CONFIG_SHIELDBLOCK)) { REMOVE_BIT(ch->new_config, CONFIG_SHIELDBLOCK); stc("You will no longer Shield block incomming attacks.\n", ch); } else { SET_BIT(ch->new_config, CONFIG_SHIELDBLOCK); stc("You will now attempt to Shield block incomming attacks.\n", ch); } return; } if (!str_prefix(arg, "roll")) { if (IS_SET (ch->new_config, CONFIG_ROLL)) { REMOVE_BIT(ch->new_config, CONFIG_ROLL); stc("You will no longer roll away to avoid incomming attacks.\n", ch); } else { SET_BIT(ch->new_config, CONFIG_ROLL); stc("You will now attempt to roll awat to avoid incomming attacks.\n", ch); } return; } if (!str_prefix(arg, "leap")) { if (IS_SET (ch->new_config, CONFIG_LEAP)) { REMOVE_BIT(ch->new_config, CONFIG_LEAP); stc("You will no longer leap to avoid incomming attacks.\n", ch); } else { SET_BIT(ch->new_config, CONFIG_LEAP); stc("You will now attempt to leap to avoid incomming attacks.\n", ch); } return; } else { cmd_combatconfig(ch, ""); return; } } /* * Check for parry. */ bool check_parry (CHAR_DATA * ch, CHAR_DATA * victim) { int chance; if (!IS_AWAKE (victim)) return FALSE; if (!IS_SET (victim->new_config, CONFIG_PARRY)) 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 (!can_see (ch, victim)) chance /= 2; /* Casting Penalty */ if (ch->action[0] == ACTION_CASTING) { chance /= 2; } if (number_percent () >= chance) return FALSE; if (victim->action[0] == ACTION_CASTING) { act ("You lose your concentration as you parry $n's attack.", ch, NULL, victim, TO_VICT); act ("$N parries your attack, and studders on their spell.", ch, NULL, victim, TO_CHAR); victim->cast_count += 1; victim->spell_vars[3] += 1; check_improve (victim, gsn_parry, TRUE, 6); return TRUE; } else { act ("You parry $n's attack.", ch, NULL, victim, TO_VICT); act ("$N parries your attack.", ch, NULL, victim, TO_CHAR); 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; OBJ_DATA * obj; if (!IS_AWAKE (victim)) return FALSE; if (!IS_SET (victim->new_config, CONFIG_SHIELDBLOCK)) return FALSE; chance = get_skill (victim, gsn_shield_block) / 2 + 35; if (get_eq_char (victim, WEAR_SHIELD) == NULL) return FALSE; if (number_percent () >= chance) return FALSE; act ("You block $n's attack with your shield.", ch, NULL, victim, TO_VICT); act ("$N blocks your attack with a shield.", ch, NULL, victim, TO_CHAR); check_improve (victim, gsn_shield_block, TRUE, 6); /* Shield bash */ chance = get_skill(victim, gsn_shield_bash) * 2 / 3; if (number_percent() >= chance) { obj = get_eq_char (victim, WEAR_SHIELD); if (obj == NULL) { log_string("shield bash without a shield? boggle"); } else { act ("You bash into $n with your shield!", ch, NULL, victim, TO_VICT); act ("$N bashes into you with their shield!", ch, NULL, victim, TO_CHAR); check_improve (victim, gsn_shield_bash, TRUE, 5); damage (victim, ch, obj->level * 2 + number_range(1, 100) / 2, gsn_shield_bash, DAM_BASH, TRUE, FALSE); } } return TRUE; } /* * Check for dodge. */ bool check_dodge (CHAR_DATA * ch, CHAR_DATA * victim) { int chance; if (!IS_AWAKE (victim)) return FALSE; if (!IS_SET (victim->new_config, CONFIG_DODGE)) return FALSE; chance = get_skill (victim, gsn_dodge) / 2; if (!can_see (victim, ch)) chance /= 2; if (victim->action[0] == ACTION_CASTING) chance /= 2; if (number_percent () >= chance) return FALSE; if (victim->action[0] == ACTION_CASTING) { act ("You stop your spell for a second to dodge $n's attack.", ch, NULL, victim, TO_VICT); act ("$N stops their spell for a second to dodge your attack.", ch, NULL, victim, TO_CHAR); victim->cast_count += 1; victim->spell_vars[3] += 1; check_improve (victim, gsn_dodge, TRUE, 6); return TRUE; } else { act ("You dodge $n's attack.", ch, NULL, victim, TO_VICT); act ("$N dodges your attack.", ch, NULL, victim, TO_CHAR); check_improve (victim, gsn_dodge, TRUE, 6); return TRUE; } } /* * Check for Roll. */ bool check_roll (CHAR_DATA * ch, CHAR_DATA * victim) { int chance; if (!IS_AWAKE (victim)) return FALSE; if (!IS_SET (victim->new_config, CONFIG_ROLL)) return FALSE; chance = get_skill (victim, gsn_roll) / 2; if (!can_see (victim, ch)) chance /= 2; if (victim->action[0] == ACTION_CASTING) chance /= 2; if (number_percent () >= chance) return FALSE; if (victim->action[0] == ACTION_CASTING) { act ("You stop your spell for a second to roll away from $n's attack.", ch, NULL, victim, TO_VICT); act ("$N stops their spell for a second and rolls away from your attack.", ch, NULL, victim, TO_CHAR); victim->cast_count += 1; victim->spell_vars[3] += 1; check_improve (victim, gsn_roll, TRUE, 6); return TRUE; } else { act ("You skillfully roll away from $n's attack.", ch, NULL, victim, TO_VICT); act ("$N skillfuly rolls their body away from your attack.", ch, NULL, victim, TO_CHAR); check_improve (victim, gsn_roll, TRUE, 6); return TRUE; } } /* * Check for leap. */ bool check_leap (CHAR_DATA * ch, CHAR_DATA * victim) { int chance; if (!IS_AWAKE (victim)) return FALSE; if (!IS_SET (victim->new_config, CONFIG_LEAP)) return FALSE; chance = get_skill (victim, gsn_leap) / 3; if (!can_see (victim, ch)) chance /= 2; if (victim->action[0] == ACTION_CASTING) chance /= 2; if (number_percent () >= chance) return FALSE; if (victim->action[0] == ACTION_CASTING) { act ("You quickly leap away $n's attack, and resume your spell.", ch, NULL, victim, TO_VICT); act ("$N quickly leaps away from your attack, and resumes their spell.", ch, NULL, victim, TO_CHAR); victim->cast_count += 1; victim->spell_vars[3] += 1; check_improve (victim, gsn_leap, TRUE, 6); return TRUE; } else { act ("You quickly leap away from $n's attack.", ch, NULL, victim, TO_VICT); act ("$N quickly leaps away from your attack.", ch, NULL, victim, TO_CHAR); check_improve (victim, gsn_leap, TRUE, 6); return TRUE; } }