/* * File: tilepick.cc * Created by: ennewalker on Sat Jan 5 01:33:53 2008 UTC */ #include "AppHdr.h" #ifdef USE_TILE #include #include "artefact.h" #include "decks.h" #include "colour.h" #include "coord.h" #include "coordit.h" #include "directn.h" #include "env.h" #include "map_knowledge.h" #include "fprop.h" #include "externs.h" #include "options.h" #include "food.h" #include "itemname.h" #include "items.h" #include "itemprop.h" #include "kills.h" #include "macro.h" #include "mon-stuff.h" #include "mon-util.h" #include "player.h" #include "shopping.h" #include "showsymb.h" #include "spells3.h" // for the halo #include "stuff.h" #include "terrain.h" #include "tiles.h" #include "tilemcache.h" #include "tiledef-dngn.h" #include "tiledef-player.h" #include "tiledef-gui.h" #include "tiledef-unrand.h" #include "transform.h" #include "traps.h" #include "travel.h" #include "view.h" #include "viewgeom.h" void TileNewLevel(bool first_time) { tiles.clear_minimap(); for (unsigned int x = 0; x < GXM; x++) for (unsigned int y = 0; y < GYM; y++) tiles.update_minimap(x, y); if (first_time) tile_init_flavour(); if (!player_in_mappable_area() || first_time) { for (unsigned int x = 0; x < GXM; x++) for (unsigned int y = 0; y < GYM; y++) { env.tile_bk_fg[x][y] = 0; env.tile_bk_bg[x][y] = TILE_DNGN_UNSEEN; } } // Fix up stair markers. The travel information isn't hooked up // until after we change levels. So, look through all of the stairs // on this level and check if they still need the stair flag. for (unsigned int x = 0; x < GXM; x++) for (unsigned int y = 0; y < GYM; y++) { unsigned int tile = env.tile_bk_bg[x][y]; if (!(tile & TILE_FLAG_NEW_STAIR)) continue; if (!is_unknown_stair(coord_def(x,y))) env.tile_bk_bg[x][y] &= ~TILE_FLAG_NEW_STAIR; } } /**** tile index routines ****/ int tile_unseen_flag(const coord_def& gc) { if (!map_bounds(gc)) return TILE_FLAG_UNSEEN; else if (is_terrain_known(gc) && !is_terrain_seen(gc) || is_map_knowledge_detected_item(gc) || is_map_knowledge_detected_mons(gc)) { return TILE_FLAG_MM_UNSEEN; } else return TILE_FLAG_UNSEEN; } // Special case for *taurs which have a different tile // for when they have a bow. static int _bow_offset(const monsters *mon) { int mon_wep = mon->inv[MSLOT_WEAPON]; if (mon_wep == NON_ITEM) return (1); switch (mitm[mon_wep].sub_type) { case WPN_BOW: case WPN_LONGBOW: case WPN_CROSSBOW: return (0); default: return (1); } } static int _get_random_monster_tile(const monsters *mon, const int base_tile) { if (!mon->props.exists("tile_num")) return (base_tile); const int variants = tile_player_count(base_tile); return base_tile + (mon->props["tile_num"].get_short() % variants); } int tileidx_monster_base(const monsters *mon, bool detected) { bool in_water = feat_is_water(grd(mon->pos())); int type = mon->type; if (!crawl_state.arena && you.misled()) type = mon->get_mislead_type(); // Show only base class for detected monsters. if (detected) type = mons_detected_base(mon->type); if (mon->props.exists("monster_tile")) return int(mon->props["monster_tile"].get_short()); switch (type) { // program bug case MONS_PROGRAM_BUG: return TILEP_MONS_PROGRAM_BUG; // insects ('a') case MONS_GIANT_COCKROACH: return TILEP_MONS_GIANT_COCKROACH; case MONS_GIANT_ANT: return TILEP_MONS_GIANT_ANT; case MONS_SOLDIER_ANT: return TILEP_MONS_SOLDIER_ANT; // batty monsters ('b') case MONS_GIANT_BAT: return TILEP_MONS_GIANT_BAT; case MONS_BUTTERFLY: return TILEP_MONS_BUTTERFLY + ((mon->colour) % 7); // centaurs ('c') case MONS_CENTAUR: return TILEP_MONS_CENTAUR + _bow_offset(mon); case MONS_CENTAUR_WARRIOR: return TILEP_MONS_CENTAUR_WARRIOR + _bow_offset(mon); case MONS_YAKTAUR: return TILEP_MONS_YAKTAUR + _bow_offset(mon); case MONS_YAKTAUR_CAPTAIN: return TILEP_MONS_YAKTAUR_CAPTAIN + _bow_offset(mon); // draconians ('d'): case MONS_DRACONIAN: return TILEP_DRACO_BASE; // elves ('e') case MONS_ELF: return TILEP_MONS_ELF; case MONS_DEEP_ELF_SOLDIER: return TILEP_MONS_DEEP_ELF_SOLDIER; case MONS_DEEP_ELF_FIGHTER: return TILEP_MONS_DEEP_ELF_FIGHTER; case MONS_DEEP_ELF_KNIGHT: return TILEP_MONS_DEEP_ELF_KNIGHT; case MONS_DEEP_ELF_MAGE: return TILEP_MONS_DEEP_ELF_MAGE; case MONS_DEEP_ELF_SUMMONER: return TILEP_MONS_DEEP_ELF_SUMMONER; case MONS_DEEP_ELF_CONJURER: return TILEP_MONS_DEEP_ELF_CONJURER; case MONS_DEEP_ELF_PRIEST: return TILEP_MONS_DEEP_ELF_PRIEST; case MONS_DEEP_ELF_HIGH_PRIEST: return TILEP_MONS_DEEP_ELF_HIGH_PRIEST; case MONS_DEEP_ELF_DEMONOLOGIST: return TILEP_MONS_DEEP_ELF_DEMONOLOGIST; case MONS_DEEP_ELF_ANNIHILATOR: return TILEP_MONS_DEEP_ELF_ANNIHILATOR; case MONS_DEEP_ELF_SORCERER: return TILEP_MONS_DEEP_ELF_SORCERER; case MONS_DEEP_ELF_DEATH_MAGE: return TILEP_MONS_DEEP_ELF_DEATH_MAGE; case MONS_DEEP_ELF_BLADEMASTER: return TILEP_MONS_DEEP_ELF_BLADEMASTER; case MONS_DEEP_ELF_MASTER_ARCHER: return TILEP_MONS_DEEP_ELF_MASTER_ARCHER; // fungi ('f') case MONS_BALLISTOMYCETE: if (!detected && mon->has_ench(ENCH_SPORE_PRODUCTION)) return TILEP_MONS_BALLISTOMYCETE_ACTIVE; return TILEP_MONS_BALLISTOMYCETE_INACTIVE; case MONS_TOADSTOOL: return _get_random_monster_tile(mon, TILEP_MONS_TOADSTOOL); case MONS_FUNGUS: return TILEP_MONS_FUNGUS; case MONS_WANDERING_MUSHROOM: return TILEP_MONS_WANDERING_MUSHROOM; // goblins ('g') case MONS_GOBLIN: return TILEP_MONS_GOBLIN; case MONS_HOBGOBLIN: return TILEP_MONS_HOBGOBLIN; case MONS_GNOLL: return TILEP_MONS_GNOLL; case MONS_BOGGART: return TILEP_MONS_BOGGART; // hounds ('h') case MONS_JACKAL: return TILEP_MONS_JACKAL; case MONS_HOUND: return TILEP_MONS_HOUND; case MONS_WARG: return TILEP_MONS_WARG; case MONS_WOLF: return TILEP_MONS_WOLF; case MONS_WAR_DOG: return TILEP_MONS_WAR_DOG; case MONS_HOG: return TILEP_MONS_HOG; case MONS_HELL_HOUND: return TILEP_MONS_HELL_HOUND; case MONS_HELL_HOG: return TILEP_MONS_HELL_HOG; // slugs ('j') case MONS_ELEPHANT_SLUG: return TILEP_MONS_ELEPHANT_SLUG; case MONS_GIANT_SLUG: return TILEP_MONS_GIANT_SLUG; case MONS_GIANT_SNAIL: return TILEP_MONS_GIANT_SNAIL; // killer bees ('k') case MONS_KILLER_BEE: return TILEP_MONS_KILLER_BEE; case MONS_BUMBLEBEE: return TILEP_MONS_BUMBLEBEE; // lizards ('l') case MONS_GIANT_NEWT: return TILEP_MONS_GIANT_NEWT; case MONS_GIANT_GECKO: return TILEP_MONS_GIANT_GECKO; case MONS_GIANT_IGUANA: return TILEP_MONS_GIANT_IGUANA; case MONS_GIANT_LIZARD: return TILEP_MONS_GIANT_LIZARD; case MONS_GILA_MONSTER: return TILEP_MONS_GILA_MONSTER; case MONS_KOMODO_DRAGON: return TILEP_MONS_KOMODO_DRAGON; // drakes (also 'l', but dragon type) case MONS_SWAMP_DRAKE: return TILEP_MONS_SWAMP_DRAKE; case MONS_FIRE_DRAKE: return TILEP_MONS_FIRE_DRAKE; case MONS_LINDWURM: return TILEP_MONS_LINDWURM; case MONS_DEATH_DRAKE: return TILEP_MONS_DEATH_DRAKE; // merfolk ('m') case MONS_MERFOLK: if (in_water) return TILEP_MONS_MERFOLK_WATER; else return TILEP_MONS_MERFOLK; case MONS_MERFOLK_IMPALER: if (in_water) return TILEP_MONS_MERFOLK_IMPALER_WATER; else return TILEP_MONS_MERFOLK_IMPALER; case MONS_MERFOLK_AQUAMANCER: if (in_water) return TILEP_MONS_MERFOLK_AQUAMANCER_WATER; else return TILEP_MONS_MERFOLK_AQUAMANCER; case MONS_MERFOLK_JAVELINEER: if (in_water) return TILEP_MONS_MERFOLK_JAVELINEER_WATER; else return TILEP_MONS_MERFOLK_JAVELINEER; case MONS_MERMAID: if (in_water) return TILEP_MONS_MERMAID_WATER; else return TILEP_MONS_MERMAID; case MONS_SIREN: if (in_water) return TILEP_MONS_SIREN_WATER; else return TILEP_MONS_SIREN; // rotting monsters ('n') case MONS_NECROPHAGE: return TILEP_MONS_NECROPHAGE; case MONS_GHOUL: return TILEP_MONS_GHOUL; case MONS_ROTTING_HULK: return TILEP_MONS_ROTTING_HULK; // orcs ('o') case MONS_ORC: return TILEP_MONS_ORC; case MONS_ORC_WIZARD: return TILEP_MONS_ORC_WIZARD; case MONS_ORC_PRIEST: return TILEP_MONS_ORC_PRIEST; case MONS_ORC_WARRIOR: return TILEP_MONS_ORC_WARRIOR; case MONS_ORC_KNIGHT: return TILEP_MONS_ORC_KNIGHT; case MONS_ORC_WARLORD: return TILEP_MONS_ORC_WARLORD; case MONS_ORC_SORCERER: return TILEP_MONS_ORC_SORCERER; case MONS_ORC_HIGH_PRIEST: return TILEP_MONS_ORC_HIGH_PRIEST; // phantoms and ghosts ('p') case MONS_PHANTOM: return TILEP_MONS_PHANTOM; case MONS_HUNGRY_GHOST: return TILEP_MONS_HUNGRY_GHOST; case MONS_FLAYED_GHOST: return TILEP_MONS_FLAYED_GHOST; case MONS_PLAYER_GHOST: return TILEP_MONS_PLAYER_GHOST; case MONS_INSUBSTANTIAL_WISP: return TILEP_MONS_INSUBSTANTIAL_WISP; // rodents ('r') case MONS_RAT: return TILEP_MONS_RAT; case MONS_QUOKKA: return TILEP_MONS_QUOKKA; case MONS_GREY_RAT: return TILEP_MONS_GREY_RAT; case MONS_GREEN_RAT: return TILEP_MONS_GREEN_RAT; case MONS_ORANGE_RAT: return TILEP_MONS_ORANGE_RAT; // spiders ('s') case MONS_GIANT_MITE: return TILEP_MONS_GIANT_MITE; case MONS_GIANT_CENTIPEDE: return TILEP_MONS_GIANT_CENTIPEDE; case MONS_SCORPION: return TILEP_MONS_SCORPION; case MONS_WOLF_SPIDER: return TILEP_MONS_WOLF_SPIDER; case MONS_TRAPDOOR_SPIDER: return TILEP_MONS_TRAPDOOR_SPIDER; case MONS_REDBACK: return TILEP_MONS_REDBACK; // turtles ('t') case MONS_SNAPPING_TURTLE: return TILEP_MONS_SNAPPING_TURTLE; case MONS_ALLIGATOR_SNAPPING_TURTLE: return TILEP_MONS_ALLIGATOR_SNAPPING_TURTLE; // ugly things ('u') case MONS_UGLY_THING: case MONS_VERY_UGLY_THING: { const int ugly_tile = (type == MONS_VERY_UGLY_THING) ? TILEP_MONS_VERY_UGLY_THING : TILEP_MONS_UGLY_THING; int colour_offset = ugly_thing_colour_offset(mon->colour); if (detected || colour_offset == -1) colour_offset = 0; return (ugly_tile + colour_offset); } // vortices ('v') case MONS_FIRE_VORTEX: return TILEP_MONS_FIRE_VORTEX; case MONS_SPATIAL_VORTEX: return TILEP_MONS_SPATIAL_VORTEX; // elementals (different symbols) case MONS_AIR_ELEMENTAL: return TILEP_MONS_AIR_ELEMENTAL; case MONS_EARTH_ELEMENTAL: return TILEP_MONS_EARTH_ELEMENTAL; case MONS_FIRE_ELEMENTAL: return TILEP_MONS_FIRE_ELEMENTAL; case MONS_WATER_ELEMENTAL: return TILEP_MONS_WATER_ELEMENTAL; // worms and larvae ('w') case MONS_KILLER_BEE_LARVA: return TILEP_MONS_KILLER_BEE_LARVA; case MONS_WORM: return TILEP_MONS_WORM; case MONS_ANT_LARVA: return TILEP_MONS_ANT_LARVA; case MONS_BRAIN_WORM: return TILEP_MONS_BRAIN_WORM; case MONS_SWAMP_WORM: return TILEP_MONS_SWAMP_WORM; case MONS_GIANT_LEECH: return TILEP_MONS_GIANT_LEECH; case MONS_SPINY_WORM: return TILEP_MONS_SPINY_WORM; // small abominations ('x') case MONS_UNSEEN_HORROR: return TILEP_MONS_UNSEEN_HORROR; case MONS_ABOMINATION_SMALL: return TILEP_MONS_ABOMINATION_SMALL; // flying insects ('y') case MONS_YELLOW_WASP: return TILEP_MONS_YELLOW_WASP; case MONS_GIANT_MOSQUITO: return TILEP_MONS_GIANT_MOSQUITO; case MONS_GIANT_BLOWFLY: return TILEP_MONS_GIANT_BLOWFLY; case MONS_RED_WASP: return TILEP_MONS_RED_WASP; case MONS_MOTH_OF_WRATH: return TILEP_MONS_MOTH_OF_WRATH; // small zombies etc. ('z') case MONS_ZOMBIE_SMALL: return TILEP_MONS_ZOMBIE_SMALL; case MONS_SIMULACRUM_SMALL: return TILEP_MONS_SIMULACRUM_SMALL; case MONS_SKELETON_SMALL: return TILEP_MONS_SKELETON_SMALL; case MONS_SKELETAL_WARRIOR: return TILEP_MONS_SKELETAL_WARRIOR; case MONS_FLYING_SKULL: return TILEP_MONS_FLYING_SKULL; case MONS_FLAMING_CORPSE: return TILEP_MONS_FLAMING_CORPSE; case MONS_CURSE_SKULL: return TILEP_MONS_CURSE_SKULL; case MONS_CURSE_TOE: return TILEP_MONS_CURSE_TOE; // angelic beings ('A') case MONS_ANGEL: return TILEP_MONS_ANGEL; case MONS_DAEVA: return TILEP_MONS_DAEVA; // beetles ('B') case MONS_GIANT_BEETLE: return TILEP_MONS_GIANT_BEETLE; case MONS_BOULDER_BEETLE: return TILEP_MONS_BOULDER_BEETLE; case MONS_BORING_BEETLE: return TILEP_MONS_BORING_BEETLE; // cyclops and giants ('C') case MONS_HILL_GIANT: return TILEP_MONS_HILL_GIANT; case MONS_ETTIN: return TILEP_MONS_ETTIN; case MONS_CYCLOPS: return TILEP_MONS_CYCLOPS; case MONS_FIRE_GIANT: return TILEP_MONS_FIRE_GIANT; case MONS_FROST_GIANT: return TILEP_MONS_FROST_GIANT; case MONS_STONE_GIANT: return TILEP_MONS_STONE_GIANT; case MONS_TITAN: return TILEP_MONS_TITAN; // dragons ('D') case MONS_WYVERN: return TILEP_MONS_WYVERN; case MONS_DRAGON: return TILEP_MONS_DRAGON; case MONS_HYDRA: // Number of heads return TILEP_MONS_HYDRA + std::min((int)mon->number, 7) - 1; case MONS_ICE_DRAGON: return TILEP_MONS_ICE_DRAGON; case MONS_STEAM_DRAGON: return TILEP_MONS_STEAM_DRAGON; case MONS_SWAMP_DRAGON: return TILEP_MONS_SWAMP_DRAGON; case MONS_MOTTLED_DRAGON: return TILEP_MONS_MOTTLED_DRAGON; case MONS_QUICKSILVER_DRAGON: return TILEP_MONS_QUICKSILVER_DRAGON; case MONS_IRON_DRAGON: return TILEP_MONS_IRON_DRAGON; case MONS_STORM_DRAGON: return TILEP_MONS_STORM_DRAGON; case MONS_GOLDEN_DRAGON: return TILEP_MONS_GOLDEN_DRAGON; case MONS_SHADOW_DRAGON: return TILEP_MONS_SHADOW_DRAGON; case MONS_SKELETAL_DRAGON: return TILEP_MONS_SKELETAL_DRAGON; case MONS_SERPENT_OF_HELL: return TILEP_MONS_SERPENT_OF_HELL; // efreet ('E') case MONS_EFREET: return TILEP_MONS_EFREET; // frogs ('F') case MONS_GIANT_FROG: return TILEP_MONS_GIANT_FROG; case MONS_GIANT_TOAD: return TILEP_MONS_GIANT_TOAD; case MONS_SPINY_FROG: return TILEP_MONS_SPINY_FROG; case MONS_BLINK_FROG: return TILEP_MONS_BLINK_FROG; // eyes and spores ('G') case MONS_GIANT_SPORE: return TILEP_MONS_GIANT_SPORE; case MONS_GIANT_EYEBALL: return TILEP_MONS_GIANT_EYEBALL; case MONS_EYE_OF_DRAINING: return TILEP_MONS_EYE_OF_DRAINING; case MONS_GIANT_ORANGE_BRAIN: return TILEP_MONS_GIANT_ORANGE_BRAIN; case MONS_GREAT_ORB_OF_EYES: return TILEP_MONS_GREAT_ORB_OF_EYES; case MONS_SHINING_EYE: return TILEP_MONS_SHINING_EYE; case MONS_EYE_OF_DEVASTATION: return TILEP_MONS_EYE_OF_DEVASTATION; case MONS_GOLDEN_EYE: return TILEP_MONS_GOLDEN_EYE; // hybrids ('H') case MONS_HIPPOGRIFF: return TILEP_MONS_HIPPOGRIFF; case MONS_MANTICORE: return TILEP_MONS_MANTICORE; case MONS_GRIFFON: return TILEP_MONS_GRIFFON; case MONS_SPHINX: return TILEP_MONS_SPHINX; case MONS_HARPY: return TILEP_MONS_HARPY; case MONS_MINOTAUR: return TILEP_MONS_MINOTAUR; // ice beast ('I') case MONS_ICE_BEAST: return TILEP_MONS_ICE_BEAST; // jellies ('J') case MONS_OOZE: return TILEP_MONS_OOZE; case MONS_JELLY: return TILEP_MONS_JELLY; case MONS_SLIME_CREATURE: ASSERT(mon->number <= 5); return TILEP_MONS_SLIME_CREATURE + mon->number / 2; case MONS_PULSATING_LUMP: return TILEP_MONS_PULSATING_LUMP; case MONS_GIANT_AMOEBA: return TILEP_MONS_GIANT_AMOEBA; case MONS_BROWN_OOZE: return TILEP_MONS_BROWN_OOZE; case MONS_AZURE_JELLY: return TILEP_MONS_AZURE_JELLY; case MONS_DEATH_OOZE: return TILEP_MONS_DEATH_OOZE; case MONS_ACID_BLOB: return TILEP_MONS_ACID_BLOB; case MONS_ROYAL_JELLY: return TILEP_MONS_ROYAL_JELLY; // kobolds ('K') case MONS_KOBOLD: return TILEP_MONS_KOBOLD; case MONS_BIG_KOBOLD: return TILEP_MONS_BIG_KOBOLD; case MONS_KOBOLD_DEMONOLOGIST: return TILEP_MONS_KOBOLD_DEMONOLOGIST; // liches ('L') case MONS_LICH: return TILEP_MONS_LICH; case MONS_ANCIENT_LICH: return TILEP_MONS_ANCIENT_LICH; // mummies ('M') case MONS_MUMMY: return TILEP_MONS_MUMMY; case MONS_GUARDIAN_MUMMY: return TILEP_MONS_GUARDIAN_MUMMY; case MONS_GREATER_MUMMY: return TILEP_MONS_GREATER_MUMMY; case MONS_MUMMY_PRIEST: return TILEP_MONS_MUMMY_PRIEST; // nagas ('N') case MONS_NAGA: return TILEP_MONS_NAGA; case MONS_GUARDIAN_SERPENT: return TILEP_MONS_GUARDIAN_SERPENT; case MONS_NAGA_MAGE: return TILEP_MONS_NAGA_MAGE; case MONS_NAGA_WARRIOR: return TILEP_MONS_NAGA_WARRIOR; case MONS_GREATER_NAGA: return TILEP_MONS_GREATER_NAGA; // ogres ('O') case MONS_OGRE: return TILEP_MONS_OGRE; case MONS_TWO_HEADED_OGRE: return TILEP_MONS_TWO_HEADED_OGRE; case MONS_OGRE_MAGE: return TILEP_MONS_OGRE_MAGE; // plants ('P') case MONS_PLANT: return TILEP_MONS_PLANT; case MONS_BUSH: return TILEP_MONS_BUSH; case MONS_OKLOB_PLANT: return TILEP_MONS_OKLOB_PLANT; // queen insects ('Q') case MONS_QUEEN_BEE: return TILEP_MONS_QUEEN_BEE; case MONS_QUEEN_ANT: return TILEP_MONS_QUEEN_ANT; // rakshasa ('R') case MONS_RAKSHASA: return TILEP_MONS_RAKSHASA; case MONS_RAKSHASA_FAKE: return TILEP_MONS_RAKSHASA_FAKE; // snakes ('S') case MONS_SMALL_SNAKE: return TILEP_MONS_SMALL_SNAKE; case MONS_SNAKE: return TILEP_MONS_SNAKE; case MONS_WATER_MOCCASIN: return TILEP_MONS_WATER_MOCCASIN; case MONS_BLACK_MAMBA: return TILEP_MONS_BLACK_MAMBA; case MONS_VIPER: return TILEP_MONS_VIPER; case MONS_ANACONDA: return TILEP_MONS_ANACONDA; case MONS_SEA_SNAKE: return TILEP_MONS_SEA_SNAKE; // trolls ('T') case MONS_TROLL: return TILEP_MONS_TROLL; case MONS_ROCK_TROLL: return TILEP_MONS_ROCK_TROLL; case MONS_IRON_TROLL: return TILEP_MONS_IRON_TROLL; case MONS_DEEP_TROLL: return TILEP_MONS_DEEP_TROLL; // bears ('U') case MONS_BEAR: return TILEP_MONS_BEAR; case MONS_GRIZZLY_BEAR: return TILEP_MONS_GRIZZLY_BEAR; case MONS_POLAR_BEAR: return TILEP_MONS_POLAR_BEAR; case MONS_BLACK_BEAR: return TILEP_MONS_BLACK_BEAR; // vampires ('V') case MONS_VAMPIRE: return TILEP_MONS_VAMPIRE; case MONS_VAMPIRE_KNIGHT: return TILEP_MONS_VAMPIRE_KNIGHT; case MONS_VAMPIRE_MAGE: return TILEP_MONS_VAMPIRE_MAGE; // wraiths ('W') case MONS_WIGHT: return TILEP_MONS_WIGHT; case MONS_WRAITH: return TILEP_MONS_WRAITH; case MONS_SHADOW_WRAITH: return TILEP_MONS_SHADOW_WRAITH; case MONS_FREEZING_WRAITH: return TILEP_MONS_FREEZING_WRAITH; case MONS_SPECTRAL_WARRIOR: return TILEP_MONS_SPECTRAL_WARRIOR; case MONS_SPECTRAL_THING: return TILEP_MONS_SPECTRAL_THING; // large abominations ('X') case MONS_ABOMINATION_LARGE: return TILEP_MONS_ABOMINATION_LARGE + ((mon->colour) % 7); case MONS_TENTACLED_MONSTROSITY: return TILEP_MONS_TENTACLED_MONSTROSITY; case MONS_ORB_GUARDIAN: return TILEP_MONS_ORB_GUARDIAN; case MONS_TEST_SPAWNER: return TILEP_MONS_TEST_SPAWNER; // yaks and sheep ('Y') case MONS_SHEEP: return TILEP_MONS_SHEEP; case MONS_YAK: return TILEP_MONS_YAK; case MONS_DEATH_YAK: return TILEP_MONS_DEATH_YAK; // large zombies etc. ('Z') case MONS_ZOMBIE_LARGE: return TILEP_MONS_ZOMBIE_LARGE; case MONS_SKELETON_LARGE: return TILEP_MONS_SKELETON_LARGE; case MONS_SIMULACRUM_LARGE: return TILEP_MONS_SIMULACRUM_LARGE; // water monsters case MONS_BIG_FISH: return TILEP_MONS_BIG_FISH; case MONS_GIANT_GOLDFISH: return TILEP_MONS_GIANT_GOLDFISH; case MONS_ELECTRIC_EEL: return TILEP_MONS_ELECTRIC_EEL; case MONS_SHARK: return TILEP_MONS_SHARK; case MONS_JELLYFISH: return TILEP_MONS_JELLYFISH; case MONS_KRAKEN: return TILEP_MONS_KRAKEN_HEAD; case MONS_KRAKEN_TENTACLE: // Pick a random tentacle tile. return TILEP_MONS_KRAKEN_TENTACLE + random2(tile_player_count(TILEP_MONS_KRAKEN_TENTACLE)); // lava monsters case MONS_LAVA_WORM: return TILEP_MONS_LAVA_WORM; case MONS_LAVA_FISH: return TILEP_MONS_LAVA_FISH; case MONS_LAVA_SNAKE: return TILEP_MONS_LAVA_SNAKE; case MONS_SALAMANDER: return TILEP_MONS_SALAMANDER; // monsters moving through rock case MONS_ROCK_WORM: return TILEP_MONS_ROCK_WORM; // humans ('@') case MONS_HUMAN: return TILEP_MONS_HUMAN; case MONS_HELL_KNIGHT: return TILEP_MONS_HELL_KNIGHT; case MONS_NECROMANCER: return TILEP_MONS_NECROMANCER; case MONS_WIZARD: return TILEP_MONS_WIZARD; case MONS_VAULT_GUARD: return TILEP_MONS_VAULT_GUARD; case MONS_SHAPESHIFTER: return TILEP_MONS_SHAPESHIFTER; case MONS_GLOWING_SHAPESHIFTER: return TILEP_MONS_GLOWING_SHAPESHIFTER; case MONS_KILLER_KLOWN: return TILEP_MONS_KILLER_KLOWN; case MONS_SLAVE: return _get_random_monster_tile(mon, TILEP_MONS_SLAVE); // mimics case MONS_GOLD_MIMIC: case MONS_WEAPON_MIMIC: case MONS_ARMOUR_MIMIC: case MONS_SCROLL_MIMIC: case MONS_POTION_MIMIC: return tileidx_item(get_mimic_item(mon)); case MONS_DANCING_WEAPON: { // Use item tile. item_def item = mitm[mon->inv[MSLOT_WEAPON]]; return tileidx_item(item) | TILE_FLAG_ANIM_WEP; } // '5' demons case MONS_IMP: return TILEP_MONS_IMP; case MONS_QUASIT: return TILEP_MONS_QUASIT; case MONS_WHITE_IMP: return TILEP_MONS_WHITE_IMP; case MONS_LEMURE: return TILEP_MONS_LEMURE; case MONS_UFETUBUS: return TILEP_MONS_UFETUBUS; case MONS_MANES: return TILEP_MONS_MANES; case MONS_MIDGE: return TILEP_MONS_MIDGE; case MONS_SHADOW_IMP: return TILEP_MONS_SHADOW_IMP; // '4' demons case MONS_RED_DEVIL: return TILEP_MONS_RED_DEVIL; case MONS_HAIRY_DEVIL: return TILEP_MONS_HAIRY_DEVIL; case MONS_ROTTING_DEVIL: return TILEP_MONS_ROTTING_DEVIL; case MONS_SMOKE_DEMON: return TILEP_MONS_SMOKE_DEMON; // case MONS_SIXFIRHY: // TODO // return TILEP_MONS_SIXFIRHY; case MONS_HELLWING: return TILEP_MONS_HELLWING; // '3' demons case MONS_HELLION: return TILEP_MONS_HELLION; case MONS_TORMENTOR: return TILEP_MONS_TORMENTOR; case MONS_BLUE_DEVIL: return TILEP_MONS_BLUE_DEVIL; case MONS_IRON_DEVIL: return TILEP_MONS_IRON_DEVIL; case MONS_NEQOXEC: return TILEP_MONS_NEQOXEC; case MONS_ORANGE_DEMON: return TILEP_MONS_ORANGE_DEMON; case MONS_YNOXINUL: return TILEP_MONS_YNOXINUL; case MONS_DEMONIC_CRAWLER: return TILEP_MONS_DEMONIC_CRAWLER; case MONS_SHADOW_DEMON: return TILEP_MONS_SHADOW_DEMON; case MONS_CHAOS_SPAWN: return TILEP_MONS_CHAOS_SPAWN; // '2' demon case MONS_BEAST: return TILEP_MONS_BEAST; case MONS_SUN_DEMON: return TILEP_MONS_SUN_DEMON; case MONS_REAPER: return TILEP_MONS_REAPER; case MONS_SOUL_EATER: return TILEP_MONS_SOUL_EATER; case MONS_ICE_DEVIL: return TILEP_MONS_ICE_DEVIL; case MONS_LOROCYPROCA: return TILEP_MONS_LOROCYPROCA; // '1' demons case MONS_FIEND: return TILEP_MONS_FIEND; case MONS_ICE_FIEND: return TILEP_MONS_ICE_FIEND; case MONS_SHADOW_FIEND: return TILEP_MONS_SHADOW_FIEND; case MONS_PIT_FIEND: return TILEP_MONS_PIT_FIEND; case MONS_EXECUTIONER: return TILEP_MONS_EXECUTIONER; case MONS_GREEN_DEATH: return TILEP_MONS_GREEN_DEATH; case MONS_BLUE_DEATH: return TILEP_MONS_BLUE_DEATH; case MONS_BALRUG: return TILEP_MONS_BALRUG; case MONS_CACODEMON: return TILEP_MONS_CACODEMON; // non-living creatures // golems ('8') case MONS_CLAY_GOLEM: return TILEP_MONS_CLAY_GOLEM; case MONS_WOOD_GOLEM: return TILEP_MONS_WOOD_GOLEM; case MONS_IRON_GOLEM: return TILEP_MONS_IRON_GOLEM; case MONS_STONE_GOLEM: return TILEP_MONS_STONE_GOLEM; case MONS_CRYSTAL_GOLEM: return TILEP_MONS_CRYSTAL_GOLEM; case MONS_TOENAIL_GOLEM: return TILEP_MONS_TOENAIL_GOLEM; case MONS_ELECTRIC_GOLEM: return TILEP_MONS_ELECTRIC_GOLEM; // statues (also '8') case MONS_ICE_STATUE: return TILEP_MONS_ICE_STATUE; case MONS_SILVER_STATUE: return TILEP_MONS_SILVER_STATUE; case MONS_ORANGE_STATUE: return TILEP_MONS_ORANGE_CRYSTAL_STATUE; // gargoyles ('9') case MONS_GARGOYLE: return TILEP_MONS_GARGOYLE; case MONS_METAL_GARGOYLE: return TILEP_MONS_METAL_GARGOYLE; case MONS_MOLTEN_GARGOYLE: return TILEP_MONS_MOLTEN_GARGOYLE; // major demons ('&') case MONS_PANDEMONIUM_DEMON: return TILEP_MONS_PANDEMONIUM_DEMON; // ball lightning / orb of fire ('*') case MONS_BALL_LIGHTNING: return TILEP_MONS_BALL_LIGHTNING; case MONS_ORB_OF_FIRE: return TILEP_MONS_ORB_OF_FIRE; case MONS_ORB_OF_DESTRUCTION: return TILEP_MONS_ORB_OF_DESTRUCTION; // other symbols case MONS_VAPOUR: return TILEP_MONS_VAPOUR; case MONS_SHADOW: return TILEP_MONS_SHADOW; case MONS_DEATH_COB: return TILEP_MONS_DEATH_COB; // ------------------------------------- // non-human uniques, sorted by glyph, then difficulty // ------------------------------------- // centaur ('c') case MONS_NESSOS: return TILEP_MONS_NESSOS; // draconian ('d') case MONS_TIAMAT: return TILEP_MONS_TIAMAT; // elves ('e') case MONS_DOWAN: return TILEP_MONS_DEEP_ELF_MAGE; // TODO case MONS_DUVESSA: return TILEP_MONS_DEEP_ELF_FIGHTER; // TODO // goblins and gnolls ('g') case MONS_IJYB: return TILEP_MONS_IJYB; case MONS_CRAZY_YIUF: return TILEP_MONS_CRAZY_YIUF; case MONS_GRUM: return TILEP_MONS_GRUM; // slug ('j') case MONS_GASTRONOK: return TILEP_MONS_GASTRONOK; // merfolk ('m') case MONS_ILSUIW: if (in_water) return TILEP_MONS_ILSUIW_WATER; else return TILEP_MONS_ILSUIW; // orcs ('o') case MONS_BLORK_THE_ORC: return TILEP_MONS_BLORK_THE_ORC; case MONS_URUG: return TILEP_MONS_URUG; case MONS_NERGALLE: return TILEP_MONS_NERGALLE; case MONS_SAINT_ROKA: return TILEP_MONS_SAINT_ROKA; // curse skull ('z') case MONS_MURRAY: return TILEP_MONS_MURRAY; // cyclops and giants ('C') case MONS_POLYPHEMUS: return TILEP_MONS_POLYPHEMUS; case MONS_ANTAEUS: return TILEP_MONS_ANTAEUS; // dragons and hydras ('D') case MONS_LERNAEAN_HYDRA: return TILEP_MONS_LERNAEAN_HYDRA; case MONS_XTAHUA: return TILEP_MONS_XTAHUA; // efreet ('E') case MONS_AZRAEL: return TILEP_MONS_AZRAEL; // frog ('F') case MONS_PRINCE_RIBBIT: return TILEP_MONS_PRINCE_RIBBIT; // jelly ('J') case MONS_DISSOLUTION: return TILEP_MONS_DISSOLUTION; // kobolds ('K') case MONS_SONJA: return TILEP_MONS_SONJA; case MONS_PIKEL: return TILEP_MONS_PIKEL; // lich ('L') case MONS_BORIS: return TILEP_MONS_BORIS; // mummies ('M') case MONS_MENKAURE: return TILEP_MONS_MENKAURE; case MONS_KHUFU: return TILEP_MONS_KHUFU; // guardian serpent ('N') case MONS_AIZUL: return TILEP_MONS_AIZUL; // ogre ('O') case MONS_EROLCHA: return TILEP_MONS_EROLCHA; // rakshasas ('R') case MONS_MARA: return TILEP_MONS_MARA; case MONS_MARA_FAKE: return TILEP_MONS_MARA_FAKE; // trolls ('T') case MONS_PURGY: return TILEP_MONS_PURGY; case MONS_SNORG: return TILEP_MONS_SNORG; // statue ('8') case MONS_ROXANNE: return TILEP_MONS_ROXANNE; // ------------------------------------- // non-human uniques ('@') // ------------------------------------- case MONS_TERENCE: return TILEP_MONS_TERENCE; case MONS_JESSICA: return TILEP_MONS_JESSICA; case MONS_SIGMUND: return TILEP_MONS_SIGMUND; case MONS_EDMUND: return TILEP_MONS_EDMUND; case MONS_PSYCHE: return TILEP_MONS_PSYCHE; case MONS_DONALD: return TILEP_MONS_DONALD; case MONS_JOSEPH: return TILEP_MONS_JOSEPH; case MONS_ERICA: return TILEP_MONS_ERICA; case MONS_JOSEPHINE: return TILEP_MONS_JOSEPHINE; case MONS_HAROLD: return TILEP_MONS_HAROLD; case MONS_NORBERT: return TILEP_MONS_NORBERT; case MONS_JOZEF: return TILEP_MONS_JOZEF; case MONS_AGNES: return TILEP_MONS_AGNES; case MONS_MAUD: return TILEP_MONS_MAUD; case MONS_LOUISE: return TILEP_MONS_LOUISE; case MONS_FRANCIS: return TILEP_MONS_FRANCIS; case MONS_FRANCES: return TILEP_MONS_FRANCES; case MONS_RUPERT: return TILEP_MONS_RUPERT; case MONS_WAYNE: return TILEP_MONS_WAYNE; case MONS_DUANE: return TILEP_MONS_DUANE; case MONS_NORRIS: return TILEP_MONS_NORRIS; case MONS_FREDERICK: return TILEP_MONS_FREDERICK; case MONS_MARGERY: return TILEP_MONS_MARGERY; case MONS_EUSTACHIO: return TILEP_MONS_EUSTACHIO; case MONS_KIRKE: return TILEP_MONS_KIRKE; case MONS_NIKOLA: return TILEP_MONS_NIKOLA; case MONS_MAURICE: return TILEP_MONS_MAURICE; // unique major demons ('&') case MONS_MNOLEG: return TILEP_MONS_MNOLEG; case MONS_LOM_LOBON: return TILEP_MONS_LOM_LOBON; case MONS_CEREBOV: return TILEP_MONS_CEREBOV; case MONS_GLOORX_VLOQ: return TILEP_MONS_GLOORX_VLOQ; case MONS_GERYON: return TILEP_MONS_GERYON; case MONS_DISPATER: return TILEP_MONS_DISPATER; case MONS_ASMODEUS: return TILEP_MONS_ASMODEUS; case MONS_ERESHKIGAL: return TILEP_MONS_ERESHKIGAL; } return TILEP_MONS_PROGRAM_BUG; } int tileidx_monster(const monsters *mons, bool detected) { int ch = tileidx_monster_base(mons, detected); if (mons_flies(mons)) ch |= TILE_FLAG_FLYING; if (mons->has_ench(ENCH_HELD)) ch |= TILE_FLAG_NET; if (mons->has_ench(ENCH_POISON)) ch |= TILE_FLAG_POISON; if (mons->has_ench(ENCH_STICKY_FLAME)) ch |= TILE_FLAG_FLAME; if (mons->berserk()) ch |= TILE_FLAG_BERSERK; if (mons->friendly()) ch |= TILE_FLAG_PET; else if (mons->good_neutral()) ch |= TILE_FLAG_GD_NEUTRAL; else if (mons->neutral()) ch |= TILE_FLAG_NEUTRAL; else if (mons_looks_stabbable(mons)) ch |= TILE_FLAG_STAB; else if (mons_looks_distracted(mons)) ch |= TILE_FLAG_MAY_STAB; std::string damage_desc; mon_dam_level_type damage_level; mons_get_damage_level(mons, damage_desc, damage_level); // If no messages about wounds, don't display an icon either. if (monster_descriptor(mons->type, MDSC_NOMSG_WOUNDS)) damage_level = MDAM_OKAY; switch (damage_level) { case MDAM_DEAD: case MDAM_ALMOST_DEAD: ch |= TILE_FLAG_MDAM_ADEAD; break; case MDAM_SEVERELY_DAMAGED: ch |= TILE_FLAG_MDAM_SEV; break; case MDAM_HEAVILY_DAMAGED: ch |= TILE_FLAG_MDAM_HEAVY; break; case MDAM_MODERATELY_DAMAGED: ch |= TILE_FLAG_MDAM_MOD; break; case MDAM_LIGHTLY_DAMAGED: ch |= TILE_FLAG_MDAM_LIGHT; break; case MDAM_OKAY: default: // no flag for okay. break; } return ch; } static int _tileidx_monster(int mon_idx, bool detected) { ASSERT(mon_idx != -1); const monsters* mons = &menv[mon_idx]; return tileidx_monster(mons, detected); } static int _tileidx_unrand_artefact(int idx) { const int tile = unrandart_to_tile(idx); if (tile != -1) return tile; return TILE_TODO; } static int _get_etype(const item_def &item) { switch (item.flags & ISFLAG_COSMETIC_MASK) { case ISFLAG_EMBROIDERED_SHINY: return 1; case ISFLAG_RUNED: return 2; case ISFLAG_GLOWING: return 3; default: return (is_random_artefact(item) ? 4 : 0); } } static int _apply_variations(const item_def &item, int tile) { static const int etable[5][5] = { {0, 0, 0, 0, 0}, {0, 1, 1, 1, 1}, {0, 1, 1, 1, 2}, {0, 1, 1, 2, 3}, {0, 1, 2, 3, 4} }; int etype = _get_etype(item); int idx = tile_main_count(tile) - 1; ASSERT(idx < 5); tile += etable[idx][etype]; return tile; } static int _tileidx_weapon_base(const item_def &item) { int race = item.flags & ISFLAG_RACIAL_MASK; switch (item.sub_type) { case WPN_KNIFE: return TILE_WPN_KNIFE; case WPN_DAGGER: if (race == ISFLAG_ORCISH) return TILE_WPN_DAGGER_ORC; if (race == ISFLAG_ELVEN) return TILE_WPN_DAGGER_ELF; return TILE_WPN_DAGGER; case WPN_SHORT_SWORD: if (race == ISFLAG_ORCISH) return TILE_WPN_SHORT_SWORD_ORC; if (race == ISFLAG_ELVEN) return TILE_WPN_SHORT_SWORD_ELF; return TILE_WPN_SHORT_SWORD; case WPN_QUICK_BLADE: return TILE_WPN_QUICK_BLADE; case WPN_SABRE: return TILE_WPN_SABRE; case WPN_FALCHION: return TILE_WPN_FALCHION; case WPN_KATANA: return TILE_WPN_KATANA; case WPN_LONG_SWORD: if (race == ISFLAG_ORCISH) return TILE_WPN_LONG_SWORD_ORC; return TILE_WPN_LONG_SWORD; case WPN_GREAT_SWORD: if (race == ISFLAG_ORCISH) return TILE_WPN_GREAT_SWORD_ORC; return TILE_WPN_GREAT_SWORD; case WPN_SCIMITAR: return TILE_WPN_SCIMITAR; case WPN_DOUBLE_SWORD: return TILE_WPN_DOUBLE_SWORD; case WPN_TRIPLE_SWORD: return TILE_WPN_TRIPLE_SWORD; case WPN_HAND_AXE: return TILE_WPN_HAND_AXE; case WPN_WAR_AXE: return TILE_WPN_WAR_AXE; case WPN_BROAD_AXE: return TILE_WPN_BROAD_AXE; case WPN_BATTLEAXE: return TILE_WPN_BATTLEAXE; case WPN_EXECUTIONERS_AXE: return TILE_WPN_EXECUTIONERS_AXE; case WPN_BLOWGUN: return TILE_WPN_BLOWGUN; case WPN_SLING: return TILE_WPN_SLING; case WPN_BOW: return TILE_WPN_BOW; case WPN_CROSSBOW: return TILE_WPN_CROSSBOW; case WPN_SPEAR: return TILE_WPN_SPEAR; case WPN_TRIDENT: return TILE_WPN_TRIDENT; case WPN_HALBERD: return TILE_WPN_HALBERD; case WPN_SCYTHE: return TILE_WPN_SCYTHE; case WPN_GLAIVE: if (race == ISFLAG_ORCISH) return TILE_WPN_GLAIVE_ORC; return TILE_WPN_GLAIVE; case WPN_QUARTERSTAFF: return TILE_WPN_QUARTERSTAFF; case WPN_CLUB: return TILE_WPN_CLUB; case WPN_HAMMER: return TILE_WPN_HAMMER; case WPN_MACE: return TILE_WPN_MACE; case WPN_FLAIL: return TILE_WPN_FLAIL; case WPN_SPIKED_FLAIL: return TILE_WPN_SPIKED_FLAIL; case WPN_GREAT_MACE: return TILE_WPN_GREAT_MACE; case WPN_DIRE_FLAIL: return TILE_WPN_GREAT_FLAIL; case WPN_MORNINGSTAR: return TILE_WPN_MORNINGSTAR; case WPN_EVENINGSTAR: return TILE_WPN_EVENINGSTAR; case WPN_GIANT_CLUB: return TILE_WPN_GIANT_CLUB; case WPN_GIANT_SPIKED_CLUB: return TILE_WPN_GIANT_SPIKED_CLUB; case WPN_ANKUS: return TILE_WPN_ANKUS; case WPN_WHIP: return TILE_WPN_WHIP; case WPN_DEMON_BLADE: return TILE_WPN_DEMON_BLADE; case WPN_DEMON_WHIP: return TILE_WPN_DEMON_WHIP; case WPN_DEMON_TRIDENT: return TILE_WPN_DEMON_TRIDENT; case WPN_HOLY_EUDEMON_BLADE: return TILE_WPN_BLESSED_BLADE; case WPN_LONGBOW: return TILE_WPN_LONGBOW; case WPN_LAJATANG: return TILE_WPN_LAJATANG; case WPN_BARDICHE: return TILE_WPN_BARDICHE; case WPN_BLESSED_FALCHION: return TILE_WPN_FALCHION; case WPN_BLESSED_LONG_SWORD: return TILE_WPN_LONG_SWORD; case WPN_BLESSED_SCIMITAR: return TILE_WPN_SCIMITAR; case WPN_BLESSED_KATANA: return TILE_WPN_KATANA; case WPN_BLESSED_GREAT_SWORD: return TILE_WPN_GREAT_SWORD; case WPN_BLESSED_DOUBLE_SWORD: return TILE_WPN_DOUBLE_SWORD; case WPN_BLESSED_TRIPLE_SWORD: return TILE_WPN_TRIPLE_SWORD; } return TILE_ERROR; } static int _tileidx_weapon(const item_def &item) { int tile = _tileidx_weapon_base(item); return _apply_variations(item, tile); } static int _tileidx_missile(const item_def &item) { int brand = item.special; switch (item.sub_type) { case MI_STONE: return TILE_MI_STONE; case MI_ARROW: return TILE_MI_ARROW; case MI_BOLT: return TILE_MI_BOLT; case MI_LARGE_ROCK: return TILE_MI_LARGE_ROCK; case MI_SLING_BULLET: return TILE_MI_SLING_BULLET; case MI_JAVELIN: return TILE_MI_JAVELIN; case MI_THROWING_NET: return TILE_MI_THROWING_NET; case MI_DART: if (brand == SPMSL_POISONED) return TILE_MI_DART_P; return TILE_MI_DART; case MI_NEEDLE: if (brand == SPMSL_POISONED) return TILE_MI_NEEDLE_P; return TILE_MI_NEEDLE; } return TILE_ERROR; } static int _tileidx_armour_base(const item_def &item) { int race = item.flags & ISFLAG_RACIAL_MASK; int type = item.sub_type; switch (type) { case ARM_ROBE: return TILE_ARM_ROBE; case ARM_LEATHER_ARMOUR: if (race == ISFLAG_ORCISH) return TILE_ARM_LEATHER_ARMOUR_ORC; if (race == ISFLAG_ELVEN) return TILE_ARM_LEATHER_ARMOUR_ELF; return TILE_ARM_LEATHER_ARMOUR; case ARM_RING_MAIL: if (race == ISFLAG_ORCISH) return TILE_ARM_RING_MAIL_ORC; if (race == ISFLAG_ELVEN) return TILE_ARM_RING_MAIL_ELF; if (race == ISFLAG_DWARVEN) return TILE_ARM_RING_MAIL_DWA; return TILE_ARM_RING_MAIL; case ARM_SCALE_MAIL: if (race == ISFLAG_ELVEN) return TILE_ARM_SCALE_MAIL_ELF; return TILE_ARM_SCALE_MAIL; case ARM_CHAIN_MAIL: if (race == ISFLAG_ELVEN) return TILE_ARM_CHAIN_MAIL_ELF; if (race == ISFLAG_ORCISH) return TILE_ARM_CHAIN_MAIL_ORC; return TILE_ARM_CHAIN_MAIL; case ARM_SPLINT_MAIL: return TILE_ARM_SPLINT_MAIL; case ARM_BANDED_MAIL: return TILE_ARM_BANDED_MAIL; case ARM_PLATE_MAIL: if (race == ISFLAG_ORCISH) return TILE_ARM_PLATE_MAIL_ORC; return TILE_ARM_PLATE_MAIL; case ARM_CRYSTAL_PLATE_MAIL: return TILE_ARM_CRYSTAL_PLATE_MAIL; case ARM_SHIELD: return TILE_ARM_SHIELD; case ARM_CLOAK: return TILE_ARM_CLOAK; case ARM_WIZARD_HAT: return TILE_THELM_WIZARD_HAT; case ARM_CAP: return TILE_THELM_CAP; case ARM_HELMET: return TILE_THELM_HELM; case ARM_GLOVES: return TILE_ARM_GLOVES; case ARM_BOOTS: return TILE_ARM_BOOTS; case ARM_BUCKLER: return TILE_ARM_BUCKLER; case ARM_LARGE_SHIELD: return TILE_ARM_LARGE_SHIELD; case ARM_CENTAUR_BARDING: return TILE_ARM_CENTAUR_BARDING; case ARM_NAGA_BARDING: return TILE_ARM_NAGA_BARDING; case ARM_ANIMAL_SKIN: return TILE_ARM_ANIMAL_SKIN; case ARM_TROLL_HIDE: return TILE_ARM_TROLL_HIDE; case ARM_TROLL_LEATHER_ARMOUR: return TILE_ARM_TROLL_LEATHER_ARMOUR; case ARM_DRAGON_HIDE: return TILE_ARM_DRAGON_HIDE; case ARM_DRAGON_ARMOUR: return TILE_ARM_DRAGON_ARMOUR; case ARM_ICE_DRAGON_HIDE: return TILE_ARM_ICE_DRAGON_HIDE; case ARM_ICE_DRAGON_ARMOUR: return TILE_ARM_ICE_DRAGON_ARMOUR; case ARM_STEAM_DRAGON_HIDE: return TILE_ARM_STEAM_DRAGON_HIDE; case ARM_STEAM_DRAGON_ARMOUR: return TILE_ARM_STEAM_DRAGON_ARMOUR; case ARM_MOTTLED_DRAGON_HIDE: return TILE_ARM_MOTTLED_DRAGON_HIDE; case ARM_MOTTLED_DRAGON_ARMOUR: return TILE_ARM_MOTTLED_DRAGON_ARMOUR; case ARM_STORM_DRAGON_HIDE: return TILE_ARM_STORM_DRAGON_HIDE; case ARM_STORM_DRAGON_ARMOUR: return TILE_ARM_STORM_DRAGON_ARMOUR; case ARM_GOLD_DRAGON_HIDE: return TILE_ARM_GOLD_DRAGON_HIDE; case ARM_GOLD_DRAGON_ARMOUR: return TILE_ARM_GOLD_DRAGON_ARMOUR; case ARM_SWAMP_DRAGON_HIDE: return TILE_ARM_SWAMP_DRAGON_HIDE; case ARM_SWAMP_DRAGON_ARMOUR: return TILE_ARM_SWAMP_DRAGON_ARMOUR; } return TILE_ERROR; } static int _tileidx_armour(const item_def &item) { int tile = _tileidx_armour_base(item); return _apply_variations(item, tile); } static int _tileidx_chunk(const item_def &item) { if (food_is_rotten(item)) { if (!is_inedible(item)) { if (is_poisonous(item)) return TILE_FOOD_CHUNK_ROTTEN_POISONED; if (is_mutagenic(item)) return TILE_FOOD_CHUNK_ROTTEN_MUTAGENIC; if (causes_rot(item)) return TILE_FOOD_CHUNK_ROTTEN_ROTTING; if (is_forbidden_food(item)) return TILE_FOOD_CHUNK_ROTTEN_FORBIDDEN; if (is_contaminated(item)) return TILE_FOOD_CHUNK_ROTTEN_CONTAMINATED; } return TILE_FOOD_CHUNK_ROTTEN; } if (is_inedible(item)) return TILE_FOOD_CHUNK; if (is_poisonous(item)) return TILE_FOOD_CHUNK_POISONED; if (is_mutagenic(item)) return TILE_FOOD_CHUNK_MUTAGENIC; if (causes_rot(item)) return TILE_FOOD_CHUNK_ROTTING; if (is_forbidden_food(item)) return TILE_FOOD_CHUNK_FORBIDDEN; if (is_contaminated(item)) return TILE_FOOD_CHUNK_CONTAMINATED; return TILE_FOOD_CHUNK; } static int _tileidx_food(const item_def &item) { switch (item.sub_type) { case FOOD_MEAT_RATION: return TILE_FOOD_MEAT_RATION; case FOOD_BREAD_RATION: return TILE_FOOD_BREAD_RATION; case FOOD_PEAR: return TILE_FOOD_PEAR; case FOOD_APPLE: return TILE_FOOD_APPLE; case FOOD_CHOKO: return TILE_FOOD_CHOKO; case FOOD_HONEYCOMB: return TILE_FOOD_HONEYCOMB; case FOOD_ROYAL_JELLY: return TILE_FOOD_ROYAL_JELLY; case FOOD_SNOZZCUMBER: return TILE_FOOD_SNOZZCUMBER; case FOOD_PIZZA: return TILE_FOOD_PIZZA; case FOOD_APRICOT: return TILE_FOOD_APRICOT; case FOOD_ORANGE: return TILE_FOOD_ORANGE; case FOOD_BANANA: return TILE_FOOD_BANANA; case FOOD_STRAWBERRY: return TILE_FOOD_STRAWBERRY; case FOOD_RAMBUTAN: return TILE_FOOD_RAMBUTAN; case FOOD_LEMON: return TILE_FOOD_LEMON; case FOOD_GRAPE: return TILE_FOOD_GRAPE; case FOOD_SULTANA: return TILE_FOOD_SULTANA; case FOOD_LYCHEE: return TILE_FOOD_LYCHEE; case FOOD_BEEF_JERKY: return TILE_FOOD_BEEF_JERKY; case FOOD_CHEESE: return TILE_FOOD_CHEESE; case FOOD_SAUSAGE: return TILE_FOOD_SAUSAGE; case FOOD_CHUNK: return _tileidx_chunk(item); } return TILE_ERROR; } // Returns index of corpse tiles. // Parameter item holds the corpse. static int _tileidx_corpse(const item_def &item) { const int type = item.plus; switch (type) { // insects ('a') case MONS_GIANT_COCKROACH: return TILE_CORPSE_GIANT_COCKROACH; case MONS_GIANT_ANT: return TILE_CORPSE_GIANT_ANT; case MONS_SOLDIER_ANT: return TILE_CORPSE_SOLDIER_ANT; // batty monsters ('b') case MONS_GIANT_BAT: return TILE_CORPSE_GIANT_BAT; case MONS_BUTTERFLY: return TILE_CORPSE_BUTTERFLY; // centaurs ('c') case MONS_CENTAUR: case MONS_CENTAUR_WARRIOR: return TILE_CORPSE_CENTAUR; case MONS_YAKTAUR: case MONS_YAKTAUR_CAPTAIN: return TILE_CORPSE_YAKTAUR; // draconians ('d') case MONS_DRACONIAN: return TILE_CORPSE_DRACONIAN_BROWN; case MONS_BLACK_DRACONIAN: return TILE_CORPSE_DRACONIAN_BLACK; case MONS_YELLOW_DRACONIAN: return TILE_CORPSE_DRACONIAN_YELLOW; case MONS_PALE_DRACONIAN: return TILE_CORPSE_DRACONIAN_PALE; case MONS_GREEN_DRACONIAN: return TILE_CORPSE_DRACONIAN_GREEN; case MONS_PURPLE_DRACONIAN: return TILE_CORPSE_DRACONIAN_PURPLE; case MONS_RED_DRACONIAN: return TILE_CORPSE_DRACONIAN_RED; case MONS_WHITE_DRACONIAN: return TILE_CORPSE_DRACONIAN_WHITE; case MONS_MOTTLED_DRACONIAN: return TILE_CORPSE_DRACONIAN_MOTTLED; case MONS_DRACONIAN_CALLER: case MONS_DRACONIAN_MONK: case MONS_DRACONIAN_ZEALOT: case MONS_DRACONIAN_SHIFTER: case MONS_DRACONIAN_ANNIHILATOR: case MONS_DRACONIAN_KNIGHT: case MONS_DRACONIAN_SCORCHER: return TILE_CORPSE_DRACONIAN_BROWN; // elves ('e') case MONS_ELF: case MONS_DEEP_ELF_SOLDIER: case MONS_DEEP_ELF_FIGHTER: case MONS_DEEP_ELF_KNIGHT: case MONS_DEEP_ELF_BLADEMASTER: case MONS_DEEP_ELF_MASTER_ARCHER: case MONS_DEEP_ELF_MAGE: case MONS_DEEP_ELF_SUMMONER: case MONS_DEEP_ELF_CONJURER: case MONS_DEEP_ELF_PRIEST: case MONS_DEEP_ELF_HIGH_PRIEST: case MONS_DEEP_ELF_DEMONOLOGIST: case MONS_DEEP_ELF_ANNIHILATOR: case MONS_DEEP_ELF_SORCERER: case MONS_DEEP_ELF_DEATH_MAGE: return TILE_CORPSE_ELF; // goblins ('g') case MONS_GOBLIN: return TILE_CORPSE_GOBLIN; case MONS_HOBGOBLIN: return TILE_CORPSE_HOBGOBLIN; case MONS_GNOLL: return TILE_CORPSE_GNOLL; // hounds ('h') case MONS_JACKAL: return TILE_CORPSE_JACKAL; case MONS_HOUND: return TILE_CORPSE_HOUND; case MONS_WARG: return TILE_CORPSE_WARG; case MONS_WOLF: return TILE_CORPSE_WOLF; case MONS_WAR_DOG: return TILE_CORPSE_WAR_DOG; case MONS_HOG: return TILE_CORPSE_HOG; // slugs ('j') case MONS_ELEPHANT_SLUG: return TILE_CORPSE_ELEPHANT_SLUG; case MONS_GIANT_SLUG: return TILE_CORPSE_GIANT_SLUG; case MONS_GIANT_SNAIL: return TILE_CORPSE_GIANT_SNAIL; // bees ('k') case MONS_KILLER_BEE: return TILE_CORPSE_KILLER_BEE; case MONS_BUMBLEBEE: return TILE_CORPSE_BUMBLEBEE; // lizards ('l') case MONS_GIANT_NEWT: return TILE_CORPSE_GIANT_NEWT; case MONS_GIANT_GECKO: return TILE_CORPSE_GIANT_GECKO; case MONS_GIANT_IGUANA: return TILE_CORPSE_GIANT_IGUANA; case MONS_GIANT_LIZARD: return TILE_CORPSE_GIANT_LIZARD; case MONS_GILA_MONSTER: return TILE_CORPSE_GILA_MONSTER; case MONS_KOMODO_DRAGON: return TILE_CORPSE_KOMODO_DRAGON; // drakes (also 'l') case MONS_SWAMP_DRAKE: return TILE_CORPSE_SWAMP_DRAKE; case MONS_FIRE_DRAKE: return TILE_CORPSE_FIRE_DRAKE; case MONS_LINDWURM: return TILE_CORPSE_LINDWURM; case MONS_DEATH_DRAKE: return TILE_CORPSE_DEATH_DRAKE; // merfolk ('m') case MONS_MERFOLK: return TILE_CORPSE_MERFOLK; case MONS_MERMAID: return TILE_CORPSE_MERMAID; case MONS_SIREN: return TILE_CORPSE_SIREN; // rotting monsters ('n') case MONS_NECROPHAGE: return TILE_CORPSE_NECROPHAGE; case MONS_GHOUL: return TILE_CORPSE_GHOUL; // orcs ('o') case MONS_ORC: case MONS_ORC_WIZARD: case MONS_ORC_PRIEST: case MONS_ORC_WARRIOR: case MONS_ORC_KNIGHT: case MONS_ORC_WARLORD: case MONS_ORC_SORCERER: case MONS_ORC_HIGH_PRIEST: return TILE_CORPSE_ORC; // rodents ('r') case MONS_RAT: return TILE_CORPSE_RAT; case MONS_QUOKKA: return TILE_CORPSE_QUOKKA; case MONS_GREY_RAT: return TILE_CORPSE_GREY_RAT; case MONS_GREEN_RAT: return TILE_CORPSE_GREEN_RAT; case MONS_ORANGE_RAT: return TILE_CORPSE_ORANGE_RAT; // spiders ('s') case MONS_GIANT_MITE: return TILE_CORPSE_GIANT_MITE; case MONS_GIANT_CENTIPEDE: return TILE_CORPSE_GIANT_CENTIPEDE; case MONS_SCORPION: return TILE_CORPSE_SCORPION; case MONS_WOLF_SPIDER: return TILE_CORPSE_WOLF_SPIDER; case MONS_TRAPDOOR_SPIDER: return TILE_CORPSE_TRAPDOOR_SPIDER; case MONS_REDBACK: return TILE_CORPSE_REDBACK; // turtles ('t') case MONS_SNAPPING_TURTLE: return TILE_CORPSE_SNAPPING_TURTLE; case MONS_ALLIGATOR_SNAPPING_TURTLE: return TILE_CORPSE_ALLIGATOR_SNAPPING_TURTLE; // ugly things ('u') case MONS_UGLY_THING: case MONS_VERY_UGLY_THING: { const int ugly_corpse_tile = (type == MONS_VERY_UGLY_THING) ? TILE_CORPSE_VERY_UGLY_THING : TILE_CORPSE_UGLY_THING; int colour_offset = ugly_thing_colour_offset(item.colour); if (colour_offset == -1) colour_offset = 0; return (ugly_corpse_tile + colour_offset); } // worms ('w') case MONS_KILLER_BEE_LARVA: return TILE_CORPSE_KILLER_BEE_LARVA; case MONS_ANT_LARVA: return TILE_CORPSE_ANT_LARVA; case MONS_WORM: return TILE_CORPSE_WORM; case MONS_BRAIN_WORM: return TILE_CORPSE_BRAIN_WORM; case MONS_SWAMP_WORM: return TILE_CORPSE_SWAMP_WORM; case MONS_GIANT_LEECH: return TILE_CORPSE_GIANT_LEECH; case MONS_ROCK_WORM: return TILE_CORPSE_ROCK_WORM; case MONS_SPINY_WORM: return TILE_CORPSE_SPINY_WORM; // wasps ('y') case MONS_GIANT_MOSQUITO: return TILE_CORPSE_GIANT_MOSQUITO; case MONS_GIANT_BLOWFLY: return TILE_CORPSE_GIANT_BLOWFLY; case MONS_YELLOW_WASP: return TILE_CORPSE_YELLOW_WASP; case MONS_RED_WASP: return TILE_CORPSE_RED_WASP; // beetles ('B') case MONS_GIANT_BEETLE: return TILE_CORPSE_GIANT_BEETLE; case MONS_BOULDER_BEETLE: return TILE_CORPSE_BOULDER_BEETLE; case MONS_BORING_BEETLE: return TILE_CORPSE_BORING_BEETLE; // giants ('C') case MONS_HILL_GIANT: return TILE_CORPSE_HILL_GIANT; case MONS_ETTIN: return TILE_CORPSE_ETTIN; case MONS_CYCLOPS: return TILE_CORPSE_CYCLOPS; case MONS_FIRE_GIANT: return TILE_CORPSE_FIRE_GIANT; case MONS_FROST_GIANT: return TILE_CORPSE_FROST_GIANT; case MONS_STONE_GIANT: return TILE_CORPSE_STONE_GIANT; case MONS_TITAN: return TILE_CORPSE_TITAN; // dragons ('D') case MONS_WYVERN: return TILE_CORPSE_WYVERN; case MONS_DRAGON: return TILE_CORPSE_DRAGON; case MONS_HYDRA: return TILE_CORPSE_HYDRA; case MONS_ICE_DRAGON: return TILE_CORPSE_ICE_DRAGON; case MONS_IRON_DRAGON: return TILE_CORPSE_IRON_DRAGON; case MONS_QUICKSILVER_DRAGON: return TILE_CORPSE_QUICKSILVER_DRAGON; case MONS_STEAM_DRAGON: return TILE_CORPSE_STEAM_DRAGON; case MONS_SWAMP_DRAGON: return TILE_CORPSE_SWAMP_DRAGON; case MONS_MOTTLED_DRAGON: return TILE_CORPSE_MOTTLED_DRAGON; case MONS_STORM_DRAGON: return TILE_CORPSE_STORM_DRAGON; case MONS_GOLDEN_DRAGON: return TILE_CORPSE_GOLDEN_DRAGON; case MONS_SHADOW_DRAGON: return TILE_CORPSE_SHADOW_DRAGON; // frogs ('F') case MONS_GIANT_FROG: return TILE_CORPSE_GIANT_FROG; case MONS_GIANT_TOAD: return TILE_CORPSE_GIANT_TOAD; case MONS_SPINY_FROG: return TILE_CORPSE_SPINY_FROG; case MONS_BLINK_FROG: return TILE_CORPSE_BLINK_FROG; // eyes ('G') case MONS_GIANT_EYEBALL: return TILE_CORPSE_GIANT_EYEBALL; case MONS_EYE_OF_DRAINING: return TILE_CORPSE_EYE_OF_DRAINING; case MONS_GIANT_ORANGE_BRAIN: return TILE_CORPSE_GIANT_ORANGE_BRAIN; case MONS_GREAT_ORB_OF_EYES: return TILE_CORPSE_GREAT_ORB_OF_EYES; // hybrids ('H') case MONS_HIPPOGRIFF: return TILE_CORPSE_HIPPOGRIFF; case MONS_MANTICORE: return TILE_CORPSE_MANTICORE; case MONS_GRIFFON: return TILE_CORPSE_GRIFFON; case MONS_HARPY: return TILE_CORPSE_HARPY; case MONS_MINOTAUR: return TILE_CORPSE_MINOTAUR; // jellies ('J') case MONS_GIANT_AMOEBA: return TILE_CORPSE_GIANT_AMOEBA; // kobolds ('K') case MONS_KOBOLD: return TILE_CORPSE_KOBOLD; case MONS_BIG_KOBOLD: return TILE_CORPSE_BIG_KOBOLD; // nagas ('N') case MONS_NAGA: case MONS_NAGA_MAGE: case MONS_NAGA_WARRIOR: case MONS_GREATER_NAGA: return TILE_CORPSE_NAGA; case MONS_GUARDIAN_SERPENT: return TILE_CORPSE_GUARDIAN_SERPENT; // ogres ('O') case MONS_OGRE: case MONS_OGRE_MAGE: return TILE_CORPSE_OGRE; case MONS_TWO_HEADED_OGRE: return TILE_CORPSE_TWO_HEADED_OGRE; // queen insects ('Q') case MONS_QUEEN_BEE: return TILE_CORPSE_QUEEN_BEE; case MONS_QUEEN_ANT: return TILE_CORPSE_QUEEN_ANT; // snakes ('S') case MONS_SMALL_SNAKE: return TILE_CORPSE_SMALL_SNAKE; case MONS_SNAKE: return TILE_CORPSE_SNAKE; case MONS_ANACONDA: return TILE_CORPSE_ANACONDA; case MONS_WATER_MOCCASIN: return TILE_CORPSE_WATER_MOCCASIN; case MONS_BLACK_MAMBA: return TILE_CORPSE_BLACK_MAMBA; case MONS_VIPER: return TILE_CORPSE_VIPER; case MONS_SEA_SNAKE: return TILE_CORPSE_SEA_SNAKE; // trolls ('T') case MONS_TROLL: return TILE_CORPSE_TROLL; case MONS_ROCK_TROLL: return TILE_CORPSE_ROCK_TROLL; case MONS_IRON_TROLL: return TILE_CORPSE_IRON_TROLL; case MONS_DEEP_TROLL: return TILE_CORPSE_DEEP_TROLL; // bears ('U') case MONS_BEAR: return TILE_CORPSE_BEAR; case MONS_GRIZZLY_BEAR: return TILE_CORPSE_GRIZZLY_BEAR; case MONS_POLAR_BEAR: return TILE_CORPSE_POLAR_BEAR; case MONS_BLACK_BEAR: return TILE_CORPSE_BLACK_BEAR; // cattle ('Y') case MONS_SHEEP: return TILE_CORPSE_SHEEP; case MONS_YAK: return TILE_CORPSE_YAK; case MONS_DEATH_YAK: return TILE_CORPSE_DEATH_YAK; // water monsters case MONS_BIG_FISH: return TILE_CORPSE_BIG_FISH; case MONS_GIANT_GOLDFISH: return TILE_CORPSE_GIANT_GOLDFISH; case MONS_ELECTRIC_EEL: return TILE_CORPSE_ELECTRIC_EEL; case MONS_SHARK: return TILE_CORPSE_SHARK; case MONS_KRAKEN: return TILE_CORPSE_KRAKEN; case MONS_JELLYFISH: return TILE_CORPSE_JELLYFISH; // humans ('@') case MONS_HUMAN: case MONS_HELL_KNIGHT: case MONS_NECROMANCER: case MONS_WIZARD: return TILE_CORPSE_HUMAN; case MONS_SHAPESHIFTER: return TILE_CORPSE_SHAPESHIFTER; case MONS_GLOWING_SHAPESHIFTER: return TILE_CORPSE_GLOWING_SHAPESHIFTER; default: return TILE_ERROR; } } static int _tileidx_rune(const item_def &item) { switch (item.plus) { // the hell runes: case RUNE_DIS: return TILE_MISC_RUNE_DIS; case RUNE_GEHENNA: return TILE_MISC_RUNE_GEHENNA; case RUNE_COCYTUS: return TILE_MISC_RUNE_COCYTUS; case RUNE_TARTARUS: return TILE_MISC_RUNE_TARTARUS; // special pandemonium runes: case RUNE_MNOLEG: return TILE_MISC_RUNE_MNOLEG; case RUNE_LOM_LOBON: return TILE_MISC_RUNE_LOM_LOBON; case RUNE_CEREBOV: return TILE_MISC_RUNE_CEREBOV; case RUNE_GLOORX_VLOQ: return TILE_MISC_RUNE_GLOORX_VLOQ; // All others use the default rune for now. case RUNE_SLIME_PITS: case RUNE_VAULTS: case RUNE_SNAKE_PIT: case RUNE_ELVEN_HALLS: case RUNE_TOMB: case RUNE_SWAMP: case RUNE_SHOALS: // pandemonium and abyss runes: case RUNE_DEMONIC: case RUNE_ABYSSAL: default: return TILE_MISC_RUNE_OF_ZOT; } } static int _tileidx_misc(const item_def &item) { switch (item.sub_type) { case MISC_BOTTLED_EFREET: return TILE_MISC_BOTTLED_EFREET; case MISC_CRYSTAL_BALL_OF_SEEING: return TILE_MISC_CRYSTAL_BALL_OF_SEEING; case MISC_AIR_ELEMENTAL_FAN: return TILE_MISC_AIR_ELEMENTAL_FAN; case MISC_LAMP_OF_FIRE: return TILE_MISC_LAMP_OF_FIRE; case MISC_STONE_OF_EARTH_ELEMENTALS: return TILE_MISC_STONE_OF_EARTH_ELEMENTALS; case MISC_LANTERN_OF_SHADOWS: return TILE_MISC_LANTERN_OF_SHADOWS; case MISC_HORN_OF_GERYON: return TILE_MISC_HORN_OF_GERYON; case MISC_BOX_OF_BEASTS: return TILE_MISC_BOX_OF_BEASTS; case MISC_CRYSTAL_BALL_OF_ENERGY: return TILE_MISC_CRYSTAL_BALL_OF_ENERGY; case MISC_EMPTY_EBONY_CASKET: return TILE_MISC_EMPTY_EBONY_CASKET; case MISC_CRYSTAL_BALL_OF_FIXATION: return TILE_MISC_CRYSTAL_BALL_OF_FIXATION; case MISC_DISC_OF_STORMS: return TILE_MISC_DISC_OF_STORMS; case MISC_DECK_OF_ESCAPE: case MISC_DECK_OF_DESTRUCTION: case MISC_DECK_OF_DUNGEONS: case MISC_DECK_OF_SUMMONING: case MISC_DECK_OF_WONDERS: case MISC_DECK_OF_PUNISHMENT: case MISC_DECK_OF_WAR: case MISC_DECK_OF_CHANGES: case MISC_DECK_OF_DEFENCE: { int ch = TILE_ERROR; switch (item.special) { case DECK_RARITY_LEGENDARY: ch = TILE_MISC_DECK_LEGENDARY; break; case DECK_RARITY_RARE: ch = TILE_MISC_DECK_RARE; break; case DECK_RARITY_COMMON: default: ch = TILE_MISC_DECK; break; } if (item.flags & ISFLAG_KNOW_TYPE) { // NOTE: order of tiles must be identical to order of decks. int offset = item.sub_type - MISC_DECK_OF_ESCAPE + 1; ch += offset; } return ch; } case MISC_RUNE_OF_ZOT: return _tileidx_rune(item); } return TILE_ERROR; } /*****************************************************/ int tileidx_item(const item_def &item) { int clas = item.base_type; int type = item.sub_type; int special = item.special; int colour = item.colour; id_arr& id = get_typeid_array(); switch (clas) { case OBJ_WEAPONS: if (is_unrandom_artefact( item )) return _tileidx_unrand_artefact(find_unrandart_index(item)); else return _tileidx_weapon(item); case OBJ_MISSILES: return _tileidx_missile(item); case OBJ_ARMOUR: if (is_unrandom_artefact( item )) return _tileidx_unrand_artefact(find_unrandart_index(item)); else return _tileidx_armour(item); case OBJ_WANDS: if (id[ IDTYPE_WANDS ][type] == ID_KNOWN_TYPE || (item.flags &ISFLAG_KNOW_TYPE )) { return TILE_WAND_FLAME + type; } else return TILE_WAND_OFFSET + special % 12; case OBJ_FOOD: return _tileidx_food(item); case OBJ_SCROLLS: if (id[ IDTYPE_SCROLLS ][type] == ID_KNOWN_TYPE || (item.flags &ISFLAG_KNOW_TYPE )) { return TILE_SCR_IDENTIFY + type; } return TILE_SCROLL; case OBJ_GOLD: return TILE_GOLD; case OBJ_JEWELLERY: if (type < NUM_RINGS) { if (is_random_artefact( item )) return TILE_RING_RANDOM_OFFSET + colour - 1; else if (id[ IDTYPE_JEWELLERY][type] == ID_KNOWN_TYPE || (item.flags & ISFLAG_KNOW_TYPE)) { return TILE_RING_REGENERATION + type - RING_FIRST_RING; } else { return TILE_RING_NORMAL_OFFSET + special % 13; } } else { if (is_unrandom_artefact( item )) return _tileidx_unrand_artefact(find_unrandart_index(item)); else if (is_random_artefact( item )) return TILE_AMU_RANDOM_OFFSET + colour - 1; else if (id[ IDTYPE_JEWELLERY][type] == ID_KNOWN_TYPE || (item.flags & ISFLAG_KNOW_TYPE)) { return TILE_AMU_RAGE + type - AMU_FIRST_AMULET; } else { return TILE_AMU_NORMAL_OFFSET + special % 13; } } case OBJ_POTIONS: if (id[ IDTYPE_POTIONS ][type] == ID_KNOWN_TYPE || (item.flags &ISFLAG_KNOW_TYPE )) { return TILE_POT_HEALING + type; } else { return TILE_POTION_OFFSET + item.plus % 14; } case OBJ_BOOKS: if (is_random_artefact(item)) { int offset = special % tile_main_count(TILE_BOOK_RANDART_OFFSET); return TILE_BOOK_RANDART_OFFSET + offset; } switch (special % 10) { default: case 0: case 1: return TILE_BOOK_PAPER_OFFSET + colour; case 2: return TILE_BOOK_LEATHER_OFFSET + special/10; case 3: return TILE_BOOK_METAL_OFFSET + special/10; case 4: return TILE_BOOK_PAPYRUS; } case OBJ_STAVES: if (item_is_rod(item)) { if (id[IDTYPE_STAVES][type] == ID_KNOWN_TYPE || (item.flags & ISFLAG_KNOW_TYPE )) { return TILE_ROD_SMITING + type - STAFF_SMITING; } return TILE_ROD_OFFSET + (special / 4) % 10; } else { if (id[IDTYPE_STAVES][type] == ID_KNOWN_TYPE || (item.flags & ISFLAG_KNOW_TYPE )) { return TILE_STAFF_WIZARDRY + type; } return TILE_STAFF_OFFSET + (special / 4) % 10; } case OBJ_CORPSES: if (item.sub_type == CORPSE_SKELETON) return TILE_FOOD_BONE; else return _tileidx_corpse(item); case OBJ_ORBS: return TILE_ORB + random2(tile_main_count(TILE_ORB)); case OBJ_MISCELLANY: return _tileidx_misc(item); default: return TILE_ERROR; } } // Determine Octant of missile direction // .---> X+ // | // | 701 // Y 6O2 // + 543 // // The octant boundary slope tan(pi/8)=sqrt(2)-1 = 0.414 is approximated by 2/5. static int _tile_bolt_dir(int dx, int dy) { int ax = abs(dx); int ay = abs(dy); if (5*ay < 2*ax) return (dx > 0) ? 2 : 6; else if (5*ax < 2*ay) return (dy > 0) ? 4 : 0; else if (dx > 0) return (dy > 0) ? 3 : 1; else return (dy > 0) ? 5: 7; } int tileidx_item_throw(const item_def &item, int dx, int dy) { if (item.base_type == OBJ_MISSILES) { int ch = -1; int dir = _tile_bolt_dir(dx, dy); // Thrown items with multiple directions switch (item.sub_type) { case MI_ARROW: ch = TILE_MI_ARROW0; break; case MI_BOLT: ch = TILE_MI_BOLT0; break; case MI_DART: ch = TILE_MI_DART0; break; case MI_NEEDLE: ch = TILE_MI_NEEDLE0; break; case MI_JAVELIN: ch = TILE_MI_JAVELIN0; break; case MI_THROWING_NET: ch = TILE_MI_THROWING_NET0; default: break; } if (ch != -1) return ch + dir; // Thrown items with a single direction switch (item.sub_type) { case MI_STONE: ch = TILE_MI_STONE0; break; case MI_SLING_BULLET: ch = TILE_MI_SLING_BULLET0; break; case MI_LARGE_ROCK: ch = TILE_MI_LARGE_ROCK0; break; case MI_THROWING_NET: ch = TILE_MI_THROWING_NET0; break; default: break; } if (ch != -1) return ch; } // If not a special case, just return the default tile. return tileidx_item(item); } static int _tileidx_trap(trap_type type) { switch (type) { case TRAP_DART: return TILE_DNGN_TRAP_DART; case TRAP_ARROW: return TILE_DNGN_TRAP_ARROW; case TRAP_SPEAR: return TILE_DNGN_TRAP_SPEAR; case TRAP_AXE: return TILE_DNGN_TRAP_AXE; case TRAP_TELEPORT: return TILE_DNGN_TRAP_TELEPORT; case TRAP_ALARM: return TILE_DNGN_TRAP_ALARM; case TRAP_BLADE: return TILE_DNGN_TRAP_BLADE; case TRAP_BOLT: return TILE_DNGN_TRAP_BOLT; case TRAP_NET: return TILE_DNGN_TRAP_NET; case TRAP_ZOT: return TILE_DNGN_TRAP_ZOT; case TRAP_NEEDLE: return TILE_DNGN_TRAP_NEEDLE; case TRAP_SHAFT: return TILE_DNGN_TRAP_SHAFT; default: return TILE_DNGN_ERROR; } } static int _tileidx_shop(coord_def where) { const shop_struct *shop = get_shop(where); if (!shop) return TILE_DNGN_ERROR; switch (shop->type) { case SHOP_WEAPON: case SHOP_WEAPON_ANTIQUE: return TILE_SHOP_WEAPONS; case SHOP_ARMOUR: case SHOP_ARMOUR_ANTIQUE: return TILE_SHOP_ARMOUR; case SHOP_JEWELLERY: return TILE_SHOP_JEWELLERY; case SHOP_WAND: return TILE_SHOP_WANDS; case SHOP_FOOD: return TILE_SHOP_FOOD; case SHOP_BOOK: return TILE_SHOP_BOOKS; case SHOP_SCROLL: return TILE_SHOP_SCROLLS; case SHOP_DISTILLERY: return TILE_SHOP_POTIONS; case SHOP_GENERAL: case SHOP_GENERAL_ANTIQUE: return TILE_SHOP_GENERAL; default: return TILE_DNGN_ERROR; } } int tileidx_feature(dungeon_feature_type feat, int gx, int gy) { int override = env.tile_flv[gx][gy].feat; if (override && !feat_is_door(grd[gx][gy])) return override; switch (feat) { case DNGN_UNSEEN: return TILE_DNGN_UNSEEN; case DNGN_FLOOR_SPECIAL: case DNGN_ROCK_WALL: case DNGN_PERMAROCK_WALL: return TILE_WALL_NORMAL; case DNGN_OPEN_SEA: return TILE_DNGN_OPEN_SEA; case DNGN_SECRET_DOOR: case DNGN_DETECTED_SECRET_DOOR: { const dungeon_feature_type appear = grid_secret_door_appearance(coord_def(gx, gy)); ASSERT(!feat_is_secret_door(appear)); return tileidx_feature(appear, gx, gy); } case DNGN_CLEAR_ROCK_WALL: case DNGN_CLEAR_STONE_WALL: case DNGN_CLEAR_PERMAROCK_WALL: return TILE_DNGN_TRANSPARENT_WALL; case DNGN_STONE_WALL: return TILE_DNGN_STONE_WALL; case DNGN_CLOSED_DOOR: return TILE_DNGN_CLOSED_DOOR; case DNGN_METAL_WALL: return TILE_DNGN_METAL_WALL; case DNGN_GREEN_CRYSTAL_WALL: return TILE_DNGN_GREEN_CRYSTAL_WALL; case DNGN_ORCISH_IDOL: return TILE_DNGN_ORCISH_IDOL; case DNGN_WAX_WALL: return TILE_DNGN_WAX_WALL; case DNGN_TREES: return TILE_DNGN_TREE; case DNGN_GRANITE_STATUE: return TILE_DNGN_GRANITE_STATUE; case DNGN_LAVA: return TILE_DNGN_LAVA; case DNGN_DEEP_WATER: if (env.grid_colours[gx][gy] == GREEN || env.grid_colours[gx][gy] == LIGHTGREEN) { return TILE_DNGN_DEEP_WATER_MURKY; } else if (player_in_branch(BRANCH_SHOALS)) return TILE_SHOALS_DEEP_WATER; return TILE_DNGN_DEEP_WATER; case DNGN_SHALLOW_WATER: { int t = TILE_DNGN_SHALLOW_WATER; if (env.grid_colours[gx][gy] == GREEN || env.grid_colours[gx][gy] == LIGHTGREEN) { t = TILE_DNGN_SHALLOW_WATER_MURKY; } else if (player_in_branch(BRANCH_SHOALS)) t = TILE_SHOALS_SHALLOW_WATER; monsters *mon = monster_at(coord_def(gx, gy)); if (mon) { // Add disturbance to tile. if (mon->submerged()) t += tile_dngn_count(t); } return (t); } case DNGN_FLOOR: case DNGN_UNDISCOVERED_TRAP: return TILE_FLOOR_NORMAL; case DNGN_ENTER_HELL: return TILE_DNGN_ENTER_HELL; case DNGN_OPEN_DOOR: return TILE_DNGN_OPEN_DOOR; case DNGN_TRAP_MECHANICAL: case DNGN_TRAP_MAGICAL: case DNGN_TRAP_NATURAL: return _tileidx_trap(get_trap_type(coord_def(gx, gy))); case DNGN_ENTER_SHOP: return _tileidx_shop(coord_def(gx,gy)); case DNGN_ABANDONED_SHOP: return TILE_DNGN_ABANDONED_SHOP; case DNGN_ENTER_LABYRINTH: return TILE_DNGN_ENTER_LABYRINTH; case DNGN_STONE_STAIRS_DOWN_I: case DNGN_STONE_STAIRS_DOWN_II: case DNGN_STONE_STAIRS_DOWN_III: return TILE_DNGN_STONE_STAIRS_DOWN; case DNGN_ESCAPE_HATCH_DOWN: return TILE_DNGN_ESCAPE_HATCH_DOWN; case DNGN_STONE_STAIRS_UP_I: case DNGN_STONE_STAIRS_UP_II: case DNGN_STONE_STAIRS_UP_III: if (player_in_hell()) return TILE_DNGN_RETURN_HELL; return TILE_DNGN_STONE_STAIRS_UP; case DNGN_ESCAPE_HATCH_UP: return TILE_DNGN_ESCAPE_HATCH_UP; case DNGN_ENTER_DIS: return TILE_DNGN_ENTER_DIS; case DNGN_ENTER_GEHENNA: return TILE_DNGN_ENTER_GEHENNA; case DNGN_ENTER_COCYTUS: return TILE_DNGN_ENTER_COCYTUS; case DNGN_ENTER_TARTARUS: return TILE_DNGN_ENTER_TARTARUS; case DNGN_ENTER_ABYSS: return TILE_DNGN_ENTER_ABYSS; case DNGN_EXIT_ABYSS: case DNGN_EXIT_HELL: case DNGN_EXIT_PANDEMONIUM: return TILE_DNGN_EXIT_ABYSS; case DNGN_STONE_ARCH: return TILE_DNGN_STONE_ARCH; case DNGN_ENTER_PANDEMONIUM: return TILE_DNGN_ENTER_PANDEMONIUM; case DNGN_TRANSIT_PANDEMONIUM: return TILE_DNGN_TRANSIT_PANDEMONIUM; case DNGN_ENTER_ORCISH_MINES: case DNGN_ENTER_HIVE: case DNGN_ENTER_LAIR: case DNGN_ENTER_SLIME_PITS: case DNGN_ENTER_VAULTS: case DNGN_ENTER_CRYPT: case DNGN_ENTER_HALL_OF_BLADES: case DNGN_ENTER_TEMPLE: case DNGN_ENTER_SNAKE_PIT: case DNGN_ENTER_ELVEN_HALLS: case DNGN_ENTER_TOMB: case DNGN_ENTER_SWAMP: case DNGN_ENTER_SHOALS: return TILE_DNGN_ENTER; case DNGN_ENTER_ZOT: if (you.opened_zot) return TILE_DNGN_ENTER_ZOT_OPEN; return TILE_DNGN_ENTER_ZOT_CLOSED; case DNGN_RETURN_FROM_ORCISH_MINES: case DNGN_RETURN_FROM_HIVE: case DNGN_RETURN_FROM_LAIR: case DNGN_RETURN_FROM_SLIME_PITS: case DNGN_RETURN_FROM_VAULTS: case DNGN_RETURN_FROM_CRYPT: case DNGN_RETURN_FROM_HALL_OF_BLADES: case DNGN_RETURN_FROM_TEMPLE: case DNGN_RETURN_FROM_SNAKE_PIT: case DNGN_RETURN_FROM_ELVEN_HALLS: case DNGN_RETURN_FROM_TOMB: case DNGN_RETURN_FROM_SWAMP: case DNGN_RETURN_FROM_SHOALS: return TILE_DNGN_RETURN; case DNGN_RETURN_FROM_ZOT: return TILE_DNGN_RETURN_ZOT; case DNGN_ENTER_PORTAL_VAULT: case DNGN_EXIT_PORTAL_VAULT: return TILE_DNGN_PORTAL; // altars case DNGN_ALTAR_ZIN: return TILE_DNGN_ALTAR_ZIN; case DNGN_ALTAR_SHINING_ONE: return TILE_DNGN_ALTAR_SHINING_ONE; case DNGN_ALTAR_KIKUBAAQUDGHA: return TILE_DNGN_ALTAR_KIKUBAAQUDGHA; case DNGN_ALTAR_YREDELEMNUL: return TILE_DNGN_ALTAR_YREDELEMNUL; case DNGN_ALTAR_XOM: return TILE_DNGN_ALTAR_XOM; case DNGN_ALTAR_VEHUMET: return TILE_DNGN_ALTAR_VEHUMET; case DNGN_ALTAR_OKAWARU: return TILE_DNGN_ALTAR_OKAWARU; case DNGN_ALTAR_MAKHLEB: return TILE_DNGN_ALTAR_MAKHLEB; case DNGN_ALTAR_SIF_MUNA: return TILE_DNGN_ALTAR_SIF_MUNA; case DNGN_ALTAR_TROG: return TILE_DNGN_ALTAR_TROG; case DNGN_ALTAR_NEMELEX_XOBEH: return TILE_DNGN_ALTAR_NEMELEX_XOBEH; case DNGN_ALTAR_ELYVILON: return TILE_DNGN_ALTAR_ELYVILON; case DNGN_ALTAR_LUGONU: return TILE_DNGN_ALTAR_LUGONU; case DNGN_ALTAR_BEOGH: return TILE_DNGN_ALTAR_BEOGH; case DNGN_ALTAR_JIYVA: return TILE_DNGN_ALTAR_JIYVA; case DNGN_ALTAR_FEDHAS: return TILE_DNGN_ALTAR_FEDHAS; case DNGN_ALTAR_CHEIBRIADOS: return TILE_DNGN_ALTAR_CHEIBRIADOS; case DNGN_FOUNTAIN_BLUE: return TILE_DNGN_BLUE_FOUNTAIN; case DNGN_FOUNTAIN_SPARKLING: return TILE_DNGN_SPARKLING_FOUNTAIN; case DNGN_FOUNTAIN_BLOOD: return TILE_DNGN_BLOOD_FOUNTAIN; case DNGN_DRY_FOUNTAIN_BLUE: case DNGN_DRY_FOUNTAIN_SPARKLING: case DNGN_DRY_FOUNTAIN_BLOOD: case DNGN_PERMADRY_FOUNTAIN: return TILE_DNGN_DRY_FOUNTAIN; default: return TILE_DNGN_ERROR; } } static int _tileidx_cloud(cloud_struct cl) { int type = cl.type; int decay = cl.decay; std::string override = cl.tile; int colour = cl.colour; int ch = TILE_ERROR; int dur = decay/20; if (dur > 2) dur = 2; if (!override.empty()) { unsigned int index; if (!tile_main_index(override.c_str(), index)) { mprf(MSGCH_ERROR, "Invalid tile requested for cloud: '%s'.", override.c_str()); } else { int offset = tile_main_count(index); ch = index + offset; } } else { switch (type) { case CLOUD_FIRE: ch = TILE_CLOUD_FIRE_0 + dur; break; case CLOUD_COLD: ch = TILE_CLOUD_COLD_0 + dur; break; case CLOUD_STINK: case CLOUD_POISON: ch = TILE_CLOUD_POISON_0 + dur; break; case CLOUD_BLUE_SMOKE: ch = TILE_CLOUD_BLUE_SMOKE; break; case CLOUD_PURPLE_SMOKE: case CLOUD_TLOC_ENERGY: ch = TILE_CLOUD_TLOC_ENERGY; break; case CLOUD_MIASMA: ch = TILE_CLOUD_MIASMA; break; case CLOUD_BLACK_SMOKE: ch = TILE_CLOUD_BLACK_SMOKE; break; case CLOUD_MUTAGENIC: ch = (dur == 0 ? TILE_CLOUD_MUTAGENIC_0 : dur == 1 ? TILE_CLOUD_MUTAGENIC_1 : TILE_CLOUD_MUTAGENIC_2); ch += random2(tile_main_count(ch)); break; case CLOUD_MIST: ch = TILE_CLOUD_MIST; break; case CLOUD_RAIN: ch = TILE_CLOUD_RAIN + random2(tile_main_count(TILE_CLOUD_RAIN)); break; case CLOUD_GLOOM: ch = TILE_CLOUD_GLOOM; break; default: ch = TILE_CLOUD_GREY_SMOKE; break; } } if (colour != -1) ch = tile_main_coloured(ch, colour); return (ch | TILE_FLAG_FLYING); } /**********************************************************/ int tileidx_player(int job) { int ch = TILEP_PLAYER; // Handle shapechange first switch (you.attribute[ATTR_TRANSFORMATION]) { // animals case TRAN_BAT: ch = TILEP_TRAN_BAT; break; case TRAN_SPIDER: ch = TILEP_TRAN_SPIDER; break; case TRAN_PIG: ch = TILEP_TRAN_PIG; break; // non-animals case TRAN_ICE_BEAST: ch = TILEP_TRAN_ICE_BEAST; break; case TRAN_STATUE: ch = TILEP_TRAN_STATUE; break; case TRAN_DRAGON: ch = TILEP_TRAN_DRAGON; break; case TRAN_LICH: ch = TILEP_TRAN_LICH; break; } if (you.airborne()) ch |= TILE_FLAG_FLYING; if (you.attribute[ATTR_HELD]) ch |= TILE_FLAG_NET; return ch; } void tileidx_unseen(unsigned int &fg, unsigned int &bg, int ch, const coord_def& gc) { ch &= 0xff; if (ch < 32) ch = 32; unsigned int flag = tile_unseen_flag(gc); fg = 0; bg = TILE_FLOOR_NORMAL | flag; if (ch >= '@' && ch <= 'Z' || ch >= 'a' && ch <= 'z' || ch == '&' || ch >= '1' && ch <= '5' || ch == ';') { fg = TILE_UNSEEN_MONSTER; return; } switch (ch) { //blank, walls, and floors first, since they are frequent case ' ': bg = TILE_DNGN_UNSEEN; break; case 127: //old case 176: case 177: bg = TILE_WALL_NORMAL; break; case 130: case ',': case '.': case 249: case 250: bg = TILE_FLOOR_NORMAL; break; case 137: bg = TILE_DNGN_WAX_WALL; break; case 138: bg = TILE_DNGN_STONE_WALL; break; case 139: bg = TILE_DNGN_METAL_WALL; break; case 140: bg = TILE_DNGN_GREEN_CRYSTAL_WALL; break; // others case '!': fg = TILE_POTION_OFFSET + 13; break; case '"': fg = TILE_AMU_NORMAL_OFFSET + 2; break; case '#': fg = TILE_CLOUD_GREY_SMOKE; break; case '$': fg = TILE_GOLD; break; case '%': fg = TILE_FOOD_MEAT_RATION; break; case 142: fg = TILE_UNSEEN_CORPSE; break; case '\'': case 134: bg = TILE_DNGN_OPEN_DOOR; break; case '(': case ')': fg = TILE_UNSEEN_WEAPON; break; case '*': fg = TILE_WALL_NORMAL ; break; case '+': fg = TILE_BOOK_PAPER_OFFSET + 15; break; case '/': fg = TILE_WAND_OFFSET; break; case '8': fg = TILEP_MONS_SILVER_STATUE; break; case '<': bg = TILE_DNGN_STONE_STAIRS_UP; break; case '=': fg = TILE_RING_NORMAL_OFFSET + 1; break; case '>': bg = TILE_DNGN_STONE_STAIRS_DOWN; break; case '~': case '?': fg = TILE_UNSEEN_ITEM; break; case '[': case ']': fg = TILE_UNSEEN_ARMOUR; break; case '\\': fg = TILE_STAFF_OFFSET; break; case '^': bg = TILE_DNGN_TRAP_ARROW; break; case '_': case 220: case 131: bg = TILE_DNGN_UNSEEN_ALTAR; break; case '{': case 247: case 135: bg = TILE_DNGN_DEEP_WATER; break; case 244: case 133: bg = TILE_DNGN_BLUE_FOUNTAIN; break; case '}': fg = TILE_MISC_CRYSTAL_BALL_OF_SEEING; break; case 128: //old case 254: bg = TILE_DNGN_CLOSED_DOOR; break; case 129: bg = TILE_DNGN_RETURN; break; case 239: case 132: bg = TILE_DNGN_UNSEEN_ENTRANCE; break; case 136: bg = TILE_DNGN_ENTER; break; case 141: bg = TILE_DNGN_LAVA; break; } bg |= flag; } int tileidx_bolt(const bolt &bolt) { const int col = bolt.colour; return tileidx_zap(col); } int tileidx_zap(int colour) { int col = (colour == ETC_MAGIC ? element_colour(ETC_MAGIC) : colour); if (col > 8) col -= 8; if (col < 1) col = 7; return (TILE_SYM_BOLT_OFS - 1 + col); } int tileidx_spell(spell_type spell) { switch (spell) { case SPELL_NO_SPELL: case SPELL_DEBUGGING_RAY: return TILEG_ERROR; case NUM_SPELLS: // XXX: Hack! return TILEG_MEMORISE; // Air case SPELL_SHOCK: return TILEG_SHOCK; case SPELL_SWIFTNESS: return TILEG_SWIFTNESS; case SPELL_LEVITATION: return TILEG_LEVITATION; case SPELL_REPEL_MISSILES: return TILEG_REPEL_MISSILES; case SPELL_MEPHITIC_CLOUD: return TILEG_MEPHITIC_CLOUD; case SPELL_DISCHARGE: return TILEG_STATIC_DISCHARGE; case SPELL_FLY: return TILEG_FLIGHT; case SPELL_INSULATION: return TILEG_INSULATION; case SPELL_LIGHTNING_BOLT: return TILEG_LIGHTNING_BOLT; case SPELL_AIRSTRIKE: return TILEG_AIRSTRIKE; case SPELL_SILENCE: return TILEG_SILENCE; case SPELL_DEFLECT_MISSILES: return TILEG_DEFLECT_MISSILES; case SPELL_CONJURE_BALL_LIGHTNING: return TILEG_CONJURE_BALL_LIGHTNING; case SPELL_CHAIN_LIGHTNING: return TILEG_CHAIN_LIGHTNING; // Earth case SPELL_SANDBLAST: return TILEG_SANDBLAST; case SPELL_MAXWELLS_SILVER_HAMMER: return TILEG_MAXWELLS_SILVER_HAMMER; case SPELL_STONESKIN: return TILEG_STONESKIN; case SPELL_PASSWALL: return TILEG_PASSWALL; case SPELL_STONE_ARROW: return TILEG_STONE_ARROW; case SPELL_DIG: return TILEG_DIG; case SPELL_BOLT_OF_MAGMA: return TILEG_BOLT_OF_MAGMA; case SPELL_FRAGMENTATION: return TILEG_LEES_RAPID_DECONSTRUCTION; case SPELL_IRON_SHOT: return TILEG_IRON_SHOT; case SPELL_LEHUDIBS_CRYSTAL_SPEAR: return TILEG_LEHUDIBS_CRYSTAL_SPEAR; case SPELL_SHATTER: return TILEG_SHATTER; // Fire case SPELL_FLAME_TONGUE: return TILEG_FLAME_TONGUE; case SPELL_EVAPORATE: return TILEG_EVAPORATE; case SPELL_FIRE_BRAND: return TILEG_FIRE_BRAND; case SPELL_THROW_FLAME: return TILEG_THROW_FLAME; case SPELL_CONJURE_FLAME: return TILEG_CONJURE_FLAME; case SPELL_STICKY_FLAME: return TILEG_STICKY_FLAME; case SPELL_BOLT_OF_FIRE: return TILEG_BOLT_OF_FIRE; case SPELL_IGNITE_POISON: return TILEG_IGNITE_POISON; case SPELL_FIREBALL: return TILEG_FIREBALL; case SPELL_DELAYED_FIREBALL: return TILEG_DELAYED_FIREBALL; case SPELL_RING_OF_FLAMES: return TILEG_RING_OF_FLAMES; case SPELL_FIRE_STORM: return TILEG_FIRE_STORM; // Ice case SPELL_FREEZE: return TILEG_FREEZE; case SPELL_THROW_FROST: return TILEG_THROW_FROST; case SPELL_FREEZING_AURA: return TILEG_FREEZING_AURA; case SPELL_HIBERNATION: return TILEG_ENSORCELLED_HIBERNATION; case SPELL_OZOCUBUS_ARMOUR: return TILEG_OZOCUBUS_ARMOUR; case SPELL_THROW_ICICLE: return TILEG_THROW_ICICLE; case SPELL_CONDENSATION_SHIELD: return TILEG_CONDENSATION_SHIELD; case SPELL_OZOCUBUS_REFRIGERATION: return TILEG_OZOCUBUS_REFRIGERATION; case SPELL_BOLT_OF_COLD: return TILEG_BOLT_OF_COLD; case SPELL_FREEZING_CLOUD: return TILEG_FREEZING_CLOUD; case SPELL_ENGLACIATION: return TILEG_METABOLIC_ENGLACIATION; case SPELL_SIMULACRUM: return TILEG_SIMULACRUM; case SPELL_ICE_STORM: return TILEG_ICE_STORM; // Poison case SPELL_STING: return TILEG_STING; case SPELL_CURE_POISON: return TILEG_CURE_POISON; case SPELL_POISON_WEAPON: return TILEG_POISON_BRAND; case SPELL_INTOXICATE: return TILEG_ALISTAIRS_INTOXICATION; case SPELL_OLGREBS_TOXIC_RADIANCE: return TILEG_OLGREBS_TOXIC_RADIANCE; case SPELL_RESIST_POISON: return TILEG_RESIST_POISON; case SPELL_VENOM_BOLT: return TILEG_VENOM_BOLT; case SPELL_POISON_ARROW: return TILEG_POISON_ARROW; case SPELL_POISONOUS_CLOUD: return TILEG_POISONOUS_CLOUD; // Enchantment case SPELL_CONFUSING_TOUCH: return TILEG_CONFUSING_TOUCH; case SPELL_CORONA: return TILEG_CORONA; case SPELL_PROJECTED_NOISE: return TILEG_PROJECTED_NOISE; case SPELL_SURE_BLADE: return TILEG_SURE_BLADE; case SPELL_TUKIMAS_VORPAL_BLADE: return TILEG_TUKIMAS_VORPAL_BLADE; case SPELL_BERSERKER_RAGE: return TILEG_BERSERKER_RAGE; case SPELL_CONFUSE: return TILEG_CONFUSE; case SPELL_SLOW: return TILEG_SLOW; case SPELL_TUKIMAS_DANCE: return TILEG_TUKIMAS_DANCE; case SPELL_SELECTIVE_AMNESIA: return TILEG_SELECTIVE_AMNESIA; case SPELL_ENSLAVEMENT: return TILEG_ENSLAVEMENT; case SPELL_SEE_INVISIBLE: return TILEG_SEE_INVISIBLE; case SPELL_PETRIFY: return TILEG_PETRIFY; case SPELL_CAUSE_FEAR: return TILEG_CAUSE_FEAR; case SPELL_TAME_BEASTS: return TILEG_TAME_BEASTS; case SPELL_EXTENSION: return TILEG_EXTENSION; case SPELL_HASTE: return TILEG_HASTE; case SPELL_INVISIBILITY: return TILEG_INVISIBILITY; case SPELL_MASS_CONFUSION: return TILEG_MASS_CONFUSION; // Translocation case SPELL_APPORTATION: return TILEG_APPORTATION; case SPELL_PORTAL_PROJECTILE: return TILEG_PORTAL_PROJECTILE; case SPELL_BLINK: return TILEG_BLINK; case SPELL_BANISHMENT: return TILEG_BANISHMENT; case SPELL_CONTROL_TELEPORT: return TILEG_CONTROLLED_TELEPORT; case SPELL_TELEPORT_OTHER: return TILEG_TELEPORT_OTHER; case SPELL_TELEPORT_SELF: return TILEG_TELEPORT; case SPELL_PHASE_SHIFT: return TILEG_PHASE_SHIFT; case SPELL_CONTROLLED_BLINK: return TILEG_CONTROLLED_BLINK; case SPELL_WARP_BRAND: return TILEG_WARP_WEAPON; case SPELL_DISPERSAL: return TILEG_DISPERSAL; case SPELL_PORTAL: return TILEG_PORTAL; // Summoning case SPELL_SUMMON_BUTTERFLIES: return TILEG_SUMMON_BUTTERFLIES; case SPELL_SUMMON_SMALL_MAMMALS: return TILEG_SUMMON_SMALL_MAMMALS; case SPELL_RECALL: return TILEG_RECALL; case SPELL_CALL_CANINE_FAMILIAR: return TILEG_CALL_CANINE_FAMILIAR; case SPELL_CALL_IMP: return TILEG_CALL_IMP; case SPELL_ABJURATION: return TILEG_ABJURATION; case SPELL_SUMMON_SCORPIONS: return TILEG_SUMMON_SCORPIONS; case SPELL_SUMMON_ELEMENTAL: return TILEG_SUMMON_ELEMENTAL; case SPELL_SUMMON_DEMON: return TILEG_SUMMON_DEMON; case SPELL_SUMMON_UGLY_THING: return TILEG_SUMMON_UGLY_THING; case SPELL_SHADOW_CREATURES: return TILEG_SUMMON_SHADOW_CREATURES; case SPELL_SUMMON_ICE_BEAST: return TILEG_SUMMON_ICE_BEAST; case SPELL_DEMONIC_HORDE: return TILEG_DEMONIC_HORDE; case SPELL_SUMMON_GREATER_DEMON: return TILEG_SUMMON_GREATER_DEMON; case SPELL_SUMMON_HORRIBLE_THINGS: return TILEG_SUMMON_HORRIBLE_THINGS; // Necromancy case SPELL_ANIMATE_SKELETON: return TILEG_ANIMATE_SKELETON; case SPELL_PAIN: return TILEG_PAIN; case SPELL_FULSOME_DISTILLATION: return TILEG_FULSOME_DISTILLATION; case SPELL_CORPSE_ROT: return TILEG_CORPSE_ROT; case SPELL_LETHAL_INFUSION: return TILEG_LETHAL_INFUSION; case SPELL_SUBLIMATION_OF_BLOOD: return TILEG_SUBLIMATION_OF_BLOOD; case SPELL_BONE_SHARDS: return TILEG_BONE_SHARDS; case SPELL_VAMPIRIC_DRAINING: return TILEG_VAMPIRIC_DRAINING; case SPELL_REGENERATION: return TILEG_REGENERATION; case SPELL_ANIMATE_DEAD: return TILEG_ANIMATE_DEAD; case SPELL_DISPEL_UNDEAD: return TILEG_DISPEL_UNDEAD; case SPELL_HAUNT: return TILEG_HAUNT; case SPELL_BORGNJORS_REVIVIFICATION: return TILEG_BORGNJORS_REVIVIFICATION; case SPELL_CIGOTUVIS_DEGENERATION: return TILEG_CIGOTUVIS_DEGENERATION; case SPELL_AGONY: return TILEG_AGONY; case SPELL_TWISTED_RESURRECTION: return TILEG_TWISTED_RESURRECTION; case SPELL_EXCRUCIATING_WOUNDS: return TILEG_EXCRUCIATING_WOUNDS; case SPELL_CONTROL_UNDEAD: return TILEG_CONTROL_UNDEAD; case SPELL_BOLT_OF_DRAINING: return TILEG_BOLT_OF_DRAINING; case SPELL_SYMBOL_OF_TORMENT: return TILEG_SYMBOL_OF_TORMENT; case SPELL_DEATHS_DOOR: return TILEG_DEATHS_DOOR; case SPELL_DEATH_CHANNEL: return TILEG_DEATH_CHANNEL; // Transmutation case SPELL_STICKS_TO_SNAKES: return TILEG_STICKS_TO_SNAKES; case SPELL_SPIDER_FORM: return TILEG_SPIDER_FORM; case SPELL_ICE_FORM: return TILEG_ICE_FORM; case SPELL_BLADE_HANDS: return TILEG_BLADE_HANDS; case SPELL_POLYMORPH_OTHER: return TILEG_POLYMORPH_OTHER; case SPELL_STATUE_FORM: return TILEG_STATUE_FORM; case SPELL_ALTER_SELF: return TILEG_ALTER_SELF; case SPELL_DRAGON_FORM: return TILEG_DRAGON_FORM; case SPELL_NECROMUTATION: return TILEG_NECROMUTATION; // pure Conjuration case SPELL_MAGIC_DART: return TILEG_MAGIC_DART; case SPELL_ISKENDERUNS_MYSTIC_BLAST: return TILEG_ISKENDERUNS_MYSTIC_BLAST; case SPELL_IOOD: return TILEG_IOOD; // Divination (soon to be obsolete, or moved to abilities) case SPELL_DETECT_SECRET_DOORS: return TILEG_DETECT_SECRET_DOORS; case SPELL_DETECT_TRAPS: return TILEG_DETECT_TRAPS; case SPELL_DETECT_ITEMS: return TILEG_DETECT_ITEMS; case SPELL_DETECT_CREATURES: return TILEG_DETECT_CREATURES; // -------------------------------------------- // Rods and abilities (tiles needed for later) // Abilities case SPELL_SMITING: // Beogh power case SPELL_MINOR_HEALING: // Ely power case SPELL_MAJOR_HEALING: // Ely power case SPELL_HELLFIRE: // Demonspawn ability // Rod-only spells case SPELL_PARALYSE: // we could reuse Petrify for this case SPELL_STRIKING: case SPELL_BOLT_OF_INACCURACY: case SPELL_SUMMON_SWARM: return TILEG_TODO; // -------------------------------------------- // Spells that don't need icons: case SPELL_STONEMAIL: // Xom only? case SPELL_SUMMON_DRAGON: // Xom case SPELL_DISINTEGRATE: // wand and card // Monster spells (mostly?) case SPELL_HELLFIRE_BURST: case SPELL_VAMPIRE_SUMMON: case SPELL_BRAIN_FEED: case SPELL_FAKE_RAKSHASA_SUMMON: case SPELL_STEAM_BALL: case SPELL_SUMMON_UFETUBUS: case SPELL_SUMMON_BEAST: case SPELL_ENERGY_BOLT: case SPELL_POISON_SPLASH: case SPELL_SUMMON_UNDEAD: case SPELL_CANTRIP: case SPELL_QUICKSILVER_BOLT: case SPELL_METAL_SPLINTERS: case SPELL_MIASMA: case SPELL_SUMMON_DRAKES: case SPELL_BLINK_OTHER: case SPELL_SUMMON_MUSHROOMS: case SPELL_ACID_SPLASH: case SPELL_STICKY_FLAME_SPLASH: case SPELL_FIRE_BREATH: case SPELL_COLD_BREATH: case SPELL_DRACONIAN_BREATH: case SPELL_WATER_ELEMENTALS: case SPELL_PORKALATOR: default: return TILEG_ERROR; } } // Specifically for vault-overwritten doors. We have three "sets" of tiles that // can be dealt with. The tile sets should be 2, 3, 8 and 9 respectively. They // are: // 2. Closed, open. // 3. Detected, closed, open. // 8. Closed, open, gate left closed, gate middle closed, gate right closed, // gate left open, gate middle open, gate right open. // 9. Detected, closed, open, gate left closed, gate middle closed, gate right // closed, gate left open, gate middle open, gate right open. int _get_door_offset (int base_tile, bool opened = false, bool detected = false, int gateway_type = 0) { int count = tile_dngn_count(base_tile); if (count == 1) return 0; // The location of the default "closed" tile. int offset = 0; switch (count) { case 2: return ((opened) ? 1: 0); case 3: if (opened) return 2; else if (detected) return 0; else return 1; case 8: // But is BASE_TILE for others. offset = 0; break; case 9: // It's located at BASE_TILE+1 for tile sets with detected doors offset = 1; break; default: // Passed a non-door tile base, pig out now. ASSERT(false); } // If we've reached this point, we're dealing with a gate. // Don't believe gateways deal differently with detection. if (detected) return 0; if (!opened && !detected && gateway_type == 0) return 0; return offset + gateway_type; } static int _pick_random_dngn_tile(unsigned int idx, int value = -1) { ASSERT(idx >= 0 && idx < TILE_DNGN_MAX); const int count = tile_dngn_count(idx); if (count == 1) return (idx); const int total = tile_dngn_probs(idx + count - 1); const int rand = (value == -1 ? random2(total) : value % total); for (int i = 0; i < count; ++i) { int curr = idx + i; if (rand < tile_dngn_probs(curr)) return (curr); } return (idx); } // Modify wall tile index depending on floor/wall flavour. static inline void _finalise_tile(unsigned int *tile, unsigned int wall_flv, unsigned int floor_flv, unsigned int special_flv, coord_def gc) { int orig = (*tile) & TILE_FLAG_MASK; int flag = (*tile) & (~TILE_FLAG_MASK); // TODO enne - expose this as an option, so ziggurat can use it too. // Alternatively, allow the stone type to be set. // // Hack: Swap rock/stone in crypt and tomb, because there are // only stone walls. if ((you.where_are_you == BRANCH_CRYPT || you.where_are_you == BRANCH_TOMB) && orig == TILE_DNGN_STONE_WALL) { orig = TILE_WALL_NORMAL; } if (orig == TILE_FLOOR_NORMAL) (*tile) = floor_flv; else if (orig == TILE_WALL_NORMAL) (*tile) = wall_flv; else if (orig == TILE_DNGN_CLOSED_DOOR || orig == TILE_DNGN_OPEN_DOOR) { int override = env.tile_flv(gc).feat; if (override) { // XXX: This doesn't deal properly with detected doors. bool opened = (orig == TILE_DNGN_OPEN_DOOR); int offset = _get_door_offset(override, opened, false, special_flv); (*tile) = override + offset; } else (*tile) = orig + std::min((int)special_flv, 3); } else if (orig < TILE_DNGN_MAX) { // Some tiles may change from turn to turn, but only if in view. if (orig >= TILE_DNGN_LAVA && orig < TILE_BLOOD && you.see_cell(gc)) env.tile_flv(gc).special = random2(256); (*tile) = _pick_random_dngn_tile(orig, special_flv); } (*tile) |= flag; } void tilep_calc_flags(const int parts[], int flag[]) { for (unsigned i = 0; i < TILEP_PART_MAX; i++) flag[i] = TILEP_FLAG_NORMAL; if (parts[TILEP_PART_HELM] - 1 >= TILEP_HELM_HELM_OFS) flag[TILEP_PART_HAIR] = TILEP_FLAG_HIDE; if (parts[TILEP_PART_HELM] - 1 >= TILEP_HELM_FHELM_OFS) flag[TILEP_PART_BEARD] = TILEP_FLAG_HIDE; if (parts[TILEP_PART_BASE] >= TILEP_BASE_NAGA && parts[TILEP_PART_BASE] < tilep_species_to_base_tile(SP_NAGA + 1)) { flag[TILEP_PART_BOOTS] = flag[TILEP_PART_LEG] = TILEP_FLAG_HIDE; flag[TILEP_PART_BODY] = TILEP_FLAG_CUT_NAGA; } else if (parts[TILEP_PART_BASE] >= TILEP_BASE_CENTAUR && parts[TILEP_PART_BASE] < tilep_species_to_base_tile(SP_CENTAUR + 1)) { flag[TILEP_PART_BOOTS] = flag[TILEP_PART_LEG] = TILEP_FLAG_HIDE; flag[TILEP_PART_BODY] = TILEP_FLAG_CUT_CENTAUR; } else if (parts[TILEP_PART_BASE] == TILEP_BASE_MERFOLK_WATER || parts[TILEP_PART_BASE] == TILEP_BASE_MERFOLK_WATER + 1) { flag[TILEP_PART_BOOTS] = TILEP_FLAG_HIDE; flag[TILEP_PART_LEG] = TILEP_FLAG_HIDE; flag[TILEP_PART_SHADOW] = TILEP_FLAG_HIDE; } else if (parts[TILEP_PART_BASE] >= TILEP_BASE_DRACONIAN && parts[TILEP_PART_BASE] <= TILEP_BASE_DRACONIAN_WHITE + 1) { flag[TILEP_PART_HAIR] = flag[TILEP_PART_HELM] = TILEP_FLAG_HIDE; } } /* * Set default parts of each race * body + optional beard, hair, etc */ static int _draconian_colour(int race, int level) { if (level < 0) // hack:monster { switch (race) { case MONS_DRACONIAN: return (0); case MONS_BLACK_DRACONIAN: return (1); case MONS_YELLOW_DRACONIAN: return (2); case MONS_GREEN_DRACONIAN: return (4); case MONS_MOTTLED_DRACONIAN:return (5); case MONS_PALE_DRACONIAN: return (6); case MONS_PURPLE_DRACONIAN: return (7); case MONS_RED_DRACONIAN: return (8); case MONS_WHITE_DRACONIAN: return (9); } } if (level < 7) return (0); switch (race) { case SP_BLACK_DRACONIAN: return (1); case SP_YELLOW_DRACONIAN: return (2); case SP_GREY_DRACONIAN: return (3); case SP_GREEN_DRACONIAN: return (4); case SP_MOTTLED_DRACONIAN: return (5); case SP_PALE_DRACONIAN: return (6); case SP_PURPLE_DRACONIAN: return (7); case SP_RED_DRACONIAN: return (8); case SP_WHITE_DRACONIAN: return (9); } return (0); } int get_gender_from_tile(int parts[]) { int gender = ((parts[TILEP_PART_BASE] - tile_player_part_start[TILEP_PART_BASE]) % 2); if (gender == TILEP_GENDER_MALE || gender == TILEP_GENDER_FEMALE) return gender; return TILEP_GENDER_FEMALE; } int tilep_species_to_base_tile(int sp, int level) { switch (sp) { case SP_HUMAN: return TILEP_BASE_HUMAN; case SP_HIGH_ELF: case SP_SLUDGE_ELF: return TILEP_BASE_ELF; case SP_DEEP_ELF: return TILEP_BASE_DEEP_ELF; case SP_MOUNTAIN_DWARF: return TILEP_BASE_DWARF; case SP_HALFLING: return TILEP_BASE_HALFLING; case SP_HILL_ORC: return TILEP_BASE_ORC; case SP_KOBOLD: return TILEP_BASE_KOBOLD; case SP_MUMMY: return TILEP_BASE_MUMMY; case SP_NAGA: return TILEP_BASE_NAGA; case SP_OGRE: return TILEP_BASE_OGRE; case SP_TROLL: return TILEP_BASE_TROLL; case SP_BASE_DRACONIAN: case SP_RED_DRACONIAN: case SP_WHITE_DRACONIAN: case SP_GREEN_DRACONIAN: case SP_YELLOW_DRACONIAN: case SP_GREY_DRACONIAN: case SP_BLACK_DRACONIAN: case SP_PURPLE_DRACONIAN: case SP_MOTTLED_DRACONIAN: case SP_PALE_DRACONIAN: { const int colour_offset = _draconian_colour(sp, level); return (TILEP_BASE_DRACONIAN + colour_offset * 2); } case SP_CENTAUR: return TILEP_BASE_CENTAUR; case SP_DEMIGOD: return TILEP_BASE_DEMIGOD; case SP_SPRIGGAN: return TILEP_BASE_SPRIGGAN; case SP_MINOTAUR: return TILEP_BASE_MINOTAUR; case SP_DEMONSPAWN: return TILEP_BASE_DEMONSPAWN; case SP_GHOUL: return TILEP_BASE_GHOUL; case SP_KENKU: return TILEP_BASE_KENKU; case SP_MERFOLK: return TILEP_BASE_MERFOLK; case SP_VAMPIRE: return TILEP_BASE_VAMPIRE; case SP_DEEP_DWARF: return TILEP_BASE_DEEP_DWARF; default: return TILEP_BASE_HUMAN; } } void tilep_draconian_init(int sp, int level, int &base, int &head, int &wing) { const int colour_offset = _draconian_colour(sp, level); base = TILEP_BASE_DRACONIAN + colour_offset * 2; head = tile_player_part_start[TILEP_PART_DRCHEAD] + colour_offset; if (player_mutation_level(MUT_BIG_WINGS)) wing = tile_player_part_start[TILEP_PART_DRCWING] + colour_offset; } void tilep_race_default(int sp, int gender, int level, int *parts) { if (gender == -1) gender = get_gender_from_tile(parts); int result = tilep_species_to_base_tile(sp, level) + gender; int hair = 0; int beard = 0; int wing = 0; int head = 0; if (gender == TILEP_GENDER_MALE) hair = TILEP_HAIR_SHORT_BLACK; else hair = TILEP_HAIR_LONG_BLACK; switch (sp) { case SP_ELF: case SP_HIGH_ELF: case SP_SLUDGE_ELF: hair = TILEP_HAIR_ELF_YELLOW; break; case SP_DEEP_ELF: hair = TILEP_HAIR_ELF_WHITE; break; case SP_HILL_DWARF: case SP_MOUNTAIN_DWARF: if (gender == TILEP_GENDER_MALE) { hair = TILEP_HAIR_SHORT_RED; beard = TILEP_BEARD_LONG_RED; } else { hair = TILEP_HAIR_LONG_RED; beard = TILEP_BEARD_SHORT_RED; } break; case SP_HILL_ORC: hair = 0; break; case SP_KOBOLD: hair = 0; break; case SP_MUMMY: hair = 0; break; case SP_TROLL: hair = 0; break; case SP_BASE_DRACONIAN: case SP_RED_DRACONIAN: case SP_WHITE_DRACONIAN: case SP_GREEN_DRACONIAN: case SP_YELLOW_DRACONIAN: case SP_GREY_DRACONIAN: case SP_BLACK_DRACONIAN: case SP_PURPLE_DRACONIAN: case SP_MOTTLED_DRACONIAN: case SP_PALE_DRACONIAN: { tilep_draconian_init(sp, level, result, head, wing); hair = 0; break; } case SP_MINOTAUR: hair = 0; break; case SP_DEMONSPAWN: hair = 0; break; case SP_GHOUL: hair = 0; break; case SP_MERFOLK: result = you.in_water() ? TILEP_BASE_MERFOLK_WATER : TILEP_BASE_MERFOLK; break; case SP_VAMPIRE: if (gender == TILEP_GENDER_MALE) hair = TILEP_HAIR_ARAGORN; else hair = TILEP_HAIR_ARWEN; break; case SP_DEEP_DWARF: if (gender == TILEP_GENDER_MALE) { hair = TILEP_HAIR_SHORT_WHITE; beard = TILEP_BEARD_LONG_WHITE; } else { hair = TILEP_HAIR_FEM_WHITE; beard = TILEP_BEARD_SHORT_WHITE; } break; default: // nothing to do break; } parts[TILEP_PART_BASE] = result; // Don't overwrite doll parts defined elsewhere. if (parts[TILEP_PART_HAIR] == TILEP_SHOW_EQUIP) parts[TILEP_PART_HAIR] = hair; if (parts[TILEP_PART_BEARD] == TILEP_SHOW_EQUIP) parts[TILEP_PART_BEARD] = beard; if (parts[TILEP_PART_SHADOW] == TILEP_SHOW_EQUIP) parts[TILEP_PART_SHADOW] = TILEP_SHADOW_SHADOW; if (parts[TILEP_PART_DRCHEAD] == TILEP_SHOW_EQUIP) parts[TILEP_PART_DRCHEAD] = head; if (parts[TILEP_PART_DRCWING] == TILEP_SHOW_EQUIP) parts[TILEP_PART_DRCWING] = wing; } void tilep_job_default(int job, int gender, int *parts) { parts[TILEP_PART_CLOAK] = TILEP_SHOW_EQUIP; parts[TILEP_PART_BOOTS] = TILEP_SHOW_EQUIP; parts[TILEP_PART_LEG] = TILEP_SHOW_EQUIP; parts[TILEP_PART_BODY] = TILEP_SHOW_EQUIP; parts[TILEP_PART_ARM] = TILEP_SHOW_EQUIP; parts[TILEP_PART_HAND1] = TILEP_SHOW_EQUIP; parts[TILEP_PART_HAND2] = TILEP_SHOW_EQUIP; parts[TILEP_PART_HELM] = TILEP_SHOW_EQUIP; switch (job) { case JOB_FIGHTER: parts[TILEP_PART_LEG] = TILEP_LEG_METAL_SILVER; break; case JOB_CRUSADER: parts[TILEP_PART_BODY] = TILEP_BODY_SHIRT_WHITE3; parts[TILEP_PART_LEG] = TILEP_LEG_SKIRT_OFS; parts[TILEP_PART_HELM] = TILEP_HELM_HELM_OFS; parts[TILEP_PART_ARM] = TILEP_ARM_GLOVE_GRAY; parts[TILEP_PART_BOOTS] = TILEP_BOOTS_MIDDLE_GRAY; parts[TILEP_PART_CLOAK] = TILEP_CLOAK_BLUE; break; case JOB_PALADIN: parts[TILEP_PART_BODY] = TILEP_BODY_ROBE_WHITE; parts[TILEP_PART_LEG] = TILEP_LEG_PANTS_BROWN; parts[TILEP_PART_HELM] = TILEP_HELM_HELM_OFS; parts[TILEP_PART_ARM] = TILEP_ARM_GLOVE_GRAY; parts[TILEP_PART_BOOTS] = TILEP_BOOTS_MIDDLE_GRAY; parts[TILEP_PART_CLOAK] = TILEP_CLOAK_BLUE; break; case JOB_DEATH_KNIGHT: parts[TILEP_PART_BODY] = TILEP_BODY_SHIRT_BLACK3; parts[TILEP_PART_LEG] = TILEP_LEG_METAL_GRAY; parts[TILEP_PART_HELM] = TILEP_HELM_FHELM_OFS; parts[TILEP_PART_ARM] = TILEP_ARM_GLOVE_BLACK; parts[TILEP_PART_CLOAK] = TILEP_CLOAK_YELLOW; parts[TILEP_PART_HAND2] = TILEP_HAND2_BOOK_BLACK; break; case JOB_CHAOS_KNIGHT: parts[TILEP_PART_BODY] = TILEP_BODY_BELT1; parts[TILEP_PART_LEG] = TILEP_LEG_METAL_GRAY; parts[TILEP_PART_HELM] = TILEP_HELM_FHELM_PLUME; parts[TILEP_PART_BOOTS] = TILEP_BOOTS_SHORT_BROWN; break; case JOB_BERSERKER: parts[TILEP_PART_BODY] = TILEP_BODY_ANIMAL_SKIN; parts[TILEP_PART_LEG] = TILEP_LEG_BELT_REDBROWN; break; case JOB_REAVER: parts[TILEP_PART_BODY] = TILEP_BODY_ROBE_BLACK_GOLD; parts[TILEP_PART_LEG] = TILEP_LEG_PANTS_BROWN; parts[TILEP_PART_HAND2] = TILEP_HAND2_BOOK_RED_DIM; parts[TILEP_PART_BOOTS] = TILEP_BOOTS_SHORT_BROWN; break; case JOB_THIEF: parts[TILEP_PART_HELM] = TILEP_HELM_HOOD_YBROWN; parts[TILEP_PART_BODY] = TILEP_BODY_LEATHER_JACKET; parts[TILEP_PART_LEG] = TILEP_LEG_PANTS_SHORT_GRAY; parts[TILEP_PART_HAND1] = TILEP_HAND1_SWORD_THIEF; parts[TILEP_PART_ARM] = TILEP_ARM_GLOVE_WRIST_PURPLE; parts[TILEP_PART_CLOAK] = TILEP_CLOAK_LBROWN; parts[TILEP_PART_BOOTS] = TILEP_BOOTS_MIDDLE_BROWN2; break; case JOB_STALKER: parts[TILEP_PART_HELM] = TILEP_HELM_HOOD_GREEN; parts[TILEP_PART_BODY] = TILEP_BODY_LEATHER_JACKET; parts[TILEP_PART_LEG] = TILEP_LEG_PANTS_SHORT_GRAY; parts[TILEP_PART_HAND1] = TILEP_HAND1_SWORD_THIEF; parts[TILEP_PART_HAND2] = TILEP_HAND2_BOOK_GREEN_DIM; parts[TILEP_PART_ARM] = TILEP_ARM_GLOVE_WRIST_PURPLE; parts[TILEP_PART_CLOAK] = TILEP_CLOAK_GREEN; parts[TILEP_PART_BOOTS] = TILEP_BOOTS_MIDDLE_BROWN2; break; case JOB_ASSASSIN: parts[TILEP_PART_HELM] = TILEP_HELM_MASK_NINJA_BLACK; parts[TILEP_PART_BODY] = TILEP_BODY_SHIRT_BLACK3; parts[TILEP_PART_LEG] = TILEP_LEG_PANTS_BLACK; parts[TILEP_PART_HAND1] = TILEP_HAND1_SWORD_THIEF; parts[TILEP_PART_ARM] = TILEP_ARM_GLOVE_BLACK; parts[TILEP_PART_CLOAK] = TILEP_CLOAK_BLACK; parts[TILEP_PART_BOOTS] = TILEP_BOOTS_SHORT_BROWN2; break; case JOB_WIZARD: parts[TILEP_PART_BODY] = TILEP_BODY_GANDALF_G; parts[TILEP_PART_HAND1] = TILEP_HAND1_GANDALF; parts[TILEP_PART_HAND2] = TILEP_HAND2_BOOK_CYAN_DIM; parts[TILEP_PART_BOOTS] = TILEP_BOOTS_SHORT_BROWN; parts[TILEP_PART_HELM] = TILEP_HELM_GANDALF; break; case JOB_PRIEST: parts[TILEP_PART_BODY] = TILEP_BODY_ROBE_WHITE; parts[TILEP_PART_ARM] = TILEP_ARM_GLOVE_WHITE; parts[TILEP_PART_BOOTS] = TILEP_BOOTS_SHORT_BROWN; break; case JOB_HEALER: parts[TILEP_PART_BODY] = TILEP_BODY_ROBE_WHITE; parts[TILEP_PART_ARM] = TILEP_ARM_GLOVE_WHITE; parts[TILEP_PART_HAND1] = TILEP_HAND1_DAGGER; parts[TILEP_PART_BOOTS] = TILEP_BOOTS_SHORT_BROWN; parts[TILEP_PART_HELM] = TILEP_HELM_FHELM_HEALER; break; case JOB_NECROMANCER: parts[TILEP_PART_BODY] = TILEP_BODY_ROBE_BLACK; parts[TILEP_PART_HAND1] = TILEP_HAND1_STAFF_SKULL; parts[TILEP_PART_HAND2] = TILEP_HAND2_BOOK_BLACK; parts[TILEP_PART_BOOTS] = TILEP_BOOTS_SHORT_BROWN; break; case JOB_FIRE_ELEMENTALIST: parts[TILEP_PART_BODY] = TILEP_BODY_ROBE_RED; parts[TILEP_PART_HAND1] = TILEP_HAND1_GANDALF; parts[TILEP_PART_HAND2] = TILEP_HAND2_BOOK_RED_DIM; parts[TILEP_PART_BOOTS] = TILEP_BOOTS_SHORT_BROWN; break; case JOB_ICE_ELEMENTALIST: parts[TILEP_PART_BODY] = TILEP_BODY_ROBE_BLUE; parts[TILEP_PART_HAND1] = TILEP_HAND1_GANDALF; parts[TILEP_PART_HAND2] = TILEP_HAND2_BOOK_BLUE_DIM; parts[TILEP_PART_BOOTS] = TILEP_BOOTS_SHORT_BROWN; break; case JOB_AIR_ELEMENTALIST: parts[TILEP_PART_BODY] = TILEP_BODY_ROBE_CYAN; parts[TILEP_PART_HAND1] = TILEP_HAND1_GANDALF; parts[TILEP_PART_HAND2] = TILEP_HAND2_BOOK_CYAN_DIM; parts[TILEP_PART_BOOTS] = TILEP_BOOTS_SHORT_BROWN; break; case JOB_EARTH_ELEMENTALIST: parts[TILEP_PART_BODY] = TILEP_BODY_ROBE_YELLOW; parts[TILEP_PART_HAND1] = TILEP_HAND1_GANDALF; parts[TILEP_PART_HAND2] = TILEP_HAND2_BOOK_YELLOW_DIM; parts[TILEP_PART_BOOTS] = TILEP_BOOTS_SHORT_BROWN; break; case JOB_VENOM_MAGE: parts[TILEP_PART_BODY] = TILEP_BODY_ROBE_GREEN; parts[TILEP_PART_HAND1] = TILEP_HAND1_GANDALF; parts[TILEP_PART_HAND2] = TILEP_HAND2_BOOK_GREEN_DIM; parts[TILEP_PART_BOOTS] = TILEP_BOOTS_SHORT_BROWN; break; case JOB_TRANSMUTER: parts[TILEP_PART_BODY] = TILEP_BODY_ROBE_RAINBOW; parts[TILEP_PART_HAND1] = TILEP_HAND1_STAFF_RUBY; parts[TILEP_PART_HAND2] = TILEP_HAND2_BOOK_MAGENTA_DIM; parts[TILEP_PART_BOOTS] = TILEP_BOOTS_SHORT_BROWN; break; case JOB_CONJURER: parts[TILEP_PART_BODY] = TILEP_BODY_ROBE_MAGENTA; parts[TILEP_PART_HELM] = TILEP_HELM_GANDALF; parts[TILEP_PART_HAND1] = TILEP_HAND1_STAFF_MAGE2; parts[TILEP_PART_HAND2] = TILEP_HAND2_BOOK_RED_DIM; parts[TILEP_PART_BOOTS] = TILEP_BOOTS_SHORT_BROWN; break; case JOB_ENCHANTER: parts[TILEP_PART_BODY] = TILEP_BODY_ROBE_YELLOW; parts[TILEP_PART_HELM] = TILEP_HELM_GANDALF; parts[TILEP_PART_HAND1] = TILEP_HAND1_STAFF_MAGE; parts[TILEP_PART_HAND2] = TILEP_HAND2_BOOK_BLUE_DIM; parts[TILEP_PART_BOOTS] = TILEP_BOOTS_SHORT_BROWN; break; case JOB_SUMMONER: parts[TILEP_PART_BODY] = TILEP_BODY_ROBE_BROWN; parts[TILEP_PART_HELM] = TILEP_HELM_GANDALF; parts[TILEP_PART_HAND1] = TILEP_HAND1_STAFF_RING_BLUE; parts[TILEP_PART_HAND2] = TILEP_HAND2_BOOK_YELLOW_DIM; parts[TILEP_PART_BOOTS] = TILEP_BOOTS_SHORT_BROWN; break; case JOB_WARPER: parts[TILEP_PART_BODY] = TILEP_BODY_ROBE_BROWN; parts[TILEP_PART_HELM] = TILEP_HELM_GANDALF; parts[TILEP_PART_HAND1] = TILEP_HAND1_SARUMAN; parts[TILEP_PART_HAND2] = TILEP_HAND2_BOOK_WHITE; parts[TILEP_PART_BOOTS] = TILEP_BOOTS_SHORT_BROWN; parts[TILEP_PART_CLOAK] = TILEP_CLOAK_RED; break; case JOB_ARCANE_MARKSMAN: parts[TILEP_PART_BODY] = TILEP_BODY_ROBE_BROWN; parts[TILEP_PART_HELM] = TILEP_HELM_GANDALF; parts[TILEP_PART_HAND1] = TILEP_HAND1_SARUMAN; parts[TILEP_PART_HAND2] = TILEP_HAND2_BOOK_WHITE; parts[TILEP_PART_BOOTS] = TILEP_BOOTS_SHORT_BROWN; parts[TILEP_PART_CLOAK] = TILEP_CLOAK_RED; break; case JOB_HUNTER: parts[TILEP_PART_BODY] = TILEP_BODY_LEATHER_ARMOUR2; parts[TILEP_PART_LEG] = TILEP_LEG_PANTS_BROWN; parts[TILEP_PART_HAND1] = TILEP_HAND1_BOW; parts[TILEP_PART_ARM] = TILEP_ARM_GLOVE_BROWN; parts[TILEP_PART_BOOTS] = TILEP_BOOTS_MIDDLE_BROWN; break; case JOB_GLADIATOR: parts[TILEP_PART_HAND2] = TILEP_HAND2_SHIELD_ROUND2; if (gender == TILEP_GENDER_MALE) { parts[TILEP_PART_BODY] = TILEP_BODY_BELT1; parts[TILEP_PART_LEG] = TILEP_LEG_BELT_GRAY; parts[TILEP_PART_BOOTS] = TILEP_BOOTS_MIDDLE_GRAY; } else { parts[TILEP_PART_BODY] = TILEP_BODY_BIKINI_RED; parts[TILEP_PART_LEG] = TILEP_LEG_BIKINI_RED; parts[TILEP_PART_BOOTS] = TILEP_BOOTS_LONG_RED; } break; case JOB_MONK: parts[TILEP_PART_BODY] = TILEP_BODY_MONK_BLACK; break; case JOB_WANDERER: parts[TILEP_PART_BODY] = TILEP_BODY_SHIRT_HAWAII; parts[TILEP_PART_LEG] = TILEP_LEG_PANTS_SHORT_BROWN; parts[TILEP_PART_BOOTS] = TILEP_BOOTS_MIDDLE_BROWN3; break; case JOB_ARTIFICER: parts[TILEP_PART_HAND1] = TILEP_HAND1_SCEPTRE; parts[TILEP_PART_BODY] = TILEP_BODY_LEATHER_ARMOUR3; parts[TILEP_PART_LEG] = TILEP_LEG_PANTS_BLACK; break; } } /* * Parts index to string */ void tilep_part_to_str(int number, char *buf) { //special if (number == TILEP_SHOW_EQUIP) { buf[0] = buf[1] = buf[2] = '*'; } else { //normal 2 digits buf[0] = '0' + (number/100) % 10; buf[1] = '0' + (number/ 10) % 10; buf[2] = '0' + number % 10; } buf[3] ='\0'; } /* * Parts string to index */ int tilep_str_to_part(char *str) { //special if (str[0] == '*') return TILEP_SHOW_EQUIP; //normal 3 digits return atoi(str); } // This order is to preserve dolls.txt integrity over multiple versions. // Newer entries should be added to the end before the -1 terminator. const int parts_saved[TILEP_PART_MAX + 1] = { TILEP_PART_SHADOW, TILEP_PART_BASE, TILEP_PART_CLOAK, TILEP_PART_BOOTS, TILEP_PART_LEG, TILEP_PART_BODY, TILEP_PART_ARM, TILEP_PART_HAND1, TILEP_PART_HAND2, TILEP_PART_HAIR, TILEP_PART_BEARD, TILEP_PART_HELM, TILEP_PART_HALO, TILEP_PART_ENCH, TILEP_PART_DRCWING, TILEP_PART_DRCHEAD, -1 }; /* * scan input line from dolls.txt */ void tilep_scan_parts(char *fbuf, dolls_data &doll) { char ibuf[8]; int gcount = 0; int ccount = 0; for (int i = 0; parts_saved[i] != -1; ++i) { ccount = 0; int p = parts_saved[i]; while (fbuf[gcount] != ':' && fbuf[gcount] != '\n' && ccount < 4 && gcount < (i+1)*4) { ibuf[ccount++] = fbuf[gcount++]; } ibuf[ccount] = '\0'; gcount++; int idx = tilep_str_to_part(ibuf); if (idx == 0) doll.parts[p] = 0; else if (idx == TILEP_SHOW_EQUIP) doll.parts[p] = TILEP_SHOW_EQUIP; else if (idx > tile_player_part_count[p]) doll.parts[p] = tile_player_part_start[p]; else { int idx2 = tile_player_part_start[p] + idx - 1; if (idx2 < TILE_MAIN_MAX || idx2 >= TILEP_PLAYER_MAX) doll.parts[p] = TILEP_SHOW_EQUIP; else doll.parts[p] = idx2; } } } /* * format-print parts */ void tilep_print_parts(char *fbuf, const dolls_data &doll) { char *ptr = fbuf; for (unsigned i = 0; parts_saved[i] != -1; ++i) { int p = parts_saved[i]; int idx = doll.parts[p]; if (idx != 0 && idx != TILEP_SHOW_EQUIP) { idx = doll.parts[p] - tile_player_part_start[p] + 1; if (idx < 0 || idx > tile_player_part_count[p]) idx = 0; } tilep_part_to_str(idx, ptr); ptr += 3; *ptr = ':'; ptr++; } ptr--; // erase the last ':' *ptr = 0; } /* * return equip-dependent parts index */ int tilep_equ_weapon(const item_def &item) { if (item.base_type == OBJ_STAVES) { if (item_is_rod(item)) return TILEP_HAND1_ROD_BROWN + (item.special / 4) % 10; else return TILEP_HAND1_STAFF_LARGE + (item.special / 4) % 10; } if (item.base_type == OBJ_MISCELLANY) { switch (item.sub_type) { case MISC_BOTTLED_EFREET: return TILEP_HAND1_BOTTLE; case MISC_AIR_ELEMENTAL_FAN: return TILEP_HAND1_FAN; case MISC_STONE_OF_EARTH_ELEMENTALS: return TILEP_HAND1_STONE; case MISC_DISC_OF_STORMS: return TILEP_HAND1_DISC; case MISC_CRYSTAL_BALL_OF_SEEING: case MISC_CRYSTAL_BALL_OF_ENERGY: case MISC_CRYSTAL_BALL_OF_FIXATION: return TILEP_HAND1_CRYSTAL; case MISC_LAMP_OF_FIRE: return TILEP_HAND1_LANTERN; case MISC_LANTERN_OF_SHADOWS: return TILEP_HAND1_BONE_LANTERN; case MISC_HORN_OF_GERYON: return TILEP_HAND1_HORN; case MISC_BOX_OF_BEASTS: case MISC_EMPTY_EBONY_CASKET: return TILEP_HAND1_BOX; case MISC_DECK_OF_ESCAPE: case MISC_DECK_OF_DESTRUCTION: case MISC_DECK_OF_DUNGEONS: case MISC_DECK_OF_SUMMONING: case MISC_DECK_OF_WONDERS: case MISC_DECK_OF_PUNISHMENT: case MISC_DECK_OF_WAR: case MISC_DECK_OF_CHANGES: case MISC_DECK_OF_DEFENCE: return TILEP_HAND1_DECK; } } if (item.base_type != OBJ_WEAPONS) return 0; if (is_unrandom_artefact( item )) { const int tile = unrandart_to_doll_tile(find_unrandart_index(item)); if (tile != -1) return tile; } switch (item.sub_type) { // Blunt case WPN_CLUB: return TILEP_HAND1_CLUB_SLANT; case WPN_MACE: return TILEP_HAND1_MACE; case WPN_GREAT_MACE: return TILEP_HAND1_GREAT_MACE; case WPN_FLAIL: return TILEP_HAND1_FLAIL; case WPN_SPIKED_FLAIL: return TILEP_HAND1_SPIKED_FLAIL; case WPN_DIRE_FLAIL: return TILEP_HAND1_GREAT_FLAIL; case WPN_MORNINGSTAR: return TILEP_HAND1_MORNINGSTAR; case WPN_EVENINGSTAR: return TILEP_HAND1_EVENINGSTAR; case WPN_GIANT_CLUB: return TILEP_HAND1_GIANT_CLUB_PLAIN; case WPN_GIANT_SPIKED_CLUB: return TILEP_HAND1_GIANT_CLUB_SPIKE_SLANT; case WPN_ANKUS: return TILEP_HAND1_MACE; case WPN_WHIP: return TILEP_HAND1_WHIP; case WPN_DEMON_WHIP: return TILEP_HAND1_BLACK_WHIP; // Edge case WPN_KNIFE: return TILEP_HAND1_DAGGER_SLANT; case WPN_DAGGER: return TILEP_HAND1_DAGGER_SLANT; case WPN_SHORT_SWORD: return TILEP_HAND1_SHORT_SWORD_SLANT; case WPN_LONG_SWORD: return TILEP_HAND1_LONG_SWORD_SLANT; case WPN_GREAT_SWORD: return TILEP_HAND1_GREAT_SWORD_SLANT; case WPN_SCIMITAR: return TILEP_HAND1_SCIMITAR; case WPN_FALCHION: return TILEP_HAND1_FALCHION; case WPN_SABRE: return TILEP_HAND1_SABRE; case WPN_DEMON_BLADE: return TILEP_HAND1_DEMON_BLADE; case WPN_QUICK_BLADE: return TILEP_HAND1_DAGGER; case WPN_KATANA: return TILEP_HAND1_KATANA_SLANT; case WPN_DOUBLE_SWORD: return TILEP_HAND1_DOUBLE_SWORD; case WPN_TRIPLE_SWORD: return TILEP_HAND1_TRIPLE_SWORD; case WPN_HOLY_EUDEMON_BLADE: return TILEP_HAND1_BLESSED_BLADE; // new blessed weapons case WPN_BLESSED_LONG_SWORD: return TILEP_HAND1_LONG_SWORD_SLANT; case WPN_BLESSED_GREAT_SWORD: return TILEP_HAND1_GREAT_SWORD_SLANT; case WPN_BLESSED_SCIMITAR: return TILEP_HAND1_SCIMITAR; case WPN_BLESSED_FALCHION: return TILEP_HAND1_FALCHION; case WPN_BLESSED_KATANA: return TILEP_HAND1_KATANA_SLANT; case WPN_BLESSED_DOUBLE_SWORD: return TILEP_HAND1_DOUBLE_SWORD; case WPN_BLESSED_TRIPLE_SWORD: return TILEP_HAND1_TRIPLE_SWORD; // Axe case WPN_HAND_AXE: return TILEP_HAND1_HAND_AXE; case WPN_BATTLEAXE: return TILEP_HAND1_BATTLEAXE; case WPN_BROAD_AXE: return TILEP_HAND1_BROAD_AXE; case WPN_WAR_AXE: return TILEP_HAND1_WAR_AXE; case WPN_EXECUTIONERS_AXE: return TILEP_HAND1_EXECUTIONERS_AXE; case WPN_BARDICHE: return TILEP_HAND1_GLAIVE3; // Pole case WPN_SPEAR: return TILEP_HAND1_SPEAR; case WPN_HALBERD: return TILEP_HAND1_HALBERD; case WPN_GLAIVE: return TILEP_HAND1_GLAIVE; case WPN_QUARTERSTAFF: return TILEP_HAND1_QUARTERSTAFF1; case WPN_SCYTHE: return TILEP_HAND1_SCYTHE; case WPN_HAMMER: return TILEP_HAND1_HAMMER; case WPN_DEMON_TRIDENT: return TILEP_HAND1_DEMON_TRIDENT; case WPN_TRIDENT: return TILEP_HAND1_TRIDENT2; case WPN_LAJATANG: return TILEP_HAND1_DIRE_LAJATANG;; // Ranged case WPN_SLING: return TILEP_HAND1_SLING; case WPN_BOW: return TILEP_HAND1_BOW2; case WPN_CROSSBOW: return TILEP_HAND1_CROSSBOW; case WPN_BLOWGUN: return TILEP_HAND1_BLOWGUN; case WPN_LONGBOW: return TILEP_HAND1_BOW3; default: return 0; } } int tilep_equ_armour(const item_def &item) { if (item.base_type != OBJ_ARMOUR) return 0; if (is_unrandom_artefact( item )) { const int tile = unrandart_to_doll_tile(find_unrandart_index(item)); if (tile != -1) return tile; } switch (item.sub_type) { case ARM_ROBE: switch (item.colour) { // We've got a zillion robes; let's use 'em! case BLACK: return TILEP_BODY_ROBE_BLACK_RED; case BLUE: return TILEP_BODY_ROBE_BLUE; case LIGHTBLUE: return TILEP_BODY_ROBE_BLUE_WHITE; case GREEN: return TILEP_BODY_ROBE_GREEN; case LIGHTGREEN: return TILEP_BODY_ROBE_BLUE_GREEN; case CYAN: return TILEP_BODY_ROBE_WHITE_GREEN; case LIGHTCYAN: return TILEP_BODY_ROBE_CYAN; case RED: return TILEP_BODY_ROBE_RED; case LIGHTRED: return TILEP_BODY_ROBE_RED_GOLD; case MAGENTA: return TILEP_BODY_ROBE_MAGENTA; case LIGHTMAGENTA:return TILEP_BODY_ROBE_RED3; case BROWN: return TILEP_BODY_ROBE_BROWN; case YELLOW: return TILEP_BODY_ROBE_YELLOW; case LIGHTGREY: return TILEP_BODY_ROBE_GRAY2; case DARKGREY: return TILEP_BODY_GANDALF_G; case WHITE: return TILEP_BODY_ROBE_WHITE; default: return 0; } case ARM_LEATHER_ARMOUR: return TILEP_BODY_LEATHER_ARMOUR3; case ARM_RING_MAIL: return TILEP_BODY_RINGMAIL; case ARM_CHAIN_MAIL: return TILEP_BODY_CHAINMAIL; case ARM_SCALE_MAIL: return TILEP_BODY_SCALEMAIL; case ARM_SPLINT_MAIL: return TILEP_BODY_BANDED; case ARM_BANDED_MAIL: return TILEP_BODY_BANDED; case ARM_PLATE_MAIL: return TILEP_BODY_PLATE_BLACK; case ARM_CRYSTAL_PLATE_MAIL: return TILEP_BODY_CRYSTAL_PLATE; case ARM_DRAGON_HIDE: return TILEP_BODY_DRAGONSC_GREEN; case ARM_ICE_DRAGON_HIDE: return TILEP_BODY_DRAGONSC_CYAN; case ARM_STEAM_DRAGON_HIDE: return TILEP_BODY_DRAGONSC_WHITE; case ARM_MOTTLED_DRAGON_HIDE: return TILEP_BODY_DRAGONSC_MAGENTA; case ARM_STORM_DRAGON_HIDE: return TILEP_BODY_DRAGONSC_BLUE; case ARM_GOLD_DRAGON_HIDE: return TILEP_BODY_DRAGONSC_GOLD; case ARM_SWAMP_DRAGON_HIDE: return TILEP_BODY_DRAGONSC_BROWN; case ARM_DRAGON_ARMOUR: return TILEP_BODY_DRAGONARM_GREEN; case ARM_ICE_DRAGON_ARMOUR: return TILEP_BODY_DRAGONARM_CYAN; case ARM_STEAM_DRAGON_ARMOUR: return TILEP_BODY_DRAGONARM_WHITE; case ARM_MOTTLED_DRAGON_ARMOUR: return TILEP_BODY_DRAGONARM_MAGENTA; case ARM_STORM_DRAGON_ARMOUR: return TILEP_BODY_DRAGONARM_BLUE; case ARM_GOLD_DRAGON_ARMOUR: return TILEP_BODY_DRAGONARM_GOLD; case ARM_SWAMP_DRAGON_ARMOUR: return TILEP_BODY_DRAGONARM_BROWN; case ARM_ANIMAL_SKIN: return TILEP_BODY_ANIMAL_SKIN; case ARM_TROLL_HIDE: case ARM_TROLL_LEATHER_ARMOUR: return TILEP_BODY_TROLL_HIDE; default: return 0; } } int tilep_equ_shield(const item_def &item) { if (you.equip[EQ_SHIELD] == -1) return 0; if (item.base_type != OBJ_ARMOUR) return 0; if (is_unrandom_artefact( item )) { const int tile = unrandart_to_doll_tile(find_unrandart_index(item)); if (tile != -1) return tile; } switch (item.sub_type) { case ARM_SHIELD: return TILEP_HAND2_SHIELD_KNIGHT_BLUE; case ARM_BUCKLER: return TILEP_HAND2_SHIELD_ROUND_SMALL; case ARM_LARGE_SHIELD: return TILEP_HAND2_SHIELD_LONG_RED; default: return 0; } } int tilep_equ_cloak(const item_def &item) { if (you.equip[EQ_CLOAK] == -1) return 0; if (item.base_type != OBJ_ARMOUR || item.sub_type != ARM_CLOAK) return 0; if (is_unrandom_artefact( item )) { const int tile = unrandart_to_doll_tile(find_unrandart_index(item)); if (tile != -1) return tile; } switch (item.colour) { case BLACK: case BLUE: case LIGHTBLUE: return TILEP_CLOAK_BLUE; case GREEN: case LIGHTGREEN: return TILEP_CLOAK_GREEN; case CYAN: case LIGHTCYAN: return TILEP_CLOAK_CYAN; case RED: case LIGHTRED: return TILEP_CLOAK_RED; case MAGENTA: case LIGHTMAGENTA:return TILEP_CLOAK_MAGENTA; case BROWN: return TILEP_CLOAK_LBROWN; case YELLOW: return TILEP_CLOAK_YELLOW; case LIGHTGREY: return TILEP_CLOAK_GRAY; case DARKGREY: return TILEP_CLOAK_BLACK; case WHITE: return TILEP_CLOAK_WHITE; default: return 0; } } int tilep_equ_helm(const item_def &item) { if (you.equip[EQ_HELMET] == -1) return 0; if (item.base_type != OBJ_ARMOUR) return 0; if (is_unrandom_artefact(item)) { const int tile = unrandart_to_doll_tile(find_unrandart_index(item)); if (tile != -1) return tile; // Although there shouldn't be any, just in case // unhandled artefacts fall through to defaults... } int etype = _get_etype(item); int helmet_desc = get_helmet_desc(item); switch (item.sub_type) { case ARM_CAP: switch (item.colour) { case BLACK: case BLUE: case LIGHTBLUE: return TILEP_HELM_FEATHER_BLUE; case GREEN: case LIGHTGREEN: case CYAN: case LIGHTCYAN: return TILEP_HELM_FEATHER_GREEN; case RED: case LIGHTRED: case MAGENTA: case LIGHTMAGENTA: return TILEP_HELM_FEATHER_RED; case BROWN: case YELLOW: return TILEP_HELM_FEATHER_YELLOW; case LIGHTGREY: case DARKGREY: case WHITE: return TILEP_HELM_FEATHER_WHITE; } return 0; case ARM_WIZARD_HAT: switch (item.colour) { case MAGENTA: case LIGHTMAGENTA: case BLACK: return TILEP_HELM_WIZARD_BLACKRED; case BLUE: case LIGHTBLUE: return TILEP_HELM_WIZARD_BLUE; case GREEN: case LIGHTGREEN: return TILEP_HELM_WIZARD_DARKGREEN; case CYAN: return TILEP_HELM_WIZARD_PURPLE; case LIGHTCYAN: return TILEP_HELM_WIZARD_BLUEGREEN; case RED: case LIGHTRED: return TILEP_HELM_WIZARD_RED; case BROWN: return TILEP_HELM_WIZARD_BROWN; case YELLOW: return TILEP_HELM_WIZARD_BLACKGOLD; case LIGHTGREY: case DARKGREY: case WHITE: return TILEP_HELM_WIZARD_WHITE; } return 0; case ARM_HELMET: switch (helmet_desc) { case THELM_DESC_PLAIN: switch (etype) { default: return TILEP_HELM_CHAIN; case 1: return TILEP_HELM_HELM_GIMLI; case 2: return TILEP_HELM_HELM_OFS; // urgh case 3: return TILEP_HELM_FHELM_GRAY2; case 4: return TILEP_HELM_FHELM_BLACK; } case THELM_DESC_WINGED: return TILEP_HELM_YELLOW_WING; case THELM_DESC_HORNED: switch (etype) { default: return TILEP_HELM_FHELM_HORN2; case 1: return TILEP_HELM_BLUE_HORN_GOLD; case 2: return TILEP_HELM_FHELM_HORN_GRAY; case 3: return TILEP_HELM_FHELM_HORN_YELLOW; case 4: return TILEP_HELM_FHELM_OFS; // urgh } case THELM_DESC_CRESTED: return TILEP_HELM_FHELM_ISILDUR; case THELM_DESC_PLUMED: return TILEP_HELM_FHELM_PLUME; case THELM_DESC_SPIKED: return TILEP_HELM_FHELM_EVIL; case THELM_DESC_VISORED: return TILEP_HELM_FHELM_GRAY3; case THELM_DESC_GOLDEN: return TILEP_HELM_FULL_GOLD; } } return 0; } int tilep_equ_gloves(const item_def &item) { if (you.equip[EQ_GLOVES] == -1) return 0; if (item.base_type != OBJ_ARMOUR || item.sub_type != ARM_GLOVES) return 0; if (is_unrandom_artefact(item)) { const int tile = unrandart_to_doll_tile(find_unrandart_index(item)); if (tile != -1) return tile; } switch (_get_etype(item)) { default: case 0: switch (item.colour) { case LIGHTBLUE: return TILEP_ARM_GLOVE_BLUE; default: case BROWN: return TILEP_ARM_GLOVE_BROWN; } case 1: case 2: case 3: case 4: switch (item.colour) { case LIGHTBLUE: default: return TILEP_ARM_GLOVE_CHUNLI; case BROWN: return TILEP_ARM_GLOVE_GRAYFIST; } } return 0; } int tilep_equ_boots(const item_def &item) { if (you.equip[EQ_BOOTS] == -1) return 0; if (item.base_type != OBJ_ARMOUR) return 0; int etype = _get_etype(item); if (item.sub_type == ARM_NAGA_BARDING) return TILEP_BOOTS_NAGA_BARDING + std::min(etype, 3); if (item.sub_type == ARM_CENTAUR_BARDING) return TILEP_BOOTS_CENTAUR_BARDING + std::min(etype, 3); if (item.sub_type != ARM_BOOTS) return 0; if (is_unrandom_artefact(item)) { const int tile = unrandart_to_doll_tile(find_unrandart_index(item)); if (tile != -1) return tile; } switch (etype) { default: case 0: return TILEP_BOOTS_MIDDLE_BROWN3; case 1: case 2: switch (item.colour) { case BROWN: default: return TILEP_BOOTS_MESH_RED; case BLUE: return TILEP_BOOTS_MESH_BLUE; } case 3: case 4: switch (item.colour) { case BROWN: return TILEP_BOOTS_LONG_RED; default: case BLUE: return TILEP_BOOTS_BLUE_GOLD; } } return 0; } #ifdef TILEP_DEBUG /* * Debugging routines */ const char *get_ctg_name(int part) { return tilep_parts_name[part]; } int get_ctg_idx(char *name) { int i; for (i = 0; i < TILEP_PART_MAX; i++) if (strcmp(name, tilep_parts_name[i]) == 0) return i; return 0; } const char *get_parts_name(int part, int idx) { static char tmp[10]; const char *ptr = tilep_comment[ tilep_comment_ofs[part] -1 + idx ]; if (idx == 0) return ""; if (ptr[0] == 0) { sprintf(tmp,"%02d",idx); return tmp; } return ptr; } int get_parts_idx(int part, char *name) { int res = atoi(name); int i; for (i = 0; i < tilep_parts_total[part]; i++) if (strcmp(name, tilep_comment[ tilep_comment_ofs[part]+i]) == 0) return i+1; return res; } #endif /* TILEP_DEBUG */ /* * Tile data preparation */ // for clarity enum SpecialIdx { SPECIAL_N = 0, SPECIAL_NE = 1, SPECIAL_E = 2, SPECIAL_SE = 3, SPECIAL_S = 4, SPECIAL_SW = 5, SPECIAL_W = 6, SPECIAL_NW = 7, SPECIAL_FULL = 8 }; int jitter(SpecialIdx i) { return (i + random_range(-1, 1) + 8) % 8; } void tile_clear_flavour() { for (rectangle_iterator ri(1); ri; ++ri) { env.tile_flv(*ri).floor = 0; env.tile_flv(*ri).wall = 0; env.tile_flv(*ri).special = 0; env.tile_flv(*ri).feat = 0; } } // For floors and walls that have not already been set to a particular tile, // set them to a random instance of the default floor and wall tileset. void tile_init_flavour() { for (rectangle_iterator ri(0); ri; ++ri) tile_init_flavour(*ri); } void tile_init_flavour(const coord_def &gc) { if (!map_bounds(gc)) return; if (!env.tile_flv(gc).floor) { int floor_base = env.tile_default.floor; int colour = env.grid_colours(gc); if (colour) floor_base = tile_dngn_coloured(floor_base, colour); env.tile_flv(gc).floor = _pick_random_dngn_tile(floor_base); } if (!env.tile_flv(gc).wall) { int wall_base = env.tile_default.wall; int colour = env.grid_colours(gc); if (colour) wall_base = tile_dngn_coloured(wall_base, colour); env.tile_flv(gc).wall = _pick_random_dngn_tile(wall_base); } if (feat_is_door(grd(gc))) { // Check for horizontal gates. const coord_def left(gc.x - 1, gc.y); const coord_def right(gc.x + 1, gc.y); bool door_left = (grd(left) == grd(gc)); bool door_right = (grd(right) == grd(gc)); if (door_left || door_right) { int target; if (door_left && door_right) target = TILE_DNGN_GATE_CLOSED_MIDDLE; else if (door_left) target = TILE_DNGN_GATE_CLOSED_RIGHT; else target = TILE_DNGN_GATE_CLOSED_LEFT; // NOTE: This requires that closed gates and open gates // are positioned in the tile set relative to their // door counterpart. env.tile_flv(gc).special = target - TILE_DNGN_CLOSED_DOOR; } else env.tile_flv(gc).special = 0; } else if (feat_is_secret_door(grd(gc))) env.tile_flv(gc).special = 0; else if (!env.tile_flv(gc).special) env.tile_flv(gc).special = random2(256); } static bool _adjacent_target(dungeon_feature_type target, int x, int y) { for (int i = -1; i <= 1; i++) for (int j = -1; j <= 1; j++) { if (!map_bounds(x+i, y+j)) continue; if (grd[x+i][y+j] == target) return (true); } return (false); } void tile_floor_halo(dungeon_feature_type target, int tile) { for (int x = 0; x < GXM; x++) { for (int y = 0; y < GYM; y++) { if (grd[x][y] < DNGN_FLOOR_MIN) continue; if (!_adjacent_target(target, x, y)) continue; bool l_flr = (x > 0) ? grd[x-1][y] >= DNGN_FLOOR_MIN : false; bool r_flr = (x < GXM - 1) ? grd[x+1][y] >= DNGN_FLOOR_MIN : false; bool u_flr = (y > 0) ? grd[x][y-1] >= DNGN_FLOOR_MIN : false; bool d_flr = (y < GYM - 1) ? grd[x][y+1] >= DNGN_FLOOR_MIN : false; bool l_target = _adjacent_target(target, x-1, y); bool r_target = _adjacent_target(target, x+1, y); bool u_target = _adjacent_target(target, x, y-1); bool d_target = _adjacent_target(target, x, y+1); // The special tiles contains part floor and part special, so // if there are adjacent floor or special tiles, we should // do our best to "connect" them appropriately. If there are // are other tiles there (walls, doors, whatever...) then it // doesn't matter. bool l_nrm = (l_flr && !l_target); bool r_nrm = (r_flr && !r_target); bool u_nrm = (u_flr && !u_target); bool d_nrm = (d_flr && !d_target); bool l_spc = (l_flr && l_target); bool r_spc = (r_flr && r_target); bool u_spc = (u_flr && u_target); bool d_spc = (d_flr && d_target); if (l_nrm && r_nrm || u_nrm && d_nrm) { // Not much to do here... env.tile_flv[x][y].floor = tile + SPECIAL_FULL; } else if (l_nrm) { if (u_nrm) env.tile_flv[x][y].floor = tile + SPECIAL_NW; else if (d_nrm) env.tile_flv[x][y].floor = tile + SPECIAL_SW; else if (u_spc && d_spc) env.tile_flv[x][y].floor = tile + SPECIAL_W; else if (u_spc && r_spc) env.tile_flv[x][y].floor = tile + SPECIAL_SW; else if (d_spc && r_spc) env.tile_flv[x][y].floor = tile + SPECIAL_NW; else if (u_spc) { env.tile_flv[x][y].floor = tile + (coinflip() ? SPECIAL_W : SPECIAL_SW); } else if (d_spc) { env.tile_flv[x][y].floor = tile + (coinflip() ? SPECIAL_W : SPECIAL_NW); } else env.tile_flv[x][y].floor = tile + jitter(SPECIAL_W); } else if (r_nrm) { if (u_nrm) env.tile_flv[x][y].floor = tile + SPECIAL_NE; else if (d_nrm) env.tile_flv[x][y].floor = tile + SPECIAL_SE; else if (u_spc && d_spc) env.tile_flv[x][y].floor = tile + SPECIAL_E; else if (u_spc && l_spc) env.tile_flv[x][y].floor = tile + SPECIAL_SE; else if (d_spc && l_spc) env.tile_flv[x][y].floor = tile + SPECIAL_NE; else if (u_spc) env.tile_flv[x][y].floor = tile + (coinflip() ? SPECIAL_E : SPECIAL_SE); else if (d_spc) env.tile_flv[x][y].floor = tile + (coinflip() ? SPECIAL_E : SPECIAL_NE); else env.tile_flv[x][y].floor = tile + jitter(SPECIAL_E); } else if (u_nrm) { if (r_spc && l_spc) env.tile_flv[x][y].floor = tile + SPECIAL_N; else if (r_spc && d_spc) env.tile_flv[x][y].floor = tile + SPECIAL_NW; else if (l_spc && d_spc) env.tile_flv[x][y].floor = tile + SPECIAL_NE; else if (r_spc) { env.tile_flv[x][y].floor = tile + (coinflip() ? SPECIAL_N : SPECIAL_NW); } else if (l_spc) { env.tile_flv[x][y].floor = tile + (coinflip() ? SPECIAL_N : SPECIAL_NE); } else env.tile_flv[x][y].floor = tile + jitter(SPECIAL_N); } else if (d_nrm) { if (r_spc && l_spc) env.tile_flv[x][y].floor = tile + SPECIAL_S; else if (r_spc && u_spc) env.tile_flv[x][y].floor = tile + SPECIAL_SW; else if (l_spc && u_spc) env.tile_flv[x][y].floor = tile + SPECIAL_SE; else if (r_spc) { env.tile_flv[x][y].floor = tile + (coinflip() ? SPECIAL_S : SPECIAL_SW); } else if (l_spc) { env.tile_flv[x][y].floor = tile + (coinflip() ? SPECIAL_S : SPECIAL_SE); } else env.tile_flv[x][y].floor = tile + jitter(SPECIAL_S); } else if (u_spc && d_spc) { // We know this value is already initialised and // is necessarily in bounds. int t = env.tile_flv[x][y-1].floor - tile; if (t == SPECIAL_NE || t == SPECIAL_E) env.tile_flv[x][y].floor = tile + SPECIAL_E; else if (t == SPECIAL_NW || t == SPECIAL_W) env.tile_flv[x][y].floor = tile + SPECIAL_W; else env.tile_flv[x][y].floor = tile + SPECIAL_FULL; } else if (r_spc && l_spc) { // We know this value is already initialised and // is necessarily in bounds. int t = env.tile_flv[x-1][y].floor - tile; if (t == SPECIAL_NW || t == SPECIAL_N) env.tile_flv[x][y].floor = tile + SPECIAL_N; else if (t == SPECIAL_SW || t == SPECIAL_S) env.tile_flv[x][y].floor = tile + SPECIAL_S; else env.tile_flv[x][y].floor = tile + SPECIAL_FULL; } else if (u_spc && l_spc) { env.tile_flv[x][y].floor = tile + SPECIAL_SE; } else if (u_spc && r_spc) { env.tile_flv[x][y].floor = tile + SPECIAL_SW; } else if (d_spc && l_spc) { env.tile_flv[x][y].floor = tile + SPECIAL_NE; } else if (d_spc && r_spc) { env.tile_flv[x][y].floor = tile + SPECIAL_NW; } else { env.tile_flv[x][y].floor = tile + SPECIAL_FULL; } } } // Second pass for clean up. The only bad part about the above // algorithm is that it could turn a block of floor like this: // // N4NN // 3125 // NN6N // // (KEY: N = normal floor, # = special floor) // // Into these flavours: // 1 - SPECIAL_S // 2 - SPECIAL_N // 3-6, not important // // Generally the tiles don't fit with a north to the right or left // of a south tile. What we really want to do is to separate the // two regions, by making 1 a SPECIAL_SE and 2 a SPECIAL_NW tile. for (int y = 0; y < GYM - 1; ++y) for (int x = 0; x < GXM - 1; ++x) { int this_spc = env.tile_flv[x][y].floor - tile; if (this_spc < 0 || this_spc > 8) continue; if (this_spc != SPECIAL_N && this_spc != SPECIAL_S && this_spc != SPECIAL_E && this_spc != SPECIAL_W) { continue; } int right_spc = x < GXM - 1 ? env.tile_flv[x+1][y].floor - tile : SPECIAL_FULL; int down_spc = y < GYM - 1 ? env.tile_flv[x][y+1].floor - tile : SPECIAL_FULL; if (this_spc == SPECIAL_N && right_spc == SPECIAL_S) { env.tile_flv[x][y].floor = tile + SPECIAL_NE; env.tile_flv[x+1][y].floor = tile + SPECIAL_SW; } else if (this_spc == SPECIAL_S && right_spc == SPECIAL_N) { env.tile_flv[x][y].floor = tile + SPECIAL_SE; env.tile_flv[x+1][y].floor = tile + SPECIAL_NW; } else if (this_spc == SPECIAL_E && down_spc == SPECIAL_W) { env.tile_flv[x][y].floor = tile + SPECIAL_SE; env.tile_flv[x][y+1].floor = tile + SPECIAL_NW; } else if (this_spc == SPECIAL_W && down_spc == SPECIAL_E) { env.tile_flv[x][y].floor = tile + SPECIAL_NE; env.tile_flv[x][y+1].floor = tile + SPECIAL_SW; } } } // Called from item() in view.cc void tile_place_item(int x, int y, int idx) { ASSERT(idx != NON_ITEM); int t = tileidx_item(mitm[idx]); if (mitm[idx].link != NON_ITEM) t |= TILE_FLAG_S_UNDER; env.tile_fg[x][y] = t; if (item_needs_autopickup(mitm[idx])) env.tile_bg[x][y] |= TILE_FLAG_CURSOR3; } // Called from item() in view.cc void tile_place_item_marker(int x, int y, int idx) { ASSERT(idx != NON_ITEM); env.tile_fg[x][y] |= TILE_FLAG_S_UNDER; if (item_needs_autopickup(mitm[idx])) env.tile_bg[x][y] |= TILE_FLAG_CURSOR3; } // Called from monster_grid() in view.cc void tile_place_monster(int gx, int gy, int idx, bool foreground, bool detected) { if (idx == NON_MONSTER) return; const coord_def gc(gx, gy); const coord_def ep = view2show(grid2view(gc)); int t = _tileidx_monster(idx, detected); int t0 = t & TILE_FLAG_MASK; int flag = t & (~TILE_FLAG_MASK); if (mons_is_mimic(menv[idx].type)) { const monsters *mon = &menv[idx]; if (!mons_is_known_mimic(mon)) { // If necessary add item brand. if (you.visible_igrd(gc) != NON_ITEM) { if (foreground) t |= TILE_FLAG_S_UNDER; else t0 |= TILE_FLAG_S_UNDER; } if (item_needs_autopickup(get_mimic_item(mon))) { if (foreground) env.tile_bg[ep.x][ep.y] |= TILE_FLAG_CURSOR3; else env.tile_bk_bg(gc) |= TILE_FLAG_CURSOR3; } } } else if (menv[idx].holiness() == MH_PLANT) { // If necessary add item brand. if (you.visible_igrd(gc) != NON_ITEM) { if (foreground) t |= TILE_FLAG_S_UNDER; else t0 |= TILE_FLAG_S_UNDER; } } else { unsigned int mcache_idx = mcache.register_monster(&menv[idx]); t = flag | (mcache_idx ? mcache_idx : t0); } if (foreground) { env.tile_fg[ep.x][ep.y] = t; const monsters *mon = &menv[idx]; if (!mon->visible_to(&you) || mons_is_lurking(mon) || mons_is_unknown_mimic(mon) || mons_class_flag(mon->type, M_NO_EXP_GAIN)) { return; } const tag_pref pref = Options.tile_tag_pref; if (pref == TAGPREF_NONE) return; else if (pref == TAGPREF_TUTORIAL) { const long kills = you.kills->num_kills(mon); const int limit = 0; if (!mon->is_named() && kills > limit) return; } else if (!mon->is_named()) return; if (pref != TAGPREF_NAMED && mon->friendly()) return; // HACK. Names cover up pan demons in a weird way. if (mon->type == MONS_PANDEMONIUM_DEMON) return; tiles.add_text_tag(TAG_NAMED_MONSTER, mon); } else { // Retain the magic mapped terrain, but don't give away the real // features. if (is_terrain_mapped(gc)) { unsigned int fg; unsigned int bg; tileidx_unseen(fg, bg, get_feat_symbol(grd(gc)), gc); env.tile_bk_bg(gc) = bg; // env.tile_bk_bg(gc) = fg; } env.tile_bk_fg(gc) = t0; } } void tile_place_cloud(int x, int y, cloud_struct cl) { env.tile_fg[x][y] = _tileidx_cloud(cl); } unsigned int num_tile_rays = 0; struct tile_ray { coord_def ep; bool in_range; }; FixedVector tile_ray_vec; void tile_place_ray(const coord_def& gc, bool in_range) { // Record rays for later. The curses version just applies // rays directly to the screen. The tiles version doesn't have // (nor want) such direct access. So, it batches up all of the // rays and applies them in viewwindow(...). if (num_tile_rays < tile_ray_vec.size() - 1) { tile_ray_vec[num_tile_rays].in_range = in_range; tile_ray_vec[num_tile_rays++].ep = view2show(grid2view(gc)); } } void tile_draw_rays(bool reset_count) { for (unsigned int i = 0; i < num_tile_rays; i++) { int flag = tile_ray_vec[i].in_range ? TILE_FLAG_RAY : TILE_FLAG_RAY_OOR; env.tile_bg[tile_ray_vec[i].ep.x][tile_ray_vec[i].ep.y] |= flag; } if (reset_count) num_tile_rays = 0; } void tile_finish_dngn(unsigned int *tileb, int cx, int cy) { int x, y; int count = 0; for (y = 0; y < crawl_view.viewsz.y; y++) for (x = 0; x < crawl_view.viewsz.x; x++) { const coord_def ep = coord_def(x, y) + crawl_view.viewp + coord_def(cx, cy) - crawl_view.vgrdc; const coord_def gc = view2grid(ep); unsigned int wall_flv = 0; unsigned int floor_flv = 0; unsigned int special_flv = 0; const bool in_bounds = (map_bounds(gc)); if (in_bounds) { wall_flv = env.tile_flv(gc).wall; floor_flv = env.tile_flv(gc).floor; special_flv = env.tile_flv(gc).special; } _finalise_tile(&tileb[count+1], wall_flv, floor_flv, special_flv, gc); if (is_excluded(gc)) { if (is_exclude_root(gc)) tileb[count+1] |= TILE_FLAG_EXCL_CTR; else tileb[count+1] |= TILE_FLAG_TRAV_EXCL; } if (in_bounds) { bool print_blood = true; if (you.halo_contains(gc)) { monsters *mon = monster_at(gc); if (you.see_cell(gc) && mon) { if (!mons_class_flag(mon->type, M_NO_EXP_GAIN) && (!mons_is_mimic(mon->type) || testbits(mon->flags, MF_KNOWN_MIMIC))) { tileb[count+1] |= TILE_FLAG_HALO; print_blood = false; } } } if (print_blood && is_bloodcovered(gc)) tileb[count+1] |= TILE_FLAG_BLOOD; if (is_sanctuary(gc)) tileb[count+1] |= TILE_FLAG_SANCTUARY; } count += 2; } } static FixedVector tag_prefs("none", "tutorial", "named", "enemy"); tag_pref string2tag_pref(const char *opt) { for (int i = 0; i < TAGPREF_MAX; i++) { if (!stricmp(opt, tag_prefs[i])) return ((tag_pref)i); } return TAGPREF_ENEMY; } const char *tag_pref2string(tag_pref pref) { return tag_prefs[pref]; } #endif