From 4519fcec4a3e199b40a2fef814b0563f9b621f1e Mon Sep 17 00:00:00 2001 From: GickerLDS Date: Wed, 10 Apr 2024 19:28:00 +0000 Subject: [PATCH] [Apr 10 2024] - Gicker Added the leadership feat. Speed can now affect combat bonuses. See HELP SPEED for more info. Characters can now multiclass with up to 5 different classes, up from 3. Added Knight of the Rose class [Apr 01 2024] - Gicker Added the holy aura spell for clerics Fixed a bug where Sometimes character advancement bugged out by an unspent class feat. Increase max number of classes per character for multiclassing from 3 to 4 Added the Knight of the Sword prestige class [Mar 30 2024] - Gicker Modified the 'class' command (class info, class feats, etc.) so that you can now use spaces when specifying the class name to view info on. Added the Knight of the Crown prestige class. Has no account experience cost. See more info with 'class info knight of the crown' Barghest and Banshee hunt trophies were reversed by mistake. This is now fixed. Temporarily disabled the etheral shift travel domain power as we don't have planar travel and need to recode this ability. --- act.h | 8 + act.informative.c | 6 + act.movement.c | 15 +- act.offensive.c | 413 ++++++++++++++++++++++++++++++++++++++++++++- act.other.c | 100 +++++------ assign_wpn_armor.c | 9 + clan.c | 9 +- class.c | 348 +++++++++++++++++++++++++++++++++++++- constants.c | 12 ++ domains_schools.c | 4 +- feats.c | 138 ++++++++++++--- fight.c | 79 ++++++++- handler.c | 3 +- hunts.c | 8 +- interpreter.c | 17 ++ limits.c | 2 + magic.c | 187 ++++++++++++++++++-- mud_event.c | 52 +++++- mud_event.h | 8 + players.c | 18 ++ spec_abilities.c | 13 ++ spec_procs.c | 4 + spell_parser.c | 26 +++ spells.h | 11 +- structs.h | 27 ++- study.c | 3 +- treasure.c | 2 +- utils.c | 108 +++++++++++- utils.h | 13 +- 29 files changed, 1507 insertions(+), 136 deletions(-) diff --git a/act.h b/act.h index 37b4940d..1f31c45c 100755 --- a/act.h +++ b/act.h @@ -642,6 +642,14 @@ ACMD_DECL(do_grand_destiny); ACMD_DECL(do_evoweb); ACMD_DECL(do_evobreath); ACMD_DECL(do_vital_strike); +ACMD_DECL(do_strength_of_honor); +ACMD_DECL(do_crown_of_knighthood); +ACMD_DECL(do_soul_of_knighthood); +ACMD_DECL(do_rallying_cry); +ACMD_DECL(do_inspire_courage); +ACMD_DECL(do_wisdom_of_the_measure); +ACMD_DECL(do_final_stand); +ACMD_DECL(do_knighthoods_flower); /***************************************************************************** * Begin Functions and defines for act.other.c diff --git a/act.informative.c b/act.informative.c index c5c976de..7034da8c 100755 --- a/act.informative.c +++ b/act.informative.c @@ -2022,6 +2022,12 @@ void perform_cooldowns(struct char_data *ch, struct char_data *k) send_to_char(ch, "Channel Energy Cooldown - Duration: %d seconds\r\n", (int)(event_time(pMudEvent->pEvent) / 10)); if ((pMudEvent = char_has_mud_event(k, eEVOBREATH))) send_to_char(ch, "Eidolon Breath Weapon Cooldown - Duration: %d seconds\r\n", (int)(event_time(pMudEvent->pEvent) / 10)); + if ((pMudEvent = char_has_mud_event(k, eSTRENGTHOFHONOR))) + send_to_char(ch, "Strength of Honor Cooldown - Duration: %d seconds\r\n", (int)(event_time(pMudEvent->pEvent) / 10)); + if ((pMudEvent = char_has_mud_event(k, eCROWNOFKNIGHTHOOD))) + send_to_char(ch, "Crown of Knighthood Cooldown - Duration: %d seconds\r\n", (int)(event_time(pMudEvent->pEvent) / 10)); + if ((pMudEvent = char_has_mud_event(k, eSOULOFKNIGHTHOOD))) + send_to_char(ch, "Crown of Knighthood Cooldown - Duration: %d seconds\r\n", (int)(event_time(pMudEvent->pEvent) / 10)); if (GET_SETCLOAK_TIMER(ch) > 0) send_to_char(ch, "Vampire 'Setcloak' Cooldown - Duration: %d seconds\r\n", GET_SETCLOAK_TIMER(ch) * 6); diff --git a/act.movement.c b/act.movement.c index 80e2fc30..e5fad224 100755 --- a/act.movement.c +++ b/act.movement.c @@ -3916,12 +3916,17 @@ ACMD(do_pullswitch) int get_speed(struct char_data *ch, sbyte to_display) { + if (!ch) return 30; + + int speed = 30; + + if (IS_NPC(ch) && MOB_FLAGGED(ch, MOB_MOUNTABLE)) + speed = 50; + // if mounted, we'll use the mount's speed instead. if (RIDING(ch)) return get_speed(RIDING(ch), to_display); - int speed = 30; - if (!IS_NPC(ch)) { switch (GET_RACE(ch)) @@ -3936,9 +3941,6 @@ int get_speed(struct char_data *ch, sbyte to_display) } } - if (IS_NPC(ch) && MOB_FLAGGED(ch, MOB_MOUNTABLE)) - speed = 50; - if (is_flying(ch)) { if (HAS_FEAT(ch, FEAT_FAE_FLIGHT)) @@ -3967,6 +3969,9 @@ int get_speed(struct char_data *ch, sbyte to_display) if (affected_by_spell(ch, SPELL_GREASE)) speed -= 10; + if (affected_by_spell(ch, AFFECT_RALLYING_CRY)) + speed += 5; + // if they're slowed, it's half regardless. Same with entangled. // if they're blind, they can make an acrobatics check against dc 10 // to avoid halving their speed, but we only want to do this is the diff --git a/act.offensive.c b/act.offensive.c index 0c84577f..2663a6b4 100755 --- a/act.offensive.c +++ b/act.offensive.c @@ -40,6 +40,8 @@ /* externs */ extern char cast_arg2[MAX_INPUT_LENGTH]; +int roll_initiative(struct char_data *ch); + /* defines */ #define RAGE_AFFECTS 7 #define SACRED_FLAMES_AFFECTS 1 @@ -2843,14 +2845,8 @@ ACMD(do_hit) { /* INITIATIVE */ - chInitiative = d20(ch); - if (!IS_NPC(ch) && HAS_FEAT(ch, FEAT_IMPROVED_INITIATIVE)) - chInitiative += 4; - chInitiative += GET_DEX(ch); - victInitiative = d20(vict); - if (!IS_NPC(vict) && HAS_FEAT(vict, FEAT_IMPROVED_INITIATIVE)) - victInitiative += 4; - victInitiative += GET_DEX(vict); + chInitiative = roll_initiative(ch); + victInitiative = roll_initiative(vict); if (chInitiative >= victInitiative || GET_POS(vict) < POS_FIGHTING || !CAN_SEE(vict, ch)) { @@ -10131,6 +10127,407 @@ ACMD(do_vital_strike) } +ACMD(do_strength_of_honor) +{ + + struct affected_type af; + int abil_mod = 0; + int uses_remaining = 0; + + if (!HAS_REAL_FEAT(ch, FEAT_STRENGTH_OF_HONOR)) { + send_to_char(ch, "You do not have the strength of honor ability.\r\n"); + return; + } + + if (affected_by_spell(ch, ABILITY_STRENGTH_OF_HONOR)) + { + send_to_char(ch, "You are already benefitting from strength of honor.\r\n"); + return; + } + + if ((uses_remaining = daily_uses_remaining(ch, FEAT_STRENGTH_OF_HONOR)) == 0) + { + send_to_char(ch, "You need to recover your strength in order to use this ability again.\r\n"); + return; + } + + if (uses_remaining < 0) + { + send_to_char(ch, "You have no uses in this ability.\r\n"); + return; + } + + if (!is_action_available(ch, atSWIFT, TRUE)) + { + send_to_char(ch, "Strength of Honor requires a swift action available to use.\r\n"); + return; + } + + if (HAS_FEAT(ch, FEAT_STRENGTH_OF_HONOR)) + { + abil_mod = 4; + } + + if (HAS_FEAT(ch, FEAT_MIGHT_OF_HONOR)) + { + abil_mod = 6; + } + + new_affect(&af); + af.location = APPLY_STR; + af.bonus_type = BONUS_TYPE_MORALE; + af.spell = ABILITY_STRENGTH_OF_HONOR; + af.duration = 10 * (1 + HAS_REAL_FEAT(ch, FEAT_MIGHT_OF_HONOR)); + af.modifier = abil_mod; + + affect_join(ch, &af, FALSE, FALSE, FALSE, FALSE); + + send_to_char(ch, "You lift your weapon in a knightly salute and recite your oath of honor.\r\n"); + act("$n lifts $s weapon in a knightly salute and powerfully recites $s oath of honor.", false, ch, 0, 0, TO_NOTVICT); + + if (!IS_NPC(ch)) + start_daily_use_cooldown(ch, FEAT_STRENGTH_OF_HONOR); + + USE_SWIFT_ACTION(ch); +} + +ACMD(do_crown_of_knighthood) +{ + + struct affected_type af[6]; + int uses_remaining = 0, i = 0; + + if (!HAS_REAL_FEAT(ch, FEAT_CROWN_OF_KNIGHTHOOD)) { + send_to_char(ch, "You do not have the crown of knighthood ability.\r\n"); + return; + } + + if (affected_by_spell(ch, ABILITY_CROWN_OF_KNIGHTHOOD)) + { + send_to_char(ch, "You are already benefitting from crown of knighthood.\r\n"); + return; + } + + if ((uses_remaining = daily_uses_remaining(ch, FEAT_CROWN_OF_KNIGHTHOOD)) == 0) + { + send_to_char(ch, "You need to recover your strength in order to use this ability again.\r\n"); + return; + } + + if (uses_remaining < 0) + { + send_to_char(ch, "You have no uses in this ability.\r\n"); + return; + } + + if (!is_action_available(ch, atSWIFT, TRUE)) + { + send_to_char(ch, "Crown of knighthood requires a swift action available to use.\r\n"); + return; + } + + /* init affect array */ + for (i = 0; i < 6; i++) + { + new_affect(&(af[i])); + af[i].spell = ABILITY_CROWN_OF_KNIGHTHOOD; + af[i].duration = 75; + af[i].modifier = 4; + af[i].bonus_type = BONUS_TYPE_MORALE; + } + + af[0].location = APPLY_HITROLL; + af[1].location = APPLY_DAMROLL; + af[2].location = APPLY_SAVING_FORT; + af[3].location = APPLY_SAVING_WILL; + af[4].location = APPLY_SAVING_REFL; + af[5].location = APPLY_HIT; + af[5].modifier = 20; + + for (i = 0; i < 6; i++) + affect_join(ch, af + i, FALSE, FALSE, FALSE, FALSE); + + send_to_char(ch, "You close your eyes and allow the oath and measure to fill your soul.\r\n"); + act("$n closes $s eyes and seems to grow in confidence.", false, ch, 0, 0, TO_NOTVICT); + + if (!IS_NPC(ch)) + start_daily_use_cooldown(ch, FEAT_CROWN_OF_KNIGHTHOOD); + + USE_SWIFT_ACTION(ch); +} + +ACMD(do_soul_of_knighthood) +{ + + int uses_remaining = 0; + + if (!HAS_REAL_FEAT(ch, FEAT_SOUL_OF_KNIGHTHOOD)) { + send_to_char(ch, "You do not have the soul of knighthood ability.\r\n"); + return; + } + + if (affected_by_spell(ch, SPELL_HOLY_AURA)) + { + send_to_char(ch, "You are already benefitting from soul of knighthood/holy aura.\r\n"); + return; + } + + if ((uses_remaining = daily_uses_remaining(ch, FEAT_SOUL_OF_KNIGHTHOOD)) == 0) + { + send_to_char(ch, "You need to recover your strength in order to use this ability again.\r\n"); + return; + } + + if (uses_remaining < 0) + { + send_to_char(ch, "You have no uses in this ability.\r\n"); + return; + } + + if (!is_action_available(ch, atSWIFT, TRUE)) + { + send_to_char(ch, "Soul of knighthood requires a swift action available to use.\r\n"); + return; + } + + send_to_char(ch, "You close your eyes and connect with the triumvirate's power.\r\n"); + act("$n closes $s eyes and seems to grow in confidence.", false, ch, 0, 0, TO_NOTVICT); + + call_magic(ch, ch, 0, SPELL_HOLY_AURA, 0, CASTER_LEVEL(ch), CAST_INNATE); + + if (!IS_NPC(ch)) + start_daily_use_cooldown(ch, FEAT_SOUL_OF_KNIGHTHOOD); + + USE_SWIFT_ACTION(ch); +} + +ACMD(do_rallying_cry) +{ + + int uses_remaining = 0; + + if (!HAS_REAL_FEAT(ch, FEAT_RALLYING_CRY)) + { + send_to_char(ch, "You do not have the rallying cry ability.\r\n"); + return; + } + + if (affected_by_spell(ch, AFFECT_RALLYING_CRY)) + { + send_to_char(ch, "You are already benefitting from rallying cry.\r\n"); + return; + } + + if ((uses_remaining = daily_uses_remaining(ch, FEAT_RALLYING_CRY)) == 0) + { + send_to_char(ch, "You need to recover your strength in order to use this ability again.\r\n"); + return; + } + + if (uses_remaining < 0) + { + send_to_char(ch, "You have no uses in this ability.\r\n"); + return; + } + + if (!is_action_available(ch, atSWIFT, TRUE)) + { + send_to_char(ch, "Rallying cry requires a swift action available to use.\r\n"); + return; + } + + send_to_char(ch, "You raise your arm and rally your allies!\r\n"); + act("$n raises $s arm and rallies $s allies.", false, ch, 0, 0, TO_ROOM); + + call_magic(ch, ch, 0, AFFECT_RALLYING_CRY, 0, CASTER_LEVEL(ch), CAST_INNATE); + + if (!IS_NPC(ch)) + start_daily_use_cooldown(ch, FEAT_RALLYING_CRY); + + USE_SWIFT_ACTION(ch); +} + +ACMD(do_inspire_courage) +{ + + int uses_remaining = 0; + + if (!HAS_REAL_FEAT(ch, FEAT_INSPIRE_COURAGE)) + { + send_to_char(ch, "You do not have the inspire courage ability.\r\n"); + return; + } + + if (affected_by_spell(ch, AFFECT_INSPIRE_COURAGE) || affected_by_spell(ch, AFFECT_INSPIRE_GREATNESS)) + { + send_to_char(ch, "You are already benefitting from inspire courage.\r\n"); + return; + } + + if ((uses_remaining = daily_uses_remaining(ch, FEAT_INSPIRE_COURAGE)) == 0) + { + send_to_char(ch, "You need to recover your strength in order to use this ability again.\r\n"); + return; + } + + if (uses_remaining < 0) + { + send_to_char(ch, "You have no uses in this ability.\r\n"); + return; + } + + if (!is_action_available(ch, atSWIFT, TRUE)) + { + send_to_char(ch, "Inspire courage requires a swift action available to use.\r\n"); + return; + } + + send_to_char(ch, "You shout words of encouragement, bolstering the courage of your allies.\r\n"); + act("$n shouts words of encouragement to $s allies.", false, ch, 0, 0, TO_ROOM); + + if (HAS_FEAT(ch, FEAT_INSPIRE_GREATNESS)) + call_magic(ch, ch, 0, AFFECT_INSPIRE_GREATNESS, 0, CASTER_LEVEL(ch), CAST_INNATE); + else + call_magic(ch, ch, 0, AFFECT_INSPIRE_COURAGE, 0, CASTER_LEVEL(ch), CAST_INNATE); + + if (!IS_NPC(ch)) + start_daily_use_cooldown(ch, FEAT_INSPIRE_COURAGE); + + USE_SWIFT_ACTION(ch); +} + + +ACMD(do_wisdom_of_the_measure) +{ + + int uses_remaining = 0; + + if (!HAS_REAL_FEAT(ch, FEAT_WISDOM_OF_THE_MEASURE)) + { + send_to_char(ch, "You do not have the wisdom of the measure ability.\r\n"); + return; + } + + if ((uses_remaining = daily_uses_remaining(ch, FEAT_WISDOM_OF_THE_MEASURE)) == 0) + { + send_to_char(ch, "You need to recover your strength in order to use this ability again.\r\n"); + return; + } + + if (uses_remaining < 0) + { + send_to_char(ch, "You have no uses in this ability.\r\n"); + return; + } + + if (!is_action_available(ch, atSWIFT, TRUE)) + { + send_to_char(ch, "Wisdom of the measure requires a swift action available to use.\r\n"); + return; + } + + send_to_char(ch, "You tap into your knowledge of the measure, and the power of Paladine offers you special insight.\r\n"); + + spell_augury(CASTER_LEVEL(ch), ch, ch, 0, CAST_INNATE); + + if (!IS_NPC(ch)) + start_daily_use_cooldown(ch, FEAT_WISDOM_OF_THE_MEASURE); + + USE_SWIFT_ACTION(ch); +} + +ACMD(do_final_stand) +{ + + int uses_remaining = 0; + + if (!HAS_REAL_FEAT(ch, FEAT_FINAL_STAND)) + { + send_to_char(ch, "You do not have the final stand ability.\r\n"); + return; + } + + if (affected_by_spell(ch, AFFECT_FINAL_STAND)) + { + send_to_char(ch, "You are already benefitting from final stand.\r\n"); + return; + } + + if ((uses_remaining = daily_uses_remaining(ch, FEAT_FINAL_STAND)) == 0) + { + send_to_char(ch, "You need to recover your strength in order to use this ability again.\r\n"); + return; + } + + if (uses_remaining < 0) + { + send_to_char(ch, "You have no uses in this ability.\r\n"); + return; + } + + if (!is_action_available(ch, atSWIFT, TRUE)) + { + send_to_char(ch, "Final stand requires a swift action available to use.\r\n"); + return; + } + + send_to_char(ch, "You guide your allies into a defensive formation.\r\n"); + act("$n guides $s allies into a defensive formation.", false, ch, 0, 0, TO_ROOM); + + call_magic(ch, ch, 0, AFFECT_FINAL_STAND, 0, CASTER_LEVEL(ch), CAST_INNATE); + + if (!IS_NPC(ch)) + start_daily_use_cooldown(ch, FEAT_FINAL_STAND); + + USE_SWIFT_ACTION(ch); +} + +ACMD(do_knighthoods_flower) +{ + + int uses_remaining = 0; + + if (!HAS_REAL_FEAT(ch, FEAT_KNIGHTHOODS_FLOWER)) + { + send_to_char(ch, "You do not have the knighthood's flower ability.\r\n"); + return; + } + + if (affected_by_spell(ch, AFFECT_KNIGHTHOODS_FLOWER)) + { + send_to_char(ch, "You are already benefitting from knighthood's flower.\r\n"); + return; + } + + if ((uses_remaining = daily_uses_remaining(ch, FEAT_KNIGHTHOODS_FLOWER)) == 0) + { + send_to_char(ch, "You need to recover your strength in order to use this ability again.\r\n"); + return; + } + + if (uses_remaining < 0) + { + send_to_char(ch, "You have no uses in this ability.\r\n"); + return; + } + + if (!is_action_available(ch, atSWIFT, TRUE)) + { + send_to_char(ch, "Knighthood's flower requires a swift action available to use.\r\n"); + return; + } + + send_to_char(ch, "Recalling the Oath and the Measure fills you with courage and purpose!\r\n"); + act("$n looks filled with courage and purpose!", false, ch, 0, 0, TO_ROOM); + + call_magic(ch, ch, 0, AFFECT_KNIGHTHOODS_FLOWER, 0, CASTER_LEVEL(ch), CAST_INNATE); + + if (!IS_NPC(ch)) + start_daily_use_cooldown(ch, FEAT_KNIGHTHOODS_FLOWER); + + USE_SWIFT_ACTION(ch); +} + /* cleanup! */ #undef RAGE_AFFECTS #undef D_STANCE_AFFECTS diff --git a/act.other.c b/act.other.c index c672fbdc..30e736bd 100755 --- a/act.other.c +++ b/act.other.c @@ -57,7 +57,13 @@ /* some defines for gain/respec */ #define MODE_CLASSLIST_NORMAL 0 #define MODE_CLASSLIST_RESPEC 1 +#if defined(CAMPAIGN_DL) + +#define MULTICAP 5 +#else #define MULTICAP 3 +#endif + #define WILDSHAPE_AFFECTS 4 #define TOG_OFF 0 #define TOG_ON 1 @@ -929,6 +935,12 @@ ACMD(do_abundantstep) * shifting of self and group members to the ethereal plane and back */ ACMDU(do_ethshift) { + +#if defined(CAMPAIGN_DL) || defined(CAMPAIGN_FR) + send_to_char(ch, "This power is disabled as there is no planar travel on this game. This ability will be recoded to reflect that soon.\r\n"); + return; +#endif + struct char_data *shiftee = NULL; room_rnum shift_dest = NOWHERE; // int counter = 0; @@ -2606,6 +2618,45 @@ ACMD(do_gain) return; } + for (class = 0; class < NUM_CLASSES; class++) + { + /* need to spend their points before advancing */ + if ((GET_PRACTICES(ch) != 0) || + (GET_TRAINS(ch) > 1) || + (GET_BOOSTS(ch) != 0) || + (GET_CLASS_FEATS(ch, class) != 0) || + (GET_EPIC_CLASS_FEATS(ch, class) != 0) || + (GET_FEAT_POINTS(ch) != 0) || + (GET_EPIC_FEAT_POINTS(ch) != 0)) + { + if (GET_TRAINS(ch) > 1) + send_to_char(ch, "You must use all but one of your skill points before gaining " + "another level. You have %d skill point%s remaining.\r\n", + GET_TRAINS(ch), (GET_TRAINS(ch) > 1 ? "s" : "")); + if (GET_BOOSTS(ch) != 0) + send_to_char(ch, "You must use all ability score boosts before gaining another level. " + "You have %d boost%s remaining.\r\n", + GET_BOOSTS(ch), (GET_BOOSTS(ch) > 1 ? "s" : "")); + if (GET_FEAT_POINTS(ch) != 0) + send_to_char(ch, "You must use all feat points before gaining another level. " + "You have %d feat point%s remaining.\r\n", + GET_FEAT_POINTS(ch), (GET_FEAT_POINTS(ch) > 1 ? "s" : "")); + if (GET_CLASS_FEATS(ch, class) != 0) + send_to_char(ch, "You must use all class feat points before gaining another level. " + "You have %d '%s' class feat%s remaining.\r\n", + GET_CLASS_FEATS(ch, class), class_list[class].name, (GET_CLASS_FEATS(ch, class) > 1 ? "s" : "")); + if (GET_EPIC_CLASS_FEATS(ch, class) != 0) + send_to_char(ch, "You must use all epic class feat points before gaining another level. " + "You have %d epic class feat%s remaining.\r\n", + GET_EPIC_CLASS_FEATS(ch, class), (GET_EPIC_CLASS_FEATS(ch, class) > 1 ? "s" : "")); + if (GET_EPIC_FEAT_POINTS(ch) != 0) + send_to_char(ch, "You must use all epic feat points before gaining another level. " + "You have %d epic feat point%s remaining.\r\n", + GET_EPIC_FEAT_POINTS(ch), (GET_EPIC_FEAT_POINTS(ch) > 1 ? "s" : "")); + return; + } + } + if (GET_PREMADE_BUILD_CLASS(ch) < 0) one_argument(argument, arg, sizeof(arg)); else @@ -2672,53 +2723,8 @@ ACMD(do_gain) return; } - /* need to spend their points before advancing */ - if ((GET_PRACTICES(ch) != 0) || - (GET_TRAINS(ch) > 1) || - (GET_BOOSTS(ch) != 0) || - (GET_CLASS_FEATS(ch, class) != 0) || - (GET_EPIC_CLASS_FEATS(ch, class) != 0) || - (GET_FEAT_POINTS(ch) != 0) || - (GET_EPIC_FEAT_POINTS(ch) != 0)) - { // || - /* ((CLASS_LEVEL(ch, CLASS_SORCERER) && !IS_SORC_LEARNED(ch)) || - (CLASS_LEVEL(ch, CLASS_WIZARD) && !IS_WIZ_LEARNED(ch)) || - (CLASS_LEVEL(ch, CLASS_BARD) && !IS_BARD_LEARNED(ch)) || - (CLASS_LEVEL(ch, CLASS_DRUID) && !IS_DRUID_LEARNED(ch))|| - (CLASS_LEVEL(ch, CLASS_RANGER) && !IS_RANG_LEARNED(ch)))) { - */ - /* The last level has not been completely gained yet - The player must - * use all trains, pracs, boosts and choose spells and other benefits - * vis 'study' before they can gain a level. */ - // if (GET_PRACTICES(ch) != 0) - // send_to_char(ch, "You must use all practices before gaining another level. You have %d practice%s remaining.\r\n", GET_PRACTICES(ch), (GET_PRACTICES(ch) > 1 ? "s" : "")); - if (GET_TRAINS(ch) > 1) - send_to_char(ch, "You must use all but one of your skill points before gaining " - "another level. You have %d skill point%s remaining.\r\n", - GET_TRAINS(ch), (GET_TRAINS(ch) > 1 ? "s" : "")); - if (GET_BOOSTS(ch) != 0) - send_to_char(ch, "You must use all ability score boosts before gaining another level. " - "You have %d boost%s remaining.\r\n", - GET_BOOSTS(ch), (GET_BOOSTS(ch) > 1 ? "s" : "")); - if (GET_FEAT_POINTS(ch) != 0) - send_to_char(ch, "You must use all feat points before gaining another level. " - "You have %d feat point%s remaining.\r\n", - GET_FEAT_POINTS(ch), (GET_FEAT_POINTS(ch) > 1 ? "s" : "")); - if (GET_CLASS_FEATS(ch, class) != 0) - send_to_char(ch, "You must use all class feat points before gaining another level. " - "You have %d class feat%s remaining.\r\n", - GET_CLASS_FEATS(ch, class), (GET_CLASS_FEATS(ch, class) > 1 ? "s" : "")); - if (GET_EPIC_CLASS_FEATS(ch, class) != 0) - send_to_char(ch, "You must use all epic class feat points before gaining another level. " - "You have %d epic class feat%s remaining.\r\n", - GET_EPIC_CLASS_FEATS(ch, class), (GET_EPIC_CLASS_FEATS(ch, class) > 1 ? "s" : "")); - if (GET_EPIC_FEAT_POINTS(ch) != 0) - send_to_char(ch, "You must use all epic feat points before gaining another level. " - "You have %d epic feat point%s remaining.\r\n", - GET_EPIC_FEAT_POINTS(ch), (GET_EPIC_FEAT_POINTS(ch) > 1 ? "s" : "")); - return; - } - else if (GET_LEVEL(ch) < LVL_IMMORT - CONFIG_NO_MORT_TO_IMMORT && + + if (GET_LEVEL(ch) < LVL_IMMORT - CONFIG_NO_MORT_TO_IMMORT && GET_EXP(ch) >= level_exp(ch, GET_LEVEL(ch) + 1)) { GET_LEVEL(ch) += 1; diff --git a/assign_wpn_armor.c b/assign_wpn_armor.c index f444f295..016a4db5 100644 --- a/assign_wpn_armor.c +++ b/assign_wpn_armor.c @@ -1293,6 +1293,8 @@ int compute_gear_armor_type(struct char_data *ch) { /* ok we have an armor piece... */ armor_compare = armor_list[GET_OBJ_VAL(obj, 1)].armorType; + if (armor_compare == ARMOR_TYPE_HEAVY && HAS_FEAT(ch, FEAT_ARMORED_MOBILITY)) + armor_compare = ARMOR_TYPE_MEDIUM; if (armor_compare < ARMOR_TYPE_SHIELD && armor_compare > armor_type) { armor_type = armor_compare; @@ -1546,6 +1548,9 @@ int compute_gear_armor_penalty(struct char_data *ch) if ((masterwork_bonus / 4) >= 1) armor_penalty++; + if (HAS_FEAT(ch, FEAT_ARMORED_MOBILITY)) + armor_penalty += 2; + if (count) { armor_penalty = armor_penalty / count; @@ -1594,7 +1599,11 @@ int compute_gear_max_dex(struct char_data *ch) if (count > 0) { dexterity_cap = dexterity_cap / count; + dexterity_cap += HAS_FEAT(ch, FEAT_ARMOR_TRAINING); + + if (HAS_FEAT(ch, FEAT_ARMORED_MOBILITY)) + dexterity_cap += 2; } else /* not wearing armor */ dexterity_cap = 99; diff --git a/clan.c b/clan.c index b48bf59d..e2688743 100755 --- a/clan.c +++ b/clan.c @@ -1695,8 +1695,13 @@ ACMD(do_claninfo) /* Information about clans */ } else { - send_to_char(ch, "There %s %d clan%s in realm of Luminari.\r\n", - (count == 1) ? "is" : "are", count, (count == 1) ? "" : "s"); +#if defined(CAMPAIGN_DL) + send_to_char(ch, "There %s %d clan%s in realm of Krynn.\r\n", (count == 1) ? "is" : "are", count, (count == 1) ? "" : "s"); +#elif defined (CAMPAIGN_FR) + send_to_char(ch, "There %s %d clan%s in realm of Faerun.\r\n", (count == 1) ? "is" : "are", count, (count == 1) ? "" : "s"); +#else + send_to_char(ch, "There %s %d clan%s in realm of Luminari.\r\n", (count == 1) ? "is" : "are", count, (count == 1) ? "" : "s"); +#endif } return; } diff --git a/class.c b/class.c index 3b91bd99..2c34f769 100755 --- a/class.c +++ b/class.c @@ -1205,6 +1205,10 @@ bool view_class_feats(struct char_data *ch, const char *classname) send_to_char(ch, "The warrior class gets a bonus class feat every two " "levels.\r\n"); } + if (class == CLASS_KNIGHT_OF_THE_CROWN) + { + send_to_char(ch, "The knight of the crown class gets a bonus class feat every odd knight of the crown level.\r\n"); + } if (class == CLASS_WIZARD) { send_to_char(ch, "The wizard class gets a bonus class feat every five " @@ -1374,6 +1378,14 @@ int valid_align_by_class(int alignment, int class) return TRUE; else return FALSE; + // lawful good or lawful neutral only + case CLASS_KNIGHT_OF_THE_CROWN: + case CLASS_KNIGHT_OF_THE_SWORD: + case CLASS_KNIGHT_OF_THE_ROSE: + if (alignment == LAWFUL_GOOD || alignment == LAWFUL_NEUTRAL) + return TRUE; + else + return FALSE; case CLASS_BLACKGUARD: if (alignment == LAWFUL_EVIL) return TRUE; @@ -1512,8 +1524,13 @@ int parse_class_long(const char *arg_in) int l = 0; /* string length */ - for (l = 0; *(arg + l); l++) /* convert to lower case */ + for (l = 0; *(arg + l); l++) + { + /* convert to lower case */ *(arg + l) = LOWER(*(arg + l)); + if (*(arg + l) == ' ') + *(arg + l) = '-'; + } if (is_abbrev(arg, "wizard")) return CLASS_WIZARD; @@ -1571,6 +1588,18 @@ int parse_class_long(const char *arg_in) return CLASS_STALWART_DEFENDER; if (is_abbrev(arg, "stalwart-defender")) return CLASS_STALWART_DEFENDER; + if (is_abbrev(arg, "knightofthecrown")) + return CLASS_KNIGHT_OF_THE_CROWN; + if (is_abbrev(arg, "knight-of-the-crown")) + return CLASS_KNIGHT_OF_THE_CROWN; + if (is_abbrev(arg, "knightofthesword")) + return CLASS_KNIGHT_OF_THE_SWORD; + if (is_abbrev(arg, "knight-of-the-sword")) + return CLASS_KNIGHT_OF_THE_SWORD; + if (is_abbrev(arg, "knightoftherose")) + return CLASS_KNIGHT_OF_THE_ROSE; + if (is_abbrev(arg, "knight-of-the-rose")) + return CLASS_KNIGHT_OF_THE_ROSE; if (is_abbrev(arg, "shifter")) return CLASS_SHIFTER; if (is_abbrev(arg, "sacred-fist")) @@ -2741,6 +2770,9 @@ void init_start_char(struct char_data *ch) // this is here so that new characters can't get extra stat points from racefix command. ch->player_specials->saved.new_race_stats = true; + GET_1ST_DOMAIN(ch) = DOMAIN_UNDEFINED; + GET_2ND_DOMAIN(ch) = DOMAIN_UNDEFINED; + /* clear immortal flags */ if (PRF_FLAGGED(ch, PRF_HOLYLIGHT)) i = PRF_TOG_CHK(ch, PRF_HOLYLIGHT); @@ -3423,6 +3455,10 @@ void advance_level(struct char_data *ch, int class) // else if (IS_EPIC(ch)) // epic_class_feats++; } + if (class == CLASS_KNIGHT_OF_THE_CROWN && (CLASS_LEVEL(ch, CLASS_WARRIOR) % 2) ) + { + class_feats++; + } if (class == CLASS_BARD) { @@ -3751,6 +3787,9 @@ int level_exp(struct char_data *ch, int level) case CLASS_WARLOCK: case CLASS_SUMMONER: case CLASS_NECROMANCER: + case CLASS_KNIGHT_OF_THE_CROWN: + case CLASS_KNIGHT_OF_THE_SWORD: + case CLASS_KNIGHT_OF_THE_ROSE: level--; if (level < 0) level = 0; @@ -4485,6 +4524,7 @@ void load_class_list(void) spell_assignment(CLASS_CLERIC, SPELL_SALVATION, 15); spell_assignment(CLASS_CLERIC, SPELL_SPRING_OF_LIFE, 15); spell_assignment(CLASS_CLERIC, SPELL_RESURRECT, 15); + spell_assignment(CLASS_CLERIC, SPELL_HOLY_AURA, 15); /* class num spell level acquired */ /* 9th circle */ @@ -7047,6 +7087,312 @@ void load_class_list(void) class_prereq_feat(CLASS_STALWART_DEFENDER, FEAT_ARMOR_PROFICIENCY_LIGHT, 1); /****************************************************************************/ + /****************************************************************************/ + /* class-number name abrv clr-abrv menu-name*/ + classo(CLASS_KNIGHT_OF_THE_CROWN, "knightofthecrown", "KCr", "\tWKCr\tn", "g) \tWKnight of the Crown\tn", + /* max-lvl lock? prestige? BAB HD psp move trains in-game? unlkCst, eFeatp*/ + 5, N, Y, H, 12, 0, 1, 2, Y, 0, 0, + /*prestige spell progression*/ "none", + /*primary attributes*/ "Strength, Con/Dex for survivability", + /*descrip*/ + "The Order of the Crown forms the basis of the Knights of Solamnia, providing the " + "backbone of their armed forces and the training group for young Knights. The " + "Crowns are led by the High Warrior. They are the opposite of the Knights of the " + "Thorn" + "\r\n" + "The Measure of the Crown establishes Loyalty and Obedience as the foundation of " + "honor and of the Knighthood. Knights of this Order believe fealty to the " + "Knighthood and to the ideals of the Gods of Good is of great importance. The " + "Measure teaches that true loyalty is fealty given freely to those worthy of it, " + "and that such loyalty forms the backbone of virtue and the bonds that are the " + "true strength of the Knighthood. Obedience is considered the brother virtue of " + "loyalty, teaching a Knight to accept the rightful authority of his superiors. " + "Both virtues are believed to reflect discipline of the soul and temperance. " + "\r\n" + "The Order of the Crown had Habbakuk as its patron and is generally revered by " + "them." + ); + /* class-number then saves: fortitude, reflex, will, poison, death */ + assign_class_saves(CLASS_KNIGHT_OF_THE_CROWN, G, B, G, B, B); + assign_class_abils(CLASS_KNIGHT_OF_THE_CROWN, /* class number */ + /*acrobatics,stealth,perception,heal,intimidate,concentration, spellcraft*/ + CC, CC, CA, CA, CA, CC, CC, + /*appraise,discipline,total_defense,lore,ride,climb,sleight_of_hand,bluff*/ + CC, CA, CA, CA, CA, CA, CC, CC, + /*diplomacy,disable_device,disguise,escape_artist,handle_animal,sense_motive*/ + CA, CC, CC, CC, CA, CA, + /*survival,swim,use_magic_device,perform*/ + CC, CA, CC, CC); + + assign_class_titles(CLASS_KNIGHT_OF_THE_CROWN, /* class number */ + "Knight of the Crown", /* <= 4 */ + "Knight of the Crown", /* <= 9 */ + "Knight of the Crown", /* <= 14 */ + "Knight of the Crown", /* <= 19 */ + "Knight of the Crown", /* <= 24 */ + "Knight of the Crown", /* <= 29 */ + "Knight of the Crown", /* <= 30 */ + "Knight of the Crown", /* <= LVL_IMMMORT */ + "Knight of the Crown", /* <= LVL_STAFF */ + "Knight of the Crown", /* <= LVL_GRSTAFF */ + "Knight of the Crown" /* default */ + ); + /* feat assignment */ + /* class num feat cfeat lvl stack */ + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_SIMPLE_WEAPON_PROFICIENCY, Y, 1, Y); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_MARTIAL_WEAPON_PROFICIENCY, Y, 1, Y); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_STRENGTH_OF_HONOR, Y, 1, Y); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_KNIGHTLY_COURAGE, Y, 1, Y); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_HEROIC_INITIATIVE, Y, 2, Y); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_DIEHARD, Y, 2, Y); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_HONORABLE_WILL, Y, 3, Y); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_MIGHT_OF_HONOR, Y, 4, Y); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_ARMORED_MOBILITY, Y, 4, Y); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_CROWN_OF_KNIGHTHOOD, Y, 5, Y); + + // CLASS FEATS + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_ARMOR_SKIN, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_ARMOR_SPECIALIZATION_LIGHT, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_ARMOR_SPECIALIZATION_MEDIUM, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_ARMOR_SPECIALIZATION_HEAVY, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_BLIND_FIGHT, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_CLEAVE, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_COMBAT_EXPERTISE, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_COMBAT_REFLEXES, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_DEFLECT_ARROWS, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_DAMAGE_REDUCTION, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_DODGE, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_EXOTIC_WEAPON_PROFICIENCY, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_FAR_SHOT, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_GREAT_CLEAVE, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_DAZZLING_DISPLAY, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_VITAL_STRIKE, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_IMPROVED_VITAL_STRIKE, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_GREATER_VITAL_STRIKE, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_GREATER_TWO_WEAPON_FIGHTING, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_GREATER_WEAPON_FOCUS, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_GREATER_WEAPON_SPECIALIZATION, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_IMPROVED_BULL_RUSH, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_IMPROVED_CRITICAL, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_IMPROVED_DISARM, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_IMPROVED_FEINT, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_IMPROVED_GRAPPLE, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_IMPROVED_INITIATIVE, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_IMPROVED_OVERRUN, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_IMPROVED_PRECISE_SHOT, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_IMPROVED_SHIELD_PUNCH, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_KNOCKDOWN, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_SHIELD_CHARGE, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_SHIELD_SLAM, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_IMPROVED_SUNDER, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_IMPROVED_TRIP, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_IMPROVED_TWO_WEAPON_FIGHTING, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_IMPROVED_UNARMED_STRIKE, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_MANYSHOT, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_MOBILITY, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_MOUNTED_ARCHERY, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_MOUNTED_COMBAT, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_POINT_BLANK_SHOT, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_POWER_ATTACK, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_DEADLY_AIM, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_PRECISE_SHOT, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_QUICK_DRAW, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_RAPID_RELOAD, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_RAPID_SHOT, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_RIDE_BY_ATTACK, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_ROBILARS_GAMBIT, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_SHOT_ON_THE_RUN, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_SNATCH_ARROWS, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_SPIRITED_CHARGE, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_SPRING_ATTACK, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_STUNNING_FIST, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_SWARM_OF_ARROWS, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_TRAMPLE, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_TWO_WEAPON_DEFENSE, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_TWO_WEAPON_FIGHTING, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_OVERSIZED_TWO_WEAPON_FIGHTING, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_WEAPON_FINESSE, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_WEAPON_FOCUS, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_WEAPON_SPECIALIZATION, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_WHIRLWIND_ATTACK, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_FAST_HEALING, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_WEAPON_MASTERY, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_WEAPON_FLURRY, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_WEAPON_SUPREMACY, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_DOUBLE_WEAPON_FOCUS, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_DOUBLE_WEAPON_SPECIALIZATION, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_DOUBLE_WEAPON_CRITICAL, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_DOUBLE_WEAPON_DEFENSE, Y, NOASSIGN_FEAT, N); + /* epic class */ + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_EPIC_PROWESS, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_GREAT_STRENGTH, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_GREAT_DEXTERITY, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_GREAT_CONSTITUTION, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_EPIC_TOUGHNESS, Y, NOASSIGN_FEAT, N); + feat_assignment(CLASS_KNIGHT_OF_THE_CROWN, FEAT_EPIC_WEAPON_SPECIALIZATION, Y, NOASSIGN_FEAT, N); + /* no spell assignment */ + /* class prereqs */ + class_prereq_bab(CLASS_KNIGHT_OF_THE_CROWN, 3); + class_prereq_ability(CLASS_KNIGHT_OF_THE_CROWN, ABILITY_DIPLOMACY, 3); + class_prereq_ability(CLASS_KNIGHT_OF_THE_CROWN, ABILITY_RIDE, 2); + class_prereq_feat(CLASS_KNIGHT_OF_THE_CROWN, FEAT_ARMOR_PROFICIENCY_HEAVY, 1); + class_prereq_feat(CLASS_KNIGHT_OF_THE_CROWN, FEAT_ARMOR_PROFICIENCY_SHIELD, 1); + /****************************************************************************/ + + /****************************************************************************/ + /* class-number name abrv clr-abrv menu-name*/ + classo(CLASS_KNIGHT_OF_THE_SWORD, "knightofthesword", "KSw", "\tWKSw\tn", "g) \tWKnight of the Sword\tn", + /* max-lvl lock? prestige? BAB HD psp move trains in-game? unlkCst, eFeatp*/ + 5, Y, Y, H, 10, 0, 1, 2, Y, 5000, 0, + /*prestige spell progression*/ "none", + /*primary attributes*/ "Strength, Con/Dex for survivability, Cha for class abilities", + /*descrip*/ + "The Knights of the Sword serve the people of Ansalon as warrior-clerics, " + "crusaders, and knights errant, combining the purest ideals of heroism and " + "courage with the power of the Gods of Good and of the heart. They are the " + "opposite of the Knights of the Skull " + "\r\n" + "The Measure of the Sword teaches the value of Courage, Heroism, and Faith as key " + "components of the honorable life. To the Sword Knight, life is a continual " + "struggle against Evil, both in the world and within the Knight's own heart. " + "Courage is necessary to resist the terrors and temptations of darkness, while " + "heroism involves self-sacrifice and daring effort to force back Evil and aid the " + "innocent and virtuous. It is from Faith, meanwhile, that the Knight's commitment " + "to what is right springs, as well as the strength that can sustain him when all " + "else seems lost. " + "\r\n" + "Kiri-Jolith serves as patron to the Knights of the Sword. " + ); + /* class-number then saves: fortitude, reflex, will, poison, death */ + assign_class_saves(CLASS_KNIGHT_OF_THE_SWORD, G, B, G, B, B); + assign_class_abils(CLASS_KNIGHT_OF_THE_SWORD, /* class number */ + /*acrobatics,stealth,perception,heal,intimidate,concentration, spellcraft*/ + CC, CC, CA, CA, CA, CA, CC, + /*appraise,discipline,total_defense,lore,ride,climb,sleight_of_hand,bluff*/ + CC, CA, CA, CA, CA, CA, CC, CC, + /*diplomacy,disable_device,disguise,escape_artist,handle_animal,sense_motive*/ + CA, CC, CC, CC, CA, CA, + /*survival,swim,use_magic_device,perform*/ + CC, CA, CC, CC); + + assign_class_titles(CLASS_KNIGHT_OF_THE_SWORD, /* class number */ + "Knight of the Sword", /* <= 4 */ + "Knight of the Sword", /* <= 9 */ + "Knight of the Sword", /* <= 14 */ + "Knight of the Sword", /* <= 19 */ + "Knight of the Sword", /* <= 24 */ + "Knight of the Sword", /* <= 29 */ + "Knight of the Sword", /* <= 30 */ + "Knight of the Sword", /* <= LVL_IMMMORT */ + "Knight of the Sword", /* <= LVL_STAFF */ + "Knight of the Sword", /* <= LVL_GRSTAFF */ + "Knight of the Sword" /* default */ + ); + /* feat assignment */ + /* class num feat cfeat lvl stack */ + feat_assignment(CLASS_KNIGHT_OF_THE_SWORD, FEAT_SMITE_EVIL, Y, 1, Y); + feat_assignment(CLASS_KNIGHT_OF_THE_SWORD, FEAT_CHANNEL_ENERGY, Y, 1, Y); + feat_assignment(CLASS_KNIGHT_OF_THE_SWORD, FEAT_SMITE_EVIL, Y, 2, Y); + feat_assignment(CLASS_KNIGHT_OF_THE_SWORD, FEAT_AURA_OF_COURAGE, Y, 2, Y); + feat_assignment(CLASS_KNIGHT_OF_THE_SWORD, FEAT_SMITE_EVIL, Y, 3, Y); + feat_assignment(CLASS_KNIGHT_OF_THE_SWORD, FEAT_DEMORALIZING_STRIKE, Y, 3, Y); + feat_assignment(CLASS_KNIGHT_OF_THE_SWORD, FEAT_SMITE_EVIL, Y, 4, Y); + feat_assignment(CLASS_KNIGHT_OF_THE_SWORD, FEAT_SMITE_EVIL, Y, 5, Y); + feat_assignment(CLASS_KNIGHT_OF_THE_SWORD, FEAT_SOUL_OF_KNIGHTHOOD, Y, 5, Y); + + // No class feats + /* no spell assignment */ + /* class prereqs */ + class_prereq_bab(CLASS_KNIGHT_OF_THE_SWORD, 6); + class_prereq_ability(CLASS_KNIGHT_OF_THE_SWORD, ABILITY_LORE, 4); + class_prereq_ability(CLASS_KNIGHT_OF_THE_SWORD, ABILITY_RIDE, 4); + class_prereq_feat(CLASS_KNIGHT_OF_THE_SWORD, FEAT_DIEHARD, 1); + class_prereq_feat(CLASS_KNIGHT_OF_THE_SWORD, FEAT_ENDURANCE, 1); + class_prereq_feat(CLASS_KNIGHT_OF_THE_SWORD, FEAT_HONORBOUND, 1); + class_prereq_spellcasting(CLASS_KNIGHT_OF_THE_SWORD, CASTING_TYPE_DIVINE, PREP_TYPE_ANY, 1); + class_prereq_class_level(CLASS_KNIGHT_OF_THE_SWORD, CLASS_KNIGHT_OF_THE_CROWN, 1); + /****************************************************************************/ + + /****************************************************************************/ + /* class-number name abrv clr-abrv menu-name*/ + classo(CLASS_KNIGHT_OF_THE_ROSE, "knightoftherose", "KRs", "\tWKRs\tn", "g) \tWKnight of the Rose\tn", + /* max-lvl lock? prestige? BAB HD psp move trains in-game? unlkCst, eFeatp*/ + 10, Y, Y, H, 10, 0, 1, 2, Y, 5000, 0, + /*prestige spell progression*/ "none", + /*primary attributes*/ "Strength, Con/Dex for survivability, Cha for class abilities", + /*descrip*/ + "The Order of the Rose has always been the most prestigious branch of the Knights " + "of Solamnia. The Rose Knights provide leaders, lawgivers, and exemplars to the " + "Solamnic Knights and the world, guiding others on the path of honor by word and " + "deed alike. They are the opposite of the Knights of the Lily. " + "The Measure of the Rose focuses on Wisdom and Justice. Wisdom helps the Rose " + "Knight and those following him determine what honor truly demands, neither " + "failing in their devotion to the Oath and the Measure nor throwing lives away in " + "a misguided pursuit of honor. Justice, meanwhile, involves not only protecting " + "the innocent and punishment the guilty, but treating all people--noble and poor, " + "Good and Evil--honorably and courteously, in conformity with the Measure. This " + "is the ideal that the Order of the Rose strives to bring to Ansalon and to " + "uphold in their own lives, bringing their behavior and that of others into " + "conformity with the teachings of Goodness and the Order of Creation--not through " + "force or fear, but through teaching and example. " + "Paladine is the patron deity of the Knights of the Rose. "); + /* class-number then saves: fortitude, reflex, will, poison, death */ + assign_class_saves(CLASS_KNIGHT_OF_THE_ROSE, G, B, G, B, B); + assign_class_abils(CLASS_KNIGHT_OF_THE_ROSE, /* class number */ + /*acrobatics,stealth,perception,heal,intimidate,concentration, spellcraft*/ + CC, CC, CA, CA, CA, CA, CC, + /*appraise,discipline,total_defense,lore,ride,climb,sleight_of_hand,bluff*/ + CC, CA, CA, CA, CA, CA, CC, CC, + /*diplomacy,disable_device,disguise,escape_artist,handle_animal,sense_motive*/ + CA, CC, CC, CC, CA, CA, + /*survival,swim,use_magic_device,perform*/ + CC, CA, CC, CC); + + assign_class_titles(CLASS_KNIGHT_OF_THE_ROSE, /* class number */ + "Knight of the Rose", /* <= 4 */ + "Knight of the Rose", /* <= 9 */ + "Knight of the Rose", /* <= 14 */ + "Knight of the Rose", /* <= 19 */ + "Knight of the Rose", /* <= 24 */ + "Knight of the Rose", /* <= 29 */ + "Knight of the Rose", /* <= 30 */ + "Knight of the Rose", /* <= LVL_IMMMORT */ + "Knight of the Rose", /* <= LVL_STAFF */ + "Knight of the Rose", /* <= LVL_GRSTAFF */ + "Knight of the Rose" /* default */ + ); + /* feat assignment */ + /* class num feat cfeat lvl stack */ + feat_assignment(CLASS_KNIGHT_OF_THE_ROSE, FEAT_DETECT_EVIL, Y, 1, Y); + feat_assignment(CLASS_KNIGHT_OF_THE_ROSE, FEAT_AURA_OF_GOOD, Y, 1, Y); + feat_assignment(CLASS_KNIGHT_OF_THE_ROSE, FEAT_RALLYING_CRY, Y, 1, Y); + feat_assignment(CLASS_KNIGHT_OF_THE_ROSE, FEAT_INSPIRE_COURAGE, Y, 2, Y); + feat_assignment(CLASS_KNIGHT_OF_THE_ROSE, FEAT_LEADERSHIP, Y, 3, Y); + feat_assignment(CLASS_KNIGHT_OF_THE_ROSE, FEAT_DIVINE_GRACE, Y, 3, Y); + feat_assignment(CLASS_KNIGHT_OF_THE_ROSE, FEAT_INSPIRE_GREATNESS, Y, 4, Y); + feat_assignment(CLASS_KNIGHT_OF_THE_ROSE, FEAT_CHANNEL_ENERGY, Y, 4, Y); + feat_assignment(CLASS_KNIGHT_OF_THE_ROSE, FEAT_INSPIRE_COURAGE, Y, 5, Y); + feat_assignment(CLASS_KNIGHT_OF_THE_ROSE, FEAT_WISDOM_OF_THE_MEASURE, Y, 6, Y); + feat_assignment(CLASS_KNIGHT_OF_THE_ROSE, FEAT_LEADERSHIP, Y,7, Y); + feat_assignment(CLASS_KNIGHT_OF_THE_ROSE, FEAT_INSPIRE_COURAGE, Y, 8, Y); + feat_assignment(CLASS_KNIGHT_OF_THE_ROSE, FEAT_FINAL_STAND, Y, 9, Y); + feat_assignment(CLASS_KNIGHT_OF_THE_ROSE, FEAT_KNIGHTHOODS_FLOWER, Y, 10, Y); + + // No class feats + /* no spell assignment */ + /* class prereqs */ + class_prereq_bab(CLASS_KNIGHT_OF_THE_ROSE, 8); + class_prereq_ability(CLASS_KNIGHT_OF_THE_ROSE, ABILITY_LORE, 8); + class_prereq_ability(CLASS_KNIGHT_OF_THE_ROSE, ABILITY_RIDE, 8); + class_prereq_feat(CLASS_KNIGHT_OF_THE_ROSE, FEAT_MOUNTED_COMBAT, 1); + class_prereq_feat(CLASS_KNIGHT_OF_THE_ROSE, FEAT_ENDURANCE, 1); + class_prereq_feat(CLASS_KNIGHT_OF_THE_ROSE, FEAT_HONORBOUND, 1); + class_prereq_feat(CLASS_KNIGHT_OF_THE_ROSE, FEAT_LEADERSHIP, 1); + class_prereq_feat(CLASS_KNIGHT_OF_THE_ROSE, FEAT_AURA_OF_COURAGE, 1); + class_prereq_spellcasting(CLASS_KNIGHT_OF_THE_ROSE, CASTING_TYPE_DIVINE, PREP_TYPE_ANY, 2); + class_prereq_class_level(CLASS_KNIGHT_OF_THE_ROSE, CLASS_KNIGHT_OF_THE_SWORD, 3); + /****************************************************************************/ + /****************************************************************************/ /* class-number name abrv clr-abrv menu-name*/ classo(CLASS_SHIFTER, "shifter", "Shf", "\twS\tWh\twf\tn", "f) \twSh\tWift\twer\tn", diff --git a/constants.c b/constants.c index b9bba1c9..93ef31c4 100755 --- a/constants.c +++ b/constants.c @@ -663,6 +663,9 @@ const char *class_names[] = { "Summoner", "Warlock", "Necromancer", + "Knight of the Crown", + "Knight of the Sword", + "Knight of the Rose", // "unfinished", // "unfinished", // "unfinished", @@ -4580,6 +4583,9 @@ const char *spell_prep_dict[][4] = { {"conjure", "conjuring", "conjured", "conjurings"}, // summoner {"", "", "", ""}, /* warlock 28 */ {"", "", "", ""}, /* necromancer 29 */ + {"", "", "", ""}, // knight of the crown 30 + {"", "", "", ""}, // knight of the sword 31 + {"", "", "", ""}, // knight of the rose 32 // {"", "", "", "" }, /* psion */ // {"", "", "", "" }, /* psy warr */ // {"", "", "", "" }, /* soul knife */ @@ -4621,6 +4627,9 @@ const char *spell_consign_dict[][4] = { {"unconjure", "unconjured", "unconjuring", "unconjure"}, // summoner {"", "", "", ""}, /* warlock 28 */ {"", "", "", ""}, /* necromancer 29 */ + {"", "", "", ""}, // knight of the crown 30 + {"", "", "", ""}, // knight of the sword 31 + {"", "", "", ""}, // knight of the rose 32 // {"", "", "", "" }, /* psion 18 */ // {"", "", "", "" }, /* psy warr 19 */ // {"", "", "", "" }, /* soul knife 20 */ @@ -5181,6 +5190,9 @@ const char *class_short_descriptions[] = { "An arcane spellcaster who has mastered the art of conjuring and who controls a powerful eidolon follower.", // summoner "A savvy invoker who has dominated the arcane through sheer force of will and dark pacts.", // warlock "A master of the arcane and necromantic arts, able to take upon them the powers of undeath.", // necromancer + "The first order of the Knights of Solamnia, bound by the tenets of obedience and honor.", // knight of the crown + "The second order of the Knights of Solamnia, bound by the tenets of courage and heroism.", // knight of the Sword + "The third order of the Knights of Solamnia, bound by the tenets of nobility, bravery and leadership.", // knight of the Rose ""}; CHECK_TABLE_SIZE(class_short_descriptions, NUM_CLASSES + 1); diff --git a/domains_schools.c b/domains_schools.c index be6bfd98..b0571479 100644 --- a/domains_schools.c +++ b/domains_schools.c @@ -517,7 +517,7 @@ void assign_domains(void) /* 3rd circle */ /* 4th circle */ /* 5th circle */ SPELL_HEROISM, SPELL_RESERVED_DBC, SPELL_CIRCLE_A_EVIL, /* 6th circle */ /* 7th circle */ /* 8th circle */ - SPELL_RESERVED_DBC, SPELL_INTERPOSING_HAND, SPELL_MASS_HASTE, + SPELL_RESERVED_DBC, SPELL_INTERPOSING_HAND, SPELL_HOLY_AURA, /* 9th circle */ SPELL_PROTECT_FROM_SPELLS); @@ -532,7 +532,7 @@ void assign_domains(void) /* 3rd circle */ /* 4th circle */ /* 5th circle */ SPELL_FALSE_LIFE, SPELL_RESERVED_DBC, SPELL_VAMPIRIC_TOUCH, /* 6th circle */ /* 7th circle */ /* 8th circle */ - SPELL_RESERVED_DBC, SPELL_RESERVED_DBC, SPELL_RESERVED_DBC, + SPELL_RESERVED_DBC, SPELL_RESERVED_DBC, SPELL_HOLY_AURA, /* 9th circle */ SPELL_RESERVED_DBC); diff --git a/feats.c b/feats.c index 6864616b..08a1624a 100644 --- a/feats.c +++ b/feats.c @@ -4569,13 +4569,75 @@ feato(FEAT_MOON_ELF_RACIAL_ADJUSTMENT, "moon elf racial adjustment", TRUE, FALSE /* Knight of the Crown */ /* feat-number | name | in game? | learnable? | stackable? | feat-type | short-descrip | long descrip */ /*1*/ - feato(FEAT_STRENGTH_OF_HONOR, "strength of honor", TRUE, FALSE, TRUE, FEAT_TYPE_CLASS_ABILITY, "+4 to strength for several rounds", "+4 to strength for several rounds"); - feato(FEAT_KNIGHTLY_COURAGE, "knightly courage", TRUE, FALSE, FALSE, FEAT_TYPE_CLASS_ABILITY, "bonus to fear checks", "bonus to fear checks"); - feato(FEAT_HEROIC_INITIATIVE, "heroic initiative", TRUE, FALSE, FALSE, FEAT_TYPE_CLASS_ABILITY, "none", "bonus to initiative checks"); - feato(FEAT_HONORABLE_WILL, "honorable will", TRUE, FALSE, FALSE, FEAT_TYPE_CLASS_ABILITY, "ask staff", "ask staff"); - feato(FEAT_MIGHT_OF_HONOR, "might of honor", TRUE, FALSE, FALSE, FEAT_TYPE_CLASS_ABILITY, "ask staff", "ask staff"); - feato(FEAT_ARMORED_MOBILITY, "armored mobility", TRUE, FALSE, FALSE, FEAT_TYPE_CLASS_ABILITY, "none", "heavy armor is treated as medium armor"); - feato(FEAT_CROWN_OF_KNIGHTHOOD, "crown of knighthood", TRUE, FALSE, FALSE, FEAT_TYPE_CLASS_ABILITY, "ask staff", "ask staff"); + feato(FEAT_STRENGTH_OF_HONOR, "strength of honor", TRUE, FALSE, TRUE, FEAT_TYPE_CLASS_ABILITY, + "+4 morale bonus to strength for several rounds. Uses strengthofhonor command.", + "+4 morale bonus to strength for several rounds. Uses strengthofhonor command."); + feato(FEAT_KNIGHTLY_COURAGE, "knightly courage", TRUE, FALSE, FALSE, FEAT_TYPE_CLASS_ABILITY, + "Immune to fear affects.", + "Immune to fear affects."); + feato(FEAT_HEROIC_INITIATIVE, "heroic initiative", TRUE, FALSE, FALSE, FEAT_TYPE_CLASS_ABILITY, + "+4 bonus to initiative checks.", + "+4 bonus to initiative checks."); + feato(FEAT_HONORABLE_WILL, "honorable will", TRUE, FALSE, FALSE, FEAT_TYPE_CLASS_ABILITY, + "Improves all saving throws by the number of knight of the crown class levels possessed.", + "Improves all saving throws by the number of knight of the crown class levels possessed."); + feato(FEAT_MIGHT_OF_HONOR, "might of honor", TRUE, FALSE, FALSE, FEAT_TYPE_CLASS_ABILITY, + "Increases the strength bonus and duration of the strength of honor ability.", + "Increases the strength bonus and duration of the strength of honor ability."); + feato(FEAT_ARMORED_MOBILITY, "armored mobility", TRUE, FALSE, FALSE, FEAT_TYPE_CLASS_ABILITY, + "Heavy armor is treated as medium armor, armor check penalty is reduced by 2 and armor dexterity " + "cap increased by 2. Heavy armor proficiency still required to wear heavy armor without penalties.", + "Heavy armor is treated as medium armor, armor check penalty is reduced by 2 and armor dexterity " + "cap increased by 2. Heavy armor proficiency still required to wear heavy armor without penalties."); + feato(FEAT_CROWN_OF_KNIGHTHOOD, "crown of knighthood", TRUE, FALSE, FALSE, FEAT_TYPE_CLASS_ABILITY, + "Once per day can use the crownofknighthood command to give yourself a +4 morale bonus to attack " + "rolls, weapon damage rolls, saving throws plus 20 bonus hitpoints for 5 minutes.", + "Once per day can use the crownofknighthood command to give yourself a +4 morale bonus to attack " + "rolls, weapon damage rolls, saving throws plus 20 bonus hitpoints for 5 minutes."); + + feato(FEAT_HONORBOUND, "honorbound", TRUE, TRUE, FALSE, FEAT_TYPE_COMBAT, + "+3 to saving throws against fear and other mind-affecting abilities. +4 to discipline and sense motive skills.", + "+3 to saving throws against fear and other mind-affecting abilities. +4 to discipline and sense motive skills."); + + feato(FEAT_DEMORALIZING_STRIKE, "demoralizing strike", TRUE, FALSE, FALSE, FEAT_TYPE_CLASS_ABILITY, + "Once per combat round, on a successful melee strike, the target must save vs. will or be shaken for 1 round.", + "Once per combat round, on a successful melee strike, the target must save vs. will or be shaken for 1 round."); + + feato(FEAT_SOUL_OF_KNIGHTHOOD, "soul of knighthood", TRUE, FALSE, FALSE, FEAT_TYPE_CLASS_ABILITY, + "Allows the use of soulofknighthood command which will cast the holy aura spell on all group members. " + "Also bestows a permanent +1d6 holy damage on all melee attacks, and +2d10 holy damage on critical hits.", + "Allows the use of soulofknighthood command which will cast the holy aura spell on all group members. " + "Also bestows a permanent +1d6 holy damage on all melee attacks, and +2d10 holy damage on critical hits."); + + feato(FEAT_LEADERSHIP, "leadership", TRUE, TRUE, TRUE, FEAT_TYPE_GENERAL, + "This feat will give all party members +10% experience with the first rank, and +5% for each additional rank, for a maximum of 5 ranks.", + "This feat will give all party members +10% experience with the first rank, and +5% for each additional rank, for a maximum of 5 ranks."); + feat_prereq_attribute(FEAT_LEADERSHIP, AB_CHA, 12); + + + feato(FEAT_RALLYING_CRY, "rallying cry", TRUE, FALSE, FALSE, FEAT_TYPE_CLASS_ABILITY, + "Gives party members a +1 morale bonus to attack rolls and a +5 bonus to speed. Uses the rallyingcry command.", + "Gives party members a +1 morale bonus to attack rolls and a +5 bonus to speed. Uses the rallyingcry command."); + + feato(FEAT_INSPIRE_COURAGE, "inspire courage", TRUE, FALSE, FALSE, FEAT_TYPE_CLASS_ABILITY, + "Gives party members a +2 morale bonus to attack rolls, melee damage and willpower saving throws. Additional ranks improve bonus.", + "Gives party members a +2 morale bonus to attack rolls, melee damage and willpower saving throws. Additional ranks improve bonus."); + + feato(FEAT_INSPIRE_GREATNESS, "inspire greatness", TRUE, FALSE, FALSE, FEAT_TYPE_CLASS_ABILITY, + "Inspire courage now gives an additional +2 to attack rolls, +1 to fortitude saving throws and increases max hit points by 20.", + "Inspire courage now gives an additional +2 to attack rolls, +1 to fortitude saving throws and increases max hit points by 20."); + + feato(FEAT_WISDOM_OF_THE_MEASURE, "wisdom of the measure", TRUE, FALSE, FALSE, FEAT_TYPE_CLASS_ABILITY, + "Can use the wisdomofthemeasure command to cast the augury spell.", + "Can use the wisdomofthemeasure command to cast the augury spell."); + + feato(FEAT_FINAL_STAND, "final stand", TRUE, FALSE, FALSE, FEAT_TYPE_CLASS_ABILITY, + "Maximum and current hit points of all party members increases by 30.", + "Maximum and current hit points of all party members increases by 30."); + + feato(FEAT_KNIGHTHOODS_FLOWER, "knighthood's flower", TRUE, FALSE, FALSE, FEAT_TYPE_CLASS_ABILITY, + "Gain immunity to compulsion effects, and can use the knighthoodsflower command to gain a +2 insight bonus to armor class and reflex saving throws.", + "Gain immunity to compulsion effects, and can use the knighthoodsflower command to gain a +2 insight bonus to armor class and reflex saving throws."); /* Shadow Dancer (ShadowDancer) */ /* feat-number | name | in game? | learnable? | stackable? | feat-type | short-descrip | long descrip */ @@ -4831,25 +4893,6 @@ feato(FEAT_MOON_ELF_RACIAL_ADJUSTMENT, "moon elf racial adjustment", TRUE, FALSE /* epic */ feato(FEAT_SNEAK_ATTACK_OF_OPPORTUNITY, "sneak attack of opportunity", FALSE, TRUE, FALSE, FEAT_TYPE_COMBAT, "makes all opportunity attacks sneak attacks", "makes all opportunity attacks sneak attacks"); - /* knight of the rose (dragonlance) */ - feato(FEAT_RALLYING_CRY, "rallying cry", FALSE, FALSE, FALSE, FEAT_TYPE_CLASS_ABILITY, "ask staff", "ask staff"); - - /* knight of the sword */ - - /* knight of the crown (dragonlance) */ - feato(FEAT_HONORABLE_WILL, "honorable will", FALSE, FALSE, FALSE, FEAT_TYPE_CLASS_ABILITY, "ask staff", "ask staff"); - - /* knight of the crown / knight of the lily [SHARED] (dragonlance) */ - feato(FEAT_ARMORED_MOBILITY, "armored mobility", FALSE, FALSE, FALSE, FEAT_TYPE_CLASS_ABILITY, "heavy armor is treated as medium armor", "heavy armor is treated as medium armor"); - - /* knight of the lily (dragonlance) */ - feato(FEAT_UNBREAKABLE_WILL, "unbreakable will", FALSE, FALSE, FALSE, FEAT_TYPE_CLASS_ABILITY, "ask staff", "ask staff"); - - /* knight of the thorn (dragonlance) */ - - /* knight of the skull (dragonlance) */ - feato(FEAT_DARK_BLESSING, "dark blessing", FALSE, FALSE, FALSE, FEAT_TYPE_CLASS_ABILITY, "ask staff", "ask staff"); - /* feat-number | name | in game? | learnable? | stackable? | feat-type | short-descrip | long descrip */ /* Pale/Death Master */ @@ -5238,6 +5281,14 @@ feato(FEAT_MOON_ELF_RACIAL_ADJUSTMENT, "moon elf racial adjustment", TRUE, FALSE dailyfeat(FEAT_TABAXI_CATS_CLAWS, eCATSCLAWS); dailyfeat(FEAT_STONES_ENDURANCE, eSTONESENDURANCE); dailyfeat(FEAT_TOUCH_OF_UNDEATH, eTOUCHOFUNDEATH); + dailyfeat(FEAT_STRENGTH_OF_HONOR, eSTRENGTHOFHONOR); + dailyfeat(FEAT_CROWN_OF_KNIGHTHOOD, eCROWNOFKNIGHTHOOD); + dailyfeat(FEAT_SOUL_OF_KNIGHTHOOD, eSOULOFKNIGHTHOOD); + dailyfeat(FEAT_INSPIRE_COURAGE, eINSPIRECOURAGE); + dailyfeat(FEAT_WISDOM_OF_THE_MEASURE, eWISDOMOFTHEMEASURE); + dailyfeat(FEAT_FINAL_STAND, eFINALSTAND); + dailyfeat(FEAT_KNIGHTHOODS_FLOWER, eKNIGHTHOODSFLOWER); + dailyfeat(FEAT_RALLYING_CRY, eRALLYINGCRY); /** END **/ } @@ -5639,6 +5690,11 @@ int feat_is_available(struct char_data *ch, int featnum, int iarg, char *sarg) return FALSE; return TRUE; + case FEAT_LEADERSHIP: + if (has_feat_requirement_check(ch, FEAT_LEADERSHIP) >= 5) + return FALSE; + return TRUE; + case FEAT_EPIC_WILDSHAPE: if (has_feat_requirement_check(ch, FEAT_EPIC_WILDSHAPE) >= 5) return FALSE; @@ -7440,6 +7496,36 @@ void list_feats(struct char_data *ch, const char *arg, int list_type, struct cha strlcat(buf2, buf, sizeof(buf2)); none_shown = FALSE; } + else if (i == FEAT_LEADERSHIP) + { + if (mode == 1) + { + snprintf(buf3, sizeof(buf3), "%s (+%d%% exp)", feat_list[i].name, (HAS_FEAT(ch, FEAT_LEADERSHIP) + 1) * 5); + snprintf(buf, sizeof(buf), "\tW%-30s\tC:\tn %s\r\n", buf3, feat_list[i].short_description); + } + else + { + snprintf(buf3, sizeof(buf3), "%s (+%d%% exp)", feat_list[i].name, (HAS_FEAT(ch, FEAT_LEADERSHIP) + 1) * 5); + snprintf(buf, sizeof(buf), "%-40s ", buf3); + } + strlcat(buf2, buf, sizeof(buf2)); + none_shown = FALSE; + } + else if (i == FEAT_INSPIRE_COURAGE) + { + if (mode == 1) + { + snprintf(buf3, sizeof(buf3), "%s (+%d)", feat_list[i].name, HAS_FEAT(ch, FEAT_INSPIRE_COURAGE) + 1); + snprintf(buf, sizeof(buf), "\tW%-30s\tC:\tn %s\r\n", buf3, feat_list[i].short_description); + } + else + { + snprintf(buf3, sizeof(buf3), "%s (+%d)", feat_list[i].name, HAS_FEAT(ch, FEAT_INSPIRE_COURAGE) + 1); + snprintf(buf, sizeof(buf), "%-40s ", buf3); + } + strlcat(buf2, buf, sizeof(buf2)); + none_shown = FALSE; + } else if (i == FEAT_ELDRITCH_BLAST) { if (mode == 1) diff --git a/fight.c b/fight.c index 9cc28f9a..e66d0f54 100755 --- a/fight.c +++ b/fight.c @@ -624,7 +624,7 @@ int roll_initiative(struct char_data *ch) initiative += 2 * HAS_FEAT(ch, FEAT_IMPROVED_REACTION); initiative += GET_WIS_BONUS(ch) * HAS_FEAT(ch, FEAT_CUNNING_INITIATIVE); initiative += GET_INITIATIVE_MOD(ch); - // initiative += HAS_FEAT(ch, FEAT_HEROIC_INITIATIVE); + initiative += HAS_FEAT(ch, FEAT_HEROIC_INITIATIVE) ? 4 : 0; return initiative; } @@ -958,6 +958,11 @@ int compute_armor_class(struct char_data *attacker, struct char_data *ch, /* this will include a dex-cap bonus on equipment as well */ bonuses[BONUS_TYPE_DODGE] += GET_DEX_BONUS(ch); + if ((get_speed(ch, false) - 10) > get_speed(attacker, false)) + { + bonuses[BONUS_TYPE_DODGE] += 1; + } + if (!IS_NPC(ch) && HAS_FEAT(ch, FEAT_LUCK_OF_HEROES)) { bonuses[BONUS_TYPE_DODGE] += 1; @@ -1432,6 +1437,8 @@ bool set_fighting(struct char_data *ch, struct char_data *vict) /* start the combat loop, making sure we begin with phase "1" */ attach_mud_event(new_mud_event(eCOMBAT_ROUND, ch, strdup("1")), delay); + HAS_PERFORMED_DEMORALIZING_STRIKE(ch) = FALSE; + return TRUE; } @@ -1471,6 +1478,8 @@ void stop_fighting(struct char_data *ch) affect_from_char(ch, SKILL_SMITE_GOOD); } ch->player_specials->has_banishment_been_attempted = false; + + HAS_PERFORMED_DEMORALIZING_STRIKE(ch) = FALSE; } /* threw together this function to make corpses on the whim, originally made for @@ -6665,6 +6674,61 @@ int compute_hit_damage(struct char_data *ch, struct char_data *victim, break; } + if (victim && affected_by_spell(victim, SPELL_HOLY_AURA) && ((IS_OUTSIDER(ch) && IS_EVIL(ch)) || IS_UNDEAD(ch))) + { + if (GET_LEVEL(ch) <= 20 || (GET_LEVEL(ch) < 30 && dice(1, 5) == 1) || (GET_LEVEL(ch) >= 30 && dice(1, 10) == 1)) + { + if (!AFF_FLAGGED(ch, AFF_BLIND) && can_blind(ch) && !mag_savingthrow(victim, ch, SAVING_FORT, 0, AFFECT_HOLY_AURA_RETRIBUTION, compute_divine_level(victim), ABJURATION)) + { + struct affected_type af; + new_affect(&af); + af.spell = AFFECT_HOLY_AURA_RETRIBUTION; + af.duration = 5; + SET_BIT_AR(af.bitvector, AFF_BLIND); + affect_join(victim, &af, TRUE, FALSE, FALSE, FALSE); + act("$N's holy aura flashes with holy brilliance, blinding you!", FALSE, ch, 0, victim, TO_CHAR); + act("Your holy aura flashes with holy brilliance, blinding $n!", FALSE, ch, 0, victim, TO_VICT); + act("$N's holy aura flashes with holy brilliance, blinding $n!", FALSE, ch, 0, victim, TO_NOTVICT); + } + } + } + + if (victim && HAS_FEAT(ch, FEAT_DEMORALIZING_STRIKE) && !HAS_PERFORMED_DEMORALIZING_STRIKE(ch)) + { + HAS_PERFORMED_DEMORALIZING_STRIKE(ch) = TRUE; + if (!is_immune_mind_affecting(ch, victim, FALSE) && + !is_immune_fear(ch, victim, FALSE)) + { + struct affected_type af; + new_affect(&af); + af.spell = SPELL_AFFECT_WEAPON_OF_AWE; + af.duration = 1; + SET_BIT_AR(af.bitvector, AFF_SHAKEN); + affect_join(victim, &af, TRUE, FALSE, FALSE, FALSE); + act("Your attack demoralized $N!", FALSE, ch, 0, victim, TO_CHAR); + act("$n's attack has demoralized YOU!", FALSE, ch, 0, victim, TO_VICT); + act("$n's attack demoralized $N!", FALSE, ch, 0, victim, TO_NOTVICT); + } + } + + if (HAS_FEAT(ch, FEAT_DEMORALIZING_STRIKE) && !HAS_PERFORMED_DEMORALIZING_STRIKE(ch)) + { + HAS_PERFORMED_DEMORALIZING_STRIKE(ch) = TRUE; + if (!is_immune_mind_affecting(ch, victim, FALSE) && + !is_immune_fear(ch, victim, FALSE)) + { + struct affected_type af; + new_affect(&af); + af.spell = SPELL_AFFECT_WEAPON_OF_AWE; + af.duration = 1; + SET_BIT_AR(af.bitvector, AFF_SHAKEN); + affect_join(victim, &af, TRUE, FALSE, FALSE, FALSE); + act("Your attack demoralized $N!", FALSE, ch, 0, victim, TO_CHAR); + act("$n's attack has demoralized YOU!", FALSE, ch, 0, victim, TO_VICT); + act("$n's attack demoralized $N!", FALSE, ch, 0, victim, TO_NOTVICT); + } + } + damage_holder = dam; /* store so we don't multiply a multiply */ /* handle critical hit damage here */ @@ -6706,7 +6770,7 @@ int compute_hit_damage(struct char_data *ch, struct char_data *victim, if (has_teamwork_feat(ch, FEAT_PRECISE_FLANKING) && is_flanked(ch, victim)) dam += dice(1, 6); - if (affected_by_spell(ch, SPELL_WEAPON_OF_AWE) && !affected_by_spell(victim, SPELL_AFFECT_WEAPON_OF_AWE)) + if (victim && affected_by_spell(ch, SPELL_WEAPON_OF_AWE) && !affected_by_spell(victim, SPELL_AFFECT_WEAPON_OF_AWE)) { if (!is_immune_mind_affecting(ch, victim, FALSE) && !is_immune_fear(ch, victim, FALSE)) @@ -7858,6 +7922,11 @@ int compute_attack_bonus(struct char_data *ch, /* Attacker */ bonuses[BONUS_TYPE_CIRCUMSTANCE] += 2; } + if ((get_speed(ch, false) - 10) > get_speed(victim, false)) + { + bonuses[BONUS_TYPE_CIRCUMSTANCE] += 1; + } + if (IN_ROOM(ch) != NOWHERE && ROOM_AFFECTED(IN_ROOM(ch), RAFF_SACRED_SPACE) && IS_EVIL(ch)) bonuses[BONUS_TYPE_SACRED] -= 1; @@ -7943,6 +8012,11 @@ int compute_attack_bonus(struct char_data *ch, /* Attacker */ bonuses[BONUS_TYPE_MORALE] += 1; } + if (affected_by_spell(ch, AFFECT_RALLYING_CRY)) + { + bonuses[BONUS_TYPE_MORALE] += 1; + } + if (HAS_REAL_FEAT(ch, FEAT_DRAGONBORN_FURY) && (GET_HIT(ch) * 2) < GET_MAX_HIT(ch)) bonuses[BONUS_TYPE_MORALE] += 1; @@ -11753,6 +11827,7 @@ void perform_violence(struct char_data *ch, int phase) /* Reset combat data */ GET_TOTAL_AOO(ch) = 0; + HAS_PERFORMED_DEMORALIZING_STRIKE(ch) = FALSE; REMOVE_BIT_AR(AFF_FLAGS(ch), AFF_FLAT_FOOTED); ch->char_specials.energy_retort_used = false; diff --git a/handler.c b/handler.c index e15d8377..61274768 100755 --- a/handler.c +++ b/handler.c @@ -591,6 +591,7 @@ void compute_char_cap(struct char_data *ch, int mode) dam_cap += class_level / 3; break; case CLASS_WARRIOR: + case CLASS_KNIGHT_OF_THE_CROWN: case CLASS_WEAPON_MASTER: str_cap += class_level / 4 + 1; con_cap += class_level / 4 + 1; @@ -1520,7 +1521,7 @@ void obj_to_char(struct obj_data *object, struct char_data *ch) // log("T10: %s", object->short_description); MSDPFlush(ch->desc, eMSDP_INVENTORY); } - log("T11: %s", object->short_description); + // log("T11: %s", object->short_description); } else log("SYSERR: NULL obj (%p) or char (%p) passed to obj_to_char.", object, ch); diff --git a/hunts.c b/hunts.c index c4df0cd0..069f2c46 100644 --- a/hunts.c +++ b/hunts.c @@ -1165,7 +1165,7 @@ int get_hunt_armor_drop_vnum(int hunt_record) case HUNT_TYPE_WILL_O_WISP: return 60008; case HUNT_TYPE_BANSHEE: - return 60010; + return 60037; case HUNT_TYPE_BLACK_PUDDING: return 60012; case HUNT_TYPE_CHIMERA: @@ -1215,7 +1215,7 @@ int get_hunt_armor_drop_vnum(int hunt_record) case HUNT_TYPE_BANDERSNATCH: return 60035; case HUNT_TYPE_BARGHEST: - return 60037; + return 60010; default: return 0; } @@ -1237,7 +1237,7 @@ int get_hunt_weapon_drop_vnum(int hunt_record) case HUNT_TYPE_WILL_O_WISP: return 60009; case HUNT_TYPE_BANSHEE: - return 60011; + return 60038; case HUNT_TYPE_BLACK_PUDDING: return 60013; case HUNT_TYPE_CHIMERA: @@ -1281,7 +1281,7 @@ int get_hunt_weapon_drop_vnum(int hunt_record) case HUNT_TYPE_BANDERSNATCH: return 60036; case HUNT_TYPE_BARGHEST: - return 60038; + return 60011; default: return 0; } diff --git a/interpreter.c b/interpreter.c index 96a9e76c..cabbf496 100755 --- a/interpreter.c +++ b/interpreter.c @@ -285,6 +285,7 @@ cpp_extern const struct command_info cmd_info[] = { {"cmdlev", "cmdlev", POS_DEAD, do_cmdlev, LVL_BUILDER, 0, FALSE, ACTION_NONE, {0, 0}, NULL}, {"cexchange", "cexchange", POS_RECLINING, do_cexchange, 0, 0, TRUE, ACTION_NONE, {0, 0}, NULL}, {"createspawn", "createspawn", POS_STANDING, do_create_vampire_spawn, 1, 0, FALSE, ACTION_STANDARD, {0, 0}, can_create_vampire_spawn}, + {"crownofknighthood", "crownofknighthood", POS_FIGHTING, do_crown_of_knighthood, 0, 0, TRUE, ACTION_NONE, {0, 0}, NULL}, {"cruelties", "cruelties", POS_RECLINING, do_cruelties, 0, 0, TRUE, ACTION_NONE, {0, 0}, NULL}, {"condensed", "condensed", POS_DEAD, do_gen_tog, 0, SCMD_CONDENSED, TRUE, ACTION_NONE, {0, 0}, NULL}, {"carefulpet", "carefulpet", POS_DEAD, do_gen_tog, 0, SCMD_CAREFUL_PET, TRUE, ACTION_NONE, {0, 0}, NULL}, @@ -395,6 +396,7 @@ cpp_extern const struct command_info cmd_info[] = { {"faeriefire", "faeriefire", POS_FIGHTING, do_process_attack, 1, AA_FAERIE_FIRE, FALSE, ACTION_NONE, {0, 0}, can_faeriefire}, {"favoredenemies", "favoredenemies", POS_DEAD, do_favoredenemies, 0, 0, FALSE, ACTION_NONE, {0, 0}, NULL}, {"feymagic", "feymagic", POS_FIGHTING, do_fey_magic, 1, 0, FALSE, ACTION_SWIFT, {0, 0}, can_fey_magic}, + {"finalstand", "finalstand", POS_DEAD, do_final_stand, 0, 0, FALSE, ACTION_NONE, {0, 0}, NULL}, {"findmagic", "findmagic", POS_DEAD, do_findmagic, LVL_BUILDER, 0, FALSE, ACTION_NONE, {0, 0}, NULL}, {"finddoor", "finddoor", POS_DEAD, do_finddoor, LVL_STAFF, 0, TRUE, ACTION_NONE, {0, 0}, NULL}, {"featset", "featset", POS_SLEEPING, do_featset, LVL_IMPL, 0, TRUE, ACTION_NONE, {0, 0}, NULL}, @@ -483,6 +485,7 @@ cpp_extern const struct command_info cmd_info[] = { {"innerfire", "innerfire", POS_FIGHTING, do_innerfire, 1, 0, FALSE, ACTION_NONE, {0, 0}, NULL}, {"invoke", "invoke", POS_FIGHTING, do_use_consumable, 0, SCMD_INVOKE, FALSE, ACTION_SWIFT, {0, 6}, NULL}, {"insectbeing", "insectbeing", POS_FIGHTING, do_insectbeing, 0, 0, FALSE, ACTION_NONE, {0, 0}, can_insectbeing}, + {"inspirecourage", "inspirecourage", POS_FIGHTING, do_inspire_courage, 0, 0, FALSE, ACTION_NONE, {0, 0}, NULL}, /* {"command", "sort_as", minimum_position, *command_pointer, minimum_level, subcmd, ignore_wait, actions_required, {action_cooldowns}, *command_check_pointer},*/ @@ -496,6 +499,7 @@ cpp_extern const struct command_info cmd_info[] = { {"kill", "k", POS_FIGHTING, do_kill, 0, 0, FALSE, ACTION_STANDARD, {6, 0}, NULL}, {"kick", "ki", POS_FIGHTING, do_process_attack, 1, AA_KICK, FALSE, ACTION_NONE, {6, 0}, can_kick}, {"keycheck", "keycheck", POS_STANDING, do_keycheck, LVL_IMMORT, 0, TRUE, ACTION_NONE, {0, 0}, NULL}, + {"knighthoodsflower", "knighthoodsflower", POS_STANDING, do_knighthoods_flower, 0, 0, TRUE, ACTION_NONE, {0, 0}, NULL}, /* {"command", "sort_as", minimum_position, *command_pointer, minimum_level, subcmd, ignore_wait, actions_required, {action_cooldowns}, *command_check_pointer},*/ @@ -651,6 +655,7 @@ cpp_extern const struct command_info cmd_info[] = { {"rest", "re", POS_RECLINING, do_rest, 0, 0, FALSE, ACTION_NONE, {0, 0}, NULL}, {"reply", "r", POS_SLEEPING, do_reply, 0, 0, TRUE, ACTION_NONE, {0, 0}, NULL}, + {"rallyingcry", "rallyingcry", POS_FIGHTING, do_rallying_cry, 1, 0, FALSE, ACTION_NONE, {0, 0}, NULL}, {"rapidshot", "rapidshot", POS_FIGHTING, do_mode, 1, MODE_RAPID_SHOT, FALSE, ACTION_NONE, {0, 0}, NULL}, {"read", "rea", POS_RECLINING, do_look, 0, SCMD_READ, FALSE, ACTION_NONE, {0, 0}, NULL}, {"reforge", "reforge", POS_STANDING, do_not_here, 1, 0, FALSE, ACTION_NONE, {0, 0}, NULL}, @@ -742,6 +747,7 @@ cpp_extern const struct command_info cmd_info[] = { {"socials", "socials", POS_DEAD, do_commands, 0, SCMD_SOCIALS, TRUE, ACTION_NONE, {0, 0}, NULL}, {"sortfrom", "sortfrom", POS_RECLINING, do_sort, 0, SCMD_SORTFROM, TRUE, ACTION_NONE, {0, 0}, NULL}, {"sortto", "sortto", POS_RECLINING, do_sort, 0, SCMD_SORTTO, TRUE, ACTION_NONE, {0, 0}, NULL}, + {"soulofknighthood", "soulofknighthood", POS_FIGHTING, do_soul_of_knighthood, 0, 0, TRUE, ACTION_NONE, {0, 0}, NULL}, {"speak", "speak", POS_RECLINING, do_speak, 0, 0, TRUE, ACTION_NONE, {0, 0}, NULL}, {"spelllist", "spelllist", POS_RECLINING, do_spelllist, 1, 0, FALSE, ACTION_NONE, {0, 0}, NULL}, {"spells", "spells", POS_RECLINING, do_spells, 1, 0, FALSE, ACTION_NONE, {0, 0}, NULL}, @@ -755,6 +761,7 @@ cpp_extern const struct command_info cmd_info[] = { {"stunningfist", "stunningfist", POS_FIGHTING, do_stunningfist, 1, 0, FALSE, ACTION_NONE, {0, 0}, can_stunningfist}, {"study", "study", POS_RECLINING, do_study, 1, 0, FALSE, ACTION_NONE, {0, 0}, NULL}, {"strength", "strength", POS_FIGHTING, do_strength, 1, 0, FALSE, ACTION_MOVE, {0, 0}, NULL}, + {"strengthofhonor", "strengthofhonor", POS_FIGHTING, do_strength_of_honor, 1, 0, FALSE, ACTION_NONE, {0, 0}, NULL}, {"swallow", "swallow", POS_RECLINING, do_swallow, 1, 0, FALSE, ACTION_STANDARD, {0, 0}, NULL}, {"switch", "switch", POS_DEAD, do_switch, LVL_STAFF, 0, TRUE, ACTION_NONE, {0, 0}, NULL}, {"shapechange", "shapechange", POS_FIGHTING, do_wildshape, 1, 0, FALSE, ACTION_NONE, {0, 0}, NULL}, @@ -863,6 +870,7 @@ cpp_extern const struct command_info cmd_info[] = { {"whisper", "whisper", POS_RECLINING, do_spec_comm, 0, SCMD_WHISPER, TRUE, ACTION_NONE, {0, 0}, NULL}, {"wield", "wie", POS_RESTING, do_wield, 0, 0, FALSE, ACTION_MOVE, {0, 6}, NULL}, {"withdraw", "withdraw", POS_STANDING, do_not_here, 1, 0, FALSE, ACTION_NONE, {0, 0}, NULL}, + {"wisdomofthemeasure", "wisdomofthemeasure", POS_STANDING, do_wisdom_of_the_measure, 1, 0, FALSE, ACTION_NONE, {0, 0}, NULL}, {"wiznet", "wiz", POS_DEAD, do_wiznet, LVL_IMMORT, 0, TRUE, ACTION_NONE, {0, 0}, NULL}, {";", ";", POS_DEAD, do_wiznet, LVL_IMMORT, 0, TRUE, ACTION_NONE, {0, 0}, NULL}, {"wizhelp", "wizhelp", POS_SLEEPING, do_commands, LVL_IMMORT, SCMD_WIZHELP, TRUE, ACTION_NONE, {0, 0}, NULL}, @@ -3139,6 +3147,15 @@ switch (load_result) case CLASS_MYSTIC_THEURGE: perform_help(d, "class-mystictheurge"); break; + case CLASS_KNIGHT_OF_THE_CROWN: + perform_help(d, "class-knightofthecrown"); + break; + case CLASS_KNIGHT_OF_THE_SWORD: + perform_help(d, "class-knightofthesword"); + break; + case CLASS_KNIGHT_OF_THE_ROSE: + perform_help(d, "class-knightoftherose"); + break; case CLASS_WARRIOR: perform_help(d, "class-warrior"); break; diff --git a/limits.c b/limits.c index 678aa727..de7c1ca5 100755 --- a/limits.c +++ b/limits.c @@ -1001,6 +1001,8 @@ int gain_exp(struct char_data *ch, int gain, int mode) return 0; } + gain *= leadership_exp_multiplier(ch); + /* newbie bonus */ if (GET_LEVEL(ch) <= NEWBIE_LEVEL) gain += (int)((float)gain * ((float)NEWBIE_EXP / (float)(100))); diff --git a/magic.c b/magic.c index cedeec22..42e5d927 100755 --- a/magic.c +++ b/magic.c @@ -55,16 +55,13 @@ int compute_spell_res(struct char_data *ch, struct char_data *vict, int modifier { int resist = GET_SPELL_RES(vict); - // adjustments passed to mag_resistance - resist += modifier; - // additional adjustmenets if (HAS_FEAT(vict, FEAT_DIAMOND_SOUL)) - resist += 10 + MONK_TYPE(vict); + resist = MAX(resist, 10 + MONK_TYPE(vict)); if (!IS_NPC(vict) && HAS_FEAT(vict, FEAT_DROW_SPELL_RESISTANCE)) - resist += 10 + GET_LEVEL(vict); + resist = MAX(resist, 10 + GET_LEVEL(vict)); if (HAS_FEAT(vict, FEAT_HALF_DROW_SPELL_RESISTANCE)) { @@ -79,9 +76,9 @@ int compute_spell_res(struct char_data *ch, struct char_data *vict, int modifier if (HAS_EVOLUTION(vict, EVOLUTION_SPELL_RESISTANCE)) { if (HAS_EVOLUTION(vict, EVOLUTION_FIENDISH_APPEARANCE) || HAS_EVOLUTION(vict, EVOLUTION_CELESTIAL_APPEARANCE)) - resist = 15 + GET_LEVEL(vict); + resist = MAX(resist, 15 + GET_LEVEL(vict)); else - resist = 10 + GET_LEVEL(vict); + resist = MAX(resist, 10 + GET_LEVEL(vict)); } if (HAS_EVOLUTION(vict, EVOLUTION_CELESTIAL_APPEARANCE) || HAS_EVOLUTION(vict, EVOLUTION_FIENDISH_APPEARANCE)) @@ -93,31 +90,36 @@ int compute_spell_res(struct char_data *ch, struct char_data *vict, int modifier } if (IS_LICH(vict)) - resist += 15 + GET_LEVEL(vict); + resist = MAX(resist, 15 + GET_LEVEL(vict)); if (!IS_NPC(vict) && HAS_FEAT(vict, FEAT_IMPROVED_SPELL_RESISTANCE)) - resist += 2 * HAS_FEAT(vict, FEAT_IMPROVED_SPELL_RESISTANCE); + resist = MAX(resist, 2 * HAS_FEAT(vict, FEAT_IMPROVED_SPELL_RESISTANCE)); if (affected_by_spell(vict, SPELL_PROTECT_FROM_SPELLS)) resist += 10; if (affected_by_spell(vict, SKILL_INNER_FIRE)) - resist += 25; + resist = MAX(resist, 25); + + if (affected_by_spell(vict, SPELL_HOLY_AURA) && IS_EVIL(ch)) + resist = MAX(resist, 25); if (IS_AFFECTED(vict, AFF_SPELL_RESISTANT)) - resist += 12 + GET_LEVEL(vict); + resist = MAX(resist, 12 + GET_LEVEL(vict)); - if (!IS_NPC(vict) && GET_EQ(vict, WEAR_SHIELD) && - HAS_FEAT(vict, FEAT_ARMOR_MASTERY_2)) - resist += 25; + if (!IS_NPC(vict) && GET_EQ(vict, WEAR_SHIELD) && HAS_FEAT(vict, FEAT_ARMOR_MASTERY_2)) + resist = MAX(resist, 25); if (HAS_FEAT(vict, FEAT_FAE_RESISTANCE)) - resist += 15 + GET_LEVEL(vict); + resist = MAX(resist, 15 + GET_LEVEL(vict)); else if (IS_PIXIE(vict)) - resist += 15; + resist = MAX(resist, 15); if (IS_DRAGON(vict)) - resist += 25; + resist = MAX(resist, 25); + + // adjustments passed to mag_resistance + resist += modifier; return MIN(99, MAX(0, resist)); } @@ -200,6 +202,7 @@ int compute_mag_saves(struct char_data *vict, int type, int modifier) if (!IS_NPC(vict) && GET_SKILL(vict, SKILL_EPIC_REFLEXES)) saves += 3; break; + case SAVING_WILL: saves += GET_WIS_BONUS(vict); if (!IS_NPC(vict) && HAS_FEAT(vict, FEAT_IRON_WILL)) @@ -283,6 +286,11 @@ int mag_savingthrow_full(struct char_data *ch, struct char_data *vict, diceroll = MAX(diceroll, d20(vict)); savethrow = compute_mag_saves(vict, type, modifier) + diceroll; + if (type == SAVING_REFL && (get_speed(vict, false) - 10) > get_speed(ch, false)) + { + savethrow += 1; + } + if (GET_POS(vict) == POS_DEAD) return (FALSE); /* Guess you failed, since you are DEAD. */ @@ -2538,6 +2546,11 @@ int mag_damage(int level, struct char_data *ch, struct char_data *victim, { if (victim && HAS_REAL_FEAT(victim, FEAT_STUBBORN_MIND)) dc_mod -= 2; + if (victim && HAS_REAL_FEAT(victim, FEAT_HONORBOUND)) + dc_mod -= 2; + if (victim && HAS_REAL_FEAT(victim, FEAT_HONORABLE_WILL)) + dc_mod -= CLASS_LEVEL(victim, CLASS_KNIGHT_OF_THE_CROWN); + } if (element == DAM_POISON && KNOWS_DISCOVERY(ch, ALC_DISC_CELESTIAL_POISONS)) @@ -2713,6 +2726,10 @@ void mag_affects(int level, struct char_data *ch, struct char_data *victim, { if (victim && HAS_REAL_FEAT(victim, FEAT_STUBBORN_MIND)) dc_mod -= 2; + if (victim && HAS_REAL_FEAT(victim, FEAT_HONORBOUND)) + dc_mod -= 2; + if (victim && HAS_REAL_FEAT(victim, FEAT_HONORABLE_WILL)) + dc_mod -= CLASS_LEVEL(victim, CLASS_KNIGHT_OF_THE_CROWN); } /* elven drow resistance to certain enchantments such as sleep */ @@ -4770,6 +4787,29 @@ void mag_affects(int level, struct char_data *ch, struct char_data *victim, to_room = "A brief aura of brilliant blue surrounds $n."; break; + case SPELL_HOLY_AURA: + af[0].duration = 10 + level; + af[0].modifier = 4; + af[0].location = APPLY_AC_NEW; + af[0].bonus_type = BONUS_TYPE_DEFLECTION; + + af[1].duration = 10 + level; + af[1].modifier = 4; + af[1].location = APPLY_SAVING_FORT; + af[1].bonus_type = BONUS_TYPE_SACRED; + + af[2].duration = 10 + level; + af[2].modifier = 4; + af[2].location = APPLY_SAVING_REFL; + af[2].bonus_type = BONUS_TYPE_SACRED; + + af[3].duration = 10 + level; + af[3].modifier = 4; + af[3].location = APPLY_SAVING_WILL; + af[3].bonus_type = BONUS_TYPE_SACRED; + + break; + case SPELL_DJINNI_KIND: af[0].duration = 16000; af[0].modifier = 20; @@ -5291,6 +5331,100 @@ void mag_affects(int level, struct char_data *ch, struct char_data *victim, to_vict = "You become unable to speak!"; break; + case AFFECT_RALLYING_CRY: + + af[0].duration = level + 10; + af[0].location = APPLY_SPECIAL; + af[0].modifier = 1; + af[0].bonus_type = BONUS_TYPE_MORALE; + to_room = "$n looks more eager to fight!"; + to_vict = "You feel more confident and able in your abilities!"; + break; + + case AFFECT_FINAL_STAND: + + af[0].duration = level * 12; + af[0].location = APPLY_HIT; + af[0].modifier = 30; + af[0].bonus_type = BONUS_TYPE_CIRCUMSTANCE; + + af[1].duration = level * 12; + af[1].location = APPLY_AC_NEW; + af[1].modifier = 1; + af[1].bonus_type = BONUS_TYPE_CIRCUMSTANCE; + + to_room = "$n has taken a defensive stance."; + to_vict = "You take a defensive stance."; + break; + + case AFFECT_KNIGHTHOODS_FLOWER: + + af[0].duration = 600; + af[0].location = APPLY_AC_NEW; + af[0].modifier = 2; + af[0].bonus_type = BONUS_TYPE_INSIGHT; + + af[1].duration = 600; + af[1].location = APPLY_SAVING_REFL; + af[1].modifier = 2; + af[1].bonus_type = BONUS_TYPE_INSIGHT; + + to_room = "$n recites the Oath, 'Est Solarus Oth Mithas' and is bolstered in ability."; + to_vict = "You recite the Oath, 'Est Solarus Oth Mithas' and are bolstered in ability."; + break; + + case AFFECT_INSPIRE_GREATNESS: + + af[0].duration = level + 10; + af[0].location = APPLY_HITROLL; + af[0].modifier = 2 + HAS_FEAT(ch, FEAT_INSPIRE_COURAGE) + (2 * HAS_FEAT(ch, FEAT_INSPIRE_GREATNESS)); + af[0].bonus_type = BONUS_TYPE_MORALE; + + af[1].duration = level + 10; + af[1].location = APPLY_DAMROLL; + af[1].modifier = 2 + HAS_FEAT(ch, FEAT_INSPIRE_COURAGE) + (2 * HAS_FEAT(ch, FEAT_INSPIRE_GREATNESS)); + af[1].bonus_type = BONUS_TYPE_MORALE; + + af[2].duration = level + 10; + af[2].location = APPLY_SAVING_WILL; + af[2].modifier = 2 + HAS_FEAT(ch, FEAT_INSPIRE_COURAGE) + (2 * HAS_FEAT(ch, FEAT_INSPIRE_GREATNESS)); + af[2].bonus_type = BONUS_TYPE_MORALE; + + af[3].duration = level + 10; + af[3].location = APPLY_HIT; + af[3].modifier = 20; + af[3].bonus_type = BONUS_TYPE_MORALE; + + af[4].duration = level + 10; + af[4].location = APPLY_SAVING_FORT; + af[4].modifier = 1; + af[4].bonus_type = BONUS_TYPE_MORALE; + + to_room = "$n looks more confident!"; + to_vict = "Your courage surges and with it your fighting prowess!"; + break; + + case AFFECT_INSPIRE_COURAGE: + + af[0].duration = level + 10; + af[0].location = APPLY_HITROLL; + af[0].modifier = 2 + HAS_FEAT(ch, FEAT_INSPIRE_COURAGE); + af[0].bonus_type = BONUS_TYPE_MORALE; + + af[1].duration = level + 10; + af[1].location = APPLY_DAMROLL; + af[1].modifier = 2 + HAS_FEAT(ch, FEAT_INSPIRE_COURAGE); + af[1].bonus_type = BONUS_TYPE_MORALE; + + af[2].duration = level + 10; + af[2].location = APPLY_SAVING_WILL; + af[2].modifier = 2 + HAS_FEAT(ch, FEAT_INSPIRE_COURAGE); + af[2].bonus_type = BONUS_TYPE_MORALE; + + to_room = "$n looks more confident!"; + to_vict = "Your courage surges and with it your fighting prowess!"; + break; + case SPELL_SILENCE: // illusion if (!can_silence(victim)) { @@ -8281,6 +8415,18 @@ static void perform_mag_groups(int level, struct char_data *ch, case WARLOCK_FLEE_THE_SCENE: mag_affects(level, ch, tch, obj, WARLOCK_FLEE_THE_SCENE, savetype, casttype, 0); break; + case AFFECT_RALLYING_CRY: + mag_affects(level, ch, tch, obj, AFFECT_RALLYING_CRY, savetype, casttype, 0); + break; + case AFFECT_INSPIRE_COURAGE: + mag_affects(level, ch, tch, obj, AFFECT_INSPIRE_COURAGE, savetype, casttype, 0); + break; + case AFFECT_INSPIRE_GREATNESS: + mag_affects(level, ch, tch, obj, AFFECT_INSPIRE_GREATNESS, savetype, casttype, 0); + break; + case AFFECT_FINAL_STAND: + mag_affects(level, ch, tch, obj, AFFECT_FINAL_STAND, savetype, casttype, 0); + break; case SPELL_GROUP_HEAL: mag_points(level, ch, tch, obj, SPELL_HEAL, savetype, casttype); break; @@ -8410,6 +8556,9 @@ static void perform_mag_groups(int level, struct char_data *ch, case PSIONIC_TOWER_OF_IRON_WILL: mag_affects(level, ch, tch, obj, PSIONIC_TOWER_OF_IRON_WILL, savetype, casttype, 0); break; + case SPELL_HOLY_AURA: + mag_affects(level, ch, tch, obj, SPELL_HOLY_AURA, savetype, casttype, 0); + break; default: if (can_mastermind_power(ch, spellnum)) { @@ -8441,6 +8590,10 @@ void mag_groups(int level, struct char_data *ch, struct obj_data *obj, switch (spellnum) { + case SPELL_HOLY_AURA: + to_char = "You speak words of divine power and is surrounded by a holy aura!\tn"; + to_room = "$n speaks words of divine power and is surrounded by a holy aura!\tn"; + break; case SPELL_TACTICAL_ACUMEN: to_char = "You speak words of combat tactics and courage!\tn"; to_room = "$n speaks words of combat tactics and courage!\tn"; diff --git a/mud_event.c b/mud_event.c index 45b12a06..f815c1ab 100755 --- a/mud_event.c +++ b/mud_event.c @@ -207,7 +207,14 @@ struct mud_event_list mud_event_index[] = { {"Eidolon Breath Weapon Cooldown", event_daily_use_cooldown, EVENT_CHAR}, // eDRACBREATH {"Call Eidolon", event_countdown, EVENT_CHAR}, // eC_EIDOLON {"Touch of Undeath", event_daily_use_cooldown, EVENT_CHAR}, // eTOUCHOFUndeath - + {"Strength of Honor", event_daily_use_cooldown, EVENT_CHAR}, // eSTRENGTHOFHONOR + {"Crown of Knighthood", event_daily_use_cooldown, EVENT_CHAR}, // eCROWNOFKNIGHTHOOD + {"Soul of Knighthood", event_daily_use_cooldown, EVENT_CHAR}, // eSOULOFKNIGHTHOOD + {"Inspire Courage", event_daily_use_cooldown, EVENT_CHAR}, // eINSPIRECOURAGE + {"Wisdom of the Measure", event_daily_use_cooldown, EVENT_CHAR}, // eWISDOMOFTHEMEASURE + {"Final Stand", event_daily_use_cooldown, EVENT_CHAR}, // eFINALSTAND + {"Knighthood's Flower", event_daily_use_cooldown, EVENT_CHAR}, // eKNIGHTHOODSFLOWER + {"Rallying Cry", event_daily_use_cooldown, EVENT_CHAR}, // eRALLYINGCRY }; /* init_events() is the ideal function for starting global events. This @@ -349,6 +356,15 @@ EVENTFUNC(event_countdown) case eTOUCHOFUNDEATH: send_to_char(ch, "You are now able to use your touch of undeath again.\r\n"); break; + case eSTRENGTHOFHONOR: + send_to_char(ch, "You are now able to use your strength of honor again.\r\n"); + break; + case eCROWNOFKNIGHTHOOD: + send_to_char(ch, "You are now able to use your crown of knighthood again.\r\n"); + break; + case eSOULOFKNIGHTHOOD: + send_to_char(ch, "You are now able to use your soul of knighthood again.\r\n"); + break; case eCHANNELENERGY: send_to_char(ch, "You are now able to channel energy again.\r\n"); break; @@ -651,7 +667,7 @@ EVENTFUNC(event_daily_use_cooldown) { /* This is odd - This field should always be populated for daily-use abilities, * maybe some legacy code or bad id. */ - log("SYSERR: sVariables field is NULL for daily-use-cooldown-event: %d", pMudEvent->iId); + log("SYSERR: 1 sVariables field is NULL for daily-use-cooldown-event: %d", pMudEvent->iId); } else { @@ -744,6 +760,38 @@ EVENTFUNC(event_daily_use_cooldown) featnum = FEAT_TOUCH_OF_UNDEATH; send_to_char(ch, "One of your touch of undeath uses has recovered.\r\n"); break; + case eCROWNOFKNIGHTHOOD: + featnum = FEAT_CROWN_OF_KNIGHTHOOD; + send_to_char(ch, "One of your crown of knighthood uses has recovered.\r\n"); + break; + case eSOULOFKNIGHTHOOD: + featnum = FEAT_SOUL_OF_KNIGHTHOOD; + send_to_char(ch, "One of your soul of knighthood uses has recovered.\r\n"); + break; + case eINSPIRECOURAGE: + featnum = FEAT_INSPIRE_COURAGE; + send_to_char(ch, "One of your inspire courage uses has recovered.\r\n"); + break; + case eWISDOMOFTHEMEASURE: + featnum = FEAT_WISDOM_OF_THE_MEASURE; + send_to_char(ch, "One of your wisdom of the measure uses has recovered.\r\n"); + break; + case eFINALSTAND: + featnum = FEAT_FINAL_STAND; + send_to_char(ch, "One of your final stand uses has recovered.\r\n"); + break; + case eKNIGHTHOODSFLOWER: + featnum = FEAT_KNIGHTHOODS_FLOWER; + send_to_char(ch, "One of your knighthood's flower uses has recovered.\r\n"); + break; + case eRALLYINGCRY: + featnum = FEAT_RALLYING_CRY; + send_to_char(ch, "One of your rallying cry uses has recovered.\r\n"); + break; + case eSTRENGTHOFHONOR: + featnum = FEAT_STRENGTH_OF_HONOR; + send_to_char(ch, "One of your strength of honor uses has recovered.\r\n"); + break; case eJUDGEMENT: featnum = FEAT_JUDGEMENT; send_to_char(ch, "One of your judgement ability uses has recovered.\r\n"); diff --git a/mud_event.h b/mud_event.h index 50753213..237a845f 100755 --- a/mud_event.h +++ b/mud_event.h @@ -185,6 +185,14 @@ typedef enum eEVOBREATH, // eidolon evolution breath weapon eC_EIDOLON, // call eidolon cooldown eTOUCHOFUNDEATH, // necromancer touch of undeath ability + eSTRENGTHOFHONOR, // strength of honor knight of the crown ability + eCROWNOFKNIGHTHOOD, // crown of knighthood knight of the crown ability + eSOULOFKNIGHTHOOD, // soul of knighthood knight of the sword ability + eINSPIRECOURAGE, // inspire courage ability + eWISDOMOFTHEMEASURE, // wisdom of the measure ability + eFINALSTAND, // final stand ability + eKNIGHTHOODSFLOWER, // knighthood's flower ability + eRALLYINGCRY, // rallying cry ability } event_id; /* probably a smart place to mention to not forget to update: diff --git a/players.c b/players.c index 8531dcb4..4158c82f 100755 --- a/players.c +++ b/players.c @@ -2328,6 +2328,24 @@ void save_char(struct char_data *ch, int mode) fprintf(fl, "%d %ld\n", pMudEvent->iId, event_time(pMudEvent->pEvent)); if ((pMudEvent = char_has_mud_event(ch, eTOUCHOFUNDEATH))) fprintf(fl, "%d %ld\n", pMudEvent->iId, event_time(pMudEvent->pEvent)); + if ((pMudEvent = char_has_mud_event(ch, eSTRENGTHOFHONOR))) + fprintf(fl, "%d %ld\n", pMudEvent->iId, event_time(pMudEvent->pEvent)); + if ((pMudEvent = char_has_mud_event(ch, eCROWNOFKNIGHTHOOD))) + fprintf(fl, "%d %ld\n", pMudEvent->iId, event_time(pMudEvent->pEvent)); + if ((pMudEvent = char_has_mud_event(ch, eSOULOFKNIGHTHOOD))) + fprintf(fl, "%d %ld\n", pMudEvent->iId, event_time(pMudEvent->pEvent)); + if ((pMudEvent = char_has_mud_event(ch, eSOULOFKNIGHTHOOD))) + fprintf(fl, "%d %ld\n", pMudEvent->iId, event_time(pMudEvent->pEvent)); + if ((pMudEvent = char_has_mud_event(ch, eINSPIRECOURAGE))) + fprintf(fl, "%d %ld\n", pMudEvent->iId, event_time(pMudEvent->pEvent)); + if ((pMudEvent = char_has_mud_event(ch, eWISDOMOFTHEMEASURE))) + fprintf(fl, "%d %ld\n", pMudEvent->iId, event_time(pMudEvent->pEvent)); + if ((pMudEvent = char_has_mud_event(ch, eFINALSTAND))) + fprintf(fl, "%d %ld\n", pMudEvent->iId, event_time(pMudEvent->pEvent)); + if ((pMudEvent = char_has_mud_event(ch, eKNIGHTHOODSFLOWER))) + fprintf(fl, "%d %ld\n", pMudEvent->iId, event_time(pMudEvent->pEvent)); + if ((pMudEvent = char_has_mud_event(ch, eRALLYINGCRY))) + fprintf(fl, "%d %ld\n", pMudEvent->iId, event_time(pMudEvent->pEvent)); fprintf(fl, "-1 -1\n"); } diff --git a/spec_abilities.c b/spec_abilities.c index f65ba3af..70938641 100644 --- a/spec_abilities.c +++ b/spec_abilities.c @@ -402,6 +402,19 @@ int process_weapon_abilities(struct obj_data *weapon, /* The weapon to check fo } } + // Knight of the Sword Soul of Knighthood + if (victim && HAS_FEAT(ch, FEAT_SOUL_OF_KNIGHTHOOD)) + { + if (actmtd == ACTMTD_ON_HIT) + { + damage(ch, victim, dice(1, 6), TYPE_SPECAB_HOLY, DAM_HOLY, FALSE); + } + if (actmtd == ACTMTD_ON_CRIT) + { + damage(ch, victim, dice(2, 10), TYPE_SPECAB_HOLY, DAM_HOLY, FALSE); + } + } + if (victim) { if (actmtd == ACTMTD_ON_HIT) diff --git a/spec_procs.c b/spec_procs.c index 03fcb849..1015630e 100755 --- a/spec_procs.c +++ b/spec_procs.c @@ -1179,6 +1179,8 @@ int compute_ability_full(struct char_data *ch, int abilityNum, bool recursive) if (GET_RACE(ch) == RACE_H_ELF) value += 2; value += GET_STR_BONUS(ch); + if (HAS_REAL_FEAT(ch, FEAT_HONORBOUND)) + value += 4; value += compute_gear_armor_penalty(ch); return value; case ABILITY_TOTAL_DEFENSE: /* not srd */ @@ -1311,6 +1313,8 @@ int compute_ability_full(struct char_data *ch, int abilityNum, bool recursive) /* Unnamed bonus */ value += 2; } + if (HAS_REAL_FEAT(ch, FEAT_HONORBOUND)) + value += 4; if (HAS_FEAT(ch, FEAT_KEEN_SENSES)) { /* Unnamed bonu, elves */ diff --git a/spell_parser.c b/spell_parser.c index 2f78d794..1066b00b 100755 --- a/spell_parser.c +++ b/spell_parser.c @@ -4652,6 +4652,27 @@ void mag_assign_spells(void) spello(ABILITY_BLOOD_DRAIN, "vampiric blood drain", 0, 0, 0, POS_FIGHTING, TAR_IGNORE, TRUE, MAG_AFFECTS, NULL, 1, 1, NOSCHOOL, FALSE); + + spello(ABILITY_STRENGTH_OF_HONOR, "strength of honor", 0, 0, 0, POS_FIGHTING, + TAR_IGNORE, TRUE, MAG_AFFECTS, "Your strength of honor fades.", 1, 1, NOSCHOOL, FALSE); + + spello(ABILITY_CROWN_OF_KNIGHTHOOD, "crown of knighthood", 0, 0, 0, POS_FIGHTING, + TAR_IGNORE, TRUE, MAG_AFFECTS, "Your crown of knighthood fades.", 1, 1, NOSCHOOL, FALSE); + + spello(AFFECT_RALLYING_CRY, "rallying cry", 0, 0, 0, POS_FIGHTING, + TAR_IGNORE, TRUE, MAG_GROUPS, "The rallying cry fades.", 1, 1, NOSCHOOL, FALSE); + + spello(AFFECT_INSPIRE_COURAGE, "inspire courage", 0, 0, 0, POS_FIGHTING, + TAR_IGNORE, TRUE, MAG_GROUPS, "Your inspired courage fades.", 1, 1, NOSCHOOL, FALSE); + + spello(AFFECT_INSPIRE_GREATNESS, "inspire greatness", 0, 0, 0, POS_FIGHTING, + TAR_IGNORE, TRUE, MAG_GROUPS, "Your inspired greatness fades.", 1, 1, NOSCHOOL, FALSE); + + spello(AFFECT_FINAL_STAND, "final stand", 0, 0, 0, POS_FIGHTING, + TAR_IGNORE, TRUE, MAG_GROUPS, "Your final stand ends.", 1, 1, NOSCHOOL, FALSE); + + spello(AFFECT_KNIGHTHOODS_FLOWER, "knighthood's flower", 0, 0, 0, POS_FIGHTING, + TAR_IGNORE, TRUE, MAG_AFFECTS, "Your knighthood's flower fades.", 1, 1, NOSCHOOL, FALSE); spello(RACIAL_ABILITY_CRYSTAL_BODY, "crystal body", 0, 0, 0, POS_FIGHTING, TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_AFFECTS, @@ -4730,6 +4751,11 @@ void mag_assign_spells(void) spello(EIDOLON_MERGE_FORMS_EFFECT, "merge forms", 0, 0, 0, POS_FIGHTING, TAR_IGNORE, FALSE, MAG_AFFECTS, NULL, 1, 1, NOSCHOOL, 0); + spello(SPELL_HOLY_AURA, "holy aura", 0, 0, 0, POS_FIGHTING, + TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_GROUPS, "You are no longer bolstered by a holy aura.", 9, 21, ABJURATION, 0); + spello(AFFECT_HOLY_AURA_RETRIBUTION, "holy aura retribution", 0, 0, 0, POS_FIGHTING, + TAR_CHAR_ROOM | TAR_SELF_ONLY, FALSE, MAG_GROUPS, "Your vision returns.", 9, 21, ABJURATION, 0); + spello(ABILITY_BAAZ_DRACONIAN_DEATH_THROES, "baaz draconian death throes", 0, 0, 0, POS_FIGHTING, TAR_IGNORE, TRUE, MAG_AREAS, NULL, 5, 9, TRANSMUTATION, FALSE); diff --git a/spells.h b/spells.h index 013636e2..a22a41a4 100755 --- a/spells.h +++ b/spells.h @@ -581,9 +581,10 @@ #define SPELL_RAPID_BUFF 505 #define SPELL_GREATER_RAPID_BUFF 506 #define SPELL_POWER_WORD_SILENCE 507 +#define SPELL_HOLY_AURA 508 /** Total Number of defined spells */ -#define NUM_SPELLS 508 +#define NUM_SPELLS 509 #define LAST_SPELL_DEFINE NUM_SPELLS + 1 #define MAX_SPELL_AFFECTS 6 /* change if more needed */ @@ -663,6 +664,14 @@ #define ABILITY_DEGENERATIVE_TOUCH 1262 #define ABILITY_DESTRUCTIVE_TOUCH 1263 #define ABILITY_DEATHLESS_TOUCH 1264 +#define ABILITY_STRENGTH_OF_HONOR 1265 +#define ABILITY_CROWN_OF_KNIGHTHOOD 1266 +#define AFFECT_HOLY_AURA_RETRIBUTION 1267 +#define AFFECT_RALLYING_CRY 1268 +#define AFFECT_INSPIRE_COURAGE 1269 +#define AFFECT_FINAL_STAND 1270 +#define AFFECT_KNIGHTHOODS_FLOWER 1271 +#define AFFECT_INSPIRE_GREATNESS 1272 // 1470 to 1493 are poisons with room saved for more poisons up to 1498 diff --git a/structs.h b/structs.h index 1524e19d..0b7a7271 100755 --- a/structs.h +++ b/structs.h @@ -427,9 +427,9 @@ #define CLASS_WARLOCK 28 #define CLASS_NECROMANCER 29 #define CLASS_PALE_MASTER CLASS_NECROMANCER -// #define CLASS_KNIGHT_OF_THE_CROWN 30 -// #define CLASS_KNIGHT_OF_THE_SWORD 31 -// #define CLASS_KNIGHT_OF_THE_ROSE 32 +#define CLASS_KNIGHT_OF_THE_CROWN 30 +#define CLASS_KNIGHT_OF_THE_SWORD 31 +#define CLASS_KNIGHT_OF_THE_ROSE 32 //#define CLASS_PSYCHIC_WARRIOR 17 //#define CLASS_PSY_WARR CLASS_PSYCHIC_WARRIOR //#define CLASS_SOULKNIFE 18 @@ -438,12 +438,12 @@ /* !!!---- CRITICAL ----!!! make sure to add class names to constants.c's class_names[] - we are dependent on that for loading the feat-list */ /** Total number of available PC Classes */ -#define NUM_CLASSES 30 +#define NUM_CLASSES 33 // related to pc (classes, etc) /* note that max_classes was established to reign in some of the pfile arrays associated with classes */ -#define MAX_CLASSES 31 // total number of maximum pc classes +#define MAX_CLASSES 33 // total number of maximum pc classes #define NUM_CASTERS 9 // direct reference to pray array /* x wizard 1 * x sorcerer 2 @@ -2626,12 +2626,23 @@ #define FEAT_HEROIC_INITIATIVE 1066 #define FEAT_MIGHT_OF_HONOR 1067 #define FEAT_CROWN_OF_KNIGHTHOOD 1068 +#define FEAT_HONORBOUND 1069 +// Knight of the Sword +#define FEAT_DEMORALIZING_STRIKE 1070 +#define FEAT_SOUL_OF_KNIGHTHOOD 1071 +// Knight of The Rose +#define FEAT_LEADERSHIP 1072 +#define FEAT_INSPIRE_COURAGE 1073 +#define FEAT_INSPIRE_GREATNESS 1074 +#define FEAT_WISDOM_OF_THE_MEASURE 1075 +#define FEAT_FINAL_STAND 1076 +#define FEAT_KNIGHTHOODS_FLOWER 1077 /**************/ /** reserved above feat# + 1**/ -#define FEAT_LAST_FEAT 1069 +#define FEAT_LAST_FEAT 1078 /** FEAT_LAST_FEAT + 1 ***/ -#define NUM_FEATS 1070 +#define NUM_FEATS 1079 /** absolute cap **/ #define MAX_FEATS 1500 /*****/ @@ -4453,6 +4464,8 @@ struct char_special_data byte recently_slammed; bool deathless_touch; // when killing a victim with deathless touch, the necromancer will give bonus stats on his next animate dead or greater animation spell + + bool has_performed_demoralizing_strike; // this ensures the combatant can only do a demoralizing strike once per round. }; /* old memorization struct */ diff --git a/study.c b/study.c index ad3b9405..134d7ef6 100644 --- a/study.c +++ b/study.c @@ -2782,7 +2782,8 @@ void study_parse(struct descriptor_data *d, char *arg) GET_PREFERRED_ARCANE(ch) == CLASS_SUMMONER)) summoner_known_spells_disp_menu(d); else if (LEVELUP(ch)->class == CLASS_INQUISITOR || - ((LEVELUP(ch)->class == CLASS_MYSTIC_THEURGE || (LEVELUP(ch)->class == CLASS_NECROMANCER && NECROMANCER_CAST_TYPE(ch) == 2)) && + ((LEVELUP(ch)->class == CLASS_MYSTIC_THEURGE || LEVELUP(ch)->class == CLASS_KNIGHT_OF_THE_SWORD || LEVELUP(ch)->class == CLASS_KNIGHT_OF_THE_ROSE || + (LEVELUP(ch)->class == CLASS_NECROMANCER && NECROMANCER_CAST_TYPE(ch) == 2)) && GET_PREFERRED_DIVINE(ch) == CLASS_INQUISITOR)) inquisitor_known_spells_disp_menu(d); else if (LEVELUP(ch)->class == CLASS_WARLOCK) diff --git a/treasure.c b/treasure.c index 07d7e23d..9fae840b 100644 --- a/treasure.c +++ b/treasure.c @@ -1494,7 +1494,7 @@ void cp_modify_object_applies(struct char_data *ch, struct obj_data *obj, GET_OBJ_VAL(obj, 2) -= MIN(29, (dice(5, bonus_value) + bonus_value)); /* object level (min level to use) */ - GET_OBJ_LEVEL(obj) = bonus_value * 5; + GET_OBJ_LEVEL(obj) = MIN(30, bonus_value * 5); /** we're dropping the min level a bit here, because * we recently increased bonuses on random treasure * bonuses by +1 across the board in an effort to make diff --git a/utils.c b/utils.c index 0b0e44d9..12831268 100755 --- a/utils.c +++ b/utils.c @@ -165,7 +165,8 @@ bool can_study_known_spells(struct char_data *ch) /* inquisitor */ if (LEVELUP(ch)->class == CLASS_INQUISITOR || - ((LEVELUP(ch)->class == CLASS_MYSTIC_THEURGE || (LEVELUP(ch)->class == CLASS_NECROMANCER && NECROMANCER_CAST_TYPE(ch) == 2)) && + ((LEVELUP(ch)->class == CLASS_MYSTIC_THEURGE || LEVELUP(ch)->class == CLASS_KNIGHT_OF_THE_SWORD || LEVELUP(ch)->class == CLASS_KNIGHT_OF_THE_ROSE || + (LEVELUP(ch)->class == CLASS_NECROMANCER && NECROMANCER_CAST_TYPE(ch) == 2)) && GET_PREFERRED_DIVINE(ch) == CLASS_INQUISITOR)) return TRUE; @@ -215,6 +216,8 @@ int compute_bonus_caster_level(struct char_data *ch, int class) bonus_levels += CLASS_LEVEL(ch, CLASS_NECROMANCER); bonus_levels += CLASS_LEVEL(ch, CLASS_MYSTIC_THEURGE); bonus_levels += CLASS_LEVEL(ch, CLASS_SACRED_FIST); + bonus_levels += CLASS_LEVEL(ch, CLASS_KNIGHT_OF_THE_SWORD); + bonus_levels += CLASS_LEVEL(ch, CLASS_KNIGHT_OF_THE_ROSE); break; default: break; @@ -257,6 +260,8 @@ int compute_divine_level(struct char_data *ch) divine_level += CLASS_LEVEL(ch, CLASS_DRUID); divine_level += CLASS_LEVEL(ch, CLASS_INQUISITOR); divine_level += CLASS_LEVEL(ch, CLASS_SACRED_FIST); + divine_level += CLASS_LEVEL(ch, CLASS_KNIGHT_OF_THE_SWORD); + divine_level += CLASS_LEVEL(ch, CLASS_KNIGHT_OF_THE_ROSE); if (NECROMANCER_CAST_TYPE(ch) == 2) divine_level += CLASS_LEVEL(ch, CLASS_NECROMANCER); divine_level += MAX(0, CLASS_LEVEL(ch, CLASS_PALADIN) - 3); @@ -278,6 +283,8 @@ int compute_channel_energy_level(struct char_data *ch) level += CLASS_LEVEL(ch, CLASS_CLERIC); level += CLASS_LEVEL(ch, CLASS_INQUISITOR); level += CLASS_LEVEL(ch, CLASS_SACRED_FIST); + level += CLASS_LEVEL(ch, CLASS_KNIGHT_OF_THE_SWORD); + level += CLASS_LEVEL(ch, CLASS_KNIGHT_OF_THE_ROSE); level += MAX(0, CLASS_LEVEL(ch, CLASS_PALADIN) - 4); level += MAX(0, CLASS_LEVEL(ch, CLASS_BLACKGUARD) - 4); level += CLASS_LEVEL(ch, CLASS_MYSTIC_THEURGE) / 2; @@ -4622,6 +4629,30 @@ int get_daily_uses(struct char_data *ch, int featnum) else daily_uses = 1; break; + case FEAT_STRENGTH_OF_HONOR: + daily_uses = CLASS_LEVEL(ch, CLASS_KNIGHT_OF_THE_CROWN); + break; + case FEAT_CROWN_OF_KNIGHTHOOD: + daily_uses = 1; + break; + case FEAT_SOUL_OF_KNIGHTHOOD: + daily_uses = 1; + break; + case FEAT_RALLYING_CRY: + daily_uses = 3; + break; + case FEAT_INSPIRE_COURAGE: + daily_uses = 1 + HAS_FEAT(ch, FEAT_INSPIRE_COURAGE); + break; + case FEAT_WISDOM_OF_THE_MEASURE: + daily_uses = 2; + break; + case FEAT_FINAL_STAND: + daily_uses = 1; + break; + case FEAT_KNIGHTHOODS_FLOWER: + daily_uses = 1; + break; case FEAT_VAMPIRE_CHILDREN_OF_THE_NIGHT: daily_uses = 1; break; @@ -4800,7 +4831,7 @@ int start_daily_use_cooldown(struct char_data *ch, int featnum) { struct mud_event_data *pMudEvent = NULL; int uses = 0, daily_uses = 0; - char buf[128]; + char buf[MAX_STRING_LENGTH]; event_id iId = 0; /* Transform the feat number to the event id for that ability. */ @@ -4825,7 +4856,7 @@ int start_daily_use_cooldown(struct char_data *ch, int featnum) { /* This is odd - This field should always be populated for daily-use abilities, * maybe some legacy code or bad id. */ - log("SYSERR: sVariables field is NULL for daily-use-cooldown-event: %d", iId); + log("SYSERR: 2 sVariables field is NULL for daily-use-cooldown-event: %d", iId); } else { @@ -4849,7 +4880,9 @@ int start_daily_use_cooldown(struct char_data *ch, int featnum) { /* No event - so attach one. */ uses = 1; - attach_mud_event(new_mud_event(iId, ch, "uses:1"), (SECS_PER_MUD_DAY / daily_uses) RL_SEC); + attach_mud_event( + new_mud_event(iId, ch, "uses:1"), + (SECS_PER_MUD_DAY / daily_uses) RL_SEC); } return uses; @@ -4873,7 +4906,7 @@ int daily_uses_remaining(struct char_data *ch, int featnum) { /* This is odd - This field should always be populated for daily-use abilities, * maybe some legacy code or bad id. */ - log("SYSERR: sVariables field is NULL for daily-use-cooldown-event: %d", iId); + log("SYSERR: 3 sVariables field is NULL for daily-use-cooldown-event: %d", iId); } else { @@ -4924,7 +4957,7 @@ int start_item_specab_daily_use_cooldown(struct obj_data *obj, int specab) { /* This is odd - This field should always be populated for daily-use abilities, * maybe some legacy code or bad id. */ - log("SYSERR: sVariables field is NULL for daily-use-cooldown-event: %d", iId); + log("SYSERR: 4 sVariables field is NULL for daily-use-cooldown-event: %d", iId); } else { @@ -4972,7 +5005,7 @@ int daily_item_specab_uses_remaining(struct obj_data *obj, int specab) { /* This is odd - This field should always be populated for daily-use abilities, * maybe some legacy code or bad id. */ - log("SYSERR: sVariables field is NULL for daily-use-cooldown-event: %d", iId); + log("SYSERR: 5 sVariables field is NULL for daily-use-cooldown-event: %d", iId); } else { @@ -5170,6 +5203,9 @@ sbyte is_immune_fear(struct char_data *ch, struct char_data *victim, sbyte displ if (HAS_FEAT(ch, FEAT_KENDER_FEARLESSNESS)) return true; + + if (HAS_FEAT(ch, FEAT_KNIGHTLY_COURAGE)) + return true; if (affected_by_aura_of_cowardice(victim)) { @@ -5311,6 +5347,27 @@ sbyte is_immune_charm(struct char_data *ch, struct char_data *victim, sbyte disp } return TRUE; } + + if (affected_by_spell(victim, SPELL_HOLY_AURA)) + { + if (display) + { + send_to_char(ch, "Holy Aura protects %s!\r\n", GET_NAME(victim)); + send_to_char(victim, "Holy Aura protects you from %s!\r\n", GET_NAME(ch)); + } + return TRUE; + } + + if (affected_by_spell(victim, AFFECT_KNIGHTHOODS_FLOWER)) + { + if (display) + { + send_to_char(ch, "Knighthood's Flower protects %s!\r\n", GET_NAME(victim)); + send_to_char(victim, "Knighthood's Flower protects you from %s!\r\n", GET_NAME(ch)); + } + return TRUE; + } + if (HAS_FEAT(victim, FEAT_SLEEP_ENCHANTMENT_IMMUNITY)) return TRUE; return FALSE; @@ -5349,6 +5406,34 @@ bool has_aura_of_courage(struct char_data *ch) return has_aura; } +float leadership_exp_multiplier(struct char_data *ch) +{ + float exp_mult = 100.00; + if (!ch) + return exp_mult; + + struct char_data *tch = NULL; + + if (GROUP(ch) && GROUP(ch)->members && GROUP(ch)->members->iSize) + { + struct iterator_data Iterator; + + tch = (struct char_data *)merge_iterator(&Iterator, GROUP(ch)->members); + for (; tch; tch = next_in_list(&Iterator)) + { + if (IN_ROOM(tch) != IN_ROOM(ch)) + continue; + if (HAS_FEAT(tch, FEAT_LEADERSHIP)) + { + exp_mult = (float) MAX((int) exp_mult, 100 + ((HAS_FEAT(tch, FEAT_LEADERSHIP) + 1) * 5)); + } + } + remove_iterator(&Iterator); + } + + return exp_mult; +} + bool has_fortune_of_many_bonus(struct char_data *ch) { if (!ch) @@ -6788,6 +6873,7 @@ bool can_spell_be_revoked(int spellnum) case SPELL_SPIDER_CLIMB: case SPELL_RAGE: case SPELL_CAUSTIC_BLOOD: + case SPELL_HOLY_AURA: // psionic powers case PSIONIC_BROKER: @@ -6847,6 +6933,14 @@ bool can_spell_be_revoked(int spellnum) case RACIAL_ABILITY_INSECTBEING: case AFFECT_FOOD: case AFFECT_DRINK: + case ABILITY_STRENGTH_OF_HONOR: + case ABILITY_CROWN_OF_KNIGHTHOOD: + case AFFECT_HOLY_AURA_RETRIBUTION: + case AFFECT_RALLYING_CRY: + case AFFECT_INSPIRE_COURAGE: + case AFFECT_FINAL_STAND: + case AFFECT_KNIGHTHOODS_FLOWER: + case AFFECT_INSPIRE_GREATNESS: return true; } diff --git a/utils.h b/utils.h index bdcd0fc8..80b7062c 100755 --- a/utils.h +++ b/utils.h @@ -266,6 +266,7 @@ int file_head(FILE *file, char *buf, size_t bufsize, int lines_to_read); int file_tail(FILE *file, char *buf, size_t bufsize, int lines_to_read); size_t file_sizeof(FILE *file); int file_numlines(FILE *file); +float leadership_exp_multiplier(struct char_data *ch); void clear_misc_cooldowns(struct char_data *ch); IDXTYPE atoidx(const char *str_to_conv); char *strfrmt(char *str, int w, int h, int justify, int hpad, int vpad); @@ -1426,7 +1427,8 @@ void char_from_furniture(struct char_data *ch); // Eldritch knight spell critical ability #define HAS_ELDRITCH_SPELL_CRIT(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->has_eldritch_knight_spell_critical)) // Eldritch knight levels are added to warrior levels when determining qualification for certain warrior-only feats -#define WARRIOR_LEVELS(ch) (CLASS_LEVEL(ch, CLASS_WARRIOR) + CLASS_LEVEL(ch, CLASS_ELDRITCH_KNIGHT) + (CLASS_LEVEL(ch, CLASS_SPELLSWORD) / 2)) +#define WARRIOR_LEVELS(ch) (CLASS_LEVEL(ch, CLASS_WARRIOR) + CLASS_LEVEL(ch, CLASS_ELDRITCH_KNIGHT) + (CLASS_LEVEL(ch, CLASS_SPELLSWORD) / 2) + \ + CLASS_LEVEL(ch, CLASS_KNIGHT_OF_THE_CROWN)) /* Attacks of Opportunity (AOO) */ #define GET_TOTAL_AOO(ch) (ch->char_specials.attacks_of_opportunity) @@ -1971,13 +1973,16 @@ int ACTUAL_BAB(struct char_data *ch); #define IS_ALCHEMIST(ch) (CLASS_LEVEL(ch, CLASS_ALCHEMIST)) #define IS_BLACKGUARD(ch) (CLASS_LEVEL(ch, CLASS_BLACKGUARD)) #define IS_SUMMONER(ch) (CLASS_LEVEL(ch, CLASS_SUMMONER)) +#define IS_KNIGHT_OF_THE_CROWN(ch) (CLASS_LEVEL(ch, CLASS_KNIGHT_OF_THE_CROWN)) +#define IS_KNIGHT_OF_THE_SWORD(ch) (CLASS_LEVEL(ch, CLASS_KNIGHT_OF_THE_SWORD)) +#define IS_KNIGHT_OF_THE_ROSE(ch) (CLASS_LEVEL(ch, CLASS_KNIGHT_OF_THE_ROSE)) #define IS_CASTER(ch) (GET_LEVEL(ch) >= LVL_IMMORT || \ IS_CLERIC(ch) || IS_WIZARD(ch) || IS_DRUID(ch) || IS_SORCERER(ch) || IS_PALADIN(ch) || \ IS_RANGER(ch) || IS_BARD(ch) || IS_ALCHEMIST(ch) || IS_ARCANE_ARCHER(ch) || \ IS_MYSTICTHEURGE(ch) || IS_ARCANE_SHADOW(ch) || IS_SACRED_FIST(ch) || IS_SHIFTER(ch) || \ IS_ELDRITCH_KNIGHT(ch) || IS_BLACKGUARD(ch) || IS_INQUISITOR(ch) || IS_SUMMONER(ch) || \ - IS_NECROMANCER(ch)) + IS_NECROMANCER(ch) || IS_KNIGHT_OF_THE_SWORD(ch) || IS_KNIGHT_OF_THE_ROSE(ch)) #define IS_FIGHTER(ch) (CLASS_LEVEL(ch, CLASS_WARRIOR) || CLASS_LEVEL(ch, CLASS_WEAPON_MASTER) || \ CLASS_LEVEL(ch, CLASS_STALWART_DEFENDER) || CLASS_LEVEL(ch, CLASS_DUELIST) || \ @@ -1999,6 +2004,8 @@ int ACTUAL_BAB(struct char_data *ch); GET_CLASS(ch) == CLASS_SACRED_FIST || \ GET_CLASS(ch) == CLASS_SHIFTER || \ GET_CLASS(ch) == CLASS_INQUISITOR || \ + GET_CLASS(ch) == CLASS_KNIGHT_OF_THE_SWORD || \ + GET_CLASS(ch) == CLASS_KNIGHT_OF_THE_ROSE || \ GET_CLASS(ch) == CLASS_BARD) #define GET_CASTING_CLASS(ch) (ch->player_specials->casting_class) @@ -2158,6 +2165,8 @@ int ACTUAL_BAB(struct char_data *ch); #define INCORPOREAL_FORM_TIMER(ch) (ch->player_specials->saved.incorporeal_form_timer) #define INCORPOREAL_FORM_USES_PER_DAY(ch) (CLASS_LEVEL(ch, CLASS_SORCERER) / 3) +#define HAS_PERFORMED_DEMORALIZING_STRIKE(ch) (ch->char_specials.has_performed_demoralizing_strike) + /* IS_ for other special situations */ #define IS_INCORPOREAL(ch) (is_incorporeal(ch))