Anonymous | Login | 2024-04-25 08:23 CEST |
Main | My View | View Issues | Change Log | Wiki | Tavern | News |
Viewing Issue Simple Details [ Jump to Notes ] [ Wiki ] | [ View Advanced ] [ Issue History ] [ Print ] | ||||||||||||
ID | Category | Severity | Reproducibility | Date Submitted | Last Update | ||||||||
0007285 | [DCSS] Patches | tweak | N/A | 2013-06-29 13:55 | 2013-07-17 15:50 | ||||||||
Reporter | qoala | View Status | public | ||||||||||
Assigned To | Kate | ||||||||||||
Priority | normal | Resolution | done | ||||||||||
Status | resolved | Product Branch | 0.13 ancient branch | ||||||||||
Summary | 0007285: Spectral Weapon buffs & fineff fixes | ||||||||||||
Description |
The long awaited buffs to Spectral Weapon: - damage now scales with weapon skill, but this effect is proportional to spell power as well - AC slightly improved, EV significantly so - Beams can be freely fired through allied spectral weapon (like battlesphere) - damage sharing is now half the damage taken by the weapon - damage sharing reworked to use the actual damage taken by the weapon and use a fineff so that it leaves the player with at least 1hp regardless of target order in an AoE attack. Fixed some issues with fineffs: specifically, ::hurt being called twice on shared damage (tentacles and injury bond, as well as spectral weapon) was causing quad damage and attacker wretched to be applied twice. It's possible the buffs to Spectral Weapon are not enough, though some components might go too far (such as the damage scaling at max power). Time to get some more playtesting feedback. I think that giving it enough EV to not be auto-hit by everything will do wonders for its survivability, though AC might actually be a better defense for consistency in play. It might be preferable to add a fatal/nonfatal parameter to ouch/hurt, so that dealing non-fatal damage isn't as fragile (capping damage at hp-1, even though the amount might change later), but I'm too tired to contemplate adding more parameters to existing code. |
||||||||||||
Additional Information | |||||||||||||
Tags | No tags attached. | ||||||||||||
Attached Files |
newskald_spectralweapon_buffs_and_fineff.patch [^] (31,400 bytes) 2013-06-29 13:55 [Show Content] [Hide Content]From e64f80ba3e52b54133f12dcf0f568e5690816bb1 Mon Sep 17 00:00:00 2001 From: Ed Gonzalez <ed.gonzalez3@gmail.com> Date: Thu, 27 Jun 2013 03:33:00 -0700 Subject: [PATCH 1/8] Buff Spectral Weapon damage (scales with weapon skill) Spectral Weapon damage now scales with weapon skill similarly to how player and player ghost damage does. However, the effective skill is reduced by spell power. At 0 power, weapon skill is 1/3 as effective. At max (100) power, weapon skill is fully as effective as on the player. In between, the effect on skill scales linearly with power. There's a table in the comments of the code, showing some values. The numbers might need tweaking, since getting comparable damage at max power is likely desirable. However, encouraging players to train more charms is a good thing. --- crawl-ref/source/dungeon.cc | 2 +- crawl-ref/source/ghost.cc | 40 +++++++++++++++++++++++++++++++------ crawl-ref/source/mgen_data.h | 1 + crawl-ref/source/mon-place.cc | 2 +- crawl-ref/source/spl-summoning.cc | 2 +- 5 files changed, 38 insertions(+), 9 deletions(-) diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index 5b78c50..fe32b88 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -4891,7 +4891,7 @@ monster* dgn_place_monster(mons_spec &mspec, coord_def where, if (mons->type == MONS_DANCING_WEAPON) mons->ghost->init_dancing_weapon(*wpn, 100); else if (mons->type == MONS_SPECTRAL_WEAPON) - mons->ghost->init_spectral_weapon(*wpn, 100, 27); + mons->ghost->init_spectral_weapon(*wpn, 100, 270); mons->ghost_demon_init(); } diff --git a/crawl-ref/source/ghost.cc b/crawl-ref/source/ghost.cc index 1c428f7..c6718b6 100644 --- a/crawl-ref/source/ghost.cc +++ b/crawl-ref/source/ghost.cc @@ -717,22 +717,50 @@ void ghost_demon::init_spectral_weapon(const item_def& weapon, if (power > 100) power = 100; - if (wpn_skill > 27) - wpn_skill = 27; + // skill is on a 10 scale + if (wpn_skill > 270) + wpn_skill = 270; colour = weapon.colour; fly = FL_LEVITATE; - // Offense scales with weapon skill. - // Defenses scale with spell power. + // Hit dice (to hit) scales with weapon skill alone. + // Damage scales with weapon skill, but how well depends on spell power. + // Defenses scale with spell power alone. // Appropriate investment is rewarded with a stronger spectral weapon. - xl = wpn_skill; + xl = wpn_skill / 10; + + // At 0 power, weapon skill is 1/3 as effective as on the player + // At max power, weapon skill is as effective as on the player. + // Power has a linear effect between those endpoints. + // It's possible this ends up too strong, + // but 100 power on Hexes/Charms will take significant investment + // most players wouldn't otherwise get. + // + // Damage multiplier table: + // | weapon skill + // pow | 3 9 15 21 27 + // --- | ----- ---- ---- ---- ---- + // 0 | 1.04 1.12 1.20 1.28 1.36 + // 10 | 1.05 1.14 1.24 1.34 1.43 + // 20 | 1.06 1.17 1.28 1.39 1.50 + // 30 | 1.06 1.19 1.32 1.45 1.58 + // 40 | 1.07 1.22 1.36 1.50 1.65 + // 50 | 1.08 1.24 1.40 1.56 1.72 + // 60 | 1.09 1.26 1.44 1.62 1.79 + // 70 | 1.10 1.29 1.48 1.67 1.87 + // 80 | 1.10 1.31 1.52 1.73 1.94 + // 90 | 1.11 1.34 1.56 1.79 2.01 + // 100 | 1.12 1.36 1.60 1.84 2.08 + damage = damg; + int scale = 250 * 150 / (50 + power); + damage *= scale + wpn_skill; + damage /= scale; speed = 30; ev = 2 + div_rand_round(power,12); ac = 2 + div_rand_round(power,12); - damage = damg; max_hp = 10 + div_rand_round(power,3); } diff --git a/crawl-ref/source/mgen_data.h b/crawl-ref/source/mgen_data.h index 2f8c326..72c9f6c 100644 --- a/crawl-ref/source/mgen_data.h +++ b/crawl-ref/source/mgen_data.h @@ -9,6 +9,7 @@ #define TUKIMA_WEAPON "tukima-weapon" #define TUKIMA_POWER "tukima-power" // Technically only used for spectral weapon, not dancing weapons +// Equal to weapon skill with a scale of 10 #define TUKIMA_SKILL "tukima-skill" // A structure with all the data needed to whip up a new monster. diff --git a/crawl-ref/source/mon-place.cc b/crawl-ref/source/mon-place.cc index f24925d..2685a25 100644 --- a/crawl-ref/source/mon-place.cc +++ b/crawl-ref/source/mon-place.cc @@ -1727,7 +1727,7 @@ static monster* _place_monster_aux(const mgen_data &mg, const monster *leader, mg.props.exists(TUKIMA_POWER) ? mg.props[TUKIMA_POWER].get_int() : 100, mg.props.exists(TUKIMA_SKILL) ? - mg.props[TUKIMA_SKILL].get_int() : 27); + mg.props[TUKIMA_SKILL].get_int() : 270); } mon->set_ghost(ghost); mon->ghost_demon_init(); diff --git a/crawl-ref/source/spl-summoning.cc b/crawl-ref/source/spl-summoning.cc index b28c41d..97735db 100644 --- a/crawl-ref/source/spl-summoning.cc +++ b/crawl-ref/source/spl-summoning.cc @@ -2973,7 +2973,7 @@ spret_type cast_spectral_weapon(actor *agent, int pow, god_type god, bool fail) agent->mindex(), 0, god); - int skill_with_weapon = agent->skill(weapon_skill(*wpn), 1, false); + int skill_with_weapon = agent->skill(weapon_skill(*wpn), 10, false); mg.props[TUKIMA_WEAPON] = cp; mg.props[TUKIMA_POWER] = pow; -- 1.7.10.4 From ca0a049fd90fac05d0858eb906003cb66dbdc3ad Mon Sep 17 00:00:00 2001 From: Ed Gonzalez <ed.gonzalez3@gmail.com> Date: Thu, 27 Jun 2013 03:55:40 -0700 Subject: [PATCH 2/8] Buff Spectral Weapon (Gain immunity to allied beams) Like battlesphere, one can now throw/cast/evoke past allied spectral weapons, as if they weren't there. --- crawl-ref/source/beam.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc index 2348e43..1ef586b 100644 --- a/crawl-ref/source/beam.cc +++ b/crawl-ref/source/beam.cc @@ -4728,7 +4728,8 @@ bool bolt::ignores_monster(const monster* mon) const // battlespheres. We don't check mon->is_projectile() because that // check includes boulder beetles which should be hit. if (mons_is_projectile(mon) - || mon->type == MONS_BATTLESPHERE && mons_aligned(agent(), mon)) + || (mon->type == MONS_BATTLESPHERE || mon->type == MONS_SPECTRAL_WEAPON) + && mons_aligned(agent(), mon)) { return true; } -- 1.7.10.4 From 906eb7e51a81efd2d585f283616c1b8954529330 Mon Sep 17 00:00:00 2001 From: Ed Gonzalez <ed.gonzalez3@gmail.com> Date: Fri, 28 Jun 2013 01:26:13 -0700 Subject: [PATCH 3/8] Buff Spectral Weapon defenses (AC, EV) Instead of simply having 2-10AC, 2-10EV linearly over the range of 100 power, it now has 2-12AC, 10-20EV over that range. In particular, giving it hopefully reasonable EV should make it take less hits to share with the player. These numbers are probably still not enough, but it should be a start. Also, now it's hit dice are bounded below by 1. A monster with HD0 has a number of special cases, such as dying to any hit. Some of these might be appropriate for a no-weapon-skill spectral weapon, but I don't want to figure out all the other side effects it might have. --- crawl-ref/source/ghost.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crawl-ref/source/ghost.cc b/crawl-ref/source/ghost.cc index c6718b6..9474b4a 100644 --- a/crawl-ref/source/ghost.cc +++ b/crawl-ref/source/ghost.cc @@ -729,7 +729,7 @@ void ghost_demon::init_spectral_weapon(const item_def& weapon, // Defenses scale with spell power alone. // Appropriate investment is rewarded with a stronger spectral weapon. - xl = wpn_skill / 10; + xl = max(wpn_skill / 10, 1); // At 0 power, weapon skill is 1/3 as effective as on the player // At max power, weapon skill is as effective as on the player. @@ -759,8 +759,8 @@ void ghost_demon::init_spectral_weapon(const item_def& weapon, damage /= scale; speed = 30; - ev = 2 + div_rand_round(power,12); - ac = 2 + div_rand_round(power,12); + ev = 10 + div_rand_round(power,10); + ac = 2 + div_rand_round(power,10); max_hp = 10 + div_rand_round(power,3); } -- 1.7.10.4 From 3326cb07e74d5ebf8536ed0869d18463f81d8ab3 Mon Sep 17 00:00:00 2001 From: Ed Gonzalez <ed.gonzalez3@gmail.com> Date: Fri, 28 Jun 2013 03:18:05 -0700 Subject: [PATCH 4/8] Modify Spectral Weapon damage sharing. Moved the code from monster::hurt into monster::react_to_damage. This has the effect of using the actual damage received, after such things as capping at the weapon's current health and applying any wretched status the attacker may have. Additionally, less properties of the attack are passed to the owner. How the caller intended to use the weapon (cleanup_dead) and the attack flavour could've only caused bugs or misleading effects. --- crawl-ref/source/monster.cc | 77 ++++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 38 deletions(-) diff --git a/crawl-ref/source/monster.cc b/crawl-ref/source/monster.cc index 85a26b1..348b115 100644 --- a/crawl-ref/source/monster.cc +++ b/crawl-ref/source/monster.cc @@ -4201,44 +4201,6 @@ int monster::hurt(const actor *agent, int amount, beam_type flavour, return 0; } - // XXX: tentative damage sharing with the spectral weapon monster - // The damage shared should not be directly lethal to the player - // XXX: It might be possible that the damage might be lethal if the player is at low health and is vulnerable? - // XXX: This makes a lot of messages, especially when the spectral weapon is hit by a monster with multiple attacks and is frozen, burned, etc. - if (type == MONS_SPECTRAL_WEAPON && agent) - { - // The owner should not be able to damage itself - actor *owner = actor_by_mid(props["sw_mid"].get_int()); - if (owner && owner != agent) - { - // The damage should not exceed the weapon's current hp - // or be enough to kill the owner directly - int owner_hp = owner->is_player() ? you.hp - : owner->as_monster()->hit_points; - int shared_damage = min(min(amount,hit_points), owner_hp-1); - if (shared_damage > 0) - { - - if (owner->is_player()) - { - mpr("Your spectral weapon shares its damage with you!"); - you.hurt(agent, shared_damage, flavour, cleanup_dead); - } - else if (owner->alive()) - { - if (you.can_see(owner)) - { - string buf = " shares "; - buf += owner->pronoun(PRONOUN_POSSESSIVE); - buf += " spectral weapon's damage!"; - simple_monster_message(owner->as_monster(), buf.c_str()); - } - owner->hurt(agent, shared_damage, flavour, cleanup_dead); - } - } - } - } - if (alive()) { if (amount != INSTANT_DEATH && agent && agent->is_monster() @@ -5627,6 +5589,45 @@ void monster::react_to_damage(const actor *oppressor, int damage, if (type == MONS_ROYAL_JELLY) (new trj_spawn_fineff(oppressor, this, pos(), damage))->schedule(); + // Damage sharing from the spectral weapon to its owner + // The damage shared should not be directly lethal, though like the + // pain spell, it can leave the player at a very dangerous 1hp. + // XXX: This makes a lot of messages, especially when the spectral weapon + // is hit by a monster with multiple attacks and is frozen, burned, etc. + if (type == MONS_SPECTRAL_WEAPON && oppressor) + { + // The owner should not be able to damage itself + actor *owner = actor_by_mid(props["sw_mid"].get_int()); + if (owner && owner != oppressor) + { + // The damage should not exceed the weapon's current hp + // or be enough to kill the owner directly + int owner_hp = owner->is_player() ? you.hp + : owner->as_monster()->hit_points; + int shared_damage = min(damage, owner_hp-1); + if (shared_damage > 0) + { + + if (owner->is_player()) + { + mpr("Your spectral weapon shares its damage with you!"); + you.hurt(oppressor, shared_damage); + } + else if (owner->alive()) + { + if (you.can_see(owner)) + { + string buf = " shares "; + buf += owner->pronoun(PRONOUN_POSSESSIVE); + buf += " spectral weapon's damage!"; + simple_monster_message(owner->as_monster(), buf.c_str()); + } + owner->hurt(oppressor, shared_damage); + } + } + } + } + if (!alive()) return; -- 1.7.10.4 From 145599010ba2900db7894244b317535be88416c1 Mon Sep 17 00:00:00 2001 From: Ed Gonzalez <ed.gonzalez3@gmail.com> Date: Sat, 29 Jun 2013 02:04:05 -0700 Subject: [PATCH 5/8] Fixed some effects being applied twice to damage. When a deferred_damage_fineff is used, ::hurt is called twice. Once for the original target, and a second time for the shared target. Both calls would apply effects such as weakening from wretched and QUAD DAMAGE. While SIXTEEN TIMES damage is funny, the attacker's effects should only be applied once. Now ouch/hurt functions and the deferred_damage_fineff have an 'attacker_effects' parameter, which defaults to true. If false, then damage effects from the attacker are assumed to have already been applied. All existing uses of deferred_damage_fineff have been appropriately updated. Also applied to spectral weapon damage sharing. --- crawl-ref/source/actor.h | 3 ++- crawl-ref/source/fineff.cc | 2 +- crawl-ref/source/fineff.h | 7 +++++-- crawl-ref/source/monster.cc | 24 +++++++++++++++++------- crawl-ref/source/monster.h | 3 ++- crawl-ref/source/ouch.cc | 6 ++++-- crawl-ref/source/ouch.h | 2 +- crawl-ref/source/player.cc | 5 +++-- crawl-ref/source/player.h | 3 ++- 9 files changed, 37 insertions(+), 18 deletions(-) diff --git a/crawl-ref/source/actor.h b/crawl-ref/source/actor.h index 0ff00c9..2246ed2 100644 --- a/crawl-ref/source/actor.h +++ b/crawl-ref/source/actor.h @@ -206,7 +206,8 @@ public: bool quiet = false) = 0; virtual int hurt(const actor *attacker, int amount, beam_type flavour = BEAM_MISSILE, - bool cleanup_dead = true) = 0; + bool cleanup_dead = true, + bool attacker_effects = true) = 0; virtual bool heal(int amount, bool max_too = false) = 0; virtual void banish(actor *agent, const string &who = "") = 0; virtual void blink(bool allow_partial_control = true) = 0; diff --git a/crawl-ref/source/fineff.cc b/crawl-ref/source/fineff.cc index 83f4277..f62a84f 100644 --- a/crawl-ref/source/fineff.cc +++ b/crawl-ref/source/fineff.cc @@ -282,7 +282,7 @@ void blood_fineff::fire() void deferred_damage_fineff::fire() { if (actor *df = defender()) - df->hurt(attacker(), damage); + df->hurt(attacker(), damage, BEAM_MISSILE, true, attacker_effects); } void starcursed_merge_fineff::fire() diff --git a/crawl-ref/source/fineff.h b/crawl-ref/source/fineff.h index 43e1d34..f8c2f7e 100644 --- a/crawl-ref/source/fineff.h +++ b/crawl-ref/source/fineff.h @@ -124,8 +124,10 @@ protected: class deferred_damage_fineff : public final_effect { public: - deferred_damage_fineff(const actor *attack, const actor *defend, int dam) - : final_effect(attack, defend, coord_def()), damage(dam) + deferred_damage_fineff(const actor *attack, const actor *defend, + int dam, bool _attacker_effects) + : final_effect(attack, defend, coord_def()), + damage(dam), attacker_effects(_attacker_effects) { } bool mergeable(const final_effect &a) const; @@ -133,6 +135,7 @@ public: void fire(); protected: int damage; + bool attacker_effects; }; class starcursed_merge_fineff : public final_effect diff --git a/crawl-ref/source/monster.cc b/crawl-ref/source/monster.cc index 348b115..8ad6538 100644 --- a/crawl-ref/source/monster.cc +++ b/crawl-ref/source/monster.cc @@ -4193,7 +4193,7 @@ bool monster::rot(actor *agent, int amount, int immediate, bool quiet) } int monster::hurt(const actor *agent, int amount, beam_type flavour, - bool cleanup_dead) + bool cleanup_dead, bool attacker_effects) { if (mons_is_projectile(type) || mindex() == ANON_FRIENDLY_MONSTER || type == MONS_DIAMOND_OBELISK) @@ -4203,7 +4203,8 @@ int monster::hurt(const actor *agent, int amount, beam_type flavour, if (alive()) { - if (amount != INSTANT_DEATH && agent && agent->is_monster() + if (attacker_effects && amount != INSTANT_DEATH + && agent && agent->is_monster() && agent->as_monster()->has_ench(ENCH_WRETCHED)) { int degree = agent->as_monster()->get_ench(ENCH_WRETCHED).degree; @@ -4237,7 +4238,8 @@ int monster::hurt(const actor *agent, int amount, beam_type flavour, int split = amount / 2; if (split > 0) { - (new deferred_damage_fineff(agent, guardian, split))->schedule(); + (new deferred_damage_fineff(agent, guardian, + split, false))->schedule(); amount -= split; } } @@ -4250,7 +4252,8 @@ int monster::hurt(const actor *agent, int amount, beam_type flavour, else if (amount <= 0 && hit_points <= max_hit_points) return 0; - if (agent && agent->is_player() && you.duration[DUR_QUAD_DAMAGE] + if (attacker_effects && agent && agent->is_player() + && you.duration[DUR_QUAD_DAMAGE] && flavour != BEAM_TORMENT_DAMAGE) { amount *= 4; @@ -5611,7 +5614,10 @@ void monster::react_to_damage(const actor *oppressor, int damage, if (owner->is_player()) { mpr("Your spectral weapon shares its damage with you!"); - you.hurt(oppressor, shared_damage); + + // Don't apply attacker effects again + you.hurt(oppressor, shared_damage, + BEAM_MISSILE, true, false); } else if (owner->alive()) { @@ -5622,7 +5628,10 @@ void monster::react_to_damage(const actor *oppressor, int damage, buf += " spectral weapon's damage!"; simple_monster_message(owner->as_monster(), buf.c_str()); } - owner->hurt(oppressor, shared_damage); + + // Don't apply attacker effects again + owner->hurt(oppressor, shared_damage, + BEAM_MISSILE, true, false); } } } @@ -5646,7 +5655,8 @@ void monster::react_to_damage(const actor *oppressor, int damage, && !invalid_monster_index(number) && menv[number].is_parent_monster_of(this)) { - (new deferred_damage_fineff(oppressor, &menv[number], damage))->schedule(); + (new deferred_damage_fineff(oppressor, &menv[number], + damage, false))->schedule(); } else if (mons_species(type) == MONS_BUSH && res_fire() < 0 diff --git a/crawl-ref/source/monster.h b/crawl-ref/source/monster.h index e08644d..13f9a81 100644 --- a/crawl-ref/source/monster.h +++ b/crawl-ref/source/monster.h @@ -426,7 +426,8 @@ public: bool rot(actor *, int amount, int immediate = 0, bool quiet = false); int hurt(const actor *attacker, int amount, beam_type flavour = BEAM_MISSILE, - bool cleanup_dead = true); + bool cleanup_dead = true, + bool attacker_effects = true); bool heal(int amount, bool max_too = false); void blame_damage(const actor *attacker, int amount); void blink(bool allow_partial_control = true); diff --git a/crawl-ref/source/ouch.cc b/crawl-ref/source/ouch.cc index 8b1edc6..b909e0b 100644 --- a/crawl-ref/source/ouch.cc +++ b/crawl-ref/source/ouch.cc @@ -1101,7 +1101,8 @@ void reset_damage_counters() // death_source should be set to NON_MONSTER for non-monsters. {dlb} void ouch(int dam, int death_source, kill_method_type death_type, - const char *aux, bool see_source, const char *death_source_name) + const char *aux, bool see_source, const char *death_source_name, + bool attacker_effects) { ASSERT(!crawl_state.game_is_arena()); if (you.duration[DUR_TIME_STEP]) @@ -1110,7 +1111,8 @@ void ouch(int dam, int death_source, kill_method_type death_type, if (you.dead) // ... but eligible for revival return; - if (dam != INSTANT_DEATH && !invalid_monster_index(death_source) + if (attacker_effects && dam != INSTANT_DEATH + && !invalid_monster_index(death_source) && menv[death_source].has_ench(ENCH_WRETCHED)) { // An abstract boring simulation of reduced stats/etc due to bad muts diff --git a/crawl-ref/source/ouch.h b/crawl-ref/source/ouch.h index 0ee3fb3..3c5b21a 100644 --- a/crawl-ref/source/ouch.h +++ b/crawl-ref/source/ouch.h @@ -74,7 +74,7 @@ string morgue_name(string char_name, time_t when_crawl_got_even); void reset_damage_counters(); void ouch(int dam, int death_source, kill_method_type death_type, const char *aux = NULL, bool see_source = true, - const char *death_source_name = NULL); + const char *death_source_name = NULL, bool attacker_effects = true); void lose_level(int death_source, const char* aux); bool drain_exp(bool announce_full = true, int death_source = NON_MONSTER, diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc index c6300fb..6e34a93 100644 --- a/crawl-ref/source/player.cc +++ b/crawl-ref/source/player.cc @@ -6981,14 +6981,15 @@ void player::teleport(bool now, bool abyss_shift, bool wizard_tele) } int player::hurt(const actor *agent, int amount, beam_type flavour, - bool cleanup_dead) + bool cleanup_dead, bool attacker_effects) { // We ignore cleanup_dead here. if (agent->is_monster()) { const monster* mon = agent->as_monster(); ouch(amount, mon->mindex(), - KILLED_BY_MONSTER, "", mon->visible_to(&you)); + KILLED_BY_MONSTER, "", mon->visible_to(&you), NULL, + attacker_effects); } else { diff --git a/crawl-ref/source/player.h b/crawl-ref/source/player.h index 5d30ef0..188fd4c 100644 --- a/crawl-ref/source/player.h +++ b/crawl-ref/source/player.h @@ -600,7 +600,8 @@ public: void sentinel_mark(bool trap = false); int hurt(const actor *attacker, int amount, beam_type flavour = BEAM_MISSILE, - bool cleanup_dead = true); + bool cleanup_dead = true, + bool attacker_effects = true); bool wont_attack() const { return true; }; mon_attitude_type temp_attitude() const { return ATT_FRIENDLY; }; -- 1.7.10.4 From d94c8b40bd3ae61f49623401b2ad37b9a3503c9a Mon Sep 17 00:00:00 2001 From: Ed Gonzalez <ed.gonzalez3@gmail.com> Date: Sat, 29 Jun 2013 02:16:26 -0700 Subject: [PATCH 6/8] Halve Spectral Weapon damage sharing. --- crawl-ref/source/monster.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crawl-ref/source/monster.cc b/crawl-ref/source/monster.cc index 8ad6538..d32f90b 100644 --- a/crawl-ref/source/monster.cc +++ b/crawl-ref/source/monster.cc @@ -5607,7 +5607,7 @@ void monster::react_to_damage(const actor *oppressor, int damage, // or be enough to kill the owner directly int owner_hp = owner->is_player() ? you.hp : owner->as_monster()->hit_points; - int shared_damage = min(damage, owner_hp-1); + int shared_damage = min(damage / 2, owner_hp-1); if (shared_damage > 0) { -- 1.7.10.4 From f8a7b21ccf165c5848106cf394943a85e6e7800a Mon Sep 17 00:00:00 2001 From: Ed Gonzalez <ed.gonzalez3@gmail.com> Date: Sat, 29 Jun 2013 02:19:54 -0700 Subject: [PATCH 7/8] Fixed issue with merging deferred_damage_fineff. Merging now checks that both have the same state for attacker_effects. --- crawl-ref/source/fineff.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crawl-ref/source/fineff.cc b/crawl-ref/source/fineff.cc index f62a84f..957ef47 100644 --- a/crawl-ref/source/fineff.cc +++ b/crawl-ref/source/fineff.cc @@ -84,7 +84,8 @@ bool blood_fineff::mergeable(const final_effect &fe) const bool deferred_damage_fineff::mergeable(const final_effect &fe) const { const deferred_damage_fineff *o = dynamic_cast<const deferred_damage_fineff *>(&fe); - return o && att == o->att && def == o->def; + return o && att == o->att && def == o->def + && attacker_effects == o->attacker_effects; } bool starcursed_merge_fineff::mergeable(const final_effect &fe) const -- 1.7.10.4 From b647e5ddf97e85777317db73175c2516569537c8 Mon Sep 17 00:00:00 2001 From: Ed Gonzalez <ed.gonzalez3@gmail.com> Date: Sat, 29 Jun 2013 04:25:38 -0700 Subject: [PATCH 8/8] Make Spectral Weapon damage sharing use a fineff. This way the order of targets in an AoE shouldn't matter for the damage sharing leaving you with at least 1hp. --- crawl-ref/source/fineff.cc | 15 ++++++++++++++- crawl-ref/source/fineff.h | 5 +++-- crawl-ref/source/monster.cc | 34 +++++++++++----------------------- 3 files changed, 28 insertions(+), 26 deletions(-) diff --git a/crawl-ref/source/fineff.cc b/crawl-ref/source/fineff.cc index 957ef47..f49b78e 100644 --- a/crawl-ref/source/fineff.cc +++ b/crawl-ref/source/fineff.cc @@ -85,7 +85,7 @@ bool deferred_damage_fineff::mergeable(const final_effect &fe) const { const deferred_damage_fineff *o = dynamic_cast<const deferred_damage_fineff *>(&fe); return o && att == o->att && def == o->def - && attacker_effects == o->attacker_effects; + && attacker_effects == o->attacker_effects && fatal == o->fatal; } bool starcursed_merge_fineff::mergeable(const final_effect &fe) const @@ -283,7 +283,20 @@ void blood_fineff::fire() void deferred_damage_fineff::fire() { if (actor *df = defender()) + { + if (!fatal) + { + // Cap non-fatal damage by the defender's hit points + // FIXME: Consider adding a 'fatal' parameter to ::hurt + // to better interact with damage reduction/boosts + // which may be applied later. + int df_hp = df->is_player() ? you.hp + : df->as_monster()->hit_points; + damage = min(damage, df_hp - 1); + } + df->hurt(attacker(), damage, BEAM_MISSILE, true, attacker_effects); + } } void starcursed_merge_fineff::fire() diff --git a/crawl-ref/source/fineff.h b/crawl-ref/source/fineff.h index f8c2f7e..ce8db09 100644 --- a/crawl-ref/source/fineff.h +++ b/crawl-ref/source/fineff.h @@ -125,9 +125,9 @@ class deferred_damage_fineff : public final_effect { public: deferred_damage_fineff(const actor *attack, const actor *defend, - int dam, bool _attacker_effects) + int dam, bool _attacker_effects, bool _fatal = true) : final_effect(attack, defend, coord_def()), - damage(dam), attacker_effects(_attacker_effects) + damage(dam), attacker_effects(_attacker_effects), fatal(_fatal) { } bool mergeable(const final_effect &a) const; @@ -136,6 +136,7 @@ public: protected: int damage; bool attacker_effects; + bool fatal; }; class starcursed_merge_fineff : public final_effect diff --git a/crawl-ref/source/monster.cc b/crawl-ref/source/monster.cc index d32f90b..e877934 100644 --- a/crawl-ref/source/monster.cc +++ b/crawl-ref/source/monster.cc @@ -5603,36 +5603,24 @@ void monster::react_to_damage(const actor *oppressor, int damage, actor *owner = actor_by_mid(props["sw_mid"].get_int()); if (owner && owner != oppressor) { - // The damage should not exceed the weapon's current hp - // or be enough to kill the owner directly - int owner_hp = owner->is_player() ? you.hp - : owner->as_monster()->hit_points; - int shared_damage = min(damage / 2, owner_hp-1); + int shared_damage = damage / 2; if (shared_damage > 0) { if (owner->is_player()) - { mpr("Your spectral weapon shares its damage with you!"); - - // Don't apply attacker effects again - you.hurt(oppressor, shared_damage, - BEAM_MISSILE, true, false); - } - else if (owner->alive()) + else if (owner->alive() && you.can_see(owner)) { - if (you.can_see(owner)) - { - string buf = " shares "; - buf += owner->pronoun(PRONOUN_POSSESSIVE); - buf += " spectral weapon's damage!"; - simple_monster_message(owner->as_monster(), buf.c_str()); - } - - // Don't apply attacker effects again - owner->hurt(oppressor, shared_damage, - BEAM_MISSILE, true, false); + string buf = " shares "; + buf += owner->pronoun(PRONOUN_POSSESSIVE); + buf += " spectral weapon's damage!"; + simple_monster_message(owner->as_monster(), buf.c_str()); } + + // Share damage using a fineff, so that it's non-fatal + // regardless of processing order in an AoE attack. + (new deferred_damage_fineff(oppressor, &menv[number], + shared_damage, false, false))->schedule(); } } } -- 1.7.10.4 |
||||||||||||
|
Mantis 1.1.8[^] Copyright © 2000 - 2009 Mantis Group |