3 * Summary: Player ghost and random Pandemonium demon handling.
5 * Created for Dungeon Crawl Reference by dshaligram on
6 * Thu Mar 15 20:10:20 2007 UTC.
26 #include "mon-transit.h"
32 #define MAX_GHOST_DAMAGE 50
33 #define MAX_GHOST_HP 400
34 #define MAX_GHOST_EVASION 60
35 #define MIN_GHOST_SPEED 6
36 #define MAX_GHOST_SPEED 13
38 std::vector
<ghost_demon
> ghosts
;
40 // Order for looking for conjurations for the 1st & 2nd spell slots,
41 // when finding spells to be remembered by a player's ghost.
42 static spell_type search_order_conj
[] = {
43 SPELL_LEHUDIBS_CRYSTAL_SPEAR
,
46 SPELL_CHAIN_LIGHTNING
,
47 SPELL_BOLT_OF_DRAINING
,
53 SPELL_ISKENDERUNS_MYSTIC_BLAST
,
60 SPELL_DELAYED_FIREBALL
,
74 SPELL_NO_SPELL
, // end search
77 // Order for looking for summonings and self-enchants for the 3rd spell
79 static spell_type search_order_third
[] = {
80 SPELL_SYMBOL_OF_TORMENT
,
81 SPELL_SUMMON_GREATER_DEMON
,
82 SPELL_SUMMON_HORRIBLE_THINGS
,
84 SPELL_TUKIMAS_DANCE_PARTY
,
91 SPELL_SUMMON_BUTTERFLIES
,
92 SPELL_SUMMON_ELEMENTAL
,
94 SPELL_SUMMON_UGLY_THING
,
96 SPELL_SUMMON_ICE_BEAST
,
99 SPELL_SUMMON_SCORPIONS
,
101 SPELL_SUMMON_SMALL_MAMMALS
,
102 SPELL_MALIGN_GATEWAY
,
103 SPELL_CONTROLLED_BLINK
,
105 SPELL_NO_SPELL
, // end search
108 // Order for looking for enchants for the 4th & 5th spell slots. If
109 // this fails, go through conjurations. Note: Dig must be in misc2
110 // (5th) position to work.
111 static spell_type search_order_misc
[] = {
114 SPELL_FREEZING_CLOUD
,
118 SPELL_MEPHITIC_CLOUD
,
120 SPELL_POLYMORPH_OTHER
,
121 SPELL_TELEPORT_OTHER
,
122 SPELL_EVAPORATE
, // replaced with Mephitic Cloud, though at lower priority
125 SPELL_NO_SPELL
, // end search
128 // Last slot (emergency) can only be Teleport Self or Blink.
130 ghost_demon::ghost_demon()
135 void ghost_demon::reset()
138 species
= SP_UNKNOWN
;
140 religion
= GOD_NO_GOD
;
141 best_skill
= SK_FIGHTING
;
142 best_skill_level
= 0;
150 brand
= SPWPN_NORMAL
;
153 resists
= mon_resist_def();
155 cycle_colours
= false;
160 void ghost_demon::init_random_demon()
162 name
= make_name(random_int(), false);
164 // hp - could be defined below (as could ev, AC, etc.). Oh well, too late:
165 max_hp
= 100 + roll_dice(3, 50);
167 ev
= 5 + random2(20);
168 ac
= 5 + random2(20);
170 see_invis
= !one_chance_in(10);
172 if (!one_chance_in(3))
173 resists
.fire
= random_range(1, 2);
176 resists
.fire
= 0; // res_fire
178 if (one_chance_in(10))
182 if (!one_chance_in(3))
183 resists
.cold
= random_range(1, 2);
187 if (one_chance_in(10))
191 // Demons, like ghosts, automatically get poison res. and life prot.
193 // resist electricity:
194 resists
.elec
= one_chance_in(3);
197 damage
= 20 + roll_dice(2, 20);
199 // special attack type (uses weapon brand code):
200 brand
= SPWPN_NORMAL
;
202 if (!one_chance_in(3))
206 brand
= static_cast<brand_type
>(random2(MAX_PAN_LORD_BRANDS
));
207 // some brands inappropriate (e.g. holy wrath)
209 while (brand
== SPWPN_HOLY_WRATH
210 || (brand
== SPWPN_ORC_SLAYING
211 && mons_genus(you
.mons_species()) != MONS_ORC
)
212 || (brand
== SPWPN_DRAGON_SLAYING
213 && mons_genus(you
.mons_species()) != MONS_DRACONIAN
)
214 || brand
== SPWPN_PROTECTION
215 || brand
== SPWPN_FLAME
216 || brand
== SPWPN_FROST
);
219 // Is demon a spellcaster?
220 // Upped from one_chance_in(3)... spellcasters are more interesting
221 // and I expect named demons to typically have a trick or two. - bwr
222 spellcaster
= !one_chance_in(10);
225 fly
= (one_chance_in(3) ? FL_NONE
:
226 one_chance_in(5) ? FL_LEVITATE
230 xl
= 10 + roll_dice(2, 10);
232 // Does demon cycle colours?
233 cycle_colours
= one_chance_in(10);
235 colour
= random_colour();
237 spells
.init(SPELL_NO_SPELL
);
239 // This bit uses the list of player spells to find appropriate
240 // spells for the demon, then converts those spells to the monster
241 // spell indices. Some special monster-only spells are at the end.
245 spells
[0] = RANDOM_ELEMENT(search_order_conj
);
247 // Might duplicate the first spell, but that isn't a problem.
249 spells
[1] = RANDOM_ELEMENT(search_order_conj
);
251 if (!one_chance_in(4))
252 spells
[2] = RANDOM_ELEMENT(search_order_third
);
256 spells
[3] = RANDOM_ELEMENT(search_order_misc
);
257 if (spells
[3] == SPELL_DIG
)
258 spells
[3] = SPELL_NO_SPELL
;
262 spells
[4] = RANDOM_ELEMENT(search_order_misc
);
265 spells
[5] = SPELL_BLINK
;
267 spells
[5] = SPELL_TELEPORT_SELF
;
269 // Convert the player spell indices to monster spell ones.
270 for (int i
= 0; i
< NUM_MONSTER_SPELL_SLOTS
; ++i
)
271 spells
[i
] = translate_spell(spells
[i
]);
273 // Give demon a chance for some monster-only spells.
274 // Demon-summoning should be fairly common.
275 if (one_chance_in(25))
276 spells
[0] = SPELL_HELLFIRE_BURST
;
277 if (one_chance_in(25))
278 spells
[0] = SPELL_FIRE_STORM
;
279 if (one_chance_in(25))
280 spells
[0] = SPELL_ICE_STORM
;
281 if (one_chance_in(25))
282 spells
[0] = SPELL_METAL_SPLINTERS
;
283 if (one_chance_in(25))
284 spells
[0] = SPELL_ENERGY_BOLT
; // eye of devastation
286 if (one_chance_in(25))
287 spells
[1] = SPELL_STEAM_BALL
;
288 if (one_chance_in(25))
289 spells
[1] = SPELL_ISKENDERUNS_MYSTIC_BLAST
;
290 if (one_chance_in(25))
291 spells
[1] = SPELL_HELLFIRE
;
292 if (one_chance_in(25))
293 spells
[1] = SPELL_IOOD
;
295 if (one_chance_in(25))
296 spells
[2] = SPELL_SMITING
;
297 if (one_chance_in(25))
298 spells
[2] = SPELL_HELLFIRE_BURST
;
299 if (one_chance_in(22))
300 spells
[2] = SPELL_SUMMON_HYDRA
;
301 if (one_chance_in(20))
302 spells
[2] = SPELL_SUMMON_DRAGON
;
303 if (one_chance_in(12))
304 spells
[2] = SPELL_SUMMON_GREATER_DEMON
;
305 if (one_chance_in(12))
306 spells
[2] = SPELL_SUMMON_DEMON
;
307 if (one_chance_in(10))
308 spells
[2] = SPELL_SUMMON_EYEBALLS
;
310 if (one_chance_in(20))
311 spells
[3] = SPELL_SUMMON_GREATER_DEMON
;
312 if (one_chance_in(20))
313 spells
[3] = SPELL_SUMMON_DEMON
;
314 if (one_chance_in(20))
315 spells
[3] = SPELL_MALIGN_GATEWAY
;
317 // At least they can summon demons.
318 if (spells
[3] == SPELL_NO_SPELL
)
319 spells
[3] = SPELL_SUMMON_DEMON
;
321 if (one_chance_in(15))
322 spells
[4] = SPELL_DIG
;
326 // Returns the movement speed for a player ghost. Note that this is a
327 // real speed, not a movement cost, so higher is better.
328 static int _player_ghost_base_movement_speed()
332 if (player_mutation_level(MUT_FAST
))
333 speed
+= player_mutation_level(MUT_FAST
) + 1;
334 if (player_mutation_level(MUT_SLOW
))
335 speed
-= player_mutation_level(MUT_SLOW
) + 1;
337 if (player_equip_ego_type(EQ_BOOTS
, SPARM_RUNNING
))
341 if (speed
< MIN_GHOST_SPEED
)
342 speed
= MIN_GHOST_SPEED
;
343 else if (speed
> MAX_GHOST_SPEED
)
344 speed
= MAX_GHOST_SPEED
;
349 void ghost_demon::init_player_ghost()
351 name
= you
.your_name
;
352 max_hp
= ((get_real_hp(false) >= MAX_GHOST_HP
)
354 : get_real_hp(false));
355 ev
= player_evasion();
356 ac
= you
.armour_class();
358 if (ev
> MAX_GHOST_EVASION
)
359 ev
= MAX_GHOST_EVASION
;
361 see_invis
= you
.can_see_invisible();
362 resists
.fire
= player_res_fire();
363 resists
.cold
= player_res_cold();
364 resists
.elec
= player_res_electricity();
365 speed
= _player_ghost_base_movement_speed();
368 brand
= SPWPN_NORMAL
;
372 // This includes ranged weapons, but they're treated as melee.
374 const item_def
& weapon
= *you
.weapon();
375 if (weapon
.base_type
== OBJ_WEAPONS
|| weapon
.base_type
== OBJ_STAVES
)
377 damage
= property(weapon
, PWPN_DAMAGE
);
379 damage
*= 25 + you
.skills
[weapon_skill(weapon
)];
382 if (weapon
.base_type
== OBJ_WEAPONS
)
384 brand
= static_cast<brand_type
>(get_weapon_brand(weapon
));
386 // Ghosts can't get holy wrath, but they get to keep
388 if (brand
== SPWPN_HOLY_WRATH
)
389 brand
= SPWPN_NORMAL
;
391 // Don't copy ranged-only brands from launchers (reaping etc.).
392 if (brand
> MAX_PAN_LORD_BRANDS
)
393 brand
= SPWPN_NORMAL
;
400 if (you
.innate_mutations
[MUT_CLAWS
])
401 damage
+= you
.experience_level
;
403 damage
+= you
.skills
[SK_UNARMED_COMBAT
];
406 damage
*= 30 + you
.skills
[SK_FIGHTING
];
409 damage
+= you
.strength() / 4;
411 if (damage
> MAX_GHOST_DAMAGE
)
412 damage
= MAX_GHOST_DAMAGE
;
414 species
= you
.species
;
415 job
= you
.char_class
;
417 // Ghosts can't worship good gods.
418 if (!is_good_god(you
.religion
))
419 religion
= you
.religion
;
421 best_skill
= ::best_skill(SK_FIRST_SKILL
, SK_LAST_SKILL
);
422 best_skill_level
= you
.skills
[best_skill
];
423 xl
= you
.experience_level
;
425 // These are the same as in mon-data.h.
432 static uint8_t _ugly_thing_assign_colour(uint8_t force_colour
,
433 uint8_t force_not_colour
)
437 if (force_colour
!= BLACK
)
438 colour
= force_colour
;
442 colour
= ugly_thing_random_colour();
443 while (force_not_colour
!= BLACK
&& colour
== force_not_colour
);
449 static mon_attack_flavour
_very_ugly_thing_flavour_upgrade(mon_attack_flavour u_att_flav
)
454 u_att_flav
= AF_NAPALM
;
457 case AF_POISON_NASTY
:
458 u_att_flav
= AF_POISON_MEDIUM
;
472 mon_attack_flavour
ugly_thing_colour_to_flavour(uint8_t u_colour
)
474 mon_attack_flavour u_att_flav
= AF_PLAIN
;
476 switch (make_low_colour(u_colour
))
479 u_att_flav
= AF_FIRE
;
483 u_att_flav
= AF_ACID
;
487 u_att_flav
= AF_POISON_NASTY
;
491 u_att_flav
= AF_ELEC
;
495 u_att_flav
= AF_DISEASE
;
499 u_att_flav
= AF_COLD
;
506 if (is_high_colour(u_colour
))
507 u_att_flav
= _very_ugly_thing_flavour_upgrade(u_att_flav
);
512 void ghost_demon::init_ugly_thing(bool very_ugly
, bool only_mutate
,
513 uint8_t force_colour
)
515 // Movement speed: 11, the same as in mon-data.h.
518 // Midpoint: 10, as in mon-data.h.
521 // Midpoint: 3, as in mon-data.h.
524 // Midpoint: 12, as in mon-data.h.
525 damage
= 11 + random2(3);
527 // If we're mutating an ugly thing, leave its experience level, hit
528 // dice and maximum hit points as they are.
531 // Experience level: 8, the same as in mon-data.h.
534 // Hit dice: {8, 3, 5, 0}, the same as in mon-data.h.
535 max_hp
= hit_points(xl
, 3, 5);
538 const mon_attack_type att_types
[] =
540 AT_BITE
, AT_STING
, AT_ENGULF
, AT_CLAW
, AT_PECK
, AT_HEADBUTT
, AT_PUNCH
,
541 AT_KICK
, AT_TENTACLE_SLAP
, AT_TAIL_SLAP
, AT_GORE
, AT_TRUNK_SLAP
544 att_type
= RANDOM_ELEMENT(att_types
);
546 // An ugly thing always gets a low-intensity colour. If we're
547 // mutating it, it always gets a different colour from what it had
549 colour
= _ugly_thing_assign_colour(make_low_colour(force_colour
),
550 only_mutate
? make_low_colour(colour
)
553 // Pick a compatible attack flavour for this colour.
554 att_flav
= ugly_thing_colour_to_flavour(colour
);
556 // Pick a compatible resistance for this attack flavour.
557 ugly_thing_add_resistance(false, att_flav
);
559 // If this is a very ugly thing, upgrade it properly.
561 ugly_thing_to_very_ugly_thing();
564 void ghost_demon::ugly_thing_to_very_ugly_thing()
566 // Midpoint when added to an ugly thing: 4, as in mon-data.h.
569 // Midpoint when added to an ugly thing: 17, as in mon-data.h.
572 // Experience level when added to an ugly thing: 12, the same as in
576 // Hit dice when added to an ugly thing: {12, 3, 5, 0}, the same as
578 max_hp
+= hit_points(4, 3, 5);
580 // A very ugly thing always gets a high-intensity colour.
581 colour
= make_high_colour(colour
);
583 // A very ugly thing sometimes gets an upgraded attack flavour.
584 att_flav
= _very_ugly_thing_flavour_upgrade(att_flav
);
586 // Pick a compatible resistance for this attack flavour.
587 ugly_thing_add_resistance(true, att_flav
);
590 mon_resist_def
ugly_thing_resists(bool very_ugly
, mon_attack_flavour u_att_flav
)
592 mon_resist_def resists
;
596 resists
.sticky_flame
= false;
599 resists
.rotting
= false;
605 resists
.fire
= (very_ugly
? 2 : 1);
606 resists
.sticky_flame
= true;
610 resists
.acid
= (very_ugly
? 2 : 1);
613 case AF_POISON_NASTY
:
614 case AF_POISON_MEDIUM
:
615 resists
.poison
= (very_ugly
? 2 : 1);
619 resists
.elec
= (very_ugly
? 2 : 1);
624 resists
.rotting
= true;
628 resists
.cold
= (very_ugly
? 2 : 1);
637 void ghost_demon::ugly_thing_add_resistance(bool very_ugly
,
638 mon_attack_flavour u_att_flav
)
640 resists
= ::ugly_thing_resists(very_ugly
, u_att_flav
);
643 void ghost_demon::init_dancing_weapon(const item_def
& weapon
, int power
)
645 int mass
= item_mass(weapon
);
646 int delay
= property(weapon
, PWPN_SPEED
);
647 int damg
= property(weapon
, PWPN_DAMAGE
);
652 colour
= weapon
.colour
;
655 // We want Tukima to reward characters who invest heavily in both
656 // carrying capacity and enchantments skill. Therefore, heavy
657 // weapons are a bit stronger when animated, and benefit much more
658 // from very high skill.
660 // First set up what the monsters will look like at very high skill.
661 // Daggers are weak here! In the table, "44+22" means d44+d22 with
662 // d22 being base damage and d44 coming from power.
664 // Giant spiked club: speed 12, 44+22 damage, 35 AC, 70 HP, 16 EV
665 // Bardiche: speed 10, 40+20 damage, 20 AC, 40 HP, 15 EV
666 // Katana: speed 17, 26+13 damage, 16 AC, 32 HP, 18 EV
667 // Dagger: speed 20, 8+ 4 damage, 2 AC, 4 HP, 20 EV
668 // Quick blade: speed 23, 10+ 5 damage, 5 AC, 10 HP, 22 EV
669 // Sabre: speed 18, 14+ 7 damage, 9 AC, 18 HP, 19 EV
679 // If you aren't an awesome spellcaster, nerf the weapons. Do it in
680 // a way that lays most of the penalty on heavy weapons.
682 speed
= std::max(3, speed
- (10 - power
/ 15));
683 ev
= std::max(3, ev
- (10 - power
/ 15));
685 ac
= ac
* power
/ 200;
686 max_hp
= std::max(5, max_hp
* power
/ 150);
687 damage
= std::max(1, damage
* power
/ 150);
689 // For a spellpower 75 character (typical late midgame mage with no Ench
692 // Giant spiked club: speed 7, 22+22 damage, 17 AC, 35 HP, 11 EV
693 // Bardiche: speed 5, 20+20 damage, 10 AC, 20 HP, 10 EV
694 // Katana: speed 12, 13+13 damage, 8 AC, 16 HP, 13 EV
695 // Dagger: speed 15, 4+4 damage, 1 AC, 5 HP, 15 EV
696 // Quick blade: speed 18, 5+5 damage, 2 AC, 5 HP, 17 EV
697 // Sabre: speed 13, 7+7 damage, 4 AC, 9 HP, 14 EV
699 // At spellpower 37 (early game character with focus on Ench):
701 // Giant spiked club: speed 5, 11+22 damage, 8 AC, 17 HP, 9 EV
702 // Bardiche: speed 3, 10+20 damage, 5 AC, 10 HP, 8 EV
703 // Katana: speed 10, 6+13 damage, 4 AC, 8 HP, 11 EV
704 // Dagger: speed 13, 2+4 damage, 0 AC, 5 HP, 13 EV
705 // Quick blade: speed 16, 2+5 damage, 1 AC, 5 HP, 15 EV
706 // Sabre: speed 11, 3+7 damage, 2 AC, 5 HP, 12 EV
709 static bool _know_spell(spell_type spell
)
711 return (you
.has_spell(spell
) && spell_fail(spell
) < 50);
714 static spell_type
search_first_list(int ignore_spell
)
717 i
< sizeof(search_order_conj
) / sizeof(*search_order_conj
); ++i
)
719 if (search_order_conj
[i
] == SPELL_NO_SPELL
)
720 return (SPELL_NO_SPELL
);
722 if (search_order_conj
[i
] == ignore_spell
)
725 if (_know_spell(search_order_conj
[i
]))
726 return (search_order_conj
[i
]);
729 return (SPELL_NO_SPELL
);
732 static spell_type
search_second_list(int ignore_spell
)
735 i
< sizeof(search_order_third
) / sizeof(*search_order_third
); ++i
)
737 if (search_order_third
[i
] == SPELL_NO_SPELL
)
738 return (SPELL_NO_SPELL
);
740 if (search_order_third
[i
] == ignore_spell
)
743 if (_know_spell(search_order_third
[i
]))
744 return (search_order_third
[i
]);
747 return (SPELL_NO_SPELL
);
750 static spell_type
search_third_list(int ignore_spell
)
753 i
< sizeof(search_order_misc
) / sizeof(*search_order_misc
); ++i
)
755 if (search_order_misc
[i
] == SPELL_NO_SPELL
)
756 return (SPELL_NO_SPELL
);
758 if (search_order_misc
[i
] == ignore_spell
)
761 if (_know_spell(search_order_misc
[i
]))
762 return (search_order_misc
[i
]);
765 return (SPELL_NO_SPELL
);
768 // Used when creating ghosts: goes through and finds spells for the
769 // ghost to cast. Death is a traumatic experience, so ghosts only
770 // remember a few spells.
771 void ghost_demon::add_spells()
773 spells
.init(SPELL_NO_SPELL
);
775 spells
[0] = search_first_list(SPELL_NO_SPELL
);
776 spells
[1] = search_first_list(spells
[0]);
777 spells
[2] = search_second_list(SPELL_NO_SPELL
);
778 spells
[3] = search_third_list(SPELL_DIG
);
780 if (spells
[3] == SPELL_NO_SPELL
)
781 spells
[3] = search_first_list(SPELL_NO_SPELL
);
783 spells
[4] = search_third_list(spells
[3]);
785 if (spells
[4] == SPELL_NO_SPELL
)
786 spells
[4] = search_first_list(spells
[3]);
788 if (_know_spell(SPELL_DIG
))
789 spells
[4] = SPELL_DIG
;
791 // Look for Blink or Teleport Self for the emergency slot.
792 if (_know_spell(SPELL_CONTROLLED_BLINK
)
793 || _know_spell(SPELL_BLINK
))
795 spells
[5] = SPELL_CONTROLLED_BLINK
;
798 if (_know_spell(SPELL_TELEPORT_SELF
))
799 spells
[5] = SPELL_TELEPORT_SELF
;
801 for (int i
= 0; i
< NUM_MONSTER_SPELL_SLOTS
; ++i
)
802 spells
[i
] = translate_spell(spells
[i
]);
804 spellcaster
= has_spells();
807 bool ghost_demon::has_spells() const
809 for (int i
= 0; i
< NUM_MONSTER_SPELL_SLOTS
; ++i
)
810 if (spells
[i
] != SPELL_NO_SPELL
)
815 // When passed the number for a player spell, returns the equivalent
816 // monster spell. Returns SPELL_NO_SPELL on failure (no equivalent).
817 spell_type
ghost_demon::translate_spell(spell_type spel
) const
821 case SPELL_CONTROLLED_BLINK
:
822 return (SPELL_BLINK
); // approximate
823 case SPELL_DEMONIC_HORDE
:
824 return (SPELL_CALL_IMP
);
826 case SPELL_SYMBOL_OF_TORMENT
:
827 // Too powerful to give ghosts Torment for Agony? Nah.
828 return (SPELL_SYMBOL_OF_TORMENT
);
829 case SPELL_DELAYED_FIREBALL
:
830 return (SPELL_FIREBALL
);
832 return (SPELL_PARALYSE
);
833 case SPELL_EVAPORATE
:
834 return (SPELL_MEPHITIC_CLOUD
);
835 case SPELL_STICKY_FLAME
:
836 return (SPELL_STICKY_FLAME_RANGE
);
844 std::vector
<ghost_demon
> ghost_demon::find_ghosts()
846 std::vector
<ghost_demon
> gs
;
848 // No ghosts in the Temple.
849 if (player_in_branch(BRANCH_ECUMENICAL_TEMPLE
))
855 player
.init_player_ghost();
856 announce_ghost(player
);
857 gs
.push_back(player
);
860 // Pick up any other ghosts that happen to be on the level if we
861 // have space. If the player is undead, add one to the ghost quota
863 find_extra_ghosts(gs
, n_extra_ghosts() + 1 - gs
.size());
868 void ghost_demon::find_transiting_ghosts(
869 std::vector
<ghost_demon
> &gs
, int n
)
874 const m_transit_list
*mt
= get_transit_list(level_id::current());
877 for (m_transit_list::const_iterator i
= mt
->begin();
878 i
!= mt
->end() && n
> 0; ++i
)
880 if (i
->mons
.type
== MONS_PLAYER_GHOST
)
882 const monster
& m
= i
->mons
;
885 announce_ghost(*m
.ghost
);
886 gs
.push_back(*m
.ghost
);
894 void ghost_demon::announce_ghost(const ghost_demon
&g
)
896 #if defined(DEBUG_BONES) || defined(DEBUG_DIAGNOSTICS)
897 mprf(MSGCH_DIAGNOSTICS
, "Saving ghost: %s", g
.name
.c_str());
901 void ghost_demon::find_extra_ghosts(std::vector
<ghost_demon
> &gs
, int n
)
903 for (monster_iterator mi
; mi
&& n
> 0; ++mi
)
905 if (mi
->type
== MONS_PLAYER_GHOST
&& mi
->ghost
.get())
908 announce_ghost(*(mi
->ghost
));
909 gs
.push_back(*(mi
->ghost
));
914 // Check the transit list for the current level.
915 find_transiting_ghosts(gs
, n
);
918 // Returns the number of extra ghosts allowed on the level.
919 int ghost_demon::n_extra_ghosts()
921 if (you
.level_type
!= LEVEL_ABYSS
922 && you
.level_type
!= LEVEL_PANDEMONIUM
)
924 const int subdepth
= level_id::current().depth
;
925 // Single ghosts-only: D:1-8, Lair:1, Orc:1, and non-dungeon
926 // areas at this depth, such as portal vaults.
927 if (subdepth
< 9 && you
.where_are_you
== BRANCH_MAIN_DUNGEON
928 || subdepth
< 2 && you
.where_are_you
== BRANCH_LAIR
929 || subdepth
< 2 && you
.where_are_you
== BRANCH_ORCISH_MINES
)
935 return (MAX_GHOSTS
- 1);
938 // Sanity checks for some ghost values.
939 bool debug_check_ghosts()
941 for (unsigned int k
= 0; k
< ghosts
.size(); ++k
)
943 ghost_demon ghost
= ghosts
[k
];
944 // Values greater than the allowed maximum or less then the
945 // allowed minimum signalise bugginess.
946 if (ghost
.damage
< 0 || ghost
.damage
> MAX_GHOST_DAMAGE
)
948 if (ghost
.max_hp
< 1 || ghost
.max_hp
> MAX_GHOST_HP
)
950 if (ghost
.xl
< 1 || ghost
.xl
> 27)
952 if (ghost
.ev
> MAX_GHOST_EVASION
)
954 if (ghost
.speed
< MIN_GHOST_SPEED
|| ghost
.speed
> MAX_GHOST_SPEED
)
956 if (ghost
.resists
.fire
< -3 || ghost
.resists
.fire
> 3)
958 if (ghost
.resists
.cold
< -3 || ghost
.resists
.cold
> 3)
960 if (ghost
.resists
.elec
< 0)
962 if (ghost
.brand
< SPWPN_NORMAL
|| ghost
.brand
> MAX_PAN_LORD_BRANDS
)
964 if (ghost
.species
< 0 || ghost
.species
>= NUM_SPECIES
)
966 if (ghost
.job
< JOB_FIGHTER
|| ghost
.job
>= NUM_JOBS
)
968 if (ghost
.best_skill
< SK_FIGHTING
|| ghost
.best_skill
>= NUM_SKILLS
)
970 if (ghost
.best_skill_level
< 0 || ghost
.best_skill_level
> 27)
972 if (ghost
.religion
< GOD_NO_GOD
|| ghost
.religion
>= NUM_GODS
)
975 if (ghost
.brand
== SPWPN_HOLY_WRATH
|| is_good_god(ghost
.religion
))
978 // Only (very) ugly things get non-plain attack types and
980 if (ghost
.att_type
!= AT_HIT
|| ghost
.att_flav
!= AF_PLAIN
)
983 // Only Pandemonium lords cycle colours.
984 if (ghost
.cycle_colours
)
988 if (!validate_player_name(ghost
.name
, false))
990 // Many combining characters can come per every letter, but if there's
991 // that much, it's probably a maliciously forged ghost of some kind.
992 if (ghost
.name
.length() > kNameLen
* 10 || ghost
.name
.empty())
994 if (ghost
.name
!= trimmed_string(ghost
.name
))
997 // Check for non-existing spells.
998 for (int sp
= 0; sp
< NUM_MONSTER_SPELL_SLOTS
; ++sp
)
999 if (ghost
.spells
[sp
] < 0 || ghost
.spells
[sp
] >= NUM_SPELLS
)
1005 int ghost_level_to_rank(const int xl
)
1007 if (xl
< 4) return 0;
1008 if (xl
< 7) return 1;
1009 if (xl
< 11) return 2;
1010 if (xl
< 16) return 3;
1011 if (xl
< 22) return 4;
1012 if (xl
< 26) return 5;
1013 if (xl
< 27) return 6;
1017 ///////////////////////////////////////////////////////////////////////////////
1020 std::string
adjective_for_labrat_colour (uint8_t l_colour
)
1024 case CYAN
: return ("armoured");
1025 case YELLOW
: return ("beastly");
1026 case RED
: return ("fiery");
1027 case LIGHTCYAN
: return ("gaseous");
1028 case LIGHTRED
: return ("parasitic");
1029 case LIGHTBLUE
: return ("airborne");
1030 case LIGHTMAGENTA
: return ("mutated");
1031 case MAGENTA
: return ("shifting");
1032 case GREEN
: return ("venomous");
1033 case LIGHTGRAY
: return ("");
1035 die("invalid labrat adjective");
1043 int tile_offset_for_labrat_colour (uint8_t l_colour
)
1047 case LIGHTGRAY
: return (0);
1048 case CYAN
: return (1);
1049 case YELLOW
: return (2);
1050 case RED
: return (3);
1051 case LIGHTCYAN
: return (4);
1052 case LIGHTRED
: return (5);
1053 case LIGHTBLUE
: return (6);
1054 case LIGHTMAGENTA
: return (7);
1055 case MAGENTA
: return (8);
1056 case GREEN
: return (9);
1063 uint8_t colour_for_labrat_adjective (std::string adjective
)
1065 if (adjective
== "armoured") return CYAN
;
1066 if (adjective
== "beastly") return YELLOW
;
1067 if (adjective
== "fiery") return RED
;
1068 if (adjective
== "gaseous") return LIGHTCYAN
;
1069 if (adjective
== "parasitic") return LIGHTRED
;
1070 if (adjective
== "airborne") return LIGHTBLUE
;
1071 if (adjective
== "mutated") return LIGHTMAGENTA
;
1072 if (adjective
== "shifting") return MAGENTA
;
1073 if (adjective
== "venomous") return GREEN
;
1074 if (adjective
== "plain") return LIGHTGRAY
;
1079 static const uint8_t labrat_colour_values
[] = {
1080 CYAN
, YELLOW
, RED
, LIGHTCYAN
, LIGHTRED
, LIGHTBLUE
, LIGHTMAGENTA
, MAGENTA
, GREEN
1083 uint8_t _labrat_random_colour()
1085 return (RANDOM_ELEMENT(labrat_colour_values
));
1088 void ghost_demon::init_labrat (uint8_t force_colour
)
1090 // Base init for "plain" laboratory rats. Kept in line with mon-data.h.
1092 max_hp
= hit_points(xl
, 3, 5);
1096 colour
= force_colour
;
1097 damage
= 9 + random2(3);
1099 if (colour
== BLACK
)
1100 colour
= _labrat_random_colour();
1102 spells
.init(SPELL_NO_SPELL
);
1107 resists
.sticky_flame
= false;
1110 resists
.rotting
= false;
1114 case CYAN
: // armoured
1118 case YELLOW
: // beastly
1119 xl
= 4 + random2(4);
1120 ac
= 2 + random2(5);
1121 ev
= 7 + random2(5);
1122 speed
= 10 + random2(8);
1126 spells
[0] = SPELL_FIRE_BREATH
;
1129 resists
.sticky_flame
= true;
1131 case LIGHTCYAN
: // gaseous
1132 spells
[0] = SPELL_MEPHITIC_CLOUD
;
1134 resists
.poison
= 1; // otherwise it'll confuse itself
1136 case LIGHTRED
: // leeching
1137 att_flav
= AF_VAMPIRIC
;
1139 case LIGHTBLUE
: // floating
1141 spells
[0] = SPELL_SHOCK
;
1147 case LIGHTMAGENTA
: // mutated
1149 att_flav
= AF_MUTATE
;
1150 const mon_attack_type possibles
[] = { AT_CLAW
, AT_PECK
,
1151 AT_TENTACLE_SLAP
, AT_TRUNK_SLAP
, AT_SNAP
, AT_SPLASH
};
1152 att_type
= RANDOM_ELEMENT(possibles
);
1156 spells
[0] = spells
[1] = spells
[2] = spells
[3] =
1157 spells
[4] = spells
[5] = SPELL_BLINK
;
1161 att_flav
= AF_POISON
;