Merge branch 'panlord-colour'
[crawl.git] / crawl-ref / source / tilemcache.cc
1 #include "AppHdr.h"
2
3 #ifdef USE_TILE
4 #include "tilemcache.h"
5
6 #include "colour.h"
7 #include "env.h"
8 #include "libutil.h"
9 #include "misc.h"
10 #include "mon-info.h"
11 #include "mon-util.h"
12 #include "options.h"
13 #include "tiledef-player.h"
14 #include "tilepick.h"
15 #include "tilepick-p.h"
16
17 mcache_manager mcache;
18
19 // Used internally for streaming.
20 enum mcache_type
21 {
22     MCACHE_MONSTER,
23     MCACHE_DRACO,
24     MCACHE_GHOST,
25     MCACHE_DEMON,
26     MCACHE_MAX,
27
28     MCACHE_nullptr,
29 };
30
31 struct demon_data
32 {
33     demon_data() { head = body = wings = 0; }
34
35     tileidx_t head;
36     tileidx_t body;
37     tileidx_t wings;
38 };
39
40 // Internal mcache classes.  The mcache_manager creates these internally.
41 // The only access external clients need is through the virtual
42 // info function.
43
44 class mcache_monster : public mcache_entry
45 {
46 public:
47     mcache_monster(const monster_info& mon);
48
49     virtual int info(tile_draw_info *dinfo) const;
50
51     static bool valid(const monster_info& mon);
52
53     static bool get_weapon_offset(tileidx_t mon_tile, int *ofs_x, int *ofs_y);
54     static bool get_shield_offset(tileidx_t mon_tile, int *ofs_x, int *ofs_y);
55
56 protected:
57     monster_type mtype;
58     tileidx_t m_mon_tile;
59     tileidx_t m_equ_tile;
60     tileidx_t m_shd_tile;
61 };
62
63 class mcache_draco : public mcache_entry
64 {
65 public:
66     mcache_draco(const monster_info& mon);
67
68     virtual int info(tile_draw_info *dinfo) const;
69
70     static bool valid(const monster_info& mon);
71
72 protected:
73     tileidx_t m_mon_tile;
74     tileidx_t m_job_tile;
75     tileidx_t m_equ_tile;
76     tileidx_t m_shd_tile;
77     bool draco;
78 };
79
80 class mcache_ghost : public mcache_entry
81 {
82 public:
83     mcache_ghost(const monster_info& mon);
84
85     virtual const dolls_data *doll() const;
86
87     static bool valid(const monster_info& mon);
88
89     virtual bool transparent() const;
90
91 protected:
92     dolls_data m_doll;
93 };
94
95 class mcache_demon : public mcache_entry
96 {
97 public:
98     mcache_demon(const monster_info& minf);
99
100     virtual int info(tile_draw_info *dinfo) const;
101
102     static bool valid(const monster_info& mon);
103
104 protected:
105     demon_data m_demon;
106 };
107
108 /////////////////////////////////////////////////////////////////////////////
109 // tile_fg_store
110
111 tileidx_t tile_fg_store::operator=(tileidx_t tile)
112 {
113     if ((tile & TILE_FLAG_MASK) == (m_tile & TILE_FLAG_MASK))
114     {
115         // Update, as flags may have changed.
116         m_tile = tile;
117         return m_tile;
118     }
119
120     mcache_entry *old_entry = mcache.get(m_tile);
121     if (old_entry)
122         old_entry->dec_ref();
123
124     m_tile = tile;
125
126     mcache_entry *new_entry = mcache.get(m_tile);
127     if (new_entry)
128         new_entry->inc_ref();
129
130     return m_tile;
131 }
132
133 /////////////////////////////////////////////////////////////////////////////
134 // mcache_manager
135
136 mcache_manager::~mcache_manager()
137 {
138     clear_all();
139 }
140
141 unsigned int mcache_manager::register_monster(const monster_info& minf)
142 {
143     // TODO enne - is it worth it to search against all mcache entries?
144     // TODO enne - pool mcache types to avoid too much alloc/dealloc?
145
146     mcache_entry *entry;
147
148     if (minf.props.exists("monster_tile"))
149     {
150         if (mcache_monster::valid(minf))
151             entry = new mcache_monster(minf);
152         else
153             return 0;
154     }
155     else if (mcache_demon::valid(minf))
156         entry = new mcache_demon(minf);
157     else if (mcache_ghost::valid(minf))
158         entry = new mcache_ghost(minf);
159     else if (mcache_draco::valid(minf))
160         entry = new mcache_draco(minf);
161     else if (mcache_monster::valid(minf))
162         entry = new mcache_monster(minf);
163     else
164         return 0;
165
166     tileidx_t idx = ~0;
167
168     for (unsigned int i = 0; i < m_entries.size(); i++)
169     {
170         if (!m_entries[i])
171         {
172             m_entries[i] = entry;
173             idx = i;
174             break;
175         }
176     }
177
178     if (idx > m_entries.size())
179     {
180         idx = m_entries.size();
181         m_entries.push_back(entry);
182     }
183
184     return TILEP_MCACHE_START + idx;
185 }
186
187 void mcache_manager::clear_nonref()
188 {
189     for (mcache_entry *&entry : m_entries)
190     {
191         if (!entry || entry->ref_count() > 0)
192             continue;
193
194         delete entry;
195         entry = nullptr;
196     }
197 }
198
199 void mcache_manager::clear_all()
200 {
201     deleteAll(m_entries);
202 }
203
204 mcache_entry *mcache_manager::get(tileidx_t tile)
205 {
206     tileidx_t idx = tile & TILE_FLAG_MASK;
207     if (idx < TILEP_MCACHE_START)
208         return nullptr;
209
210     if (idx >= TILEP_MCACHE_START + m_entries.size())
211         return nullptr;
212
213     mcache_entry *entry = m_entries[idx - TILEP_MCACHE_START];
214     return entry;
215 }
216
217 /////////////////////////////////////////////////////////////////////////////
218 // mcache_monster
219
220 mcache_monster::mcache_monster(const monster_info& mon)
221 {
222     ASSERT(mcache_monster::valid(mon));
223
224     mtype = mon.type;
225     m_mon_tile = tileidx_monster(mon) & TILE_FLAG_MASK;
226
227     const item_info* mon_weapon = mon.inv[MSLOT_WEAPON].get();
228     m_equ_tile = (mon_weapon != nullptr) ? tilep_equ_weapon(*mon_weapon) : 0;
229     if (mons_class_wields_two_weapons(mon.type))
230     {
231         const item_info* mon_weapon2 = mon.inv[MSLOT_ALT_WEAPON].get();
232         if (mon_weapon2)
233         {
234             switch (tilep_equ_weapon(*mon_weapon2))
235             {
236                 case TILEP_HAND1_DAGGER:
237                     m_shd_tile = TILEP_HAND2_DAGGER;
238                     break;
239                 case TILEP_DAGGER_1:
240                     m_shd_tile = TILEP_HAND2_DAGGER_1;
241                     break;
242                 case TILEP_HAND1_RAPIER:
243                     m_shd_tile = TILEP_HAND2_RAPIER;
244                     break;
245                 case TILEP_RAPIER_1:
246                     m_shd_tile = TILEP_HAND2_RAPIER_1;
247                     break;
248                 default:
249                 case TILEP_HAND1_SHORT_SWORD_SLANT:
250                     m_shd_tile = TILEP_HAND2_SHORT_SWORD_SLANT;
251                     break;
252                 case TILEP_SHORT_SWORD_SLANT_1:
253                     m_shd_tile = TILEP_HAND2_SHORT_SWORD_SLANT_1;
254                     break;
255                 case TILEP_HAND1_GREAT_FLAIL:
256                     m_shd_tile = TILEP_HAND2_GREAT_FLAIL;
257                     break;
258                 case TILEP_GREAT_FLAIL_1:
259                     m_shd_tile = TILEP_HAND2_GREAT_FLAIL_1;
260                     break;
261                 case TILEP_HAND1_GREAT_MACE:
262                     m_shd_tile = TILEP_HAND2_GREAT_MACE;
263                     break;
264                 case TILEP_GREAT_MACE_1:
265                     m_shd_tile = TILEP_HAND2_GREAT_MACE_1;
266                     break;
267                 case TILEP_HAND1_GIANT_CLUB:
268                     m_shd_tile = TILEP_HAND2_GIANT_CLUB;
269                     break;
270                 case TILEP_HAND1_GIANT_CLUB_SLANT:
271                     m_shd_tile = TILEP_HAND2_GIANT_CLUB_SLANT;
272                     break;
273                 case TILEP_HAND1_GIANT_CLUB_SPIKE:
274                     m_shd_tile = TILEP_HAND2_GIANT_CLUB_SPIKE;
275                     break;
276                 case TILEP_HAND1_GIANT_CLUB_SPIKE_SLANT:
277                     m_shd_tile = TILEP_HAND2_GIANT_CLUB_SPIKE_SLANT;
278                     break;
279                 case TILEP_HAND1_GIANT_CLUB_PLAIN:
280                     m_shd_tile = TILEP_HAND2_GIANT_CLUB_PLAIN;
281                     break;
282             };
283         }
284         else
285             m_shd_tile = 0;
286     }
287     else
288     {
289         const item_info* mon_shield = mon.inv[MSLOT_SHIELD].get();
290         m_shd_tile = (mon_shield != nullptr) ? tilep_equ_shield(*mon_shield) : 0;
291     }
292 }
293
294 // Returns the amount of pixels necessary to shift a wielded weapon
295 // from its default placement. Tiles showing monsters already wielding
296 // a weapon should not be listed here.
297 bool mcache_monster::get_weapon_offset(tileidx_t mon_tile,
298                                        int *ofs_x, int *ofs_y)
299 {
300     switch (mon_tile)
301     {
302     // No shift necessary.
303     case TILEP_MONS_DEEP_ELF_MASTER_ARCHER:
304     case TILEP_MONS_DEEP_ELF_BLADEMASTER:
305     case TILEP_MONS_CRIMSON_IMP:
306     case TILEP_MONS_IRON_IMP:
307     case TILEP_MONS_SHADOW_IMP:
308     case TILEP_MONS_NORRIS:
309     case TILEP_MONS_MAUD:
310     case TILEP_MONS_HAROLD:
311     case TILEP_MONS_JOSEPHINE:
312     case TILEP_MONS_JOSEPH:
313     case TILEP_MONS_TERENCE:
314     case TILEP_MONS_WIGLAF:
315     case TILEP_MONS_RAKSHASA:
316     case TILEP_MONS_VAMPIRE_KNIGHT:
317     case TILEP_MONS_CHERUB:
318     case TILEP_MONS_MENNAS:
319     case TILEP_MONS_PROFANE_SERVITOR:
320     case TILEP_MONS_SPRIGGAN:
321     case TILEP_MONS_KOBOLD:
322     case TILEP_MONS_OCTOPODE:
323     case TILEP_MONS_ZOMBIE_OCTOPODE:
324     case TILEP_MONS_NIKOLA:
325     case TILEP_MONS_NAGA_RITUALIST:
326     case TILEP_MONS_ANUBIS_GUARD:
327         *ofs_x = 0;
328         *ofs_y = 0;
329         break;
330     // Shift to the left.
331     case TILEP_MONS_GNOLL:
332     case TILEP_MONS_GNOLL_SHAMAN:
333     case TILEP_MONS_GNOLL_SERGEANT:
334     case TILEP_MONS_GRUM:
335     case TILEP_MONS_CRAZY_YIUF:
336     case TILEP_MONS_DEEP_ELF_DEATH_MAGE:
337     case TILEP_MONS_SPRIGGAN_DEFENDER:
338     case TILEP_MONS_SPRIGGAN_BERSERKER:
339     case TILEP_MONS_MERFOLK:
340     case TILEP_MONS_MERFOLK_JAVELINEER:
341         *ofs_x = -1;
342         *ofs_y = 0;
343         break;
344     case TILEP_MONS_HOBGOBLIN:
345     case TILEP_MONS_ROBIN:
346     case TILEP_MONS_TIAMAT:
347     case TILEP_MONS_TIAMAT+1:
348     case TILEP_MONS_TIAMAT+2:
349     case TILEP_MONS_TIAMAT+3:
350     case TILEP_MONS_TIAMAT+4:
351     case TILEP_MONS_TIAMAT+5:
352     case TILEP_MONS_TIAMAT+6:
353     case TILEP_MONS_TIAMAT+7:
354     case TILEP_MONS_TIAMAT+8:
355     case TILEP_MONS_MERFOLK_IMPALER:
356     case TILEP_MONS_TENGU:
357     case TILEP_MONS_TENGU_CONJURER:
358     case TILEP_MONS_TENGU_WARRIOR:
359     case TILEP_MONS_TENGU_REAVER:
360     case TILEP_MONS_SOJOBO:
361         *ofs_x = -2;
362         *ofs_y = 0;
363         break;
364     case TILEP_MONS_SKELETON_LARGE:
365     case TILEP_MONS_ORC_WARLORD:
366     case TILEP_MONS_BIG_KOBOLD:
367         *ofs_x = -3;
368         *ofs_y = 0;
369         break;
370     // Shift to the right.
371     case TILEP_MONS_VAULT_GUARD:
372     case TILEP_MONS_VAULT_WARDEN:
373     case TILEP_MONS_VAULT_SENTINEL:
374     case TILEP_MONS_IRONBRAND_CONVOKER:
375     case TILEP_MONS_IRONHEART_PRESERVER:
376     case TILEP_MONS_DONALD:
377     case TILEP_MONS_GARGOYLE:
378     case TILEP_MONS_MOLTEN_GARGOYLE:
379     case TILEP_MONS_WAR_GARGOYLE:
380         *ofs_x = 1;
381         *ofs_y = 0;
382         break;
383     case TILEP_MONS_YAKTAUR_MELEE:
384     case TILEP_MONS_WIGHT:
385         *ofs_x = 2;
386         *ofs_y = 0;
387         break;
388     case TILEP_MONS_YAKTAUR_CAPTAIN_MELEE:
389         *ofs_x = 4;
390         *ofs_y = 0;
391         break;
392     case TILEP_MONS_FIRE_GIANT:
393         *ofs_x = 5;
394         *ofs_y = 0;
395         break;
396     // Shift upwards.
397     case TILEP_MONS_CENTAUR_WARRIOR_MELEE:
398     case TILEP_MONS_DEEP_ELF_SORCERER:
399     case TILEP_MONS_DEEP_ELF_HIGH_PRIEST:
400     case TILEP_MONS_RUPERT:
401     case TILEP_MONS_HELL_KNIGHT:
402     case TILEP_MONS_DEATH_KNIGHT:
403     case TILEP_MONS_MUMMY:
404     case TILEP_MONS_MUMMY_PRIEST:
405     case TILEP_MONS_GUARDIAN_MUMMY:
406     case TILEP_MONS_SKELETON_SMALL:
407     case TILEP_MONS_PSYCHE:
408     case TILEP_MONS_DUVESSA:
409         *ofs_x = 0;
410         *ofs_y = -1;
411         break;
412     case TILEP_MONS_FREDERICK:
413     case TILEP_MONS_SALAMANDER_MYSTIC:
414     case TILEP_MONS_SALAMANDER_FIREBRAND:
415         *ofs_x = 0;
416         *ofs_y = -2;
417         break;
418     case TILEP_MONS_RED_DEVIL:
419         *ofs_x = 0;
420         *ofs_y = -3;
421         break;
422     // Shift downwards.
423     case TILEP_MONS_DEEP_ELF_KNIGHT:
424     case TILEP_MONS_NAGA:
425     case TILEP_MONS_GREATER_NAGA:
426     case TILEP_MONS_NAGA_WARRIOR:
427     case TILEP_MONS_GUARDIAN_SERPENT:
428     case TILEP_MONS_NAGA_MAGE:
429     case TILEP_MONS_NAGA_SHARPSHOOTER:
430     case TILEP_MONS_VASHNIA:
431     case TILEP_MONS_THE_ENCHANTRESS:
432     case TILEP_MONS_DEEP_DWARF:
433     case TILEP_MONS_RUST_DEVIL:
434         *ofs_x = 0;
435         *ofs_y = 1;
436         break;
437     case TILEP_MONS_BLORK_THE_ORC:
438     case TILEP_MONS_BOGGART:
439     case TILEP_MONS_DEEP_ELF_FIGHTER:
440     case TILEP_MONS_UNBORN:
441     case TILEP_MONS_JORGRUN:
442     case TILEP_MONS_SIREN:
443     case TILEP_MONS_MERFOLK_AVATAR:
444     case TILEP_MONS_ILSUIW:
445     case TILEP_MONS_DIMME:
446     case TILEP_MONS_HALFLING:
447         *ofs_x = 0;
448         *ofs_y = 2;
449         break;
450     // Shift upwards and to the left.
451     case TILEP_MONS_DEEP_ELF_MAGE:
452     case TILEP_MONS_DEEP_ELF_SUMMONER:
453     case TILEP_MONS_DEEP_ELF_CONJURER:
454     case TILEP_MONS_DEEP_ELF_PRIEST:
455     case TILEP_MONS_DEEP_ELF_DEMONOLOGIST:
456     case TILEP_MONS_DEEP_ELF_ANNIHILATOR:
457     case TILEP_MONS_MINOTAUR:
458     case TILEP_MONS_VAMPIRE:
459     case TILEP_MONS_MERFOLK_IMPALER_WATER:
460         *ofs_x = -1;
461         *ofs_y = -2;
462         break;
463     case TILEP_MONS_CENTAUR_MELEE:
464         *ofs_x = -3;
465         *ofs_y = -3;
466         break;
467     case TILEP_MONS_DEMIGOD:
468     case TILEP_MONS_KIRKE:
469         *ofs_x = -1;
470         *ofs_y = -3;
471         break;
472     case TILEP_MONS_SONJA:
473     case TILEP_MONS_ANCIENT_CHAMPION:
474     case TILEP_MONS_SKELETAL_WARRIOR:
475     case TILEP_MONS_SALAMANDER:
476     case TILEP_MONS_VINE_STALKER:
477     case TILEP_MONS_NECROPHAGE:
478         *ofs_x = -2;
479         *ofs_y = -2;
480         break;
481     case TILEP_MONS_SPRIGGAN_AIR_MAGE:
482         *ofs_x = -3;
483         *ofs_y = -5;
484         break;
485     case TILEP_MONS_DEEP_ELF_ELEMENTALIST:
486     case TILEP_MONS_MERFOLK_AQUAMANCER:
487     case TILEP_MONS_FORMICID:
488         *ofs_x = -2;
489         *ofs_y = -1;
490         break;
491     case TILEP_MONS_FANNAR:
492         *ofs_x = -2;
493         *ofs_y = -4;
494         break;
495     case TILEP_MONS_ARACHNE_STAVELESS:
496         *ofs_x = -1;
497         *ofs_y = -5;
498         break;
499     case TILEP_MONS_ASTERION:
500         *ofs_x = -3;
501         *ofs_y = -1;
502         break;
503     // Shift upwards and to the right.
504     case TILEP_MONS_NECROMANCER:
505     case TILEP_MONS_WIZARD:
506     case TILEP_MONS_CLOUD_MAGE:
507     case TILEP_MONS_MASTER_ELEMENTALIST:
508     case TILEP_MONS_JESSICA:
509     case TILEP_MONS_ANGEL:
510     case TILEP_MONS_DAEVA:
511     case TILEP_MONS_MERFOLK_WATER:
512     case TILEP_MONS_MERFOLK_JAVELINEER_WATER:
513     case TILEP_MONS_MERFOLK_AQUAMANCER_WATER:
514         *ofs_x = 1;
515         *ofs_y = -1;
516         break;
517     case TILEP_MONS_AGNES:
518         *ofs_x = 0;
519         *ofs_y = 1;
520         break;
521     case TILEP_MONS_TRAINING_DUMMY:
522         *ofs_x = 3;
523         *ofs_y = -1;
524         break;
525     case TILEP_MONS_MARGERY:
526     case TILEP_MONS_FAUN:
527     case TILEP_MONS_OCTOPODE_CRUSHER:
528         *ofs_x = 1;
529         *ofs_y = -3;
530         break;
531     case TILEP_MONS_LOUISE:
532     case TILEP_MONS_SATYR:
533         *ofs_x = 1;
534         *ofs_y = -4;
535         break;
536     case TILEP_MONS_HELL_WIZARD:
537     case TILEP_MONS_HELL_WIZARD + 1:
538     case TILEP_MONS_HELL_WIZARD + 2:
539         *ofs_x = 2;
540         *ofs_y = -2;
541         break;
542     case TILEP_MONS_HUMAN:
543     case TILEP_MONS_ELF:
544         *ofs_x = 2;
545         *ofs_y = -3;
546         break;
547     case TILEP_MONS_GHOST:
548         *ofs_x = 3;
549         *ofs_y = -4;
550         break;
551     case TILEP_MONS_FRANCES: // left-handed
552         *ofs_x = 20;
553         *ofs_y = -1;
554         break;
555     // Shift downwards and to the left.
556     case TILEP_MONS_GOBLIN:
557     case TILEP_MONS_IJYB:
558         *ofs_x = -2;
559         *ofs_y = 4;
560         break;
561     case TILEP_MONS_ORC:
562     case TILEP_MONS_ORC_WARRIOR:
563     case TILEP_MONS_URUG:
564     case TILEP_MONS_ORC_PRIEST:
565     case TILEP_MONS_ORC_HIGH_PRIEST:
566         *ofs_x = -1;
567         *ofs_y = 1;
568         break;
569     case TILEP_MONS_ORC_KNIGHT:
570     case TILEP_MONS_ORC_WIZARD:
571     case TILEP_MONS_ORC_SORCERER:
572     case TILEP_MONS_NERGALLE:
573         *ofs_x = -2;
574         *ofs_y = 1;
575         break;
576     case TILEP_MONS_SAINT_ROKA:
577         *ofs_x = -3;
578         *ofs_y = 1;
579         break;
580     case TILEP_MONS_SERAPH:
581         *ofs_x = -1;
582         *ofs_y = -10;
583         break;
584     // Shift downwards and to the right.
585     case TILEP_MONS_OGRE:
586     case TILEP_MONS_OGRE_MAGE:
587         *ofs_x = 1;
588         *ofs_y = 1;
589         break;
590     case TILEP_MONS_TWO_HEADED_OGRE:
591         *ofs_x = 1;
592         *ofs_y = 2;
593         break;
594     case TILEP_MONS_ETTIN:
595         *ofs_x = 2;
596         *ofs_y = 1;
597         break;
598     case TILEP_MONS_FROST_GIANT:
599         *ofs_x = 2;
600         *ofs_y = 3;
601         break;
602     case TILEP_MONS_ZOMBIE_LARGE:
603         *ofs_x = 4;
604         *ofs_y = 1;
605         break;
606     case TILEP_MONS_ZOMBIE_SMALL:
607         *ofs_x = 4;
608         *ofs_y = 3;
609         break;
610     case TILEP_MONS_HILL_GIANT:
611         *ofs_x = 6;
612         *ofs_y = 2;
613         break;
614     case TILEP_MONS_TROLL:
615         *ofs_x = -3;
616         *ofs_y = 11;
617         break;
618     case TILEP_MONS_GHOUL:
619         *ofs_x = -3;
620         *ofs_y = -3;
621         break;
622     case TILEP_MONS_ORB_OF_FIRE:
623         *ofs_x = 0;
624         *ofs_y = 2;
625         break;
626     case TILEP_MONS_TENTACLED_MONSTROSITY:
627     case TILEP_MONS_CIGOTUVIS_MONSTER:
628         *ofs_x = -4;
629         *ofs_y = 2;
630         break;
631     case TILEP_MONS_SERPENT_OF_HELL_GEHENNA:
632     case TILEP_MONS_SERPENT_OF_HELL_COCYTUS:
633     case TILEP_MONS_SERPENT_OF_HELL_DIS:
634     case TILEP_MONS_SERPENT_OF_HELL_TARTARUS:
635         *ofs_x = -4;
636         *ofs_y = 3;
637         break;
638     case TILEP_MONS_UNSEEN_HORROR:
639         *ofs_x = -4;
640         *ofs_y = -4;
641         break;
642     case TILEP_MONS_UGLY_THING:
643     case TILEP_MONS_UGLY_THING_1:
644     case TILEP_MONS_UGLY_THING_2:
645     case TILEP_MONS_UGLY_THING_3:
646     case TILEP_MONS_UGLY_THING_4:
647     case TILEP_MONS_UGLY_THING_5:
648         *ofs_x = -4;
649         *ofs_y = -7;
650         break;
651     case TILEP_MONS_VERY_UGLY_THING:
652     case TILEP_MONS_VERY_UGLY_THING_1:
653     case TILEP_MONS_VERY_UGLY_THING_2:
654     case TILEP_MONS_VERY_UGLY_THING_3:
655     case TILEP_MONS_VERY_UGLY_THING_4:
656     case TILEP_MONS_VERY_UGLY_THING_5:
657         *ofs_x = -3;
658         *ofs_y = 4;
659         break;
660     case TILEP_MONS_ORANGE_STATUE:
661         *ofs_x = 3;
662         *ofs_y = -4;
663         break;
664     case TILEP_MONS_LOROCYPROCA:
665         *ofs_x = -4;
666         *ofs_y = 6;
667         break;
668     case TILEP_MONS_HELLION:
669         *ofs_x = -1;
670         *ofs_y = 4;
671         break;
672     case TILEP_MONS_CACODEMON:
673         *ofs_x = -3;
674         *ofs_y = -13;
675         break;
676     case TILEP_MONS_STARCURSED_MASS:
677         *ofs_x = -4;
678         *ofs_y = 4;
679         break;
680     case TILEP_MONS_WRETCHED_STAR:
681         *ofs_x = 1;
682         *ofs_y = -4;
683         break;
684     case TILEP_MONS_ELDRITCH_TENTACLE_PORTAL_9:
685         *ofs_x = -2;
686         *ofs_y = -3;
687         break;
688     case TILEP_MONS_EXECUTIONER:
689         *ofs_x = -4;
690         *ofs_y = 4;
691         break;
692     case TILEP_MONS_ICE_FIEND:
693         *ofs_x = 1;
694         *ofs_y = 2;
695         break;
696     case TILEP_MONS_PANDEMONIUM_LORD:
697         *ofs_x = -2;
698         *ofs_y = 0;
699         break;
700     case TILEP_MONS_HELL_SENTINEL:
701         *ofs_x = -1;
702         *ofs_y = 4;
703         break;
704     case TILEP_MONS_DEMONIC_PLANT:
705         *ofs_x = -1;
706         *ofs_y = 2;
707         break;
708     case TILEP_MONS_TENTACLED_STARSPAWN:
709         *ofs_x = -1;
710         *ofs_y = 1;
711         break;
712     case TILEP_MONS_ABOMINATION_LARGE_1:
713         *ofs_x = -2;
714         *ofs_y = -8;
715         break;
716     case TILEP_MONS_ABOMINATION_LARGE_2:
717         *ofs_x = -3;
718         *ofs_y = 0;
719         break;
720     case TILEP_MONS_ABOMINATION_LARGE_3:
721         *ofs_x = -4;
722         *ofs_y = -5;
723         break;
724     case TILEP_MONS_ABOMINATION_LARGE_4:
725         *ofs_x = -3;
726         *ofs_y = -10;
727         break;
728     case TILEP_MONS_ABOMINATION_LARGE_6:
729         *ofs_x = -4;
730         *ofs_y = -11;
731         break;
732     case TILEP_MONS_CHAOS_SPAWN:
733         *ofs_x = 0;
734         *ofs_y = -5;
735         break;
736     case TILEP_MONS_CHAOS_SPAWN_2:
737         *ofs_x = 2;
738         *ofs_y = -3;
739         break;
740     case TILEP_MONS_CHAOS_SPAWN_3:
741         *ofs_x = -2;
742         *ofs_y = -1;
743         break;
744     case TILEP_MONS_GREAT_ORB_OF_EYES:
745         *ofs_x = -2;
746         *ofs_y = -2;
747         break;
748     case TILEP_MONS_ILSUIW_WATER:
749         *ofs_x = 3;
750         *ofs_y = 2;
751         break;
752     case TILEP_MONS_SIREN_WATER:
753     case TILEP_MONS_MERFOLK_AVATAR_WATER:
754         *ofs_x = 5;
755         *ofs_y = 2;
756         break;
757     case TILEP_MONS_WRAITH:
758         *ofs_x = -4;
759         *ofs_y = -4;
760         break;
761     case TILEP_MONS_ORB_GUARDIAN:
762         *ofs_x = -1;
763         *ofs_y = 2;
764         break;
765     case TILEP_MONS_ORB_GUARDIAN_FETUS:
766         *ofs_x = 4;
767         *ofs_y = -7;
768         break;
769     case TILEP_MONS_JORMUNGANDR:
770         *ofs_x = 9;
771         *ofs_y = -4;
772         break;
773     default:
774         // This monster cannot be displayed with a weapon.
775         return false;
776     }
777
778     return true;
779 }
780
781 // Returns the amount of pixels necessary to shift a worn shield, like
782 // it's done with weapon.  No monster should have a shield hard-drawn
783 // on the tile.
784 bool mcache_monster::get_shield_offset(tileidx_t mon_tile,
785                                        int *ofs_x, int *ofs_y)
786 {
787     switch (mon_tile)
788     {
789     case TILEP_MONS_ORC:
790     case TILEP_MONS_URUG:
791     case TILEP_MONS_BLORK_THE_ORC:
792     case TILEP_MONS_ORC_PRIEST:
793     case TILEP_MONS_ORC_WARRIOR:
794     case TILEP_MONS_ORC_KNIGHT:
795     case TILEP_MONS_KIRKE:
796     case TILEP_MONS_SIREN:
797     case TILEP_MONS_SIREN_WATER:
798     case TILEP_MONS_MERFOLK_AVATAR:
799     case TILEP_MONS_MERFOLK_AVATAR_WATER:
800     case TILEP_MONS_ILSUIW:
801     case TILEP_MONS_ILSUIW_WATER:
802     case TILEP_MONS_DIMME:
803         *ofs_x = 1;
804         *ofs_y = 0;
805         break;
806
807     case TILEP_MONS_SAINT_ROKA:
808     case TILEP_MONS_ORC_WARLORD:
809     case TILEP_MONS_MINOTAUR:
810     case TILEP_MONS_NORRIS:
811         *ofs_x = 3;
812         *ofs_y = 0;
813         break;
814
815     case TILEP_MONS_ARACHNE_STAVELESS:
816         *ofs_x = -6;
817         *ofs_y = 1;
818         break;
819
820     case TILEP_MONS_ZOMBIE_SMALL:
821     case TILEP_MONS_SKELETON_SMALL:
822     case TILEP_MONS_VAULT_GUARD:
823     case TILEP_MONS_IRONBRAND_CONVOKER:
824     case TILEP_MONS_IRONHEART_PRESERVER:
825     case TILEP_MONS_VAULT_WARDEN:
826     case TILEP_MONS_DEEP_ELF_FIGHTER:
827         *ofs_x = -2;
828         *ofs_y = 1;
829         break;
830
831     case TILEP_MONS_HUMAN:
832     case TILEP_MONS_DEEP_ELF_BLADEMASTER: // second weapon
833     case TILEP_MONS_LOUISE:
834     case TILEP_MONS_TENGU:
835     case TILEP_MONS_TENGU_CONJURER:
836     case TILEP_MONS_TENGU_WARRIOR:
837     case TILEP_MONS_TENGU_REAVER:
838     case TILEP_MONS_SOJOBO:
839     case TILEP_MONS_FORMICID:
840     case TILEP_MONS_VINE_STALKER:
841     case TILEP_MONS_OCTOPODE:
842     case TILEP_MONS_OCTOPODE_CRUSHER:
843     case TILEP_MONS_CHERUB:
844         *ofs_x = 0;
845         *ofs_y = 0;
846         break;
847
848     case TILEP_MONS_DONALD:
849         *ofs_x = -1;
850         *ofs_y = -1;
851         break;
852
853     case TILEP_MONS_WIGLAF:
854     case TILEP_MONS_ANUBIS_GUARD:
855         *ofs_x = -1;
856         *ofs_y = 1;
857         break;
858
859     case TILEP_MONS_TWO_HEADED_OGRE: // second weapon
860         *ofs_x = 0;
861         *ofs_y = 2;
862         break;
863
864     case TILEP_MONS_ETTIN: // second weapon
865         *ofs_x = -2;
866         *ofs_y = 1;
867         break;
868
869     case TILEP_MONS_NAGA:
870     case TILEP_MONS_NAGA_MAGE:
871     case TILEP_MONS_NAGA_SHARPSHOOTER:
872     case TILEP_MONS_VASHNIA:
873     case TILEP_MONS_NAGA_WARRIOR:
874     case TILEP_MONS_GREATER_NAGA:
875         *ofs_x = -3;
876         *ofs_y = 0;
877         break;
878
879     case TILEP_MONS_SPRIGGAN:
880     case TILEP_MONS_SPRIGGAN_DEFENDER:
881     case TILEP_MONS_SPRIGGAN_BERSERKER:
882         *ofs_x = 2;
883         *ofs_y = 3;
884         break;
885
886     case TILEP_MONS_SPRIGGAN_DRUID:
887         *ofs_x = 2;
888         *ofs_y = -4;
889         break;
890
891     case TILEP_MONS_SPRIGGAN_AIR_MAGE:
892         *ofs_x = 2;
893         *ofs_y = -9;
894         break;
895
896     case TILEP_MONS_THE_ENCHANTRESS:
897         *ofs_x = 6;
898         *ofs_y = 3;
899         break;
900
901     case TILEP_MONS_ASTERION:
902         *ofs_x = 1;
903         *ofs_y = 1;
904         break;
905
906     case TILEP_MONS_SALAMANDER:
907         *ofs_x = 0;
908         *ofs_y = -1;
909         break;
910
911     case TILEP_MONS_SALAMANDER_FIREBRAND:
912     case TILEP_MONS_GNOLL_SERGEANT:
913         *ofs_x = 1;
914         *ofs_y = -1;
915         break;
916
917     case TILEP_MONS_HELL_KNIGHT:
918     case TILEP_MONS_DEATH_KNIGHT:
919         *ofs_x = -3;
920         *ofs_y = 2;
921         break;
922
923     case TILEP_MONS_KOBOLD:
924     case TILEP_MONS_SONJA:
925         *ofs_x = 3;
926         *ofs_y = -10;
927         break;
928
929     case TILEP_MONS_MUMMY:
930         *ofs_x = -6;
931         *ofs_y = 0;
932         break;
933
934     case TILEP_MONS_WRAITH:
935         *ofs_x = -4;
936         *ofs_y = -1;
937         break;
938
939     case TILEP_MONS_TROLL:
940         *ofs_x = 2;
941         *ofs_y = 7;
942         break;
943
944     case TILEP_MONS_GHOUL:
945     case TILEP_MONS_OGRE:
946         *ofs_x = 2;
947         *ofs_y = 1;
948         break;
949
950     case TILEP_MONS_GARGOYLE:
951         *ofs_x = -8;
952         *ofs_y = 1;
953         break;
954
955     case TILEP_MONS_CENTAUR_MELEE:
956         *ofs_x = -8;
957         *ofs_y = -4;
958         break;
959
960     case TILEP_MONS_HALFLING:
961         *ofs_x = -2;
962         *ofs_y = 5;
963         break;
964
965     case TILEP_MONS_DEEP_ELF_SUMMONER:
966     case TILEP_MONS_DEEP_ELF_DEMONOLOGIST:
967     case TILEP_MONS_DEEP_ELF_MAGE:
968     case TILEP_MONS_DEEP_ELF_CONJURER:
969         *ofs_x = 3;
970         *ofs_y = -7;
971         break;
972
973     case TILEP_MONS_ORB_OF_FIRE:
974         *ofs_x = -4;
975         *ofs_y = 2;
976         break;
977
978     case TILEP_MONS_TENTACLED_MONSTROSITY:
979     case TILEP_MONS_CIGOTUVIS_MONSTER:
980     case TILEP_MONS_SERPENT_OF_HELL_GEHENNA:
981     case TILEP_MONS_SERPENT_OF_HELL_COCYTUS:
982     case TILEP_MONS_SERPENT_OF_HELL_DIS:
983     case TILEP_MONS_SERPENT_OF_HELL_TARTARUS:
984         *ofs_x = 4;
985         *ofs_y = -1;
986         break;
987
988     case TILEP_MONS_UNSEEN_HORROR:
989         *ofs_x = 5;
990         *ofs_y = -1;
991         break;
992
993     case TILEP_MONS_UGLY_THING:
994     case TILEP_MONS_UGLY_THING_1:
995     case TILEP_MONS_UGLY_THING_2:
996     case TILEP_MONS_UGLY_THING_3:
997     case TILEP_MONS_UGLY_THING_4:
998     case TILEP_MONS_UGLY_THING_5:
999         *ofs_x = 4;
1000         *ofs_y = -1;
1001         break;
1002
1003     case TILEP_MONS_VERY_UGLY_THING:
1004     case TILEP_MONS_VERY_UGLY_THING_1:
1005     case TILEP_MONS_VERY_UGLY_THING_2:
1006     case TILEP_MONS_VERY_UGLY_THING_3:
1007     case TILEP_MONS_VERY_UGLY_THING_4:
1008     case TILEP_MONS_VERY_UGLY_THING_5:
1009         *ofs_x = 4;
1010         *ofs_y = 5;
1011         break;
1012
1013     case TILEP_MONS_ORANGE_STATUE:
1014         *ofs_x = -2;
1015         *ofs_y = -3;
1016         break;
1017
1018     case TILEP_MONS_LOROCYPROCA:
1019         *ofs_x = -3;
1020         *ofs_y = 0;
1021         break;
1022
1023     case TILEP_MONS_HELLION:
1024         *ofs_x = 0;
1025         *ofs_y = 4;
1026         break;
1027
1028     case TILEP_MONS_CACODEMON:
1029         *ofs_x = 4;
1030         *ofs_y = -13;
1031         break;
1032
1033     case TILEP_MONS_STARCURSED_MASS:
1034         *ofs_x = -3;
1035         *ofs_y = 2;
1036         break;
1037
1038     case TILEP_MONS_WRETCHED_STAR:
1039         *ofs_x = 1;
1040         *ofs_y = -4;
1041         break;
1042
1043     case TILEP_MONS_ELDRITCH_TENTACLE_PORTAL_9:
1044         *ofs_x = 3;
1045         *ofs_y = 0;
1046         break;
1047
1048     case TILEP_MONS_EXECUTIONER:
1049         *ofs_x = 2;
1050         *ofs_y = 4;
1051         break;
1052
1053     case TILEP_MONS_ICE_FIEND:
1054         *ofs_x = -2;
1055         *ofs_y = 2;
1056         break;
1057
1058     case TILEP_MONS_PANDEMONIUM_LORD:
1059     case TILEP_MONS_ANGEL:
1060     case TILEP_MONS_DAEVA:
1061         *ofs_x = 1;
1062         *ofs_y = 1;
1063         break;
1064
1065     case TILEP_MONS_HELL_SENTINEL:
1066         *ofs_x = 4;
1067         *ofs_y = -5;
1068         break;
1069
1070     case TILEP_MONS_DEMONIC_PLANT:
1071         *ofs_x = 5;
1072         *ofs_y = 2;
1073         break;
1074
1075     case TILEP_MONS_TENTACLED_STARSPAWN:
1076         *ofs_x = 1;
1077         *ofs_y = 1;
1078         break;
1079
1080     case TILEP_MONS_GOBLIN:
1081     case TILEP_MONS_IJYB:
1082         *ofs_x = 1;
1083         *ofs_y = 4;
1084         break;
1085
1086     case TILEP_MONS_ABOMINATION_LARGE_1:
1087         *ofs_x = 2;
1088         *ofs_y = -8;
1089         break;
1090
1091     case TILEP_MONS_ABOMINATION_LARGE_2:
1092         *ofs_x = 2;
1093         *ofs_y = 0;
1094         break;
1095
1096     case TILEP_MONS_ABOMINATION_LARGE_3:
1097         *ofs_x = -2;
1098         *ofs_y = -2;
1099         break;
1100
1101     case TILEP_MONS_ABOMINATION_LARGE_4:
1102         *ofs_x = 2;
1103         *ofs_y = -7;
1104         break;
1105
1106     case TILEP_MONS_ABOMINATION_LARGE_6:
1107         *ofs_x = 3;
1108         *ofs_y = -10;
1109         break;
1110
1111     case TILEP_MONS_CHAOS_SPAWN:
1112         *ofs_x = 0;
1113         *ofs_y = -5;
1114         break;
1115
1116     case TILEP_MONS_CHAOS_SPAWN_2:
1117         *ofs_x = 0;
1118         *ofs_y = -2;
1119         break;
1120
1121     case TILEP_MONS_CHAOS_SPAWN_3:
1122         *ofs_x = 2;
1123         *ofs_y = -1;
1124         break;
1125
1126     case TILEP_MONS_GREAT_ORB_OF_EYES:
1127     case TILEP_MONS_GHOST:
1128         *ofs_x = 2;
1129         *ofs_y = -2;
1130         break;
1131
1132     case TILEP_MONS_MERFOLK_WATER:
1133     case TILEP_MONS_MERFOLK_JAVELINEER_WATER:
1134     case TILEP_MONS_MERFOLK_AQUAMANCER_WATER:
1135         *ofs_x = 1;
1136         *ofs_y = 3;
1137         break;
1138
1139     case TILEP_MONS_MERFOLK_IMPALER_WATER:
1140         *ofs_x = 0;
1141         *ofs_y = 3;
1142         break;
1143
1144     case TILEP_MONS_FRANCES: // left-handed - shield goes in right hand
1145         *ofs_x = -20;
1146         *ofs_y = -1;
1147         break;
1148
1149     case TILEP_MONS_ORB_GUARDIAN:
1150         *ofs_x = 1;
1151         *ofs_y = 0;
1152         break;
1153
1154     case TILEP_MONS_ORB_GUARDIAN_FETUS:
1155         *ofs_x = -8;
1156         *ofs_y = 5;
1157         break;
1158
1159     case TILEP_MONS_JORMUNGANDR:
1160         *ofs_x = -2;
1161         *ofs_y = 2;
1162         break;
1163
1164     case TILEP_MONS_SERAPH:
1165         *ofs_x = -2;
1166         *ofs_y = -7;
1167         break;
1168
1169     case TILEP_MONS_SPRIGGAN_RIDER: // shield covered, out of picture
1170     default:
1171         // This monster cannot be displayed with a shield.
1172         return false;
1173     }
1174
1175     return true;
1176 }
1177
1178 int mcache_monster::info(tile_draw_info *dinfo) const
1179 {
1180     int count = 0;
1181     dinfo[count++].set(m_mon_tile);
1182
1183     int ofs_x, ofs_y;
1184
1185     if (m_equ_tile)
1186     {
1187         bool have_offs = false;
1188         // This mcache is for the player using a custom tile.
1189         if (mtype == MONS_PLAYER
1190             && Options.tile_weapon_offsets.first != INT_MAX)
1191         {
1192             ofs_x = Options.tile_weapon_offsets.first;
1193             ofs_y = Options.tile_weapon_offsets.second;
1194             have_offs = true;
1195         }
1196         else if (get_weapon_offset(m_mon_tile, &ofs_x, &ofs_y))
1197             have_offs = true;
1198
1199         if (have_offs)
1200             dinfo[count++].set(m_equ_tile, ofs_x, ofs_y);
1201     }
1202     if (m_shd_tile)
1203     {
1204         bool have_offs = false;
1205         if (mtype == MONS_PLAYER
1206             && Options.tile_shield_offsets.first != INT_MAX)
1207         {
1208             ofs_x = Options.tile_shield_offsets.first;
1209             ofs_y = Options.tile_shield_offsets.second;
1210             have_offs = true;
1211         }
1212         else if (get_shield_offset(m_mon_tile, &ofs_x, &ofs_y))
1213             have_offs = true;
1214
1215         if (have_offs)
1216             dinfo[count++].set(m_shd_tile, ofs_x, ofs_y);
1217     }
1218     return count;
1219 }
1220
1221 bool mcache_monster::valid(const monster_info& mon)
1222 {
1223     tileidx_t mon_tile = tileidx_monster(mon) & TILE_FLAG_MASK;
1224
1225     int ox, oy;
1226     bool have_weapon_offs = (mon.type == MONS_PLAYER
1227                              && Options.tile_weapon_offsets.first != INT_MAX)
1228         || get_weapon_offset(mon_tile, &ox, &oy);
1229     bool have_shield_offs = (mon.type == MONS_PLAYER
1230                              && Options.tile_shield_offsets.first != INT_MAX)
1231         || get_shield_offset(mon_tile, &ox, &oy);
1232     return (mon.inv[MSLOT_WEAPON].get() != nullptr && have_weapon_offs)
1233         || (mon.inv[MSLOT_SHIELD].get() != nullptr && have_shield_offs);
1234 }
1235
1236 /////////////////////////////////////////////////////////////////////////////
1237 // mcache_draco
1238
1239 mcache_draco::mcache_draco(const monster_info& mon)
1240 {
1241     ASSERT(mcache_draco::valid(mon));
1242     draco = mons_is_draconian(mon.type);
1243
1244     m_mon_tile = draco ? tileidx_draco_base(mon)
1245                        : tileidx_demonspawn_base(mon);
1246     const item_info* mon_wep = mon.inv[MSLOT_WEAPON].get();
1247     m_equ_tile = (mon_wep != nullptr) ? tilep_equ_weapon(*mon_wep) : 0;
1248     mon_wep = mon.inv[MSLOT_SHIELD].get();
1249     m_shd_tile = (mon_wep != nullptr) ? tilep_equ_shield(*mon_wep) : 0;
1250     m_job_tile = draco ? tileidx_draco_job(mon)
1251                        : tileidx_demonspawn_job(mon);
1252 }
1253
1254 int mcache_draco::info(tile_draw_info *dinfo) const
1255 {
1256     int i = 0;
1257
1258     dinfo[i++].set(m_mon_tile);
1259     if (m_job_tile)
1260         dinfo[i++].set(m_job_tile);
1261     if (m_equ_tile)
1262     {
1263         if (draco)
1264             dinfo[i++].set(m_equ_tile, -3, -1);
1265         else
1266             dinfo[i++].set(m_equ_tile, -1, 0);
1267     }
1268     if (m_shd_tile)
1269         dinfo[i++].set(m_shd_tile, 2, 0);
1270
1271     return i;
1272 }
1273
1274 bool mcache_draco::valid(const monster_info& mon)
1275 {
1276     return mons_is_draconian(mon.type) || mons_is_demonspawn(mon.type);
1277 }
1278
1279 /////////////////////////////////////////////////////////////////////////////
1280 // mcache_ghost
1281
1282 mcache_ghost::mcache_ghost(const monster_info& mon)
1283 {
1284     ASSERT(mcache_ghost::valid(mon));
1285
1286     const uint32_t seed = hash32(&mon.mname[0], mon.mname.size())
1287                         ^ hash32(&mon.u.ghost, sizeof(mon.u.ghost));
1288
1289     tilep_race_default(mon.u.ghost.species, 0, &m_doll);
1290     tilep_job_default(mon.u.ghost.job, &m_doll);
1291
1292     for (int p = TILEP_PART_CLOAK; p < TILEP_PART_MAX; p++)
1293     {
1294         if (m_doll.parts[p] == TILEP_SHOW_EQUIP)
1295         {
1296             int part_offset = hash_rand(tile_player_part_count[p], seed, p);
1297             m_doll.parts[p] = tile_player_part_start[p] + part_offset;
1298         }
1299     }
1300
1301     int ac = mon.u.ghost.ac;
1302     ac *= (5 + hash_rand(11, seed, 1000));
1303     ac /= 10;
1304
1305     // Become uncannily spooky!
1306     if (today_is_halloween())
1307         m_doll.parts[TILEP_PART_HELM] = TILEP_HELM_PUMPKIN;
1308
1309     if (ac > 25)
1310         m_doll.parts[TILEP_PART_BODY] = TILEP_BODY_PLATE_BLACK;
1311     else if (ac > 18)
1312         m_doll.parts[TILEP_PART_BODY]= TILEP_BODY_CHAINMAIL;
1313     else if (ac > 12)
1314         m_doll.parts[TILEP_PART_BODY]= TILEP_BODY_SCALEMAIL;
1315     else if (ac > 5)
1316         m_doll.parts[TILEP_PART_BODY]= TILEP_BODY_LEATHER_ARMOUR;
1317     else
1318         m_doll.parts[TILEP_PART_BODY]= TILEP_BODY_ROBE_BLUE;
1319
1320     int sk = mon.u.ghost.best_skill;
1321     int dam = mon.u.ghost.damage;
1322     dam *= (5 + hash_rand(11, seed, 1001));
1323     dam /= 10;
1324
1325     switch (sk)
1326     {
1327     case SK_MACES_FLAILS:
1328         if (dam > 30)
1329             m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_GREAT_FLAIL;
1330         else if (dam > 25)
1331             m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_GREAT_MACE;
1332         else if (dam > 20)
1333             m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_EVENINGSTAR;
1334         else if (dam > 15)
1335             m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_MORNINGSTAR;
1336         else if (dam > 10)
1337             m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_FLAIL;
1338         else if (dam > 5)
1339             m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_MACE;
1340         else
1341             m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_CLUB_SLANT;
1342         break;
1343
1344     case SK_SHORT_BLADES:
1345         if (dam > 20)
1346             m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_RAPIER;
1347         else if (dam > 10)
1348             m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_SHORT_SWORD_SLANT;
1349         else
1350             m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_DAGGER_SLANT;
1351         break;
1352
1353     case SK_LONG_BLADES:
1354         if (dam > 25)
1355             m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_GREAT_SWORD_SLANT;
1356         else if (dam > 20)
1357             m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_KATANA_SLANT;
1358         else if (dam > 15)
1359             m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_SCIMITAR;
1360         else if (dam > 10)
1361             m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_LONG_SWORD_SLANT;
1362         else
1363             m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_FALCHION;
1364         break;
1365
1366     case SK_AXES:
1367         if (dam > 30)
1368             m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_EXECUTIONERS_AXE;
1369         else if (dam > 20)
1370             m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_BATTLEAXE;
1371         else if (dam > 15)
1372             m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_BROAD_AXE;
1373         else if (dam > 10)
1374             m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_WAR_AXE;
1375         else
1376             m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_HAND_AXE;
1377         break;
1378
1379     case SK_POLEARMS:
1380         if (dam > 30)
1381             m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_GLAIVE;
1382         else if (dam > 20)
1383             m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_SCYTHE;
1384         else if (dam > 15)
1385             m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_HALBERD;
1386         else if (dam > 10)
1387             m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_TRIDENT2;
1388         else if (dam > 10)
1389             m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_HAMMER;
1390         else
1391             m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_SPEAR;
1392         break;
1393
1394     case SK_BOWS:
1395         m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_BOW2;
1396         break;
1397
1398     case SK_CROSSBOWS:
1399         m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_ARBALEST;
1400         break;
1401
1402     case SK_SLINGS:
1403         m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_HUNTING_SLING;
1404         break;
1405
1406     case SK_UNARMED_COMBAT:
1407     default:
1408         m_doll.parts[TILEP_PART_HAND1] = m_doll.parts[TILEP_PART_HAND2] = 0;
1409         break;
1410     }
1411 }
1412
1413 const dolls_data *mcache_ghost::doll() const
1414 {
1415     return &m_doll;
1416 }
1417
1418 bool mcache_ghost::valid(const monster_info& mon)
1419 {
1420     return mons_is_pghost(mon.type);
1421 }
1422
1423 bool mcache_ghost::transparent() const
1424 {
1425     return true;
1426 }
1427
1428 /////////////////////////////////////////////////////////////////////////////
1429 // mcache_demon
1430
1431 mcache_demon::mcache_demon(const monster_info& minf)
1432 {
1433     ASSERT(minf.type == MONS_PANDEMONIUM_LORD);
1434
1435     const uint32_t seed = hash32(&minf.mname[0], minf.mname.size());
1436
1437     m_demon.head = tile_player_coloured(TILEP_DEMON_HEAD,
1438                                         element_colour(minf.colour()))
1439         + hash_rand(tile_player_count(TILEP_DEMON_HEAD), seed, 1);
1440     m_demon.body = tile_player_coloured(TILEP_DEMON_BODY,
1441                                         element_colour(minf.colour()))
1442         + hash_rand(tile_player_count(TILEP_DEMON_BODY), seed, 2);
1443
1444     if (minf.fly)
1445     {
1446         m_demon.wings = tile_player_coloured(TILEP_DEMON_WINGS,
1447                                              element_colour(minf.colour()))
1448             + hash_rand(tile_player_count(TILEP_DEMON_WINGS), seed, 3);
1449     }
1450     else
1451         m_demon.wings = 0;
1452 }
1453
1454 int mcache_demon::info(tile_draw_info *dinfo) const
1455 {
1456     if (m_demon.wings)
1457     {
1458         dinfo[0].set(m_demon.wings);
1459         dinfo[1].set(m_demon.body);
1460         dinfo[2].set(m_demon.head);
1461         return 3;
1462     }
1463     else
1464     {
1465         dinfo[0].set(m_demon.body);
1466         dinfo[1].set(m_demon.head);
1467         return 2;
1468     }
1469 }
1470
1471 bool mcache_demon::valid(const monster_info& mon)
1472 {
1473     return mon.type == MONS_PANDEMONIUM_LORD;
1474 }
1475
1476 #endif