summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/ghost.cc
diff options
context:
space:
mode:
Diffstat (limited to 'crawl-ref/source/ghost.cc')
-rw-r--r--crawl-ref/source/ghost.cc196
1 files changed, 196 insertions, 0 deletions
diff --git a/crawl-ref/source/ghost.cc b/crawl-ref/source/ghost.cc
index 52fd438f26..8197b89c21 100644
--- a/crawl-ref/source/ghost.cc
+++ b/crawl-ref/source/ghost.cc
@@ -24,6 +24,7 @@ REVISION("$Rev$");
#include "place.h"
#include "player.h"
#include "religion.h"
+#include "view.h"
#include <vector>
#define MAX_GHOST_DAMAGE 50
@@ -138,9 +139,12 @@ void ghost_demon::reset()
speed = 10;
see_invis = false;
brand = SPWPN_NORMAL;
+ att_type = AT_HIT;
+ att_flav = AF_PLAIN;
resists = mon_resist_def();
spellcaster = false;
cycle_colours = false;
+ colour = BLACK;
fly = FL_NONE;
}
@@ -219,6 +223,8 @@ void ghost_demon::init_random_demon()
// Does demon cycle colours?
cycle_colours = one_chance_in(10);
+ colour = random_colour();
+
spells.init(SPELL_NO_SPELL);
// This bit uses the list of player spells to find appropriate
@@ -387,11 +393,201 @@ void ghost_demon::init_player_ghost()
best_skill_level = you.skills[best_skill];
xl = you.experience_level;
+ colour = mons_class_colour(MONS_PLAYER_GHOST);
fly = mons_class_flies(MONS_PLAYER_GHOST);
add_spells();
}
+static unsigned char _ugly_thing_random_colour()
+{
+ const unsigned char colours[] =
+ {
+ CYAN, GREEN, RED, LIGHTGREY, BROWN, MAGENTA
+ };
+
+ return (colours[random2(sizeof(colours) / sizeof(*colours))]);
+}
+
+static mon_attack_flavour _ugly_thing_colour_to_flavour(unsigned char u_colour)
+{
+ mon_attack_flavour u_att_flav = AF_PLAIN;
+
+ switch (u_colour)
+ {
+ case CYAN:
+ u_att_flav = AF_ELEC;
+ break;
+
+ case GREEN:
+ u_att_flav = AF_POISON;
+ break;
+
+ case RED:
+ u_att_flav = AF_FIRE;
+ break;
+
+ case LIGHTGREY:
+ u_att_flav = AF_COLD;
+ break;
+
+ case BROWN:
+ u_att_flav = AF_ACID;
+ break;
+
+ case MAGENTA:
+ u_att_flav = AF_DISEASE;
+ break;
+
+ default:
+ break;
+ }
+
+ return (u_att_flav);
+}
+
+static mon_attack_flavour _ugly_thing_flavour_upgrade(mon_attack_flavour u_att_flav)
+{
+ switch (u_att_flav)
+ {
+ case AF_POISON:
+ u_att_flav = AF_POISON_MEDIUM;
+ break;
+
+ case AF_FIRE:
+ u_att_flav = AF_NAPALM;
+ break;
+
+ case AF_DISEASE:
+ u_att_flav = AF_ROT;
+ break;
+
+ default:
+ break;
+ }
+
+ return (u_att_flav);
+}
+
+void ghost_demon::init_ugly_thing(bool very_ugly)
+{
+ // Midpoint: 10, as in mon-data.h.
+ speed = 9 + random2(3);
+
+ // Midpoint: 10, as in mon-data.h.
+ ev = 9 + random2(3);
+
+ // Midpoint: 3, as in mon-data.h.
+ ac = 2 + random2(3);
+
+ // Midpoint: 12, as in mon-data.h.
+ damage = 11 + random2(3);
+
+ // Experience level: 8, the same as in mon-data.h.
+ xl = 8;
+
+ // Hit dice: {8, 3, 5, 0}, the same as in mon-data.h.
+ max_hp = hit_points(xl, 3, 5);
+
+ resists.elec = 0;
+ resists.poison = 0;
+ resists.fire = 0;
+ resists.cold = 0;
+ resists.acid = 0;
+ resists.sticky_flame = false;
+
+ // An ugly thing gets one random resistance.
+ ugly_thing_add_resistance();
+
+ const mon_attack_type att_types[] =
+ {
+ AT_BITE, AT_STING, AT_CLAW, AT_PUNCH, AT_KICK, AT_TENTACLE_SLAP,
+ AT_TAIL_SLAP, AT_BUTT
+ };
+
+ att_type = att_types[random2(sizeof(att_types) / sizeof(*att_types))];
+
+ // An ugly thing always gets a low-intensity colour.
+ colour = _ugly_thing_random_colour();
+
+ // Pick a compatible attack flavour for this colour.
+ att_flav = _ugly_thing_colour_to_flavour(colour);
+
+ // If this is a very ugly thing, upgrade it properly.
+ if (very_ugly)
+ ugly_thing_to_very_ugly_thing();
+}
+
+void ghost_demon::ugly_thing_to_very_ugly_thing()
+{
+ // Midpoint when added to an ugly thing: 4, as in mon-data.h.
+ ac++;
+
+ // Midpoint when added to an ugly thing: 17, as in mon-data.h.
+ damage += 5;
+
+ // Experience level when added to an ugly thing: 12, the same as in
+ // mon-data.h.
+ xl += 4;
+
+ // Hit dice when added to an ugly thing: {12, 3, 5, 0}, the same as
+ // in mon-data.h.
+ max_hp += hit_points(4, 3, 5);
+
+ // A very ugly thing always gets a high-intensity colour.
+ colour = make_high_colour(colour);
+
+ // A very ugly thing sometimes gets a stronger attack flavour.
+ if (one_chance_in(3))
+ att_flav = _ugly_thing_flavour_upgrade(att_flav);
+
+ // A very ugly thing gets one more random resistance, and another
+ // possible resistance based on its stronger attack flavour.
+ ugly_thing_add_resistance();
+}
+
+void ghost_demon::ugly_thing_add_resistance()
+{
+ int base_rand = 6;
+ if (resists.sticky_flame)
+ base_rand--;
+
+ switch (random2(base_rand))
+ {
+ case 0:
+ resists.elec++;
+ break;
+
+ case 1:
+ resists.poison++;
+ break;
+
+ case 2:
+ resists.fire++;
+ break;
+
+ case 3:
+ resists.cold++;
+ break;
+
+ case 4:
+ resists.acid++;
+ break;
+
+ case 5:
+ resists.sticky_flame = true;
+ break;
+ }
+
+ // Guarantee certain resistances for stronger attack flavours.
+ if (att_flav == AF_POISON_MEDIUM && !resists.poison)
+ resists.poison++;
+ else if (att_flav == AF_ACID && !resists.acid)
+ resists.acid++;
+ else if (att_flav == AF_NAPALM && !resists.sticky_flame)
+ resists.sticky_flame = true;
+}
+
static spell_type search_first_list(int ignore_spell)
{
for (unsigned i = 0;