diff options
-rw-r--r-- | crawl-ref/source/beam.cc | 1192 | ||||
-rw-r--r-- | crawl-ref/source/beam.h | 6 | ||||
-rw-r--r-- | crawl-ref/source/command.cc | 4 | ||||
-rw-r--r-- | crawl-ref/source/direct.cc | 212 | ||||
-rw-r--r-- | crawl-ref/source/fight.cc | 188 | ||||
-rw-r--r-- | crawl-ref/source/mon-util.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/monstuff.cc | 10 |
7 files changed, 826 insertions, 788 deletions
diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc index f8bf3d3df4..c77948cf80 100644 --- a/crawl-ref/source/beam.cc +++ b/crawl-ref/source/beam.cc @@ -91,9 +91,9 @@ static void _beam_explodes(bolt &beam, int x, int y); static int _affect_wall(bolt &beam, int x, int y); static int _affect_place_clouds(bolt &beam, int x, int y); static void _affect_place_explosion_clouds(bolt &beam, int x, int y); -static int _affect_player(bolt &beam); +static int _affect_player(bolt &beam, item_def *item = NULL); static void _affect_items(bolt &beam, int x, int y); -static int _affect_monster(bolt &beam, monsters *mon); +static int _affect_monster(bolt &beam, monsters *mon, item_def *item = NULL); static int _affect_monster_enchantment(bolt &beam, monsters *mon); static void _beam_paralyses_monster( bolt &pbolt, monsters *monster ); static int _range_used_on_hit(bolt &beam); @@ -223,18 +223,18 @@ void zapping(zap_type ztype, int power, bolt &pbolt) // stuff monsters throw/zap. // all of the following might be changed by zappy(): - pbolt.range = 8 + random2(5); // default for "0" beams (I think) - pbolt.rangeMax = 0; - pbolt.hit = 0; // default for "0" beams (I think) - pbolt.damage = dice_def( 1, 0 ); // default for "0" beams (I think) - pbolt.type = 0; // default for "0" beams - pbolt.flavour = BEAM_MAGIC; // default for "0" beams - pbolt.ench_power = power; + pbolt.range = 8 + random2(5); // default for "0" beams (I think) + pbolt.rangeMax = 0; + pbolt.hit = 0; // default for "0" beams (I think) + pbolt.damage = dice_def( 1, 0 ); // default for "0" beams (I think) + pbolt.type = 0; // default for "0" beams + pbolt.flavour = BEAM_MAGIC; // default for "0" beams + pbolt.ench_power = power; pbolt.obvious_effect = false; - pbolt.is_beam = false; // default for all beams. - pbolt.is_tracer = false; // default for all player beams - pbolt.thrower = KILL_YOU_MISSILE; // missile from player - pbolt.aux_source.clear(); // additional source info, unused + pbolt.is_beam = false; // default for all beams. + pbolt.is_tracer = false; // default for all player beams + pbolt.thrower = KILL_YOU_MISSILE; // missile from player + pbolt.aux_source.clear(); // additional source info, unused // fill in the bolt structure _zappy( ztype, power, pbolt ); @@ -269,7 +269,7 @@ dice_def calc_dice( int num_dice, int max_damage ) { // Divide the damage among the dice, and add one // occasionally to make up for the fractions. -- bwr - ret.size = max_damage / num_dice; + ret.size = max_damage / num_dice; ret.size += (random2( num_dice ) < max_damage % num_dice); } @@ -539,521 +539,498 @@ static void _zappy( zap_type z_type, int power, bolt &pbolt ) switch (z_type) { case ZAP_STRIKING: // cap 25 - pbolt.name = "force bolt"; - pbolt.colour = BLACK; - pbolt.range = 8 + random2(5); - pbolt.damage = dice_def( 1, 5 ); // dam: 5 - pbolt.hit = 8 + power / 10; // 25: 10 - pbolt.type = dchar_glyph(DCHAR_SPACE); - pbolt.flavour = BEAM_MMISSILE; // unresistable + pbolt.name = "force bolt"; + pbolt.colour = BLACK; + pbolt.range = 8 + random2(5); + pbolt.damage = dice_def( 1, 5 ); // dam: 5 + pbolt.hit = 8 + power / 10; // 25: 10 + pbolt.type = dchar_glyph(DCHAR_SPACE); + pbolt.flavour = BEAM_MMISSILE; // unresistable pbolt.obvious_effect = true; break; case ZAP_MAGIC_DARTS: // cap 25 - pbolt.name = "magic dart"; - pbolt.colour = LIGHTMAGENTA; - pbolt.range = random2(5) + 8; - pbolt.damage = dice_def( 1, 3 + power / 5 ); // 25: 1d8 - pbolt.hit = AUTOMATIC_HIT; // hits always - pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); - pbolt.flavour = BEAM_MMISSILE; // unresistable + pbolt.name = "magic dart"; + pbolt.colour = LIGHTMAGENTA; + pbolt.range = random2(5) + 8; + pbolt.damage = dice_def( 1, 3 + power / 5 ); // 25: 1d8 + pbolt.hit = AUTOMATIC_HIT; // hits always + pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); + pbolt.flavour = BEAM_MMISSILE; // unresistable pbolt.obvious_effect = true; break; case ZAP_STING: // cap 25 - pbolt.name = "sting"; - pbolt.colour = GREEN; - pbolt.range = 8 + random2(5); - pbolt.damage = dice_def( 1, 3 + power / 5 ); // 25: 1d8 - pbolt.hit = 8 + power / 5; // 25: 13 - pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); - pbolt.flavour = BEAM_POISON; // extra damage - + pbolt.name = "sting"; + pbolt.colour = GREEN; + pbolt.range = 8 + random2(5); + pbolt.damage = dice_def( 1, 3 + power / 5 ); // 25: 1d8 + pbolt.hit = 8 + power / 5; // 25: 13 + pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); + pbolt.flavour = BEAM_POISON; // extra damage pbolt.obvious_effect = true; break; case ZAP_ELECTRICITY: // cap 20 - pbolt.name = "zap"; - pbolt.colour = LIGHTCYAN; - pbolt.range = 6 + random2(8); // extended in beam - pbolt.damage = dice_def( 1, 3 + random2(power) / 2 ); // 25: 1d11 - pbolt.hit = 8 + power / 7; // 25: 11 - pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); - pbolt.flavour = BEAM_ELECTRICITY; // beams & reflects - + pbolt.name = "zap"; + pbolt.colour = LIGHTCYAN; + pbolt.range = 6 + random2(8); // extended in beam + pbolt.damage = dice_def( 1, 3 + random2(power) / 2 );// 25: 1d11 + pbolt.hit = 8 + power / 7; // 25: 11 + pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); + pbolt.flavour = BEAM_ELECTRICITY; // beams & reflects pbolt.obvious_effect = true; - pbolt.is_beam = true; + pbolt.is_beam = true; break; case ZAP_DISRUPTION: // cap 25 - pbolt.name = "0"; - pbolt.flavour = BEAM_DISINTEGRATION; - pbolt.range = 7 + random2(8); - pbolt.damage = dice_def( 1, 4 + power / 5 ); // 25: 1d9 - pbolt.ench_power *= 3; + pbolt.name = "0"; + pbolt.flavour = BEAM_DISINTEGRATION; + pbolt.range = 7 + random2(8); + pbolt.damage = dice_def( 1, 4 + power / 5 ); // 25: 1d9 + pbolt.ench_power *= 3; break; case ZAP_PAIN: // cap 25 - pbolt.name = "0"; - pbolt.flavour = BEAM_PAIN; - pbolt.range = 7 + random2(8); - pbolt.damage = dice_def( 1, 4 + power / 5 ); // 25: 1d9 - pbolt.ench_power *= 7; - pbolt.ench_power /= 2; + pbolt.name = "0"; + pbolt.flavour = BEAM_PAIN; + pbolt.range = 7 + random2(8); + pbolt.damage = dice_def( 1, 4 + power / 5 ); // 25: 1d9 + pbolt.ench_power *= 7; + pbolt.ench_power /= 2; break; case ZAP_FLAME_TONGUE: // cap 25 - pbolt.name = "flame"; - pbolt.colour = RED; + pbolt.name = "flame"; + pbolt.colour = RED; - pbolt.range = 1 + random2(2) + random2(power) / 10; + pbolt.range = 1 + random2(2) + random2(power) / 10; if (pbolt.range > 4) pbolt.range = 4; - pbolt.damage = dice_def( 1, 8 + power / 4 ); // 25: 1d14 - pbolt.hit = 7 + power / 6; // 25: 11 - pbolt.type = dchar_glyph(DCHAR_FIRED_BOLT); - pbolt.flavour = BEAM_FIRE; - + pbolt.damage = dice_def( 1, 8 + power / 4 ); // 25: 1d14 + pbolt.hit = 7 + power / 6; // 25: 11 + pbolt.type = dchar_glyph(DCHAR_FIRED_BOLT); + pbolt.flavour = BEAM_FIRE; pbolt.obvious_effect = true; break; case ZAP_SMALL_SANDBLAST: // cap 25 - pbolt.name = "blast of "; - - temp_rand = random2(4); - - pbolt.name += (temp_rand == 0) ? "dust" : - (temp_rand == 1) ? "dirt" : - (temp_rand == 2) ? "grit" : "sand"; - - pbolt.colour = BROWN; - pbolt.range = (random2(power) > random2(30)) ? 2 : 1; - pbolt.damage = dice_def( 1, 8 + power / 4 ); // 25: 1d14 - pbolt.hit = 8 + power / 5; // 25: 13 - pbolt.type = dchar_glyph(DCHAR_FIRED_BOLT); - pbolt.flavour = BEAM_FRAG; // extra AC resist - + pbolt.name = "blast of "; + + temp_rand = random2(4); + pbolt.name += (temp_rand == 0) ? "dust" : + (temp_rand == 1) ? "dirt" : + (temp_rand == 2) ? "grit" : "sand"; + + pbolt.colour = BROWN; + pbolt.range = (random2(power) > random2(30)) ? 2 : 1; + pbolt.damage = dice_def( 1, 8 + power / 4 ); // 25: 1d14 + pbolt.hit = 8 + power / 5; // 25: 13 + pbolt.type = dchar_glyph(DCHAR_FIRED_BOLT); + pbolt.flavour = BEAM_FRAG; // extra AC resist pbolt.obvious_effect = true; break; case ZAP_SANDBLAST: // cap 50 - pbolt.name = coinflip() ? "blast of rock" : "rocky blast"; - pbolt.colour = BROWN; + pbolt.name = coinflip() ? "blast of rock" : "rocky blast"; + + pbolt.colour = BROWN; - pbolt.range = 2 + random2(power) / 20; + pbolt.range = 2 + random2(power) / 20; if (pbolt.range > 4) pbolt.range = 4; - pbolt.damage = dice_def( 2, 4 + power / 3 ); // 25: 2d12 - pbolt.hit = 13 + power / 10; // 25: 15 - pbolt.type = dchar_glyph(DCHAR_FIRED_BOLT); - pbolt.flavour = BEAM_FRAG; // extra AC resist - + pbolt.damage = dice_def( 2, 4 + power / 3 ); // 25: 2d12 + pbolt.hit = 13 + power / 10; // 25: 15 + pbolt.type = dchar_glyph(DCHAR_FIRED_BOLT); + pbolt.flavour = BEAM_FRAG; // extra AC resist pbolt.obvious_effect = true; break; case ZAP_BONE_SHARDS: - pbolt.name = "spray of bone shards"; - pbolt.colour = LIGHTGREY; - pbolt.range = 7 + random2(10); + pbolt.name = "spray of bone shards"; + pbolt.colour = LIGHTGREY; + pbolt.range = 7 + random2(10); // Incoming power is highly dependant on mass (see spells3.cc). // Basic function is power * 15 + mass... with the largest // available mass (3000) we get a power of 4500 at a power // level of 100 (for 3d20). - pbolt.damage = dice_def( 3, 2 + (power / 250) ); - pbolt.hit = 8 + (power / 100); // max hit: 53 - pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); - pbolt.flavour = BEAM_MAGIC; // unresisted - + pbolt.damage = dice_def( 3, 2 + (power / 250) ); + pbolt.hit = 8 + (power / 100); // max hit: 53 + pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); + pbolt.flavour = BEAM_MAGIC; // unresisted pbolt.obvious_effect = true; - pbolt.is_beam = true; + pbolt.is_beam = true; break; case ZAP_FLAME: // cap 50 - pbolt.name = "puff of flame"; - pbolt.colour = RED; - pbolt.range = 8 + random2(5); - pbolt.damage = dice_def( 2, 4 + power / 10 ); // 25: 2d6 50: 2d9 - pbolt.hit = 8 + power / 10; // 25: 10 50: 13 - pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); - pbolt.flavour = BEAM_FIRE; - + pbolt.name = "puff of flame"; + pbolt.colour = RED; + pbolt.range = 8 + random2(5); + pbolt.damage = dice_def( 2, 4 + power / 10 );// 25: 2d6 50: 2d9 + pbolt.hit = 8 + power / 10; // 25: 10 50: 13 + pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); + pbolt.flavour = BEAM_FIRE; pbolt.obvious_effect = true; break; case ZAP_FROST: // cap 50 - pbolt.name = "puff of frost"; - pbolt.colour = WHITE; - pbolt.range = 8 + random2(5); - pbolt.damage = dice_def( 2, 4 + power / 10 ); // 25: 2d6 50: 2d9 - pbolt.hit = 8 + power / 10; // 50: 10 50: 13 - pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); - pbolt.flavour = BEAM_COLD; - + pbolt.name = "puff of frost"; + pbolt.colour = WHITE; + pbolt.range = 8 + random2(5); + pbolt.damage = dice_def( 2, 4 + power / 10 );// 25: 2d6 50: 2d9 + pbolt.hit = 8 + power / 10; // 25: 10 50: 13 + pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); + pbolt.flavour = BEAM_COLD; pbolt.obvious_effect = true; break; case ZAP_STONE_ARROW: // cap 100 - pbolt.name = "stone arrow"; - pbolt.colour = LIGHTGREY; - pbolt.range = 8 + random2(5); - pbolt.damage = dice_def( 2, 5 + power / 7 ); // 25: 2d8 50: 2d12 - pbolt.hit = 8 + power / 10; // 25: 10 50: 13 - pbolt.type = dchar_glyph(DCHAR_FIRED_MISSILE); - pbolt.flavour = BEAM_MMISSILE; // irresistible - + pbolt.name = "stone arrow"; + pbolt.colour = LIGHTGREY; + pbolt.range = 8 + random2(5); + pbolt.damage = dice_def( 2, 5 + power / 7 );// 25: 2d8 50: 2d12 + pbolt.hit = 8 + power / 10; // 25: 10 50: 13 + pbolt.type = dchar_glyph(DCHAR_FIRED_MISSILE); + pbolt.flavour = BEAM_MMISSILE; // irresistible pbolt.obvious_effect = true; break; case ZAP_STICKY_FLAME: // cap 100 - pbolt.name = "sticky flame"; // extra damage - pbolt.colour = RED; - pbolt.range = 8 + random2(5); - pbolt.damage = dice_def( 2, 3 + power / 12 ); // 50: 2d7 100: 2d11 - pbolt.hit = 11 + power / 10; // 50: 16 100: 21 - pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); - pbolt.flavour = BEAM_FIRE; - + pbolt.name = "sticky flame"; // extra damage + pbolt.colour = RED; + pbolt.range = 8 + random2(5); + // 50: 2d7 100: 2d11 + pbolt.damage = dice_def( 2, 3 + power / 12 ); + // 50: 16 100: 21 + pbolt.hit = 11 + power / 10; + pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); + pbolt.flavour = BEAM_FIRE; pbolt.obvious_effect = true; break; case ZAP_MYSTIC_BLAST: // cap 100 - pbolt.name = "orb of energy"; - pbolt.colour = LIGHTMAGENTA; - pbolt.range = 8 + random2(5); - pbolt.damage = calc_dice( 2, 15 + (power * 2) / 5 ); - pbolt.hit = 10 + power / 7; // 50: 17 100: 24 - pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); - pbolt.flavour = BEAM_MMISSILE; // unresistable - + pbolt.name = "orb of energy"; + pbolt.colour = LIGHTMAGENTA; + pbolt.range = 8 + random2(5); + pbolt.damage = calc_dice( 2, 15 + (power * 2) / 5 ); + pbolt.hit = 10 + power / 7; // 50: 17 100: 24 + pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); + pbolt.flavour = BEAM_MMISSILE; // unresistable pbolt.obvious_effect = true; break; case ZAP_ICE_BOLT: // cap 100 - pbolt.name = "bolt of ice"; - pbolt.colour = WHITE; - pbolt.range = 8 + random2(5); - pbolt.damage = calc_dice( 3, 10 + power / 2 ); - pbolt.hit = 9 + power / 12; // 50: 13 100: 17 - pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); - pbolt.flavour = BEAM_ICE; // half resistable + pbolt.name = "bolt of ice"; + pbolt.colour = WHITE; + pbolt.range = 8 + random2(5); + pbolt.damage = calc_dice( 3, 10 + power / 2 ); + pbolt.hit = 9 + power / 12; // 50: 13 100: 17 + pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); + pbolt.flavour = BEAM_ICE; // half resistable break; case ZAP_DISPEL_UNDEAD: // cap 100 - pbolt.name = "0"; - pbolt.flavour = BEAM_DISPEL_UNDEAD; - pbolt.range = 7 + random2(8); - pbolt.damage = calc_dice( 3, 20 + (power * 3) / 4 ); - pbolt.ench_power *= 3; - pbolt.ench_power /= 2; + pbolt.name = "0"; + pbolt.flavour = BEAM_DISPEL_UNDEAD; + pbolt.range = 7 + random2(8); + pbolt.damage = calc_dice( 3, 20 + (power * 3) / 4 ); + pbolt.ench_power *= 3; + pbolt.ench_power /= 2; break; case ZAP_MAGMA: // cap 150 - pbolt.name = "bolt of magma"; - pbolt.colour = RED; - pbolt.range = 5 + random2(4); - pbolt.damage = calc_dice( 4, 10 + (power * 3) / 5 ); - pbolt.hit = 8 + power / 25; // 50: 10 100: 14 - pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); - pbolt.flavour = BEAM_LAVA; - + pbolt.name = "bolt of magma"; + pbolt.colour = RED; + pbolt.range = 5 + random2(4); + pbolt.damage = calc_dice( 4, 10 + (power * 3) / 5 ); + pbolt.hit = 8 + power / 25; // 50: 10 100: 14 + pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); + pbolt.flavour = BEAM_LAVA; pbolt.obvious_effect = true; - pbolt.is_beam = true; + pbolt.is_beam = true; break; case ZAP_FIRE: // cap 150 - pbolt.name = "bolt of fire"; - pbolt.colour = RED; - pbolt.range = 7 + random2(10); - pbolt.damage = calc_dice( 6, 18 + power * 2 / 3 ); - pbolt.hit = 10 + power / 25; // 50: 12 100: 14 - pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); - pbolt.flavour = BEAM_FIRE; - + pbolt.name = "bolt of fire"; + pbolt.colour = RED; + pbolt.range = 7 + random2(10); + pbolt.damage = calc_dice( 6, 18 + power * 2 / 3 ); + pbolt.hit = 10 + power / 25; // 50: 12 100: 14 + pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); + pbolt.flavour = BEAM_FIRE; pbolt.obvious_effect = true; - pbolt.is_beam = true; + pbolt.is_beam = true; break; case ZAP_COLD: // cap 150 - pbolt.name = "bolt of cold"; - pbolt.colour = WHITE; - pbolt.range = 7 + random2(10); - pbolt.damage = calc_dice( 6, 18 + power * 2 / 3 ); - pbolt.hit = 10 + power / 25; // 50: 12 100: 14 - pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); - pbolt.flavour = BEAM_COLD; - + pbolt.name = "bolt of cold"; + pbolt.colour = WHITE; + pbolt.range = 7 + random2(10); + pbolt.damage = calc_dice( 6, 18 + power * 2 / 3 ); + pbolt.hit = 10 + power / 25; // 50: 12 100: 14 + pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); + pbolt.flavour = BEAM_COLD; pbolt.obvious_effect = true; - pbolt.is_beam = true; + pbolt.is_beam = true; break; case ZAP_VENOM_BOLT: // cap 150 - pbolt.name = "bolt of poison"; - pbolt.colour = LIGHTGREEN; - pbolt.range = 8 + random2(10); - pbolt.damage = calc_dice( 4, 15 + power / 2 ); - pbolt.hit = 8 + power / 20; // 50: 10 100: 13 - pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); - pbolt.flavour = BEAM_POISON; // extra damage - + pbolt.name = "bolt of poison"; + pbolt.colour = LIGHTGREEN; + pbolt.range = 8 + random2(10); + pbolt.damage = calc_dice( 4, 15 + power / 2 ); + pbolt.hit = 8 + power / 20; // 50: 10 100: 13 + pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); + pbolt.flavour = BEAM_POISON; // extra damage pbolt.obvious_effect = true; - pbolt.is_beam = true; + pbolt.is_beam = true; break; case ZAP_NEGATIVE_ENERGY: // cap 150 // these always auto-identify, so no generic name - pbolt.name = "bolt of negative energy"; - pbolt.colour = DARKGREY; - pbolt.range = 7 + random2(10); - pbolt.damage = calc_dice( 4, 15 + (power * 3) / 5 ); - pbolt.hit = 8 + power / 20; // 50: 10 100: 13 - pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); - pbolt.flavour = BEAM_NEG; // drains levels + pbolt.name = "bolt of negative energy"; + pbolt.colour = DARKGREY; + pbolt.range = 7 + random2(10); + pbolt.damage = calc_dice( 4, 15 + (power * 3) / 5 ); + pbolt.hit = 8 + power / 20; // 50: 10 100: 13 + pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); + pbolt.flavour = BEAM_NEG; // drains levels pbolt.obvious_effect = true; - - pbolt.is_beam = true; + pbolt.is_beam = true; break; case ZAP_IRON_BOLT: // cap 150 - pbolt.name = "iron bolt"; - pbolt.colour = LIGHTCYAN; - pbolt.range = 5 + random2(5); - pbolt.damage = calc_dice( 9, 15 + (power * 3) / 4 ); - pbolt.hit = 7 + power / 15; // 50: 10 100: 13 - pbolt.type = dchar_glyph(DCHAR_FIRED_MISSILE); - pbolt.flavour = BEAM_MMISSILE; // unresistable + pbolt.name = "iron bolt"; + pbolt.colour = LIGHTCYAN; + pbolt.range = 5 + random2(5); + pbolt.damage = calc_dice( 9, 15 + (power * 3) / 4 ); + pbolt.hit = 7 + power / 15; // 50: 10 100: 13 + pbolt.type = dchar_glyph(DCHAR_FIRED_MISSILE); + pbolt.flavour = BEAM_MMISSILE; // unresistable pbolt.obvious_effect = true; break; case ZAP_POISON_ARROW: // cap 150 - pbolt.name = "poison arrow"; - pbolt.colour = LIGHTGREEN; - pbolt.range = 8 + random2(5); - pbolt.damage = calc_dice( 4, 15 + power ); - pbolt.hit = 5 + power / 10; // 50: 10 100: 15 - pbolt.type = dchar_glyph(DCHAR_FIRED_MISSILE); - pbolt.flavour = BEAM_POISON_ARROW; // extra damage + pbolt.name = "poison arrow"; + pbolt.colour = LIGHTGREEN; + pbolt.range = 8 + random2(5); + pbolt.damage = calc_dice( 4, 15 + power ); + pbolt.hit = 5 + power / 10; // 50: 10 100: 15 + pbolt.type = dchar_glyph(DCHAR_FIRED_MISSILE); + pbolt.flavour = BEAM_POISON_ARROW; // extra damage pbolt.obvious_effect = true; break; case ZAP_DISINTEGRATION: // cap 150 - pbolt.name = "0"; - pbolt.flavour = BEAM_DISINTEGRATION; - pbolt.range = 7 + random2(8); - pbolt.damage = calc_dice( 3, 15 + (power * 3) / 4 ); - pbolt.ench_power *= 5; - pbolt.ench_power /= 2; - pbolt.is_beam = true; + pbolt.name = "0"; + pbolt.flavour = BEAM_DISINTEGRATION; + pbolt.range = 7 + random2(8); + pbolt.damage = calc_dice( 3, 15 + (power * 3) / 4 ); + pbolt.ench_power *= 5; + pbolt.ench_power /= 2; + pbolt.is_beam = true; break; case ZAP_LIGHTNING: // cap 150 // also for breath (at pow = lev * 2; max dam: 33) - pbolt.name = "bolt of lightning"; - pbolt.colour = LIGHTCYAN; - pbolt.range = 8 + random2(10); // extended in beam - pbolt.damage = calc_dice( 1, 10 + (power * 3) / 5 ); - pbolt.hit = 7 + random2(power) / 20; // 50: 7-9 100: 7-12 - pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); - pbolt.flavour = BEAM_ELECTRICITY; // beams & reflects - + pbolt.name = "bolt of lightning"; + pbolt.colour = LIGHTCYAN; + pbolt.range = 8 + random2(10); // extended in beam + pbolt.damage = calc_dice( 1, 10 + (power * 3) / 5 ); + pbolt.hit = 7 + random2(power) / 20; // 50: 7-9 100: 7-12 + pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); + pbolt.flavour = BEAM_ELECTRICITY; // beams & reflects pbolt.obvious_effect = true; - pbolt.is_beam = true; + pbolt.is_beam = true; break; case ZAP_FIREBALL: // cap 150 - pbolt.name = "fireball"; - pbolt.colour = RED; - pbolt.range = 8 + random2(5); - pbolt.damage = calc_dice( 3, 10 + power / 2 ); - pbolt.hit = 40; // hit: 40 - pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); - pbolt.flavour = BEAM_FIRE; // fire - pbolt.is_explosion = true; + pbolt.name = "fireball"; + pbolt.colour = RED; + pbolt.range = 8 + random2(5); + pbolt.damage = calc_dice( 3, 10 + power / 2 ); + pbolt.hit = 40; // hit: 40 + pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); + pbolt.flavour = BEAM_FIRE; // fire + pbolt.is_explosion = true; break; case ZAP_ORB_OF_ELECTRICITY: // cap 150 - pbolt.name = "orb of electricity"; - pbolt.colour = LIGHTBLUE; - pbolt.range = 9 + random2(12); - pbolt.damage = calc_dice( 1, 15 + (power * 4) / 5 ); - pbolt.damage.num = 0; // only does explosion damage - pbolt.hit = 40; // hit: 40 - pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); - pbolt.flavour = BEAM_ELECTRICITY; - pbolt.is_explosion = true; + pbolt.name = "orb of electricity"; + pbolt.colour = LIGHTBLUE; + pbolt.range = 9 + random2(12); + pbolt.damage = calc_dice( 1, 15 + (power * 4) / 5 ); + pbolt.damage.num = 0; // only does explosion damage + pbolt.hit = 40; // hit: 40 + pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); + pbolt.flavour = BEAM_ELECTRICITY; + pbolt.is_explosion = true; break; case ZAP_ORB_OF_FRAGMENTATION: // cap 150 - pbolt.name = "metal orb"; - pbolt.colour = CYAN; - pbolt.range = 9 + random2(7); - pbolt.damage = calc_dice( 3, 30 + (power * 3) / 4 ); - pbolt.hit = 20; // hit: 20 - pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); - pbolt.flavour = BEAM_FRAG; // extra AC resist - pbolt.is_explosion = true; + pbolt.name = "metal orb"; + pbolt.colour = CYAN; + pbolt.range = 9 + random2(7); + pbolt.damage = calc_dice( 3, 30 + (power * 3) / 4 ); + pbolt.hit = 20; // hit: 20 + pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); + pbolt.flavour = BEAM_FRAG; // extra AC resist + pbolt.is_explosion = true; break; case ZAP_CLEANSING_FLAME: - pbolt.name = "golden flame"; - pbolt.colour = YELLOW; - pbolt.range = 7; - pbolt.damage = calc_dice( 3, 20 + (power * 2) / 3 ); - pbolt.hit = 150; - pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); - pbolt.flavour = BEAM_HOLY; - + pbolt.name = "golden flame"; + pbolt.colour = YELLOW; + pbolt.range = 7; + pbolt.damage = calc_dice( 3, 20 + (power * 2) / 3 ); + pbolt.hit = 150; + pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); + pbolt.flavour = BEAM_HOLY; pbolt.obvious_effect = true; - pbolt.is_explosion = true; + pbolt.is_explosion = true; break; case ZAP_CRYSTAL_SPEAR: // cap 200 - pbolt.name = "crystal spear"; - pbolt.colour = WHITE; - pbolt.range = 6 + random2(4); - pbolt.damage = calc_dice( 10, 23 + power ); - pbolt.hit = 10 + power / 15; // 50: 13 100: 16 - pbolt.type = dchar_glyph(DCHAR_FIRED_MISSILE); - pbolt.flavour = BEAM_MMISSILE; // unresistable - + pbolt.name = "crystal spear"; + pbolt.colour = WHITE; + pbolt.range = 6 + random2(4); + pbolt.damage = calc_dice( 10, 23 + power ); + pbolt.hit = 10 + power / 15; // 50: 13 100: 16 + pbolt.type = dchar_glyph(DCHAR_FIRED_MISSILE); + pbolt.flavour = BEAM_MMISSILE; // unresistable pbolt.obvious_effect = true; break; case ZAP_HELLFIRE: // cap 200 - pbolt.name = "hellfire"; - pbolt.colour = RED; - pbolt.range = 7 + random2(10); - pbolt.damage = calc_dice( 3, 10 + (power * 3) / 4 ); - pbolt.hit = 20 + power / 10; // 50: 25 100: 30 - pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); - pbolt.flavour = BEAM_HELLFIRE; - + pbolt.name = "hellfire"; + pbolt.colour = RED; + pbolt.range = 7 + random2(10); + pbolt.damage = calc_dice( 3, 10 + (power * 3) / 4 ); + pbolt.hit = 20 + power / 10; // 50: 25 100: 30 + pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); + pbolt.flavour = BEAM_HELLFIRE; pbolt.obvious_effect = true; - pbolt.is_explosion = true; + pbolt.is_explosion = true; break; case ZAP_ICE_STORM: // cap 200 - pbolt.name = "great blast of cold"; - pbolt.colour = BLUE; - pbolt.range = 9 + random2(5); - pbolt.damage = calc_dice( 10, 18 + power ); - pbolt.damage.num = 0; // only does explosion damage - pbolt.hit = 20 + power / 10; // 50: 25 100: 30 - pbolt.ench_power = power; // used for radius - pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); - pbolt.flavour = BEAM_ICE; // half resisted - pbolt.is_explosion = true; + pbolt.name = "great blast of cold"; + pbolt.colour = BLUE; + pbolt.range = 9 + random2(5); + pbolt.damage = calc_dice( 10, 18 + power ); + pbolt.damage.num = 0; // only does explosion damage + pbolt.hit = 20 + power / 10; // 50: 25 100: 30 + pbolt.ench_power = power; // used for radius + pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); + pbolt.flavour = BEAM_ICE; // half resisted + pbolt.is_explosion = true; break; case ZAP_BEAM_OF_ENERGY: // bolt of innacuracy - pbolt.name = "narrow beam of energy"; - pbolt.colour = YELLOW; - pbolt.range = 7 + random2(10); - pbolt.damage = calc_dice( 12, 40 + (power * 3) / 2 ); - pbolt.hit = 1; - pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); - pbolt.flavour = BEAM_ENERGY; // unresisted - + pbolt.name = "narrow beam of energy"; + pbolt.colour = YELLOW; + pbolt.range = 7 + random2(10); + pbolt.damage = calc_dice( 12, 40 + (power * 3) / 2 ); + pbolt.hit = 1; + pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); + pbolt.flavour = BEAM_ENERGY; // unresisted pbolt.obvious_effect = true; - pbolt.is_beam = true; + pbolt.is_beam = true; break; case ZAP_SPIT_POISON: // cap 50 // max pow = lev + mut * 5 = 42 - pbolt.name = "splash of poison"; - pbolt.colour = GREEN; + pbolt.name = "splash of poison"; + pbolt.colour = GREEN; - pbolt.range = 3 + random2( 1 + power / 2 ); + pbolt.range = 3 + random2( 1 + power / 2 ); if (pbolt.range > 9) pbolt.range = 9; - pbolt.damage = dice_def( 1, 4 + power / 2 ); // max dam: 25 - pbolt.hit = 5 + random2( 1 + power / 3 ); // max hit: 19 - pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); - pbolt.flavour = BEAM_POISON; + pbolt.damage = dice_def( 1, 4 + power / 2 ); // max dam: 25 + pbolt.hit = 5 + random2( 1 + power / 3 ); // max hit: 19 + pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); + pbolt.flavour = BEAM_POISON; pbolt.obvious_effect = true; break; case ZAP_BREATHE_FIRE: // cap 50 // max pow = lev + mut * 4 + 12 = 51 (capped to 50) - pbolt.name = "fiery breath"; - pbolt.colour = RED; + pbolt.name = "fiery breath"; + pbolt.colour = RED; - pbolt.range = 3 + random2( 1 + power / 2 ); + pbolt.range = 3 + random2( 1 + power / 2 ); if (pbolt.range > 9) pbolt.range = 9; - pbolt.damage = dice_def( 3, 4 + power / 3 ); // max dam: 60 - pbolt.hit = 8 + random2( 1 + power / 3 ); // max hit: 25 - pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); - pbolt.flavour = BEAM_FIRE; - + pbolt.damage = dice_def( 3, 4 + power / 3 ); // max dam: 60 + pbolt.hit = 8 + random2( 1 + power / 3 ); // max hit: 25 + pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); + pbolt.flavour = BEAM_FIRE; pbolt.obvious_effect = true; - pbolt.is_beam = true; + pbolt.is_beam = true; break; case ZAP_BREATHE_FROST: // cap 50 // max power = lev = 27 - pbolt.name = "freezing breath"; - pbolt.colour = WHITE; + pbolt.name = "freezing breath"; + pbolt.colour = WHITE; - pbolt.range = 3 + random2( 1 + power / 2 ); + pbolt.range = 3 + random2( 1 + power / 2 ); if (pbolt.range > 9) pbolt.range = 9; - pbolt.damage = dice_def( 3, 4 + power / 3 ); // max dam: 39 - pbolt.hit = 8 + random2( 1 + power / 3 ); - pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); - pbolt.flavour = BEAM_COLD; - + pbolt.damage = dice_def( 3, 4 + power / 3 ); // max dam: 39 + pbolt.hit = 8 + random2( 1 + power / 3 ); + pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); + pbolt.flavour = BEAM_COLD; pbolt.obvious_effect = true; - pbolt.is_beam = true; + pbolt.is_beam = true; break; case ZAP_BREATHE_ACID: // cap 50 // max power = lev for ability, 50 for minor destruction (max dam: 57) - pbolt.name = "acid"; - pbolt.colour = YELLOW; + pbolt.name = "acid"; + pbolt.colour = YELLOW; - pbolt.range = 3 + random2( 1 + power / 2 ); + pbolt.range = 3 + random2( 1 + power / 2 ); if (pbolt.range > 9) pbolt.range = 9; - pbolt.damage = dice_def( 3, 3 + power / 3 ); // max dam: 36 - pbolt.hit = 5 + random2( 1 + power / 3 ); - pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); - pbolt.flavour = BEAM_ACID; - + pbolt.damage = dice_def( 3, 3 + power / 3 ); // max dam: 36 + pbolt.hit = 5 + random2( 1 + power / 3 ); + pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); + pbolt.flavour = BEAM_ACID; pbolt.obvious_effect = true; - pbolt.is_beam = true; + pbolt.is_beam = true; break; case ZAP_BREATHE_POISON: // leaves clouds of gas // cap 50 // max power = lev = 27 - pbolt.name = "poison gas"; - pbolt.colour = GREEN; + pbolt.name = "poison gas"; + pbolt.colour = GREEN; - pbolt.range = 3 + random2( 1 + power / 2 ); + pbolt.range = 3 + random2( 1 + power / 2 ); if (pbolt.range > 9) pbolt.range = 9; - pbolt.damage = dice_def( 3, 2 + power / 6 ); // max dam: 18 - pbolt.hit = 6 + random2( 1 + power / 3 ); - pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); - pbolt.flavour = BEAM_POISON; - + pbolt.damage = dice_def( 3, 2 + power / 6 ); // max dam: 18 + pbolt.hit = 6 + random2( 1 + power / 3 ); + pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); + pbolt.flavour = BEAM_POISON; pbolt.obvious_effect = true; - pbolt.is_beam = true; + pbolt.is_beam = true; break; case ZAP_BREATHE_POWER: // cap 50 - pbolt.name = "bolt of energy"; + pbolt.name = "bolt of energy"; // max power = lev = 27 - pbolt.colour = BLUE; + pbolt.colour = BLUE; if (random2(power) >= 8) pbolt.colour = LIGHTBLUE; if (random2(power) >= 12) @@ -1061,180 +1038,176 @@ static void _zappy( zap_type z_type, int power, bolt &pbolt ) if (random2(power) >= 17) pbolt.colour = LIGHTMAGENTA; - pbolt.range = 6 + random2( 1 + power / 2 ); + pbolt.range = 6 + random2( 1 + power / 2 ); if (pbolt.range > 9) pbolt.range = 9; - pbolt.damage = dice_def( 3, 3 + power / 3 ); // max dam: 36 - pbolt.hit = 5 + random2( 1 + power / 3 ); - pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); - pbolt.flavour = BEAM_MMISSILE; // unresistable - + pbolt.damage = dice_def( 3, 3 + power / 3 ); // max dam: 36 + pbolt.hit = 5 + random2( 1 + power / 3 ); + pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); + pbolt.flavour = BEAM_MMISSILE; // unresistable pbolt.obvious_effect = true; - pbolt.is_beam = true; + pbolt.is_beam = true; break; case ZAP_BREATHE_STEAM: // cap 50 // max power = lev = 27 - pbolt.name = "ball of steam"; - pbolt.colour = LIGHTGREY; + pbolt.name = "ball of steam"; + pbolt.colour = LIGHTGREY; - pbolt.range = 6 + random2(5); + pbolt.range = 6 + random2(5); if (pbolt.range > 9) pbolt.range = 9; - pbolt.damage = dice_def( 3, 4 + power / 5 ); // max dam: 27 - pbolt.hit = 10 + random2( 1 + power / 5 ); - pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); - pbolt.flavour = BEAM_STEAM; - + pbolt.damage = dice_def( 3, 4 + power / 5 ); // max dam: 27 + pbolt.hit = 10 + random2( 1 + power / 5 ); + pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); + pbolt.flavour = BEAM_STEAM; pbolt.obvious_effect = true; - pbolt.is_beam = true; + pbolt.is_beam = true; break; case ZAP_SLOWING: - pbolt.name = "0"; - pbolt.flavour = BEAM_SLOW; + pbolt.name = "0"; + pbolt.flavour = BEAM_SLOW; // pbolt.is_beam = true; break; case ZAP_HASTING: - pbolt.name = "0"; - pbolt.flavour = BEAM_HASTE; + pbolt.name = "0"; + pbolt.flavour = BEAM_HASTE; // pbolt.is_beam = true; break; case ZAP_PARALYSIS: - pbolt.name = "0"; - pbolt.flavour = BEAM_PARALYSIS; + pbolt.name = "0"; + pbolt.flavour = BEAM_PARALYSIS; // pbolt.is_beam = true; break; case ZAP_CONFUSION: - pbolt.name = "0"; - pbolt.flavour = BEAM_CONFUSION; + pbolt.name = "0"; + pbolt.flavour = BEAM_CONFUSION; // pbolt.is_beam = true; break; case ZAP_INVISIBILITY: - pbolt.name = "0"; - pbolt.flavour = BEAM_INVISIBILITY; + pbolt.name = "0"; + pbolt.flavour = BEAM_INVISIBILITY; // pbolt.is_beam = true; break; case ZAP_HEALING: - pbolt.name = "0"; - pbolt.flavour = BEAM_HEALING; - pbolt.damage = dice_def( 1, 7 + power / 3 ); + pbolt.name = "0"; + pbolt.flavour = BEAM_HEALING; + pbolt.damage = dice_def( 1, 7 + power / 3 ); // pbolt.is_beam = true; break; case ZAP_DIGGING: - pbolt.name = "0"; - pbolt.flavour = BEAM_DIGGING; + pbolt.name = "0"; + pbolt.flavour = BEAM_DIGGING; // not ordinary "0" beam range {dlb} - pbolt.range = 3 + random2( power / 5 ) + random2(5); - pbolt.is_beam = true; + pbolt.range = 3 + random2( power / 5 ) + random2(5); + pbolt.is_beam = true; break; case ZAP_TELEPORTATION: - pbolt.name = "0"; - pbolt.flavour = BEAM_TELEPORT; - pbolt.range = 9 + random2(5); + pbolt.name = "0"; + pbolt.flavour = BEAM_TELEPORT; + pbolt.range = 9 + random2(5); // pbolt.is_beam = true; break; case ZAP_POLYMORPH_OTHER: - pbolt.name = "0"; - pbolt.flavour = BEAM_POLYMORPH; - pbolt.range = 9 + random2(5); + pbolt.name = "0"; + pbolt.flavour = BEAM_POLYMORPH; + pbolt.range = 9 + random2(5); // pbolt.is_beam = true; break; case ZAP_ENSLAVEMENT: - pbolt.name = "0"; - pbolt.flavour = BEAM_CHARM; - pbolt.range = 7 + random2(5); + pbolt.name = "0"; + pbolt.flavour = BEAM_CHARM; + pbolt.range = 7 + random2(5); // pbolt.is_beam = true; break; case ZAP_BANISHMENT: - pbolt.name = "0"; - pbolt.flavour = BEAM_BANISH; - pbolt.range = 7 + random2(5); + pbolt.name = "0"; + pbolt.flavour = BEAM_BANISH; + pbolt.range = 7 + random2(5); // pbolt.is_beam = true; break; case ZAP_DEGENERATION: - pbolt.name = "0"; - pbolt.flavour = BEAM_DEGENERATE; - pbolt.range = 7 + random2(5); + pbolt.name = "0"; + pbolt.flavour = BEAM_DEGENERATE; + pbolt.range = 7 + random2(5); // pbolt.is_beam = true; break; case ZAP_ENSLAVE_UNDEAD: - pbolt.name = "0"; - pbolt.flavour = BEAM_ENSLAVE_UNDEAD; - pbolt.range = 7 + random2(5); + pbolt.name = "0"; + pbolt.flavour = BEAM_ENSLAVE_UNDEAD; + pbolt.range = 7 + random2(5); // pbolt.is_beam = true; break; case ZAP_AGONY: - pbolt.name = "0agony"; - pbolt.flavour = BEAM_PAIN; - pbolt.range = 7 + random2(8); - pbolt.ench_power *= 5; + pbolt.name = "0agony"; + pbolt.flavour = BEAM_PAIN; + pbolt.range = 7 + random2(8); + pbolt.ench_power *= 5; // pbolt.is_beam = true; break; case ZAP_CONTROL_DEMON: - pbolt.name = "0"; - pbolt.flavour = BEAM_ENSLAVE_DEMON; - pbolt.range = 7 + random2(5); - pbolt.ench_power *= 3; - pbolt.ench_power /= 2; + pbolt.name = "0"; + pbolt.flavour = BEAM_ENSLAVE_DEMON; + pbolt.range = 7 + random2(5); + pbolt.ench_power *= 3; + pbolt.ench_power /= 2; // pbolt.is_beam = true; break; case ZAP_SLEEP: //jmf: added - pbolt.name = "0"; - pbolt.flavour = BEAM_SLEEP; - pbolt.range = 7 + random2(5); + pbolt.name = "0"; + pbolt.flavour = BEAM_SLEEP; + pbolt.range = 7 + random2(5); // pbolt.is_beam = true; break; case ZAP_BACKLIGHT: //jmf: added - pbolt.name = "0"; - pbolt.flavour = BEAM_BACKLIGHT; - pbolt.colour = BLUE; - pbolt.range = 7 + random2(5); + pbolt.name = "0"; + pbolt.flavour = BEAM_BACKLIGHT; + pbolt.colour = BLUE; + pbolt.range = 7 + random2(5); // pbolt.is_beam = true; break; case ZAP_DEBUGGING_RAY: - pbolt.name = "debugging ray"; - pbolt.colour = random_colour(); - pbolt.range = 7 + random2(10); - pbolt.damage = dice_def( 1500, 1 ); // dam: 1500 - pbolt.hit = 1500; // hit: 1500 - pbolt.type = dchar_glyph(DCHAR_FIRED_DEBUG); - pbolt.flavour = BEAM_MMISSILE; // unresistable - + pbolt.name = "debugging ray"; + pbolt.colour = random_colour(); + pbolt.range = 7 + random2(10); + pbolt.damage = dice_def( 1500, 1 ); // dam: 1500 + pbolt.hit = 1500; // hit: 1500 + pbolt.type = dchar_glyph(DCHAR_FIRED_DEBUG); + pbolt.flavour = BEAM_MMISSILE; // unresistable pbolt.obvious_effect = true; break; default: - pbolt.name = "buggy beam"; - pbolt.colour = random_colour(); - pbolt.range = 7 + random2(10); - pbolt.damage = dice_def( 1, 0 ); - pbolt.hit = 60; - pbolt.type = dchar_glyph(DCHAR_FIRED_DEBUG); - pbolt.flavour = BEAM_MMISSILE; // unresistable - + pbolt.name = "buggy beam"; + pbolt.colour = random_colour(); + pbolt.range = 7 + random2(10); + pbolt.damage = dice_def( 1, 0 ); + pbolt.hit = 60; + pbolt.type = dchar_glyph(DCHAR_FIRED_DEBUG); + pbolt.flavour = BEAM_MMISSILE; // unresistable pbolt.obvious_effect = true; break; - } // end of switch + } if ( wearing_amulet(AMU_INACCURACY) ) { @@ -1319,16 +1292,16 @@ void fire_beam( bolt &pbolt, item_def *item, bool drop_item ) if (item) { tile_beam = tileidx_item_throw(*item, - pbolt.target_x-pbolt.source_x, - pbolt.target_y-pbolt.source_y); + pbolt.target_x-pbolt.source_x, + pbolt.target_y-pbolt.source_y); } #endif #if DEBUG_DIAGNOSTICS if (pbolt.flavour != BEAM_LINE_OF_SIGHT) { - mprf( MSGCH_DIAGNOSTICS, - "%s%s%s (%d,%d) to (%d,%d): ty=%d col=%d flav=%d hit=%d dam=%dd%d range=%d", + mprf( MSGCH_DIAGNOSTICS, "%s%s%s (%d,%d) to (%d,%d): " + "ty=%d col=%d flav=%d hit=%d dam=%dd%d range=%d", (pbolt.is_beam) ? "beam" : "missile", (pbolt.is_explosion) ? "*" : (pbolt.is_big_cloud) ? "+" : "", @@ -1342,9 +1315,8 @@ void fire_beam( bolt &pbolt, item_def *item, bool drop_item ) #endif // init - pbolt.aimed_at_feet = - (pbolt.target_x == pbolt.source_x) && - (pbolt.target_y == pbolt.source_y); + pbolt.aimed_at_feet = (pbolt.target_x == pbolt.source_x + && pbolt.target_y == pbolt.source_y); pbolt.msg_generated = false; ray_def ray; @@ -1400,7 +1372,7 @@ void fire_beam( bolt &pbolt, item_def *item, bool drop_item ) // should we ever get a tracer with a wall-affecting // beam (possible I suppose), we'll quit tracing now. if (!pbolt.is_tracer) - rangeRemaining -= affect(pbolt, tx, ty); + rangeRemaining -= affect(pbolt, tx, ty, item); // if it's still a wall, quit. if (grid_is_solid(grd[tx][ty])) @@ -1413,7 +1385,7 @@ void fire_beam( bolt &pbolt, item_def *item, bool drop_item ) if (!_isBouncy(pbolt, grd[tx][ty])) { // Affect any monster that might be in the wall. - rangeRemaining -= affect(pbolt, tx, ty); + rangeRemaining -= affect(pbolt, tx, ty, item); do { @@ -1482,7 +1454,7 @@ void fire_beam( bolt &pbolt, item_def *item, bool drop_item ) } if (!pbolt.affects_nothing) - rangeRemaining -= affect(pbolt, tx, ty); + rangeRemaining -= affect(pbolt, tx, ty, item); if (random_beam) { @@ -1518,6 +1490,7 @@ void fire_beam( bolt &pbolt, item_def *item, bool drop_item ) #ifdef USE_TILE if (tile_beam == -1) tile_beam = tileidx_bolt(pbolt); + if (tile_beam != -1 && in_los_bounds(drawx, drawy) && (tx != you.x_pos || ty != you.y_pos)) { @@ -1618,13 +1591,12 @@ int mons_adjust_flavoured( monsters *monster, bolt &pbolt, { case BEAM_FIRE: case BEAM_STEAM: - hurted - = resist_adjust_damage( - monster, - pbolt.flavour, - (pbolt.flavour == BEAM_FIRE) ? monster->res_fire() - : monster->res_steam(), - hurted, true); + hurted = resist_adjust_damage( + monster, + pbolt.flavour, + (pbolt.flavour == BEAM_FIRE) ? monster->res_fire() + : monster->res_steam(), + hurted, true); if (!hurted) { @@ -1704,17 +1676,16 @@ int mons_adjust_flavoured( monsters *monster, bolt &pbolt, case BEAM_POISON: { int res = mons_res_poison(monster); - hurted = resist_adjust_damage(monster, pbolt.flavour, res, - hurted, true); + hurted = resist_adjust_damage(monster, pbolt.flavour, res, + hurted, true); if (!hurted && res > 0) { if (doFlavouredEffects) simple_monster_message( monster, " appears unharmed." ); } else if (res <= 0 && doFlavouredEffects && !one_chance_in(3)) - { poison_monster( monster, _whose_kill(pbolt) ); - } + break; } @@ -1757,8 +1728,10 @@ int mons_adjust_flavoured( monsters *monster, bolt &pbolt, pbolt.obvious_effect = true; if (YOU_KILL(pbolt.thrower)) + { did_god_conduct(DID_NECROMANCY, 2 + random2(3), pbolt.effect_known); + } if (one_chance_in(5)) { @@ -1807,7 +1780,7 @@ int mons_adjust_flavoured( monsters *monster, bolt &pbolt, if (mons_is_unholy(monster)) hurted = (hurted * 3) / 2; else if (mons_is_holy(monster) - || (is_good_god(you.religion) && is_follower(monster))) + || is_good_god(you.religion) && is_follower(monster)) { hurted = 0; } @@ -1906,8 +1879,8 @@ int mons_adjust_flavoured( monsters *monster, bolt &pbolt, } // end mons_adjust_flavoured() static bool _monster_resists_mass_enchantment(monsters *monster, - enchant_type wh_enchant, - int pow) + enchant_type wh_enchant, + int pow) { // assuming that the only mass charm is control undead: if (wh_enchant == ENCH_CHARM) @@ -1928,8 +1901,8 @@ static bool _monster_resists_mass_enchantment(monsters *monster, else if (wh_enchant == ENCH_CONFUSION || mons_holiness(monster) == MH_NATURAL) { - if (wh_enchant == ENCH_CONFUSION && - !mons_class_is_confusable(monster->type)) + if (wh_enchant == ENCH_CONFUSION + && !mons_class_is_confusable(monster->type)) { return (true); } @@ -1971,7 +1944,7 @@ bool mass_enchantment( enchant_type wh_enchant, int pow, int origin, if (pow > 200) pow = 200; - const kill_category kc = origin == MHITYOU? KC_YOU : KC_OTHER; + const kill_category kc = (origin == MHITYOU ? KC_YOU : KC_OTHER); for (i = 0; i < MAX_MONSTERS; i++) { @@ -2047,7 +2020,9 @@ int mons_ench_f2(monsters *monster, bolt &pbolt) { if (simple_monster_message(monster, " is no longer moving quickly.")) + { pbolt.obvious_effect = true; + } return (MON_AFFECTED); } @@ -2103,13 +2078,12 @@ int mons_ench_f2(monsters *monster, bolt &pbolt) { if (simple_monster_message(monster, "'s wounds heal themselves!")) + { pbolt.obvious_effect = true; + } } - else - { - if (simple_monster_message(monster, " is healed somewhat.")) - pbolt.obvious_effect = true; - } + else if (simple_monster_message(monster, " is healed somewhat.")) + pbolt.obvious_effect = true; } return (MON_AFFECTED); @@ -2121,8 +2095,8 @@ int mons_ench_f2(monsters *monster, bolt &pbolt) if (!mons_class_is_confusable(monster->type)) return (MON_UNAFFECTED); - if (monster->add_ench( - mon_enchant(ENCH_CONFUSION, 0, _whose_kill(pbolt)))) + if (monster->add_ench( mon_enchant(ENCH_CONFUSION, 0, + _whose_kill(pbolt)) )) { // put in an exception for things you won't notice becoming confused. if (simple_monster_message(monster, " appears confused.")) @@ -2283,7 +2257,10 @@ void _sticky_flame_monster( int mn, kill_category who, int levels ) return; if (monster->add_ench(mon_enchant(ENCH_STICKY_FLAME, levels, who))) + { simple_monster_message(monster, " is covered in liquid flames!"); + behaviour_event(monster, ME_WHACK, who == KC_YOU ? MHITYOU : MHITNOT); + } } /* @@ -2303,21 +2280,21 @@ void _sticky_flame_monster( int mn, kill_category who, int levels ) void fire_tracer(const monsters *monster, bolt &pbolt) { // don't fiddle with any input parameters other than tracer stuff! - pbolt.is_tracer = true; - pbolt.source_x = monster->x; // always safe to do. - pbolt.source_y = monster->y; + pbolt.is_tracer = true; + pbolt.source_x = monster->x; // always safe to do. + pbolt.source_y = monster->y; pbolt.beam_source = monster_index(monster); pbolt.can_see_invis = (mons_see_invis(monster) != 0); pbolt.smart_monster = (mons_intel(monster->type) == I_HIGH || mons_intel(monster->type) == I_NORMAL); - pbolt.attitude = mons_attitude(monster); + pbolt.attitude = mons_attitude(monster); // init tracer variables - pbolt.foe_count = pbolt.fr_count = 0; - pbolt.foe_power = pbolt.fr_power = 0; - pbolt.fr_helped = pbolt.fr_hurt = 0; - pbolt.foe_helped = pbolt.foe_hurt = 0; - pbolt.foe_ratio = 80; // default - see mons_should_fire() + pbolt.foe_count = pbolt.fr_count = 0; + pbolt.foe_power = pbolt.fr_power = 0; + pbolt.fr_helped = pbolt.fr_hurt = 0; + pbolt.foe_helped = pbolt.foe_hurt = 0; + pbolt.foe_ratio = 80; // default - see mons_should_fire() // foe ratio for summon gtr. demons & undead -- they may be // summoned, but they're hostile and would love nothing better @@ -2329,7 +2306,7 @@ void fire_tracer(const monsters *monster, bolt &pbolt) fire_beam(pbolt); // unset tracer flag (convenience) - pbolt.is_tracer = false; + pbolt.is_tracer = false; } // end tracer_f() bool check_line_of_sight( int sx, int sy, int tx, int ty ) @@ -2382,11 +2359,15 @@ static bool _isBouncy(bolt &beam, unsigned char gridtype) { if (beam.name[0] == '0') return false; + if (beam.flavour == BEAM_ELECTRICITY && gridtype != DNGN_METAL_WALL) return true; - if ( (beam.flavour == BEAM_FIRE || beam.flavour == BEAM_COLD) && - (gridtype == DNGN_GREEN_CRYSTAL_WALL) ) + + if ( (beam.flavour == BEAM_FIRE || beam.flavour == BEAM_COLD) + && gridtype == DNGN_GREEN_CRYSTAL_WALL ) + { return true; + } return (false); } @@ -2567,14 +2548,14 @@ void beam_drop_object( bolt &beam, item_def *item, int x, int y ) // for monsters without see invis firing tracers at the player. static bool _found_player(const bolt &beam, int x, int y) { - const bool needs_fuzz = - beam.is_tracer && !beam.can_see_invis && you.invisible(); + const bool needs_fuzz = (beam.is_tracer && !beam.can_see_invis + && you.invisible()); const int dist = needs_fuzz? 2 : 0; return (grid_distance(x, y, you.x_pos, you.y_pos) <= dist); } -int affect(bolt &beam, int x, int y) +int affect(bolt &beam, int x, int y, item_def *item) { // extra range used by hitting something int rangeUsed = 0; @@ -2589,9 +2570,8 @@ int affect(bolt &beam, int x, int y) return (BEAM_STOP); if (_affects_wall(beam, grd[x][y])) - { rangeUsed += _affect_wall(beam, x, y); - } + // if it's still a wall, quit - we can't do anything else to a // wall (but we still might be able to do something to any // monster inside the wall). Otherwise effects (like clouds, @@ -2603,7 +2583,7 @@ int affect(bolt &beam, int x, int y) { monsters *mon = &menv[mid]; if (_affect_mon_in_wall(beam, NULL, x, y)) - rangeUsed += _affect_monster( beam, mon ); + rangeUsed += _affect_monster( beam, mon, item ); else if (you.can_see(mon)) { mprf("The %s protects %s from harm.", @@ -2632,7 +2612,7 @@ int affect(bolt &beam, int x, int y) if (!beam.is_big_cloud && (!beam.is_explosion || beam.in_explosion_phase)) { - rangeUsed += _affect_player( beam ); + rangeUsed += _affect_player( beam, item ); } if (_beam_term_on_target(beam, x, y)) @@ -2656,7 +2636,7 @@ int affect(bolt &beam, int x, int y) if (!beam.is_big_cloud && (!beam.is_explosion || beam.in_explosion_phase)) { - rangeUsed += _affect_monster( beam, &menv[mid] ); + rangeUsed += _affect_monster( beam, &menv[mid], item ); } if (_beam_term_on_target(beam, x, y)) @@ -2678,10 +2658,10 @@ static bool _is_superhot(const bolt &beam) if (!_is_fiery(beam)) return (false); - return beam.name == "bolt of fire" - || beam.name == "bolt of magma" - || (beam.name.find("hellfire") != std::string::npos - && beam.in_explosion_phase); + return (beam.name == "bolt of fire" + || beam.name == "bolt of magma" + || beam.name.find("hellfire") != std::string::npos + && beam.in_explosion_phase); } static bool _affects_wall(const bolt &beam, int wall) @@ -2787,7 +2767,7 @@ static int _affect_wall(bolt &beam, int x, int y) int targ_grid = grd[x][y]; if ((targ_grid == DNGN_ROCK_WALL || targ_grid == DNGN_WAX_WALL - || targ_grid == DNGN_CLEAR_ROCK_WALL) + || targ_grid == DNGN_CLEAR_ROCK_WALL) && in_bounds(x, y)) { grd[ x ][ y ] = DNGN_FLOOR; @@ -2812,14 +2792,13 @@ static int _affect_wall(bolt &beam, int x, int y) if (!see_grid( x, y )) mpr("You hear a hideous screaming!", MSGCH_SOUND); else + { mpr("The statue screams as its substance crumbles away!", MSGCH_SOUND); + } } - else - { - if (see_grid(x,y)) - mpr("The statue twists and shakes as its substance crumbles away!"); - } + else if (see_grid(x,y)) + mpr("The statue twists and shakes as its substance crumbles away!"); if (targ_grid == DNGN_ORCISH_IDOL && beam.beam_source == NON_MONSTER) @@ -2848,8 +2827,10 @@ static int _affect_place_clouds(bolt &beam, int x, int y) { // polymorph randomly changes clouds in its path if (beam.flavour == BEAM_POLYMORPH) + { env.cloud[ env.cgrid[x][y] ].type = static_cast<cloud_type>(1 + random2(8)); + } // now exit (all enchantments) if (beam.name[0] == '0') @@ -2880,16 +2861,14 @@ static int _affect_place_clouds(bolt &beam, int x, int y) place_cloud( CLOUD_POISON, x, y, random2(4) + 2, _whose_kill(beam) ); // FIRE/COLD over water/lava - if ( (grd[x][y] == DNGN_LAVA && beam.flavour == BEAM_COLD) - || (grid_is_watery(grd[x][y]) && beam.flavour == BEAM_FIRE) ) + if (grd[x][y] == DNGN_LAVA && beam.flavour == BEAM_COLD + || grid_is_watery(grd[x][y]) && beam.flavour == BEAM_FIRE) { place_cloud( CLOUD_STEAM, x, y, 2 + random2(5), _whose_kill(beam) ); } if (beam.flavour == BEAM_COLD && grid_is_watery(grd[x][y])) - { place_cloud( CLOUD_COLD, x, y, 2 + random2(5), _whose_kill(beam) ); - } // GREAT BLAST OF COLD if (beam.name == "great blast of cold") @@ -2898,14 +2877,10 @@ static int _affect_place_clouds(bolt &beam, int x, int y) // BALL OF STEAM if (beam.name == "ball of steam") - { place_cloud( CLOUD_STEAM, x, y, random2(5) + 2, _whose_kill(beam) ); - } if (beam.flavour == BEAM_MIASMA) - { place_cloud( CLOUD_MIASMA, x, y, random2(5) + 2, _whose_kill(beam) ); - } // POISON GAS if (beam.name == "poison gas") @@ -2921,9 +2896,9 @@ static void _affect_place_explosion_clouds(bolt &beam, int x, int y) int duration; // first check: FIRE/COLD over water/lava - if ( (grd[x][y] == DNGN_LAVA && beam.flavour == BEAM_COLD) - || ((grd[x][y] == DNGN_DEEP_WATER || grd[x][y] == DNGN_SHALLOW_WATER) - && beam.flavour == BEAM_FIRE) ) + if ( grd[x][y] == DNGN_LAVA && beam.flavour == BEAM_COLD + || (grd[x][y] == DNGN_DEEP_WATER || grd[x][y] == DNGN_SHALLOW_WATER) + && beam.flavour == BEAM_FIRE ) { place_cloud( CLOUD_STEAM, x, y, 2 + random2(5), _whose_kill(beam) ); return; @@ -2993,9 +2968,7 @@ static void _affect_place_explosion_clouds(bolt &beam, int x, int y) // then check for more specific explosion cloud types. if (beam.name == "ice storm") - { place_cloud( CLOUD_COLD, x, y, 2 + random2avg(5, 2), _whose_kill(beam) ); - } if (beam.name == "stinking cloud") { @@ -3045,17 +3018,15 @@ static void _affect_items(bolt &beam, int x, int y) if (igrd[x][y] != NON_ITEM) { - if (objs_vulnerable != OBJ_UNASSIGNED && - mitm[igrd[x][y]].base_type == objs_vulnerable) + if (objs_vulnerable != OBJ_UNASSIGNED + && mitm[igrd[x][y]].base_type == objs_vulnerable) { item_was_destroyed(mitm[igrd[x][y]], beam.beam_source); destroy_item( igrd[ x ][ y ] ); if (objs_vulnerable == OBJ_SCROLLS && see_grid(x,y)) - { mpr("You see a puff of smoke."); - } if (objs_vulnerable == OBJ_POTIONS && !silenced(x,y) && !silenced(you.x_pos, you.y_pos)) @@ -3121,9 +3092,10 @@ static bool _fuzz_invis_tracer(bolt &beem) const int newx = beem.target_x + xfuzz, newy = beem.target_y + yfuzz; + if (in_bounds(newx, newy) - && (newx != beem.source_x - || newy != beem.source_y)) + && (newx != beem.source_x + || newy != beem.source_y)) { beem.target_x = newx; beem.target_y = newy; @@ -3157,7 +3129,7 @@ static std::string _beam_zapper(const bolt &beam) } // return amount of extra range used up by affectation of the player -static int _affect_player( bolt &beam ) +static int _affect_player( bolt &beam, item_def *item ) { // digging -- don't care. if (beam.flavour == BEAM_DIGGING) @@ -3167,8 +3139,7 @@ static int _affect_player( bolt &beam ) if (beam.is_tracer) { // check can see player - if (beam.can_see_invis || !you.invisible() - || _fuzz_invis_tracer(beam)) + if (beam.can_see_invis || !you.invisible() || _fuzz_invis_tracer(beam)) { if (beam.attitude != ATT_HOSTILE) { @@ -3233,8 +3204,8 @@ static int _affect_player( bolt &beam ) { // non-beams can be blocked or dodged if (you.equip[EQ_SHIELD] != -1 - && !beam.aimed_at_feet - && player_shield_class() > 0) + && !beam.aimed_at_feet + && player_shield_class() > 0) { int exer = one_chance_in(3) ? 1 : 0; const int hit = random2( beam.hit * 130 / 100 @@ -3260,7 +3231,9 @@ static int _affect_player( bolt &beam ) if (player_light_armour(true) && !beam.aimed_at_feet && coinflip()) + { exercise(SK_DODGING, 1); + } if (you.duration[DUR_DEFLECT_MISSILES]) beamHit = random2(beamHit / 2); @@ -3595,32 +3568,31 @@ static int _affect_player( bolt &beam ) } } - // poisoning - if (beam.name.find("poisoned") != std::string::npos - && beam.flavour != BEAM_POISON - && beam.flavour != BEAM_POISON_ARROW - && !player_res_poison()) + // handling of missiles + if (item && item->base_type == OBJ_MISSILES) { - if (hurted || (beam.ench_power == AUTOMATIC_HIT - && random2(100) < 90 - (3 * player_AC()))) + if (item->sub_type == MI_THROWING_NET) { - poison_player( 1 + random2(3) ); + player_caught_in_net(); was_affected = true; } - } - - if (beam.name.find("throwing net") != std::string::npos) - { - player_caught_in_net(); - was_affected = true; - } - - if (beam.name.find("curare") != std::string::npos) - { - if (random2(100) < 90 - (3 * player_AC())) + else if (item->special == SPMSL_POISONED) { - curare_hits_player( _beam_ouch_agent(beam), 1 + random2(3) ); - was_affected = true; + if (!player_res_poison() + && (hurted || (beam.ench_power == AUTOMATIC_HIT + && random2(100) < 90 - (3 * player_AC())))) + { + poison_player( 1 + random2(3) ); + was_affected = true; + } + } + else if (item->special == SPMSL_CURARE) + { + if (random2(100) < 90 - (3 * player_AC())) + { + curare_hits_player( _beam_ouch_agent(beam), 1 + random2(3) ); + was_affected = true; + } } } @@ -3684,9 +3656,9 @@ static int _affect_player( bolt &beam ) static int _beam_source(const bolt &beam) { - return MON_KILL(beam.thrower) ? beam.beam_source : - beam.thrower == KILL_MISC ? MHITNOT : - MHITYOU; + return (MON_KILL(beam.thrower) ? beam.beam_source : + beam.thrower == KILL_MISC ? MHITNOT + : MHITYOU); } static int _name_to_skill_level(const std::string& name) @@ -3736,7 +3708,7 @@ static void _update_hurt_or_helped(bolt &beam, monsters *mon) } // return amount of range used up by affectation of this monster -static int _affect_monster(bolt &beam, monsters *mon) +static int _affect_monster(bolt &beam, monsters *mon, item_def *item) { const int tid = mgrd[mon->x][mon->y]; const int mons_type = menv[tid].type; @@ -3776,12 +3748,13 @@ static int _affect_monster(bolt &beam, monsters *mon) if (!see_grid( mon->x, mon->y )) mpr("You hear a hideous screaming!", MSGCH_SOUND); else + { mpr("The statue screams as its substance crumbles away!", MSGCH_SOUND); + } } - else + else if (see_grid( mon->x, mon->y )) { - if (see_grid( mon->x, mon->y )) mpr("The statue twists and shakes as its substance " "crumbles away!"); } @@ -3841,7 +3814,8 @@ static int _affect_monster(bolt &beam, monsters *mon) if (mons_is_holy(mon)) did_god_conduct(DID_ATTACK_HOLY, mon->hit_dice, true, mon); - if (you.religion == GOD_BEOGH && mons_species(mon->type) == MONS_ORC + if (you.religion == GOD_BEOGH + && mons_species(mon->type) == MONS_ORC && mon->behaviour == BEH_SLEEP && !player_under_penance() && you.piety >= piety_breakpoint(2) && mons_near(mon)) { @@ -3887,6 +3861,7 @@ static int _affect_monster(bolt &beam, monsters *mon) } if (hit_woke_orc) beogh_follower_convert(mon, true); + return (rangeUsed); // END non-tracer enchantment @@ -3934,9 +3909,7 @@ static int _affect_monster(bolt &beam, monsters *mon) } if (hurt_final < 1) - { hurt_final = 0; - } const int raw_damage = hurt_final; @@ -4095,8 +4068,12 @@ static int _affect_monster(bolt &beam, monsters *mon) } } - if (beam.name.find("throwing net") != std::string::npos) + // handling of missiles + if (item && item->base_type == OBJ_MISSILES + && item->sub_type == MI_THROWING_NET) + { monster_caught_in_net(mon, beam); + } // note that hurt_final was calculated above, so we don't need it again. // just need to apply flavoured specials (since we called with @@ -4141,46 +4118,48 @@ static int _affect_monster(bolt &beam, monsters *mon) _sticky_flame_monster( tid, _whose_kill(beam), levels ); } - /* looks for missiles which aren't poison but are poison*ed* */ - if (beam.name.find("poisoned") != std::string::npos - && beam.flavour != BEAM_POISON - && beam.flavour != BEAM_POISON_ARROW) + if (item) { - int num_levels = 0; - // ench_power == AUTOMATIC_HIT if this is a poisoned needle. - if (beam.ench_power == AUTOMATIC_HIT - && random2(100) < 90 - (3 * mon->ac)) + if (item->base_type == OBJ_MISSILES + && item->special == SPMSL_POISONED) { - num_levels = 2; - } - else if (random2(hurt_final) - random2(mon->ac) > 0) - { - num_levels = 1; - } + int num_levels = 0; + // ench_power == AUTOMATIC_HIT if this is a poisoned needle. + if (beam.ench_power == AUTOMATIC_HIT + && random2(100) < 90 - (3 * mon->ac)) + { + num_levels = 2; + } + else if (random2(hurt_final) - random2(mon->ac) > 0) + { + num_levels = 1; + } - int num_success = 0; - if ( YOU_KILL(beam.thrower) ) - { - const int skill_level = _name_to_skill_level(beam.name); - if ( skill_level + 25 > random2(50) ) - num_success++; - if ( skill_level > random2(50) ) - num_success++; - } - else - num_success = 1; + int num_success = 0; + if ( YOU_KILL(beam.thrower) ) + { + const int skill_level = _name_to_skill_level(beam.name); + if ( skill_level + 25 > random2(50) ) + num_success++; + if ( skill_level > random2(50) ) + num_success++; + } + else + num_success = 1; - if ( num_success ) - { - if ( num_success == 2 ) - num_levels++; - poison_monster( mon, _whose_kill(beam), num_levels ); + if ( num_success ) + { + if ( num_success == 2 ) + num_levels++; + poison_monster( mon, _whose_kill(beam), num_levels ); + } } } bool wake_mimic = true; - if (beam.name.find("curare") != std::string::npos) + if (item && item->base_type == OBJ_MISSILES + && item->special == SPMSL_CURARE) { if (beam.ench_power == AUTOMATIC_HIT && curare_hits_monster( beam, mon, _whose_kill(beam), 2 )) @@ -4259,9 +4238,7 @@ static int _affect_monster_enchantment(bolt &beam, monsters *mon) return mons_immune_magic(mon) ? MON_UNAFFECTED : MON_RESIST; if (you.level_type == LEVEL_ABYSS) - { simple_monster_message(mon, " wobbles for a moment."); - } else _monster_die(mon, beam); @@ -4549,90 +4526,90 @@ static void _explosion1(bolt &pbolt) if (pbolt.name == "hellfire") { - seeMsg = "The hellfire explodes!"; + seeMsg = "The hellfire explodes!"; hearMsg = "You hear a strangely unpleasant explosion."; - pbolt.type = dchar_glyph(DCHAR_FIRED_BURST); + pbolt.type = dchar_glyph(DCHAR_FIRED_BURST); pbolt.flavour = BEAM_HELLFIRE; } if (pbolt.name == "golden flame") { - seeMsg = "The flame explodes!"; + seeMsg = "The flame explodes!"; hearMsg = "You feel a deep, resonant explosion."; - pbolt.type = dchar_glyph(DCHAR_FIRED_BURST); + pbolt.type = dchar_glyph(DCHAR_FIRED_BURST); pbolt.flavour = BEAM_HOLY; ex_size = 2; } if (pbolt.name == "fireball") { - seeMsg = "The fireball explodes!"; + seeMsg = "The fireball explodes!"; hearMsg = "You hear an explosion."; - pbolt.type = dchar_glyph(DCHAR_FIRED_BURST); + pbolt.type = dchar_glyph(DCHAR_FIRED_BURST); pbolt.flavour = BEAM_FIRE; ex_size = 1; } if (pbolt.name == "orb of electricity") { - seeMsg = "The orb of electricity explodes!"; + seeMsg = "The orb of electricity explodes!"; hearMsg = "You hear a clap of thunder!"; - pbolt.type = dchar_glyph(DCHAR_FIRED_BURST); - pbolt.flavour = BEAM_ELECTRICITY; - pbolt.colour = LIGHTCYAN; + pbolt.type = dchar_glyph(DCHAR_FIRED_BURST); + pbolt.flavour = BEAM_ELECTRICITY; + pbolt.colour = LIGHTCYAN; pbolt.damage.num = 1; - ex_size = 2; + ex_size = 2; } if (pbolt.name == "orb of energy") { - seeMsg = "The orb of energy explodes."; + seeMsg = "The orb of energy explodes."; hearMsg = "You hear an explosion."; } if (pbolt.name == "metal orb") { - seeMsg = "The orb explodes into a blast of deadly shrapnel!"; + seeMsg = "The orb explodes into a blast of deadly shrapnel!"; hearMsg = "You hear an explosion!"; - pbolt.name = "blast of shrapnel"; - pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); + pbolt.name = "blast of shrapnel"; + pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); pbolt.flavour = BEAM_FRAG; // sets it from pure damage to shrapnel (which is absorbed extra by armour) } if (pbolt.name == "great blast of cold") { - seeMsg = "The blast explodes into a great storm of ice!"; + seeMsg = "The blast explodes into a great storm of ice!"; hearMsg = "You hear a raging storm!"; - pbolt.name = "ice storm"; + pbolt.name = "ice storm"; pbolt.damage.num = 6; - pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); - pbolt.colour = WHITE; - ex_size = 2 + (random2( pbolt.ench_power ) > 75); + pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); + pbolt.colour = WHITE; + ex_size = 2 + (random2( pbolt.ench_power ) > 75); } if (pbolt.name == "ball of vapour") { - seeMsg = "The ball expands into a vile cloud!"; - hearMsg = "You hear a gentle \'poof\'."; + seeMsg = "The ball expands into a vile cloud!"; + hearMsg = "You hear a gentle \'poof\'."; pbolt.name = "stinking cloud"; } if (pbolt.name == "potion") { - seeMsg = "The potion explodes!"; - hearMsg = "You hear an explosion!"; + seeMsg = "The potion explodes!"; + hearMsg = "You hear an explosion!"; pbolt.name = "cloud"; } if (seeMsg == NULL) { - seeMsg = "The beam explodes into a cloud of software bugs!"; + seeMsg = "The beam explodes into a cloud of software bugs!"; hearMsg = "You hear the sound of one hand clapping!"; } @@ -4675,7 +4652,7 @@ void explosion( bolt &beam, bool hole_in_the_middle, { ray_def ray; int max_dist = grid_distance(beam.source_x, beam.source_y, - beam.target_x, beam.target_y); + beam.target_x, beam.target_y); ray.fullray_idx = -1; // to quiet valgrind find_ray( beam.source_x, beam.source_y, beam.target_x, beam.target_y, @@ -4714,14 +4691,20 @@ void explosion( bolt &beam, bool hole_in_the_middle, #if DEBUG_DIAGNOSTICS if (!is_wall && stop_at_statues) + { mpr("Explosion beam stopped by a statue or other " "non-wall solid feature.", MSGCH_DIAGNOSTICS); + } else if (is_wall && stop_at_walls) + { mpr("Explosion beam stopped by a by wall.", MSGCH_DIAGNOSTICS); + } else + { mpr("Explosion beam stopped by someting buggy.", MSGCH_DIAGNOSTICS); + } #endif break; @@ -4870,9 +4853,8 @@ static void _explosion_cell(bolt &beam, int x, int y, bool drawOnly) if (beam.flavour == BEAM_RANDOM) { random_beam = true; - beam.flavour = - static_cast<beam_type>( - random_range(BEAM_FIRE, BEAM_ACID) ); + beam.flavour = static_cast<beam_type>( + random_range(BEAM_FIRE, BEAM_ACID) ); } affect(beam, realx, realy); @@ -4921,7 +4903,7 @@ static void _explosion_map( bolt &beam, int x, int y, int count, int dir, int r ) { // 1. check to see out of range - if (x * x + y * y > r * r + r) + if (x*x + y*y > r*r + r) return; // 2. check count diff --git a/crawl-ref/source/beam.h b/crawl-ref/source/beam.h index a384ddd6d1..2712a7dfcf 100644 --- a/crawl-ref/source/beam.h +++ b/crawl-ref/source/beam.h @@ -93,7 +93,7 @@ enum zap_type ZAP_POISON_ARROW, ZAP_BREATHE_STICKY_FLAME, ZAP_BREATHE_LIGHTNING, - ZAP_PETRIFY, + ZAP_PETRIFY, ZAP_HELLFROST, NUM_ZAPS // must remain last member {dlb} }; @@ -124,7 +124,7 @@ struct bolt bool is_energy; // mostly energy/non-physical attack bool is_launched; // was fired from launcher? bool is_thrown; // was thrown from hand? - bool target_first; // targeting by direction + bool target_first; // targeting by direction bool aimed_at_spot; // aimed at (x,y), should not cross std::string aux_source; // source of KILL_MISC beams @@ -241,7 +241,7 @@ void mimic_alert( monsters *mimic ); void zapping( zap_type ztype, int power, struct bolt &pbolt ); -int affect(bolt &beam, int x, int y); +int affect(bolt &beam, int x, int y, item_def *item = NULL); void beam_drop_object( bolt &beam, item_def *item, int x, int y ); diff --git a/crawl-ref/source/command.cc b/crawl-ref/source/command.cc index fba62439ce..025ae033e4 100644 --- a/crawl-ref/source/command.cc +++ b/crawl-ref/source/command.cc @@ -490,8 +490,8 @@ void list_weapons(void) wstring = "Secondary : "; colour = MSGCOL_BLACK; - if (is_valid_item( you.inv[i]) && - (you.inv[i].base_type == OBJ_WEAPONS + if (is_valid_item( you.inv[i]) + && (you.inv[i].base_type == OBJ_WEAPONS || you.inv[i].base_type == OBJ_STAVES || you.inv[i].base_type == OBJ_MISCELLANY)) { diff --git a/crawl-ref/source/direct.cc b/crawl-ref/source/direct.cc index fb3b24718d..afe73c0522 100644 --- a/crawl-ref/source/direct.cc +++ b/crawl-ref/source/direct.cc @@ -28,7 +28,7 @@ #include <algorithm> #ifdef DOS -#include <conio.h> + #include <conio.h> #endif #include "externs.h" @@ -739,8 +739,8 @@ void direction(dist& moves, targeting_type restricts, { const monsters *montarget = &menv[you.prev_targ]; - if (!mons_near(montarget) || - !player_monster_visible( montarget )) + if (!mons_near(montarget) + || !player_monster_visible( montarget )) { mpr("You can't see that creature any more.", MSGCH_EXAMINE_FILTER); @@ -806,11 +806,9 @@ void direction(dist& moves, targeting_type restricts, moves.tx = objfind_pos[0]; moves.ty = objfind_pos[1]; } - else - { - if (!skip_iter) - flush_input_buffer(FLUSH_ON_FAILURE); - } + else if (!skip_iter) + flush_input_buffer(FLUSH_ON_FAILURE); + break; case CMD_TARGET_CYCLE_FORWARD: @@ -823,11 +821,9 @@ void direction(dist& moves, targeting_type restricts, moves.tx = monsfind_pos[0]; moves.ty = monsfind_pos[1]; } - else - { - if (!skip_iter) - flush_input_buffer(FLUSH_ON_FAILURE); - } + else if (!skip_iter) + flush_input_buffer(FLUSH_ON_FAILURE); + break; case CMD_TARGET_CANCEL: @@ -924,10 +920,10 @@ void direction(dist& moves, targeting_type restricts, // Confirm self-targeting on TARG_ENEMY. // Conceivably we might want to confirm on TARG_ANY too. - if ( moves.isTarget && - moves.tx == you.x_pos && moves.ty == you.y_pos && - mode == TARG_ENEMY && - !yesno("Really target yourself?", false, 'n')) + if ( moves.isTarget + && moves.tx == you.x_pos && moves.ty == you.y_pos + && mode == TARG_ENEMY + && !yesno("Really target yourself?", false, 'n')) { mesclr(); show_prompt = true; @@ -1436,16 +1432,14 @@ static char find_square( int xps, int yps, const int xi = temp_xps + i - ctrx; const int yj = temp_yps + j - ctry; - if (xi >= 0 && yj <= 0) + if (xi >= 0 && yj <= 0 + && abs(xi) > abs(yj + 1)) { - if (abs(xi) > abs(yj + 1)) - { - x_change = 0; - y_change = -1; - if (xi > 0) - y_change = 1; - goto finished_spiralling; - } + x_change = 0; + y_change = -1; + if (xi > 0) + y_change = 1; + goto finished_spiralling; } x_change = -1; @@ -1601,7 +1595,7 @@ void describe_floor() // water is not terribly important if you don't mind it if ((grd[you.x_pos][you.y_pos] == DNGN_DEEP_WATER - || grd[you.x_pos][you.y_pos] == DNGN_SHALLOW_WATER) + || grd[you.x_pos][you.y_pos] == DNGN_SHALLOW_WATER) && player_likes_water()) { channel = MSGCH_EXAMINE_FILTER; @@ -2076,40 +2070,46 @@ static void describe_monster(const monsters *mon) if (!mons_is_mimic(mon->type) && mons_behaviour_perceptible(mon)) { - if (mon->behaviour == BEH_SLEEP) - { - mprf(MSGCH_EXAMINE, "%s appears to be resting.", - mon->pronoun(PRONOUN_CAP).c_str()); - } - // Applies to both friendlies and hostiles - else if (mon->behaviour == BEH_FLEE) - { - mprf(MSGCH_EXAMINE, "%s is retreating.", - mon->pronoun(PRONOUN_CAP).c_str()); - } - // hostile with target != you - else if (!mons_friendly(mon) && !mons_neutral(mon) && mon->foe != MHITYOU) - { - // special case: batty monsters get set to BEH_WANDER as - // part of their special behaviour. - if (!testbits(mon->flags, MF_BATTY)) - { - mprf(MSGCH_EXAMINE, "%s doesn't appear to have noticed you.", - mon->pronoun(PRONOUN_CAP).c_str()); - } - } + if (mon->behaviour == BEH_SLEEP) + { + mprf(MSGCH_EXAMINE, "%s appears to be resting.", + mon->pronoun(PRONOUN_CAP).c_str()); + } + // Applies to both friendlies and hostiles + else if (mon->behaviour == BEH_FLEE) + { + mprf(MSGCH_EXAMINE, "%s is retreating.", + mon->pronoun(PRONOUN_CAP).c_str()); + } + // hostile with target != you + else if (!mons_friendly(mon) && !mons_neutral(mon) && mon->foe != MHITYOU) + { + // special case: batty monsters get set to BEH_WANDER as + // part of their special behaviour. + if (!testbits(mon->flags, MF_BATTY)) + { + mprf(MSGCH_EXAMINE, "%s doesn't appear to have noticed you.", + mon->pronoun(PRONOUN_CAP).c_str()); + } + } } if (mon->attitude == ATT_FRIENDLY) + { mprf(MSGCH_EXAMINE, "%s is friendly.", mon->pronoun(PRONOUN_CAP).c_str()); + } else if (mons_neutral(mon)) // don't differentiate between permanent or not + { mprf(MSGCH_EXAMINE, "%s is indifferent to you.", mon->pronoun(PRONOUN_CAP).c_str()); + } if (mon->haloed()) + { mprf(MSGCH_EXAMINE, "%s is illuminated by a halo.", mon->pronoun(PRONOUN_CAP).c_str()); + } std::string desc = ""; std::string last_desc = ""; @@ -2193,13 +2193,10 @@ static void describe_cell(int mx, int my) { int i = mgrd[mx][my]; - if (grd[mx][my] == DNGN_SHALLOW_WATER) + if (_mon_submerged_in_water(&menv[i])) { - if (!player_monster_visible(&menv[i]) && !mons_flies(&menv[i])) - { - mpr("There is a strange disturbance in the water here.", - MSGCH_EXAMINE_FILTER); - } + mpr("There is a strange disturbance in the water here.", + MSGCH_EXAMINE_FILTER); } #if DEBUG_DIAGNOSTICS @@ -2261,12 +2258,16 @@ static void describe_cell(int mx, int my) if (mitm[ targ_item ].base_type == OBJ_GOLD) mprf( MSGCH_FLOOR_ITEMS, "A pile of gold coins." ); else + { mprf( MSGCH_FLOOR_ITEMS, "You see %s here.", mitm[targ_item].name(DESC_NOCAP_A).c_str()); + } if (mitm[ targ_item ].link != NON_ITEM) + { mprf( MSGCH_FLOOR_ITEMS, "There is something else lying underneath."); + } } item_described = true; } @@ -2313,7 +2314,9 @@ static void describe_cell(int mx, int my) // already described. if ((feat == DNGN_FLOOR || feat == DNGN_FLOOR_SPECIAL) && !bloody && (monster_described || item_described || cloud_described)) + { return; + } msg_channel_type channel = MSGCH_EXAMINE; if (feat == DNGN_FLOOR @@ -2349,8 +2352,8 @@ int targeting_behaviour::get_key() if (!crawl_state.is_replaying_keys()) flush_input_buffer(FLUSH_BEFORE_COMMAND); - return unmangle_direction_keys( - getchm(KC_TARGETING), KC_TARGETING, false, false); + return unmangle_direction_keys( getchm(KC_TARGETING), KC_TARGETING, + false, false); } command_type targeting_behaviour::get_command(int key) @@ -2360,65 +2363,70 @@ command_type targeting_behaviour::get_command(int key) switch ( key ) { - case ESCAPE: case 'x': return CMD_TARGET_CANCEL; + case ESCAPE: + case 'x': return CMD_TARGET_CANCEL; #ifdef USE_TILE - case CK_MOUSE_MOVE: return CMD_TARGET_MOUSE_MOVE; + case CK_MOUSE_MOVE: return CMD_TARGET_MOUSE_MOVE; case CK_MOUSE_CLICK: return CMD_TARGET_MOUSE_SELECT; #endif #ifdef WIZARD - case 'F': return CMD_TARGET_WIZARD_MAKE_FRIENDLY; - case 's': return CMD_TARGET_WIZARD_MAKE_SHOUT; - case 'g': return CMD_TARGET_WIZARD_GIVE_ITEM; + case 'F': return CMD_TARGET_WIZARD_MAKE_FRIENDLY; + case 's': return CMD_TARGET_WIZARD_MAKE_SHOUT; + case 'g': return CMD_TARGET_WIZARD_GIVE_ITEM; #endif - case 'v': return CMD_TARGET_DESCRIBE; - case '?': return CMD_TARGET_HELP; - case ' ': return just_looking? CMD_TARGET_CANCEL : CMD_TARGET_SELECT; + case 'v': return CMD_TARGET_DESCRIBE; + case '?': return CMD_TARGET_HELP; + case ' ': return just_looking? CMD_TARGET_CANCEL : CMD_TARGET_SELECT; #ifdef WIZARD case CONTROL('C'): return CMD_TARGET_CYCLE_BEAM; #endif - case ':': return CMD_TARGET_HIDE_BEAM; + case ':': return CMD_TARGET_HIDE_BEAM; case '\r': return CMD_TARGET_SELECT; - case '.': return CMD_TARGET_SELECT; - case '5': return CMD_TARGET_SELECT; - case '!': return CMD_TARGET_SELECT_ENDPOINT; + case '.': return CMD_TARGET_SELECT; + case '5': return CMD_TARGET_SELECT; + case '!': return CMD_TARGET_SELECT_ENDPOINT; - case '\\': case '\t': return CMD_TARGET_FIND_PORTAL; - case '^': return CMD_TARGET_FIND_TRAP; - case '_': return CMD_TARGET_FIND_ALTAR; - case '<': return CMD_TARGET_FIND_UPSTAIR; - case '>': return CMD_TARGET_FIND_DOWNSTAIR; + case '\\': + case '\t': return CMD_TARGET_FIND_PORTAL; + case '^': return CMD_TARGET_FIND_TRAP; + case '_': return CMD_TARGET_FIND_ALTAR; + case '<': return CMD_TARGET_FIND_UPSTAIR; + case '>': return CMD_TARGET_FIND_DOWNSTAIR; case CONTROL('F'): return CMD_TARGET_CYCLE_TARGET_MODE; - case 'p': return CMD_TARGET_PREV_TARGET; - case 'f': return CMD_TARGET_MAYBE_PREV_TARGET; - case 't': return CMD_TARGET_MAYBE_PREV_TARGET; // f. users of the 0.3.4 keys - - case '-': return CMD_TARGET_CYCLE_BACK; - case '+': case '=': return CMD_TARGET_CYCLE_FORWARD; - case ';': case '/': return CMD_TARGET_OBJ_CYCLE_BACK; - case '*': case '\'': return CMD_TARGET_OBJ_CYCLE_FORWARD; - - case 'b': return CMD_TARGET_DOWN_LEFT; - case 'h': return CMD_TARGET_LEFT; - case 'j': return CMD_TARGET_DOWN; - case 'k': return CMD_TARGET_UP; - case 'l': return CMD_TARGET_RIGHT; - case 'n': return CMD_TARGET_DOWN_RIGHT; - case 'u': return CMD_TARGET_UP_RIGHT; - case 'y': return CMD_TARGET_UP_LEFT; - - case 'B': return CMD_TARGET_DIR_DOWN_LEFT; - case 'H': return CMD_TARGET_DIR_LEFT; - case 'J': return CMD_TARGET_DIR_DOWN; - case 'K': return CMD_TARGET_DIR_UP; - case 'L': return CMD_TARGET_DIR_RIGHT; - case 'N': return CMD_TARGET_DIR_DOWN_RIGHT; - case 'U': return CMD_TARGET_DIR_UP_RIGHT; - case 'Y': return CMD_TARGET_DIR_UP_LEFT; - - default: return CMD_NO_CMD; + case 'p': return CMD_TARGET_PREV_TARGET; + case 'f': return CMD_TARGET_MAYBE_PREV_TARGET; + case 't': return CMD_TARGET_MAYBE_PREV_TARGET; // for the 0.3.4 keys + + case '-': return CMD_TARGET_CYCLE_BACK; + case '+': + case '=': return CMD_TARGET_CYCLE_FORWARD; + case ';': + case '/': return CMD_TARGET_OBJ_CYCLE_BACK; + case '*': + case '\'': return CMD_TARGET_OBJ_CYCLE_FORWARD; + + case 'b': return CMD_TARGET_DOWN_LEFT; + case 'h': return CMD_TARGET_LEFT; + case 'j': return CMD_TARGET_DOWN; + case 'k': return CMD_TARGET_UP; + case 'l': return CMD_TARGET_RIGHT; + case 'n': return CMD_TARGET_DOWN_RIGHT; + case 'u': return CMD_TARGET_UP_RIGHT; + case 'y': return CMD_TARGET_UP_LEFT; + + case 'B': return CMD_TARGET_DIR_DOWN_LEFT; + case 'H': return CMD_TARGET_DIR_LEFT; + case 'J': return CMD_TARGET_DIR_DOWN; + case 'K': return CMD_TARGET_DIR_UP; + case 'L': return CMD_TARGET_DIR_RIGHT; + case 'N': return CMD_TARGET_DIR_DOWN_RIGHT; + case 'U': return CMD_TARGET_DIR_UP_RIGHT; + case 'Y': return CMD_TARGET_DIR_UP_LEFT; + + default: return CMD_NO_CMD; } } diff --git a/crawl-ref/source/fight.cc b/crawl-ref/source/fight.cc index 2590aa213d..ff453ddf27 100644 --- a/crawl-ref/source/fight.cc +++ b/crawl-ref/source/fight.cc @@ -891,8 +891,7 @@ bool melee_attack::player_aux_unarmed() continue; } - unarmed_attack = - (you.species == SP_KENKU) ? "peck" : "headbutt"; + unarmed_attack = (you.species == SP_KENKU) ? "peck" : "headbutt"; aux_damage = 5 + player_mutation_level(MUT_HORNS) * 3; @@ -918,9 +917,9 @@ bool melee_attack::player_aux_unarmed() if (uattack != UNAT_TAILSLAP) { // not draconian, and not wet merfolk - if ((!player_genus(GENPC_DRACONIAN) - && (!(you.species == SP_MERFOLK && player_is_swimming())) - && !player_mutation_level( MUT_STINGER )) + if (!player_genus(GENPC_DRACONIAN) + && !(you.species == SP_MERFOLK && player_is_swimming()) + && !player_mutation_level(MUT_STINGER) || (!one_chance_in(4))) { @@ -1068,13 +1067,17 @@ bool melee_attack::player_aux_unarmed() else { if (simple_miss_message) + { mprf("You miss %s.", defender->name(DESC_NOCAP_THE).c_str()); + } else + { mprf("Your %s misses %s.", miss_verb.empty()? unarmed_attack.c_str() : miss_verb.c_str(), defender->name(DESC_NOCAP_THE).c_str()); + } if (ely_block) dec_penance(GOD_ELYVILON, 1 + random2(to_hit - def->ev)); @@ -1088,20 +1091,20 @@ bool melee_attack::player_apply_aux_unarmed() { did_hit = true; - aux_damage = player_aux_stat_modify_damage(aux_damage); + aux_damage = player_aux_stat_modify_damage(aux_damage); aux_damage += slaying_bonus(PWPN_DAMAGE); - aux_damage = random2(aux_damage); + aux_damage = random2(aux_damage); // Clobber wpn_skill - wpn_skill = SK_UNARMED_COMBAT; - aux_damage = player_apply_weapon_skill(aux_damage); - aux_damage = player_apply_fighting_skill(aux_damage, true); - aux_damage = player_apply_misc_modifiers(aux_damage); + wpn_skill = SK_UNARMED_COMBAT; + aux_damage = player_apply_weapon_skill(aux_damage); + aux_damage = player_apply_fighting_skill(aux_damage, true); + aux_damage = player_apply_misc_modifiers(aux_damage); // Clear stab bonus which will be set for the primary weapon attack. - stab_bonus = 0; - aux_damage = player_apply_monster_ac(aux_damage); + stab_bonus = 0; + aux_damage = player_apply_monster_ac(aux_damage); aux_damage = hurt_monster(def, aux_damage); damage_done = aux_damage; @@ -1253,7 +1256,7 @@ int melee_attack::player_aux_stat_modify_damage(int damage) if (dam_stat_val > 11) dammod += random2(dam_stat_val - 11) / 3; - if (dam_stat_val < 9) + else if (dam_stat_val < 9) dammod -= random2(9 - dam_stat_val) / 2; damage *= dammod; @@ -1264,14 +1267,12 @@ int melee_attack::player_aux_stat_modify_damage(int damage) int melee_attack::player_apply_water_attack_bonus(int damage) { -#if 0 // Yes, this isn't the *2 damage that monsters get, but since // monster hps and player hps are different (as are the sizes // of the attacks) it just wouldn't be fair to give merfolk // that gross a potential... still they do get something for // making use of the water. -- bwr // return (damage + random2avg(10,2)); -#endif // [dshaligram] Experimenting with the full double damage bonus since // it takes real effort to set up a water attack and it's very situational. @@ -1341,6 +1342,7 @@ int melee_attack::player_apply_weapon_bonuses(int damage) #endif if (you.piety > 80 || coinflip()) damage++; + damage += random2avg( div_rand_round( @@ -1355,10 +1357,11 @@ int melee_attack::player_apply_weapon_bonuses(int damage) damage++; } + // Demonspawn get a damage bonus for demonic weapons. if (you.species == SP_DEMONSPAWN - && (weapon->sub_type == WPN_DEMON_BLADE || - weapon->sub_type == WPN_DEMON_WHIP || - weapon->sub_type == WPN_DEMON_TRIDENT)) + && (weapon->sub_type == WPN_DEMON_BLADE + || weapon->sub_type == WPN_DEMON_WHIP + || weapon->sub_type == WPN_DEMON_TRIDENT)) { damage += random2(3); } @@ -1393,14 +1396,13 @@ int melee_attack::player_stab_weapon_bonus(int damage) if (weapon->sub_type != WPN_DAGGER) bonus /= 2; - bonus = stepdown_value( bonus, 10, 10, 30, 30 ); - + bonus = stepdown_value( bonus, 10, 10, 30, 30 ); damage += bonus; } // fall through case SK_LONG_BLADES: damage *= 10 + you.skills[SK_STABBING] / - (stab_bonus + (wpn_skill == SK_SHORT_BLADES ? 0 : 1)); + (stab_bonus + (wpn_skill == SK_SHORT_BLADES ? 0 : 1)); damage /= 10; // fall through default: @@ -1758,9 +1760,11 @@ bool melee_attack::player_monattk_hit_effects(bool mondied) if (special_damage > 0) emit_nodmg_hit_message(); else + { mprf("You %s %s, but do no damage.", attack_verb.c_str(), defender->name(DESC_NOCAP_THE).c_str()); + } } if (needs_message && !special_damage_message.empty()) @@ -1844,14 +1848,12 @@ int resist_adjust_damage(actor *defender, beam_type flavour, return std::max(resistible + irresistible, 0); } -void melee_attack::calc_elemental_brand_damage( - beam_type flavour, - int res, - const char *verb) +void melee_attack::calc_elemental_brand_damage( beam_type flavour, + int res, + const char *verb) { - special_damage = - resist_adjust_damage(defender, flavour, res, - random2(damage_done) / 2 + 1); + special_damage = resist_adjust_damage(defender, flavour, res, + random2(damage_done) / 2 + 1); if (special_damage > 0 && verb && needs_message) { @@ -1887,8 +1889,8 @@ void melee_attack::drain_defender() void melee_attack::drain_player() { drain_exp(); - special_damage = - random2(damage_done) / (2 + defender->res_negative_energy()) + 1; + special_damage = random2(damage_done) / + (2 + defender->res_negative_energy()) + 1; // Noop for monsters, but what the heck. attacker->god_conduct(DID_NECROMANCY, 2); @@ -1900,12 +1902,14 @@ void melee_attack::drain_monster() return; if (defender_visible) + { special_damage_message = make_stringf( "%s %s %s!", atk_name(DESC_CAP_THE).c_str(), attacker->conj_verb("drain").c_str(), def_name(DESC_NOCAP_THE).c_str()); + } if (one_chance_in(5)) { @@ -1937,10 +1941,12 @@ bool melee_attack::distortion_affects_defender() { emit_nodmg_hit_message(); if (defender_visible) + { special_damage_message = make_stringf("%s %s in the translocular energy.", def_name(DESC_CAP_THE).c_str(), defender->conj_verb("bask").c_str()); + } defender->heal(1 + random2avg(7, 2), true); // heh heh } @@ -1950,10 +1956,12 @@ bool melee_attack::distortion_affects_defender() if (one_chance_in(3)) { if (defender_visible) + { special_damage_message = make_stringf( "Space bends around %s.", def_name(DESC_NOCAP_THE).c_str()); + } special_damage += 1 + random2avg(7, 2); return (false); } @@ -1961,11 +1969,12 @@ bool melee_attack::distortion_affects_defender() if (one_chance_in(3)) { if (defender_visible) + { special_damage_message = make_stringf( "Space warps horribly around %s!", def_name(DESC_NOCAP_THE).c_str()); - + } special_damage += 3 + random2avg(24, 2); return (false); } @@ -2008,8 +2017,8 @@ bool melee_attack::distortion_affects_defender() else if (defender_visible) obvious_effect = true; - defender->banish( atk? atk->name(DESC_PLAIN, true) - : attacker->name(DESC_PLAIN) ); + defender->banish( atk ? atk->name(DESC_PLAIN, true) + : attacker->name(DESC_PLAIN) ); return (true); } @@ -2029,8 +2038,8 @@ bool melee_attack::apply_damage_brand() { case SPWPN_FLAMING: res = fire_res_apply_cerebov_downgrade( defender->res_fire() ); - calc_elemental_brand_damage( - BEAM_FIRE, res, defender->is_icy()? "melt" : "burn"); + calc_elemental_brand_damage( BEAM_FIRE, res, + defender->is_icy()? "melt" : "burn"); defender->expose_to_element(BEAM_FIRE); break; @@ -2040,8 +2049,8 @@ bool melee_attack::apply_damage_brand() break; case SPWPN_HOLY_WRATH: - if (defender->holiness() == MH_UNDEAD || - defender->holiness() == MH_DEMONIC) + if (defender->holiness() == MH_UNDEAD + || defender->holiness() == MH_DEMONIC) { special_damage = 1 + (random2(damage_done * 15) / 10); } @@ -2077,12 +2086,14 @@ bool melee_attack::apply_damage_brand() { special_damage = 1 + random2(3*damage_done/2); if (defender_visible) + { special_damage_message = make_stringf( "%s %s%s", defender->name(DESC_CAP_THE).c_str(), defender->conj_verb("convulse").c_str(), special_attack_punctuation().c_str()); + } } break; @@ -2094,12 +2105,14 @@ bool melee_attack::apply_damage_brand() { special_damage = 1 + random2(3*damage_done/2); if (defender_visible) + { special_damage_message = make_stringf( "%s %s%s", defender->name(DESC_CAP_THE).c_str(), defender->conj_verb("convulse").c_str(), special_attack_punctuation().c_str()); + } } break; @@ -2173,8 +2186,10 @@ bool melee_attack::apply_damage_brand() attacker->name(DESC_CAP_THE).c_str()); } else + { mprf("%s is healed.", attacker->name(DESC_CAP_THE).c_str()); + } } int hp_boost = 0; @@ -2186,9 +2201,7 @@ bool melee_attack::apply_damage_brand() hp_boost = damage_done; } else - { hp_boost = 1 + random2(damage_done); - } attacker->heal(hp_boost); @@ -2203,10 +2216,12 @@ bool melee_attack::apply_damage_brand() && random2(8) <= attacker->skill(SK_NECROMANCY)) { if (defender_visible) + { special_damage_message = make_stringf("%s %s in agony.", defender->name(DESC_CAP_THE).c_str(), defender->conj_verb("writhe").c_str()); + } special_damage += random2( 1 + attacker->skill(SK_NECROMANCY) ); } attacker->god_conduct(DID_NECROMANCY, 4); @@ -2225,8 +2240,8 @@ bool melee_attack::apply_damage_brand() const int hdcheck = (defender->holiness() == MH_NATURAL? random2(30) : random2(22)); - if (mons_class_is_confusable(def->type) && - hdcheck >= defender->get_experience_level()) + if (mons_class_is_confusable(def->type) + && hdcheck >= defender->get_experience_level()) { // declaring these just to pass to the enchant function bolt beam_temp; @@ -2234,8 +2249,8 @@ bool melee_attack::apply_damage_brand() attacker->atype() == ACT_PLAYER? KILL_YOU : KILL_MON; beam_temp.flavour = BEAM_CONFUSION; beam_temp.beam_source = - attacker->atype() == ACT_PLAYER? MHITYOU - : monster_index(atk); + attacker->atype() == ACT_PLAYER ? MHITYOU + : monster_index(atk); mons_ench_f2( def, beam_temp ); } @@ -2272,7 +2287,7 @@ bool melee_attack::chop_hydra_head( int dam, return (false); if ((dam_type == DVORP_SLICING || dam_type == DVORP_CHOPPING - || dam_type == DVORP_CLAWING) + || dam_type == DVORP_CLAWING) && dam > 0 && (dam >= 4 || wpn_brand == SPWPN_VORPAL || coinflip())) { @@ -2313,10 +2328,12 @@ bool melee_attack::chop_hydra_head( int dam, else { if (defender_visible) + { mprf( "%s %s one of %s's heads off!", atk_name(DESC_CAP_THE).c_str(), attacker->conj_verb(verb).c_str(), def_name(DESC_NOCAP_THE).c_str() ); + } if (wpn_brand == SPWPN_FLAMING) { @@ -2341,8 +2358,8 @@ bool melee_attack::decapitate_hydra(int dam, int damage_type) { if (defender->id() == MONS_HYDRA) { - const int dam_type = - damage_type != -1? damage_type : attacker->damage_type(); + const int dam_type = (damage_type != -1) ? damage_type + : attacker->damage_type(); const int wpn_brand = attacker->damage_brand(); return chop_hydra_head(dam, dam_type, wpn_brand); @@ -2358,9 +2375,8 @@ void melee_attack::player_sustain_passive_damage() int melee_attack::player_staff_damage(int skill) { - return - roll_dice(3, - 1 + (you.skills[skill] + you.skills[SK_EVOCATIONS]) / 2); + return roll_dice(3, + 1 + (you.skills[skill] + you.skills[SK_EVOCATIONS]) / 2); } void melee_attack::emit_nodmg_hit_message() @@ -2399,9 +2415,11 @@ void melee_attack::player_apply_staff_damage() player_staff_damage(SK_AIR_MAGIC)); if (special_damage) + { special_damage_message = make_stringf("%s is jolted!", defender->name(DESC_CAP_THE).c_str()); + } break; @@ -2569,8 +2587,8 @@ void melee_attack::player_calc_hit_damage() int melee_attack::calc_to_hit(bool random) { - return (attacker->atype() == ACT_PLAYER? player_to_hit(random) - : mons_to_hit()); + return (attacker->atype() == ACT_PLAYER ? player_to_hit(random) + : mons_to_hit()); } int melee_attack::player_to_hit(bool random_factor) @@ -2578,13 +2596,12 @@ int melee_attack::player_to_hit(bool random_factor) heavy_armour_penalty = calc_heavy_armour_penalty(random_factor); can_do_unarmed = player_fights_well_unarmed(heavy_armour_penalty); - hand_half_bonus = - unarmed_ok - && !can_do_unarmed - && !shield - && weapon - && !item_cursed( *weapon ) - && hands == HANDS_HALF; + hand_half_bonus = unarmed_ok + && !can_do_unarmed + && !shield + && weapon + && !item_cursed( *weapon ) + && hands == HANDS_HALF; int your_to_hit = 15 + (calc_stat_to_hit_base() / 2); @@ -2681,16 +2698,20 @@ int melee_attack::player_to_hit(bool random_factor) your_to_hit += maybe_random2(3, random_factor); if (weapon && wpn_skill == SK_SHORT_BLADES && you.duration[DUR_SURE_BLADE]) + { your_to_hit += 5 + (random_factor ? random2limit( you.duration[DUR_SURE_BLADE], 10 ) : you.duration[DUR_SURE_BLADE] / 2); + } // other stuff if (!weapon) { if ( you.duration[DUR_CONFUSING_TOUCH] ) + { // just trying to touch is easier that trying to damage your_to_hit += maybe_random2(you.dex, random_factor); + } switch ( you.attribute[ATTR_TRANSFORMATION] ) { @@ -2997,11 +3018,8 @@ int melee_attack::player_calc_base_weapon_damage() { int damage = 0; - if (weapon->base_type == OBJ_WEAPONS - || item_is_staff( *weapon )) - { + if (weapon->base_type == OBJ_WEAPONS || item_is_staff( *weapon )) damage = property( *weapon, PWPN_DAMAGE ); - } // Quarterstaves can be wielded with a worn shield, but are much // less effective. @@ -3103,10 +3121,12 @@ bool melee_attack::attack_shield_blocked(bool verbose) perceived_attack = true; if (needs_message && verbose) + { mprf("%s %s %s attack.", def_name(DESC_CAP_THE).c_str(), defender->conj_verb("block").c_str(), atk_name(DESC_NOCAP_ITS).c_str()); + } defender->shield_block_succeeded(); @@ -3278,7 +3298,7 @@ std::string melee_attack::mons_weapon_desc() { int dx = abs(attacker->pos().x - defender->pos().x); int dy = abs(attacker->pos().y - defender->pos().y); - if ((dx == 2 && dy <= 2) || (dy == 2 && dx <= 2)) + if (dx == 2 && dy <= 2 || dy == 2 && dx <= 2) result += " from afar"; } result += " with "; @@ -3300,10 +3320,13 @@ std::string melee_attack::mons_defender_name() void melee_attack::mons_announce_hit(const mon_attack_def &attk) { if (water_attack && attacker_visible && attacker != defender) + { mprf("%s uses the watery terrain to its advantage.", attacker->name(DESC_CAP_THE).c_str()); + } if (needs_message) + { mprf("%s %s %s%s%s%s", atk_name(DESC_CAP_THE).c_str(), attacker->conj_verb( mons_attack_verb(attk) ).c_str(), @@ -3311,15 +3334,18 @@ void melee_attack::mons_announce_hit(const mon_attack_def &attk) debug_damage_number().c_str(), mons_weapon_desc().c_str(), attack_strength_punctuation().c_str()); + } } void melee_attack::mons_announce_dud_hit(const mon_attack_def &attk) { if (needs_message) + { mprf("%s %s %s but doesn't do any damage.", atk_name(DESC_CAP_THE).c_str(), attacker->conj_verb( mons_attack_verb(attk) ).c_str(), mons_defender_name().c_str()); + } } void melee_attack::check_defender_train_dodging() @@ -3366,14 +3392,18 @@ void melee_attack::mons_do_poison(const mon_attack_def &attk) && (attk.type == AT_BITE || attk.type == AT_STING)) { if (attacker_visible) + { mprf("%s %s was poisonous!", apostrophise(attacker->name(DESC_CAP_THE)).c_str(), mons_attack_verb(attk).c_str()); + } } else + { mprf("%s poisons %s!", atk_name(DESC_CAP_THE).c_str(), def_name(DESC_NOCAP_THE).c_str()); + } } int amount = 1; @@ -3475,11 +3505,14 @@ void melee_attack::mons_apply_attack_flavour(const mon_attack_def &attk) BEAM_FIRE, defender->res_fire(), atk->hit_dice + random2(atk->hit_dice)); + if (needs_message && special_damage) + { mprf("%s %s engulfed in flames%s", def_name(DESC_CAP_THE).c_str(), defender->conj_verb("are").c_str(), special_attack_punctuation().c_str()); + } defender->expose_to_element(BEAM_FIRE, 2); break; @@ -3490,11 +3523,14 @@ void melee_attack::mons_apply_attack_flavour(const mon_attack_def &attk) BEAM_COLD, defender->res_cold(), atk->hit_dice + random2( 2 * atk->hit_dice )); + if (needs_message && special_damage) + { mprf("%s %s %s!", atk_name(DESC_CAP_THE).c_str(), attacker->conj_verb("freeze").c_str(), def_name(DESC_NOCAP_THE).c_str()); + } break; case AF_ELEC: @@ -3509,11 +3545,13 @@ void melee_attack::mons_apply_attack_flavour(const mon_attack_def &attk) special_damage = special_damage * 2 / 3; if (needs_message && special_damage) + { mprf("%s %s %s%s", atk_name(DESC_CAP_THE).c_str(), attacker->conj_verb("shock").c_str(), def_name(DESC_NOCAP_THE).c_str(), special_attack_punctuation().c_str()); + } #ifdef DEBUG_DIAGNOSTICS mprf(MSGCH_DIAGNOSTICS, "Shock damage: %d", special_damage); @@ -3584,8 +3622,10 @@ void melee_attack::mons_apply_attack_flavour(const mon_attack_def &attk) if (one_chance_in(3)) { if (attacker_visible) + { mprf("%s %s!", attacker->name(DESC_CAP_THE).c_str(), attacker->conj_verb("blink").c_str()); + } attacker->blink(); } break; @@ -3600,9 +3640,11 @@ void melee_attack::mons_apply_attack_flavour(const mon_attack_def &attk) atk->hit_points = -1; if (defender_visible) + { mprf("%s %s engulfed in a cloud of spores!", defender->name(DESC_CAP_THE).c_str(), defender->conj_verb("are").c_str()); + } } if (one_chance_in(10) @@ -3645,10 +3687,12 @@ void melee_attack::mons_apply_attack_flavour(const mon_attack_def &attk) break; if (needs_message) + { mprf("%s %s %s!", atk_name(DESC_CAP_THE).c_str(), attacker->conj_verb("infuriate").c_str(), def_name(DESC_NOCAP_THE).c_str()); + } defender->go_berserk(false); break; @@ -3728,9 +3772,11 @@ void melee_attack::mons_perform_attack_rounds() perceived_attack = perceived_attack || attacker_visible; if (needs_message) + { mprf("%s misses %s.", atk_name(DESC_CAP_THE).c_str(), mons_defender_name().c_str()); + } } } @@ -3867,9 +3913,9 @@ int melee_attack::mons_to_hit() static void wielded_weapon_check(const item_def *weapon) { - if (you.received_weapon_warning == false && - weapon && weapon->base_type != OBJ_STAVES && - (weapon->base_type != OBJ_WEAPONS || is_range_weapon(*weapon))) + if (you.received_weapon_warning == false + && weapon && weapon->base_type != OBJ_STAVES + && (weapon->base_type != OBJ_WEAPONS || is_range_weapon(*weapon))) { mpr("You might want to wield a more suitable implement when " "attacking monsters.", MSGCH_WARN); @@ -3969,8 +4015,8 @@ int weapon_str_weight( object_class_type wpn_class, int wpn_type ) { int ret; - const int wpn_skill = weapon_skill( wpn_class, wpn_type ); - const int hands = hands_reqd( wpn_class, wpn_type, player_size() ); + const int wpn_skill = weapon_skill( wpn_class, wpn_type ); + const int hands = hands_reqd( wpn_class, wpn_type, player_size() ); // These are low values, because we'll be adding some bonus to the // larger weapons later. Remember also that 1-1/2-hand weapons get @@ -4041,8 +4087,8 @@ static inline int player_weapon_str_weight( void ) int ret = weapon_str_weight( you.inv[weapon].base_type, you.inv[weapon].sub_type ); - const bool shield = (you.equip[EQ_SHIELD] != -1); - const int hands = hands_reqd(you.inv[weapon], player_size()); + const bool shield = (you.equip[EQ_SHIELD] != -1); + const int hands = hands_reqd(you.inv[weapon], player_size()); if (hands == HANDS_HALF && !shield) ret += 1; diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc index 5ff798e908..1902d96dbe 100644 --- a/crawl-ref/source/mon-util.cc +++ b/crawl-ref/source/mon-util.cc @@ -3919,8 +3919,10 @@ void monsters::rot(actor *agent, int rotlevel, int immed_rot) } if (rotlevel > 0) + { add_ench( mon_enchant(ENCH_ROT, std::min(rotlevel, 4), agent->kill_alignment()) ); + } } void monsters::confuse(int strength) diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index 6b0918123f..87edb41f96 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -1971,11 +1971,11 @@ static bool _wounded_damaged(int monster_type) void behaviour_event( monsters *mon, int event, int src, int src_x, int src_y ) { - bool isSmart = (mons_intel(mon->type) > I_ANIMAL); - bool isFriendly = mons_friendly(mon); + bool isSmart = (mons_intel(mon->type) > I_ANIMAL); + bool isFriendly = mons_friendly(mon); bool sourceFriendly = false; - bool setTarget = false; - bool breakCharm = false; + bool setTarget = false; + bool breakCharm = false; if (src == MHITYOU) sourceFriendly = true; @@ -2023,7 +2023,7 @@ void behaviour_event( monsters *mon, int event, int src, if (src == MHITYOU) { mon->attitude = ATT_HOSTILE; - breakCharm = true; + breakCharm = true; } } |