Apply the new ground_level method.
[crawl.git] / crawl-ref / source / tilemcache.cc
blob17c64cea9ad0792ed630ed05ecd4ac067376cb33
1 #include "AppHdr.h"
3 #ifdef USE_TILE
4 #include "tilemcache.h"
6 #include "env.h"
7 #include "ghost.h"
8 #include "mon-util.h"
9 #include "tags.h"
10 #include "tiledef-player.h"
11 #include "tilepick.h"
12 #include "tilepick-p.h"
14 mcache_manager mcache;
16 // Used internally for streaming.
17 enum mcache_type
19 MCACHE_MONSTER,
20 MCACHE_DRACO,
21 MCACHE_GHOST,
22 MCACHE_DEMON,
23 MCACHE_MAX,
25 MCACHE_NULL,
28 struct demon_data
30 demon_data() { head = body = wings = 0; }
32 tileidx_t head;
33 tileidx_t body;
34 tileidx_t wings;
37 // Custom marshall/unmarshall functions.
38 static void unmarshallDoll(reader &th, dolls_data &doll)
40 for (unsigned int i = 0; i < TILEP_PART_MAX; i++)
41 doll.parts[i] = unmarshallInt(th);
44 static void marshallDoll(writer &th, const dolls_data &doll)
46 for (unsigned int i = 0; i < TILEP_PART_MAX; i++)
47 marshallInt(th, doll.parts[i]);
50 static void unmarshallDemon(reader &th, demon_data &demon)
52 demon.head = unmarshallInt(th);
53 demon.body = unmarshallInt(th);
54 demon.wings = unmarshallInt(th);
57 static void marshallDemon(writer &th, const demon_data &demon)
59 marshallInt(th, demon.head);
60 marshallInt(th, demon.body);
61 marshallInt(th, demon.wings);
64 // Internal mcache classes. The mcache_manager creates these internally.
65 // The only access external clients need is through the virtual
66 // info function.
68 class mcache_monster : public mcache_entry
70 public:
71 mcache_monster(const monster* mon);
72 mcache_monster(reader &th);
74 virtual int info(tile_draw_info *dinfo) const;
76 static bool valid(const monster* mon);
78 static bool get_weapon_offset(tileidx_t mon_tile, int *ofs_x, int *ofs_y);
80 virtual void construct(writer &th);
82 protected:
83 tileidx_t m_mon_tile;
84 tileidx_t m_equ_tile;
87 class mcache_draco : public mcache_entry
89 public:
90 mcache_draco(const monster* mon);
91 mcache_draco(reader &th);
93 virtual int info(tile_draw_info *dinfo) const;
95 static bool valid(const monster* mon);
97 virtual void construct(writer &th);
99 protected:
100 tileidx_t m_mon_tile;
101 tileidx_t m_job_tile;
102 tileidx_t m_equ_tile;
105 class mcache_ghost : public mcache_entry
107 public:
108 mcache_ghost(const monster* mon);
109 mcache_ghost(reader &th);
111 virtual const dolls_data *doll() const;
113 static bool valid(const monster* mon);
115 virtual void construct(writer &th);
117 virtual bool transparent() const;
119 protected:
120 dolls_data m_doll;
123 class mcache_demon : public mcache_entry
125 public:
126 mcache_demon(const monster* mon);
127 mcache_demon(reader &th);
129 virtual int info(tile_draw_info *dinfo) const;
131 static bool valid(const monster* mon);
133 virtual void construct(writer &th);
135 protected:
136 demon_data m_demon;
139 /////////////////////////////////////////////////////////////////////////////
140 // tile_fg_store
142 tileidx_t tile_fg_store::operator=(tileidx_t tile)
144 if ((tile & TILE_FLAG_MASK) == (m_tile & TILE_FLAG_MASK))
146 // Update, as flags may have changed.
147 m_tile = tile;
148 return m_tile;
151 mcache_entry *old_entry = mcache.get(m_tile);
152 if (old_entry)
153 old_entry->dec_ref();
155 m_tile = tile;
157 mcache_entry *new_entry = mcache.get(m_tile);
158 if (new_entry)
159 new_entry->inc_ref();
161 return m_tile;
165 /////////////////////////////////////////////////////////////////////////////
166 // mcache_manager
168 mcache_manager::~mcache_manager()
170 clear_all();
173 unsigned int mcache_manager::register_monster(const monster* mon)
175 ASSERT(mon);
176 if (!mon)
177 return 0;
179 // TODO enne - is it worth it to search against all mcache entries?
180 // TODO enne - pool mcache types to avoid too much alloc/dealloc?
182 mcache_entry *entry;
184 if (mcache_demon::valid(mon))
185 entry = new mcache_demon(mon);
186 else if (mcache_ghost::valid(mon))
187 entry = new mcache_ghost(mon);
188 else if (mcache_draco::valid(mon))
189 entry = new mcache_draco(mon);
190 else if (mcache_monster::valid(mon))
191 entry = new mcache_monster(mon);
192 else
193 return 0;
195 tileidx_t idx = ~0;
197 for (unsigned int i = 0; i < m_entries.size(); i++)
199 if (!m_entries[i])
201 m_entries[i] = entry;
202 idx = i;
203 break;
207 if (idx > m_entries.size())
209 idx = m_entries.size();
210 m_entries.push_back(entry);
213 return (TILEP_MCACHE_START + idx);
216 void mcache_manager::clear_nonref()
218 for (unsigned int i = 0; i < m_entries.size(); i++)
220 if (!m_entries[i] || m_entries[i]->ref_count() > 0)
221 continue;
223 delete m_entries[i];
224 m_entries[i] = NULL;
228 void mcache_manager::clear_all()
230 for (unsigned int i = 0; i < m_entries.size(); i++)
231 delete m_entries[i];
233 m_entries.resize(0);
236 mcache_entry *mcache_manager::get(tileidx_t tile)
238 tileidx_t idx = tile & TILE_FLAG_MASK;
239 if (idx < TILEP_MCACHE_START)
240 return (NULL);
242 if (idx >= TILEP_MCACHE_START + m_entries.size())
243 return (NULL);
245 mcache_entry *entry = m_entries[idx - TILEP_MCACHE_START];
246 return (entry);
249 void mcache_manager::read(reader &th)
251 unsigned int size = unmarshallInt(th);
252 m_entries.reserve(size);
253 m_entries.clear();
255 for (unsigned int i = 0; i < size; i++)
257 char type = unmarshallByte(th);
259 mcache_entry *entry;
260 switch (type)
262 case MCACHE_MONSTER:
263 entry = new mcache_monster(th);
264 break;
265 case MCACHE_DRACO:
266 entry = new mcache_draco(th);
267 break;
268 case MCACHE_GHOST:
269 entry = new mcache_ghost(th);
270 break;
271 case MCACHE_DEMON:
272 entry = new mcache_demon(th);
273 break;
274 default:
275 die("Invalid streamed mcache type.");
276 case MCACHE_NULL:
277 entry = NULL;
278 break;
281 m_entries.push_back(entry);
285 void mcache_manager::construct(writer &th)
287 marshallInt(th, m_entries.size());
288 for (unsigned int i = 0; i < m_entries.size(); i++)
290 if (m_entries[i] == NULL)
292 marshallByte(th, MCACHE_NULL);
293 continue;
296 if (dynamic_cast<mcache_monster*>(m_entries[i]))
297 marshallByte(th, MCACHE_MONSTER);
298 else if (dynamic_cast<mcache_draco*>(m_entries[i]))
299 marshallByte(th, MCACHE_DRACO);
300 else if (dynamic_cast<mcache_ghost*>(m_entries[i]))
301 marshallByte(th, MCACHE_GHOST);
302 else if (dynamic_cast<mcache_demon*>(m_entries[i]))
303 marshallByte(th, MCACHE_DEMON);
304 else
306 marshallByte(th, MCACHE_NULL);
307 continue;
310 m_entries[i]->construct(th);
314 /////////////////////////////////////////////////////////////////////////////
315 // mcache_entry
317 mcache_entry::mcache_entry(reader &th)
319 m_ref_count = unmarshallInt(th);
322 void mcache_entry::construct(writer &th)
324 marshallInt(th, m_ref_count);
327 /////////////////////////////////////////////////////////////////////////////
328 // mcache_monster
330 mcache_monster::mcache_monster(const monster* mon)
332 ASSERT(mcache_monster::valid(mon));
334 m_mon_tile = tileidx_monster(mon) & TILE_FLAG_MASK;
336 const int mon_wep = mon->inv[MSLOT_WEAPON];
337 m_equ_tile = tilep_equ_weapon(mitm[mon_wep]);
340 // Returns the amount of pixels necessary to shift a wielded weapon
341 // from its default placement. Tiles showing monsters already wielding
342 // a weapon should not be listed here.
343 bool mcache_monster::get_weapon_offset(tileidx_t mon_tile,
344 int *ofs_x, int *ofs_y)
346 switch (mon_tile)
348 // No shift necessary.
349 case TILEP_MONS_VAULT_GUARD:
350 case TILEP_MONS_DEEP_ELF_MASTER_ARCHER:
351 case TILEP_MONS_DEEP_ELF_BLADEMASTER:
352 case TILEP_MONS_IMP:
353 case TILEP_MONS_IRON_IMP:
354 case TILEP_MONS_SHADOW_IMP:
355 case TILEP_MONS_NORRIS:
356 case TILEP_MONS_MAUD:
357 case TILEP_MONS_EDMUND:
358 case TILEP_MONS_FRANCES:
359 case TILEP_MONS_HAROLD:
360 case TILEP_MONS_JOSEPH:
361 case TILEP_MONS_JOZEF:
362 case TILEP_MONS_RUPERT:
363 case TILEP_MONS_TERENCE:
364 case TILEP_MONS_WIGLAF:
365 case TILEP_MONS_FREDERICK:
366 case TILEP_MONS_RAKSHASA:
367 case TILEP_MONS_RAKSHASA_FAKE:
368 case TILEP_MONS_VAMPIRE_KNIGHT:
369 case TILEP_MONS_SKELETAL_WARRIOR:
370 case TILEP_MONS_ANGEL:
371 case TILEP_MONS_CHERUB:
372 case TILEP_MONS_MERFOLK:
373 case TILEP_MONS_MERFOLK_WATER:
374 case TILEP_MONS_MERFOLK_JAVELINEER:
375 case TILEP_MONS_MERFOLK_JAVELINEER_WATER:
376 case TILEP_MONS_MERFOLK_IMPALER:
377 case TILEP_MONS_MERFOLK_IMPALER_WATER:
378 case TILEP_MONS_MERFOLK_AQUAMANCER:
379 case TILEP_MONS_MERFOLK_AQUAMANCER_WATER:
380 case TILEP_MONS_MERMAID:
381 case TILEP_MONS_MERMAID_WATER:
382 case TILEP_MONS_SIREN:
383 case TILEP_MONS_SIREN_WATER:
384 case TILEP_MONS_ILSUIW:
385 case TILEP_MONS_ILSUIW_WATER:
386 case TILEP_MONS_SPRIGGAN:
387 case TILEP_MONS_KENKU:
388 case TILEP_MONS_DEEP_DWARF_ARTIFICER:
389 case TILEP_MONS_DEEP_DWARF_DEATH_KNIGHT:
390 case TILEP_MONS_KOBOLD:
391 *ofs_x = 0;
392 *ofs_y = 0;
393 break;
394 // Shift to the left.
395 case TILEP_MONS_GNOLL:
396 case TILEP_MONS_GRUM:
397 case TILEP_MONS_CRAZY_YIUF:
398 case TILEP_MONS_DEEP_ELF_DEATH_MAGE:
399 case TILEP_MONS_SPRIGGAN_DEFENDER:
400 case TILEP_MONS_SPRIGGAN_BERSERKER:
401 case TILEP_MONS_BIG_KOBOLD:
402 *ofs_x = -1;
403 *ofs_y = 0;
404 break;
405 case TILEP_MONS_HOBGOBLIN:
406 case TILEP_MONS_TIAMAT:
407 case TILEP_MONS_TIAMAT+1:
408 case TILEP_MONS_TIAMAT+2:
409 case TILEP_MONS_TIAMAT+3:
410 case TILEP_MONS_TIAMAT+4:
411 case TILEP_MONS_TIAMAT+5:
412 case TILEP_MONS_TIAMAT+6:
413 case TILEP_MONS_TIAMAT+7:
414 case TILEP_MONS_TIAMAT+8:
415 *ofs_x = -2;
416 *ofs_y = 0;
417 break;
418 // Shift to the right.
419 case TILEP_MONS_DEMONSPAWN:
420 *ofs_x = 1;
421 *ofs_y = 0;
422 break;
423 case TILEP_MONS_YAKTAUR_MELEE:
424 *ofs_x = 2;
425 *ofs_y = 0;
426 break;
427 case TILEP_MONS_YAKTAUR_CAPTAIN_MELEE:
428 *ofs_x = 4;
429 *ofs_y = 0;
430 break;
431 case TILEP_MONS_FIRE_GIANT:
432 *ofs_x = 5;
433 *ofs_y = 0;
434 break;
435 // Shift upwards.
436 case TILEP_MONS_CENTAUR_WARRIOR_MELEE:
437 case TILEP_MONS_DEEP_ELF_SORCERER:
438 case TILEP_MONS_DEEP_ELF_HIGH_PRIEST:
439 *ofs_x = 0;
440 *ofs_y = -1;
441 break;
442 case TILEP_MONS_MIDGE:
443 *ofs_x = 0;
444 *ofs_y = -2;
445 break;
446 // Shift downwards.
447 case TILEP_MONS_DEEP_ELF_KNIGHT:
448 case TILEP_MONS_NAGA:
449 case TILEP_MONS_GREATER_NAGA:
450 case TILEP_MONS_NAGA_WARRIOR:
451 case TILEP_MONS_GUARDIAN_SERPENT:
452 case TILEP_MONS_NAGA_MAGE:
453 case TILEP_MONS_THE_ENCHANTRESS:
454 case TILEP_MONS_DEEP_DWARF:
455 case TILEP_MONS_DEEP_DWARF_SCION:
456 case TILEP_MONS_DEEP_DWARF_BERSERKER:
457 *ofs_x = 0;
458 *ofs_y = 1;
459 break;
460 case TILEP_MONS_ORC:
461 case TILEP_MONS_URUG:
462 case TILEP_MONS_BLORK_THE_ORC:
463 case TILEP_MONS_SAINT_ROKA:
464 case TILEP_MONS_ORC_WARRIOR:
465 case TILEP_MONS_ORC_KNIGHT:
466 case TILEP_MONS_ORC_WARLORD:
467 case TILEP_MONS_BOGGART:
468 case TILEP_MONS_DEEP_ELF_FIGHTER:
469 case TILEP_MONS_DEEP_ELF_SOLDIER:
470 case TILEP_MONS_DEEP_DWARF_NECROMANCER:
471 case TILEP_MONS_UNBORN_DEEP_DWARF:
472 *ofs_x = 0;
473 *ofs_y = 2;
474 break;
475 // Shift upwards and to the left.
476 case TILEP_MONS_DEEP_ELF_MAGE:
477 case TILEP_MONS_DEEP_ELF_SUMMONER:
478 case TILEP_MONS_DEEP_ELF_CONJURER:
479 case TILEP_MONS_DEEP_ELF_PRIEST:
480 case TILEP_MONS_DEEP_ELF_DEMONOLOGIST:
481 case TILEP_MONS_DEEP_ELF_ANNIHILATOR:
482 *ofs_x = -1;
483 *ofs_y = -2;
484 break;
485 case TILEP_MONS_CENTAUR_MELEE:
486 *ofs_x = -1;
487 *ofs_y = -3;
488 break;
489 case TILEP_MONS_SONJA:
490 *ofs_x = -2;
491 *ofs_y = -2;
492 break;
493 // Shift upwards and to the right.
494 case TILEP_MONS_AGNES:
495 *ofs_x = 1;
496 *ofs_y = -3;
497 break;
498 case TILEP_MONS_WIZARD:
499 *ofs_x = 2;
500 *ofs_y = -2;
501 break;
502 case TILEP_MONS_RED_DEVIL:
503 *ofs_x = 2;
504 *ofs_y = -3;
505 break;
506 // Shift downwards and to the left.
507 case TILEP_MONS_HELL_KNIGHT:
508 *ofs_x = -1;
509 *ofs_y = 3;
510 break;
511 case TILEP_MONS_GOBLIN:
512 case TILEP_MONS_IJYB:
513 *ofs_x = -2;
514 *ofs_y = 4;
515 break;
516 // Shift downwards and to the right.
517 case TILEP_MONS_ETTIN:
518 *ofs_x = 2;
519 *ofs_y = 1;
520 break;
521 case TILEP_MONS_FROST_GIANT:
522 *ofs_x = 2;
523 *ofs_y = 3;
524 break;
525 case TILEP_MONS_TRAINING_DUMMY:
526 *ofs_x = 3;
527 *ofs_y = 2;
528 break;
529 case TILEP_MONS_ELF:
530 case TILEP_MONS_ZOMBIE_LARGE:
531 *ofs_x = 4;
532 *ofs_y = 1;
533 break;
534 case TILEP_MONS_HALFLING:
535 *ofs_x = 4;
536 *ofs_y = 2;
537 break;
538 case TILEP_MONS_ZOMBIE_SMALL:
539 *ofs_x = 4;
540 *ofs_y = 3;
541 break;
542 case TILEP_MONS_HUMAN:
543 *ofs_x = 5;
544 *ofs_y = 2;
545 break;
546 case TILEP_MONS_HILL_GIANT:
547 *ofs_x = 6;
548 *ofs_y = 2;
549 break;
550 default:
551 // This monster cannot be displayed with a weapon.
552 return (false);
555 return (true);
558 int mcache_monster::info(tile_draw_info *dinfo) const
560 int ofs_x, ofs_y;
561 get_weapon_offset(m_mon_tile, &ofs_x, &ofs_y);
563 int count = 0;
564 dinfo[count++].set(m_mon_tile);
565 if (m_equ_tile)
566 dinfo[count++].set(m_equ_tile, ofs_x, ofs_y);
568 // In some cases, overlay a second weapon tile...
569 if (m_mon_tile == TILEP_MONS_DEEP_ELF_BLADEMASTER)
571 tileidx_t eq2;
572 switch (m_equ_tile)
574 case TILEP_HAND1_DAGGER:
575 eq2 = TILEP_HAND2_DAGGER;
576 break;
577 case TILEP_HAND1_SABRE:
578 eq2 = TILEP_HAND2_SABRE;
579 break;
580 default:
581 case TILEP_HAND1_SHORT_SWORD_SLANT:
582 eq2 = TILEP_HAND2_SHORT_SWORD_SLANT;
583 break;
586 if (eq2)
587 dinfo[count++].set(eq2, -ofs_x, ofs_y);
590 return (count);
593 bool mcache_monster::valid(const monster* mon)
595 if (!mon)
596 return (false);
597 int mon_wep = mon->inv[MSLOT_WEAPON];
598 if (mon_wep == NON_ITEM)
599 return (false);
601 tileidx_t mon_tile = tileidx_monster(mon) & TILE_FLAG_MASK;
603 int ox, oy;
604 return get_weapon_offset(mon_tile, &ox, &oy);
607 mcache_monster::mcache_monster(reader &th) : mcache_entry(th)
609 m_mon_tile = unmarshallInt(th);
610 m_equ_tile = unmarshallInt(th);
613 void mcache_monster::construct(writer &th)
615 mcache_entry::construct(th);
617 marshallInt(th, m_mon_tile);
618 marshallInt(th, m_equ_tile);
621 /////////////////////////////////////////////////////////////////////////////
622 // mcache_draco
624 mcache_draco::mcache_draco(const monster* mon)
626 ASSERT(mcache_draco::valid(mon));
628 m_mon_tile = tileidx_draco_base(mon);
629 int mon_wep = mon->inv[MSLOT_WEAPON];
630 m_equ_tile = (mon_wep != NON_ITEM) ? tilep_equ_weapon(mitm[mon_wep]) : 0;
631 m_job_tile = tileidx_draco_job(mon);
634 int mcache_draco::info(tile_draw_info *dinfo) const
636 int i = 0;
638 dinfo[i++].set(m_mon_tile);
639 if (m_job_tile)
640 dinfo[i++].set(m_job_tile);
641 if (m_equ_tile)
642 dinfo[i++].set(m_equ_tile, -2, 0);
644 return i;
647 bool mcache_draco::valid(const monster* mon)
649 return (mon && mons_is_draconian(mon->type));
652 mcache_draco::mcache_draco(reader &th) : mcache_entry(th)
654 m_mon_tile = unmarshallInt(th);
655 m_job_tile = unmarshallInt(th);
656 m_equ_tile = unmarshallInt(th);
659 void mcache_draco::construct(writer &th)
661 mcache_entry::construct(th);
663 marshallInt(th, m_mon_tile);
664 marshallInt(th, m_job_tile);
665 marshallInt(th, m_equ_tile);
668 /////////////////////////////////////////////////////////////////////////////
669 // mcache_ghost
671 mcache_ghost::mcache_ghost(const monster* mon)
673 ASSERT(mcache_ghost::valid(mon));
675 const class ghost_demon &ghost = *mon->ghost;
677 unsigned int pseudo_rand = ghost.max_hp * 54321 * 54321;
679 tilep_race_default(ghost.species, ghost.xl, &m_doll);
680 tilep_job_default(ghost.job, &m_doll);
682 for (int p = TILEP_PART_CLOAK; p < TILEP_PART_MAX; p++)
684 if (m_doll.parts[p] == TILEP_SHOW_EQUIP)
686 int part_offset = pseudo_rand % tile_player_part_count[p];
687 m_doll.parts[p] = tile_player_part_start[p] + part_offset;
691 int ac = ghost.ac;
692 ac *= (5 + (pseudo_rand / 11) % 11);
693 ac /= 10;
695 if (ac > 25)
696 m_doll.parts[TILEP_PART_BODY] = TILEP_BODY_PLATE_BLACK;
697 else if (ac > 20)
698 m_doll.parts[TILEP_PART_BODY]= TILEP_BODY_BANDED;
699 else if (ac > 15)
700 m_doll.parts[TILEP_PART_BODY]= TILEP_BODY_SCALEMAIL;
701 else if (ac > 10)
702 m_doll.parts[TILEP_PART_BODY]= TILEP_BODY_CHAINMAIL;
703 else if (ac > 5)
704 m_doll.parts[TILEP_PART_BODY]= TILEP_BODY_LEATHER_HEAVY;
705 else
706 m_doll.parts[TILEP_PART_BODY]= TILEP_BODY_ROBE_BLUE;
708 int sk = ghost.best_skill;
709 int dam = ghost.damage;
710 dam *= (5 + pseudo_rand % 11);
711 dam /= 10;
713 switch (sk)
715 case SK_MACES_FLAILS:
716 if (dam > 30)
717 m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_GREAT_FLAIL;
718 else if (dam > 25)
719 m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_GREAT_MACE;
720 else if (dam > 20)
721 m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_SPIKED_FLAIL;
722 else if (dam > 15)
723 m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_MORNINGSTAR;
724 else if (dam > 10)
725 m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_FLAIL;
726 else if (dam > 5)
727 m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_MACE;
728 else
729 m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_CLUB_SLANT;
730 break;
732 case SK_SHORT_BLADES:
733 if (dam > 20)
734 m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_SABRE;
735 else if (dam > 10)
736 m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_SHORT_SWORD_SLANT;
737 else
738 m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_DAGGER_SLANT;
739 break;
741 case SK_LONG_BLADES:
742 if (dam > 25)
743 m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_GREAT_SWORD_SLANT;
744 else if (dam > 20)
745 m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_KATANA_SLANT;
746 else if (dam > 15)
747 m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_SCIMITAR;
748 else if (dam > 10)
749 m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_LONG_SWORD_SLANT;
750 else
751 m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_FALCHION;
752 break;
754 case SK_AXES:
755 if (dam > 30)
756 m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_EXECUTIONERS_AXE;
757 else if (dam > 20)
758 m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_BATTLEAXE;
759 else if (dam > 15)
760 m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_BROAD_AXE;
761 else if (dam > 10)
762 m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_WAR_AXE;
763 else
764 m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_HAND_AXE;
765 break;
767 case SK_POLEARMS:
768 if (dam > 30)
769 m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_GLAIVE;
770 else if (dam > 20)
771 m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_SCYTHE;
772 else if (dam > 15)
773 m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_HALBERD;
774 else if (dam > 10)
775 m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_TRIDENT2;
776 else if (dam > 10)
777 m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_HAMMER;
778 else
779 m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_SPEAR;
780 break;
782 case SK_BOWS:
783 m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_BOW2;
784 break;
786 case SK_CROSSBOWS:
787 m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_CROSSBOW;
788 break;
790 case SK_SLINGS:
791 m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_SLING;
792 break;
794 case SK_UNARMED_COMBAT:
795 default:
796 m_doll.parts[TILEP_PART_HAND1] = m_doll.parts[TILEP_PART_HAND2] = 0;
797 break;
801 const dolls_data *mcache_ghost::doll() const
803 return &m_doll;
806 bool mcache_ghost::valid(const monster* mon)
808 return (mon && mons_is_pghost(mon->type));
811 mcache_ghost::mcache_ghost(reader &th) : mcache_entry(th)
813 unmarshallDoll(th, m_doll);
816 void mcache_ghost::construct(writer &th)
818 mcache_entry::construct(th);
820 marshallDoll(th, m_doll);
823 bool mcache_ghost::transparent() const
825 return (true);
828 /////////////////////////////////////////////////////////////////////////////
829 // mcache_demon
831 mcache_demon::mcache_demon(const monster* mon)
833 ASSERT(mcache_demon::valid(mon));
835 const class ghost_demon &ghost = *mon->ghost;
837 unsigned int pseudo_rand1 = ghost.max_hp * 54321 * 54321;
838 unsigned int pseudo_rand2 = ghost.ac * 54321 * 54321;
839 unsigned int pseudo_rand3 = ghost.ev * 54321 * 54321;
841 int head_offset = pseudo_rand1 % tile_player_count(TILEP_DEMON_HEAD);
842 m_demon.head = TILEP_DEMON_HEAD + head_offset;
844 int body_offset = pseudo_rand2 % tile_player_count(TILEP_DEMON_BODY);
845 m_demon.body = TILEP_DEMON_BODY + body_offset;
847 if (ghost.ev % 2)
849 int wings_offset = pseudo_rand3 % tile_player_count(TILEP_DEMON_WINGS);
850 m_demon.wings = TILEP_DEMON_WINGS + wings_offset;
852 else
853 m_demon.wings = 0;
856 int mcache_demon::info(tile_draw_info *dinfo) const
858 if (m_demon.wings)
860 dinfo[0].set(m_demon.wings);
861 dinfo[1].set(m_demon.body);
862 dinfo[2].set(m_demon.head);
863 return 3;
865 else
867 dinfo[0].set(m_demon.body);
868 dinfo[1].set(m_demon.head);
869 return 2;
873 bool mcache_demon::valid(const monster* mon)
875 return (mon && mon->type == MONS_PANDEMONIUM_DEMON);
878 mcache_demon::mcache_demon(reader &th) : mcache_entry(th)
880 unmarshallDemon(th, m_demon);
883 void mcache_demon::construct(writer &th)
885 mcache_entry::construct(th);
887 marshallDemon(th, m_demon);
890 #endif