diff --git a/raws/mobs.json b/raws/mobs.json index 43e3266..16768c5 100644 --- a/raws/mobs.json +++ b/raws/mobs.json @@ -2,7 +2,7 @@ { "id": "npc_barkeep", "name": "barkeep", - "renderable": { "glyph": "@", "sprite": "@", "fg": "#EE82EE", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "@", "sprite": { "id": "@" }, "fg": "#EE82EE", "bg": "#000000", "order": 1 }, "flags": ["NEUTRAL", "IS_HUMAN"], "vision_range": 4, "quips": ["Drink?", "Something to eat?", "Don't go out on an empty stomach."] @@ -10,7 +10,7 @@ { "id": "npc_townsperson", "name": "townsperson", - "renderable": { "glyph": "@", "sprite": "@", "fg": "#9fa86c", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "@", "sprite": { "id": "@" }, "fg": "#9fa86c", "bg": "#000000", "order": 1 }, "flags": ["NEUTRAL", "RANDOM_PATH", "IS_HUMAN"], "vision_range": 4, "quips": ["Hello!", "Good morning.", ""] @@ -18,7 +18,7 @@ { "id": "npc_drunk", "name": "drunk", - "renderable": { "glyph": "@", "sprite": "@", "fg": "#a0a83c", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "@", "sprite": { "id": "@" }, "fg": "#a0a83c", "bg": "#000000", "order": 1 }, "flags": ["NEUTRAL", "IS_HUMAN"], "vision_range": 4, "quips": ["Hic!", "H-Hic'.", "Get me 'nother, would you?"] @@ -26,7 +26,7 @@ { "id": "npc_fisher", "name": "fisher", - "renderable": { "glyph": "@", "sprite": "@", "fg": "#3ca3a8", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "@", "sprite": { "id": "@" }, "fg": "#3ca3a8", "bg": "#000000", "order": 1 }, "flags": ["NEUTRAL", "IS_HUMAN"], "vision_range": 4, "quips": ["Hey."] @@ -34,7 +34,7 @@ { "id": "npc_dockworker", "name": "dock worker", - "renderable": { "glyph": "@", "sprite": "@", "fg": "#68d8de", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "@", "sprite": { "id": "@" }, "fg": "#68d8de", "bg": "#000000", "order": 1 }, "flags": ["NEUTRAL", "IS_HUMAN"], "vision_range": 4, "quips": ["No boat for a few days.", "Not much for us to do."] @@ -42,7 +42,7 @@ { "id": "npc_priest", "name": "priest", - "renderable": { "glyph": "@", "sprite": "@", "fg": "#FFFFFF", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "@", "sprite": { "id": "@" }, "fg": "#FFFFFF", "bg": "#000000", "order": 1 }, "flags": ["NEUTRAL", "IS_HUMAN"], "vision_range": 4, "quips": ["Light's givings.", "", "Bless you."] @@ -50,7 +50,7 @@ { "id": "npc_miner", "name": "miner", - "renderable": { "glyph": "@", "sprite": "@", "fg": "#946123", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "@", "sprite": { "id": "@" }, "fg": "#946123", "bg": "#000000", "order": 1 }, "flags": ["NEUTRAL", "IS_HUMAN"], "vision_range": 4, "attacks": [{ "name": "hits", "hit_bonus": 0, "damage": "1d8" }], @@ -59,7 +59,7 @@ { "id": "npc_guard", "name": "smalltown guard", - "renderable": { "glyph": "@", "sprite": "@", "fg": "#034efc", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "@", "sprite": { "id": "@" }, "fg": "#034efc", "bg": "#000000", "order": 1 }, "flags": ["NEUTRAL", "RANDOM_PATH", "IS_HUMAN"], "level": 2, "attacks": [{ "name": "hits", "hit_bonus": 0, "damage": "1d8" }], @@ -69,7 +69,7 @@ { "id": "rat", "name": "rat", - "renderable": { "glyph": "r", "sprite": "r", "fg": "#aa6000", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "r", "sprite": { "id": "r" }, "fg": "#aa6000", "bg": "#000000", "order": 1 }, "flags": [], "bac": 6, "attacks": [{ "name": "bites", "hit_bonus": 0, "damage": "1d2" }], @@ -78,7 +78,7 @@ { "id": "chicken", "name": "chicken", - "renderable": { "glyph": "c", "sprite": "c", "fg": "#BB6000", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "c", "sprite": { "id": "c" }, "fg": "#BB6000", "bg": "#000000", "order": 1 }, "flags": ["HERBIVORE"], "bac": 8, "attacks": [{ "name": "bites", "hit_bonus": 0, "damage": "1d3" }] @@ -86,7 +86,7 @@ { "id": "deer_little", "name": "fawn", - "renderable": { "glyph": "q", "sprite": "q", "fg": "#a57037", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "q", "sprite": { "id": "q" }, "fg": "#a57037", "bg": "#000000", "order": 1 }, "flags": ["HERBIVORE"], "bac": 8, "attacks": [{ "name": "kicks", "hit_bonus": 0, "damage": "1d2" }] @@ -94,7 +94,7 @@ { "id": "sheep_little", "name": "lamb", - "renderable": { "glyph": "q", "sprite": "q", "fg": "#e7e7e7", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "q", "sprite": { "id": "q" }, "fg": "#e7e7e7", "bg": "#000000", "order": 1 }, "flags": ["HERBIVORE", "SMALL_GROUP"], "bac": 10, "attacks": [{ "name": "kicks", "hit_bonus": 0, "damage": "1d2" }] @@ -102,7 +102,7 @@ { "id": "chicken_little", "name": "chick", - "renderable": { "glyph": "c", "sprite": "c", "fg": "#fae478", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "c", "sprite": { "id": "c" }, "fg": "#fae478", "bg": "#000000", "order": 1 }, "flags": ["HERBIVORE"], "bac": 10, "attacks": [{ "name": "bites", "hit_bonus": 0, "damage": "1d2" }] @@ -110,7 +110,7 @@ { "id": "horse_little", "name": "pony", - "renderable": { "glyph": "u", "sprite": "u", "fg": "#b36c29", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "u", "sprite": { "id": "u" }, "fg": "#b36c29", "bg": "#000000", "order": 1 }, "flags": ["HERBIVORE", "MULTIATTACK"], "level": 3, "bac": 6, @@ -124,7 +124,7 @@ { "id": "horse", "name": "horse", - "renderable": { "glyph": "u", "sprite": "u", "fg": "#744d29", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "u", "sprite": { "id": "u" }, "fg": "#744d29", "bg": "#000000", "order": 1 }, "flags": ["MULTIATTACK"], "level": 5, "bac": 5, @@ -137,7 +137,7 @@ { "id": "horse_large", "name": "warhorse", - "renderable": { "glyph": "u", "sprite": "u", "fg": "#8a3520", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "u", "sprite": { "id": "u" }, "fg": "#8a3520", "bg": "#000000", "order": 1 }, "flags": ["MULTIATTACK"], "level": 7, "bac": 4, @@ -150,7 +150,7 @@ { "id": "rat_giant", "name": "giant rat", - "renderable": { "glyph": "r", "sprite": "r", "fg": "#bb8000", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "r", "sprite": { "id": "r" }, "fg": "#bb8000", "bg": "#000000", "order": 1 }, "flags": ["SMALL_GROUP"], "level": 1, "bac": 7, @@ -160,7 +160,7 @@ { "id": "dog_little", "name": "little dog", - "renderable": { "glyph": "d", "sprite": "d", "fg": "#FFFFFF", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "d", "sprite": { "id": "d" }, "fg": "#FFFFFF", "bg": "#000000", "order": 1 }, "flags": ["NEUTRAL"], "level": 2, "bac": 6, @@ -171,7 +171,7 @@ { "id": "dog", "name": "dog", - "renderable": { "glyph": "d", "sprite": "d", "fg": "#EEEEEE", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "d", "sprite": { "id": "d" }, "fg": "#EEEEEE", "bg": "#000000", "order": 1 }, "flags": [], "level": 4, "bac": 5, @@ -181,7 +181,7 @@ { "id": "dog_large", "name": "large dog", - "renderable": { "glyph": "d", "sprite": "d", "fg": "#DDDDDD", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "d", "sprite": { "id": "d" }, "fg": "#DDDDDD", "bg": "#000000", "order": 1 }, "flags": [], "level": 6, "bac": 4, @@ -191,7 +191,7 @@ { "id": "gnome", "name": "gnome", - "renderable": { "glyph": "G", "sprite": "g2", "fg": "#AA5500", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "G", "sprite": { "id": "g2" }, "fg": "#AA5500", "bg": "#000000", "order": 1 }, "flags": ["SMALL_GROUP", "IS_GNOME"], "level": 1, "speed": 6, @@ -201,7 +201,7 @@ { "id": "zombie_gnome", "name": "gnome zombie", - "renderable": { "glyph": "z", "sprite": "z", "fg": "#AA5500", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "z", "sprite": { "id": "z" }, "fg": "#AA5500", "bg": "#000000", "order": 1 }, "flags": ["MINDLESS"], "level": 1, "speed": 6, @@ -212,7 +212,7 @@ { "id": "goblin", "name": "goblin", - "renderable": { "glyph": "g", "sprite": "g", "fg": "#00FF00", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "g", "sprite": { "id": "g" }, "fg": "#00FF00", "bg": "#000000", "order": 1 }, "flags": [], "level": 1, "speed": 9, @@ -221,7 +221,7 @@ { "id": "kobold", "name": "kobold", - "renderable": { "glyph": "k", "sprite": "k", "fg": "#AA5500", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "k", "sprite": { "id": "k" }, "fg": "#AA5500", "bg": "#000000", "order": 1 }, "flags": [], "level": 1, "speed": 6, @@ -231,7 +231,7 @@ { "id": "zombie_kobold", "name": "kobold zombie", - "renderable": { "glyph": "z", "sprite": "z", "fg": "#AA5500", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "z", "sprite": { "id": "z" }, "fg": "#AA5500", "bg": "#000000", "order": 1 }, "flags": ["MINDLESS"], "level": 1, "speed": 6, @@ -242,7 +242,7 @@ { "id": "kobold_large", "name": "large kobold", - "renderable": { "glyph": "k", "sprite": "k", "fg": "#70461b", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "k", "sprite": { "id": "k" }, "fg": "#70461b", "bg": "#000000", "order": 1 }, "flags": [], "level": 1, "speed": 6, @@ -253,7 +253,7 @@ { "id": "zombie_orc", "name": "orc zombie", - "renderable": { "glyph": "z", "sprite": "z", "fg": "#dbd830", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "z", "sprite": { "id": "z" }, "fg": "#dbd830", "bg": "#000000", "order": 1 }, "flags": ["MINDLESS"], "level": 2, "bac": 9, @@ -265,7 +265,7 @@ { "id": "dwarf", "name": "dwarf", - "renderable": { "glyph": "h", "sprite": "h", "fg": "#d61b1b", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "h", "sprite": { "id": "h" }, "fg": "#d61b1b", "bg": "#000000", "order": 1 }, "flags": ["IS_DWARF"], "level": 2, "bac": 10, @@ -277,7 +277,7 @@ { "id": "zombie_dwarf", "name": "dwarf zombie", - "renderable": { "glyph": "z", "sprite": "z", "fg": "#d61b1b", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "z", "sprite": { "id": "z" }, "fg": "#d61b1b", "bg": "#000000", "order": 1 }, "flags": ["MINDLESS"], "level": 2, "bac": 9, @@ -289,7 +289,7 @@ { "id": "kobold_captain", "name": "kobold captain", - "renderable": { "glyph": "k", "sprite": "k", "fg": "#9331ac", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "k", "sprite": { "id": "k" }, "fg": "#9331ac", "bg": "#000000", "order": 1 }, "flags": [], "level": 2, "speed": 6, @@ -300,7 +300,7 @@ { "id": "spider_cave", "name": "cave spider", - "renderable": { "glyph": "s", "sprite": "s", "fg": "#6b6b6b", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "s", "sprite": { "id": "s" }, "fg": "#6b6b6b", "bg": "#000000", "order": 1 }, "flags": ["SMALL_GROUP"], "level": 1, "bac": 3, @@ -311,7 +311,7 @@ { "id": "ant_worker", "name": "worker ant", - "renderable": { "glyph": "a", "sprite": "a", "fg": "#ca7631", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "a", "sprite": { "id": "a" }, "fg": "#ca7631", "bg": "#000000", "order": 1 }, "flags": ["SMALL_GROUP"], "level": 2, "bac": 3, @@ -322,7 +322,7 @@ { "id": "ant_soldier", "name": "soldier ant", - "renderable": { "glyph": "a", "sprite": "a", "fg": "#ca3f26", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "a", "sprite": { "id": "a" }, "fg": "#ca3f26", "bg": "#000000", "order": 1 }, "flags": ["SMALL_GROUP", "POISON_RES"], "level": 3, "bac": 3, @@ -336,7 +336,7 @@ { "id": "caterpillar_cave", "name": "caterpillar", - "renderable": { "glyph": "a", "sprite": "a", "fg": "#6b6b6b", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "a", "sprite": { "id": "a" }, "fg": "#6b6b6b", "bg": "#000000", "order": 1 }, "flags": ["SMALL_GROUP"], "level": 1, "bac": 3, @@ -347,7 +347,7 @@ { "id": "caterpillar_giant", "name": "giant caterpillar", - "renderable": { "glyph": "a", "sprite": "a", "fg": "#b9aeae", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "a", "sprite": { "id": "a" }, "fg": "#b9aeae", "bg": "#000000", "order": 1 }, "flags": ["SMALL_GROUP"], "level": 2, "bac": 7, @@ -358,7 +358,7 @@ { "id": "jackal", "name": "jackal", - "renderable": { "glyph": "d", "sprite": "d", "fg": "#AA5500", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "d", "sprite": { "id": "d" }, "fg": "#AA5500", "bg": "#000000", "order": 1 }, "flags": ["CARNIVORE", "SMALL_GROUP"], "bac": 7, "attacks": [{ "name": "bites", "hit_bonus": 0, "damage": "1d2" }] @@ -366,7 +366,7 @@ { "id": "fox", "name": "fox", - "renderable": { "glyph": "d", "sprite": "d", "fg": "#FF0000", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "d", "sprite": { "id": "d" }, "fg": "#FF0000", "bg": "#000000", "order": 1 }, "flags": ["CARNIVORE"], "bac": 7, "attacks": [{ "name": "bites", "hit_bonus": 0, "damage": "1d3" }] @@ -374,7 +374,7 @@ { "id": "coyote", "name": "coyote", - "renderable": { "glyph": "d", "sprite": "d", "fg": "#6E3215", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "d", "sprite": { "id": "d" }, "fg": "#6E3215", "bg": "#000000", "order": 1 }, "flags": ["CARNIVORE", "SMALL_GROUP"], "level": 1, "bac": 7, @@ -383,7 +383,7 @@ { "id": "wolf", "name": "wolf", - "renderable": { "glyph": "d", "sprite": "d", "fg": "#5E4225", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "d", "sprite": { "id": "d" }, "fg": "#5E4225", "bg": "#000000", "order": 1 }, "flags": ["CARNIVORE"], "level": 5, "bac": 4, @@ -392,7 +392,7 @@ { "id": "goblin_chieftain", "name": "goblin chieftain", - "renderable": { "glyph": "g", "sprite": "g", "fg": "#9331ac", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "g", "sprite": { "id": "g" }, "fg": "#9331ac", "bg": "#000000", "order": 1 }, "flags": [], "level": 2, "speed": 9, @@ -402,7 +402,7 @@ { "id": "orc", "name": "orc", - "renderable": { "glyph": "o", "sprite": "o", "fg": "#00FF00", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "o", "sprite": { "id": "o" }, "fg": "#00FF00", "bg": "#000000", "order": 1 }, "flags": ["SMALL_GROUP"], "level": 1, "speed": 9, @@ -412,7 +412,7 @@ { "id": "orc_hill", "name": "hill orc", - "renderable": { "glyph": "o", "sprite": "o", "fg": "#dbd830", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "o", "sprite": { "id": "o" }, "fg": "#dbd830", "bg": "#000000", "order": 1 }, "flags": ["LARGE_GROUP"], "level": 2, "speed": 9, @@ -422,7 +422,7 @@ { "id": "orc_captain", "name": "orc captain", - "renderable": { "glyph": "o", "sprite": "o", "fg": "#9331ac", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "o", "sprite": { "id": "o" }, "fg": "#9331ac", "bg": "#000000", "order": 1 }, "flags": ["MULTIATTACK"], "level": 5, "speed": 5, @@ -435,7 +435,7 @@ { "id": "warg", "name": "warg", - "renderable": { "glyph": "d", "sprite": "d", "fg": "#8b7164", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "d", "sprite": { "id": "d" }, "fg": "#8b7164", "bg": "#000000", "order": 1 }, "flags": ["SMALL_GROUP"], "level": 7, "bac": 4, @@ -446,7 +446,7 @@ { "id": "jaguar", "name": "jaguar", - "renderable": { "glyph": "f", "sprite": "f", "fg": "#d3b947", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "f", "sprite": { "id": "f" }, "fg": "#d3b947", "bg": "#000000", "order": 1 }, "flags": ["MULTIATTACK"], "level": 4, "bac": 6, @@ -461,7 +461,7 @@ { "id": "lynx", "name": "lynx", - "renderable": { "glyph": "f", "sprite": "f", "fg": "#b5d347", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "f", "sprite": { "id": "f" }, "fg": "#b5d347", "bg": "#000000", "order": 1 }, "flags": ["MULTIATTACK"], "level": 5, "bac": 6, @@ -476,7 +476,7 @@ { "id": "panther", "name": "panther", - "renderable": { "glyph": "f", "sprite": "f", "fg": "#58554e", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "f", "sprite": { "id": "f" }, "fg": "#58554e", "bg": "#000000", "order": 1 }, "flags": ["MULTIATTACK"], "level": 5, "bac": 6, @@ -491,7 +491,7 @@ { "id": "ogre", "name": "ogre", - "renderable": { "glyph": "O", "sprite": "o2", "fg": "#10A70d", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "O", "sprite": { "id": "o2" }, "fg": "#10A70d", "bg": "#000000", "order": 1 }, "flags": ["SMALL_GROUP"], "level": 5, "bac": 5, @@ -502,7 +502,7 @@ { "id": "treant_small", "name": "treant sapling", - "renderable": { "glyph": "♠️", "sprite": "spade", "fg": "#10570d", "bg": "#000000", "order": 1 }, + "renderable": { "glyph": "♠️", "sprite": { "id": "spade" }, "fg": "#10570d", "bg": "#000000", "order": 1 }, "flags": ["LARGE_GROUP", "GREEN_BLOOD", "FIRE_WEAK"], "level": 2, "bac": 12, diff --git a/raws/props.json b/raws/props.json index 7f75da7..f708b9f 100644 --- a/raws/props.json +++ b/raws/props.json @@ -2,13 +2,19 @@ { "id": "door", "name": "door", - "renderable": { "glyph": "+", "sprite": "door_wood_h_closed", "colour_sprite": false, "fg": "#00FFFF", "bg": "#000000", "order": 2 }, + "renderable": { "glyph": "+", "sprite": { "id": "door_wood_h_closed", "alt": "door_wood_h_open", "colour": false }, "fg": "#00FFFF", "bg": "#000000", "order": 2 }, + "flags": ["DOOR"] + }, + { + "id": "trapdoor", + "name": "trapdoor", + "renderable": { "glyph": "+", "sprite": { "id": "trapdoor_closed", "alt": "trapdoor_open2", "colour": false, "alt_y": 1.0 }, "fg": "#00FFFF", "bg": "#000000", "order": 2 }, "flags": ["DOOR"] }, { "id": "prop_altar", "name": "altar", - "renderable": { "glyph": "_", "sprite": "tombstone", "colour_sprite": false, "fg": "#FFFFFF", "bg": "#000000", "order": 2 }, + "renderable": { "glyph": "_", "sprite": { "id": "tombstone", "colour": false }, "fg": "#FFFFFF", "bg": "#000000", "order": 2 }, "flags": ["ENTRY_TRIGGER"], "effects": { "heal": "8d8" } }, @@ -21,64 +27,64 @@ { "id": "prop_table", "name": "table", - "renderable": { "glyph": "-", "sprite": "table", "colour_sprite": false, "fg": "#AAAAAA", "bg": "#000000", "order": 2 }, + "renderable": { "glyph": "-", "sprite": { "id": "table", "colour": false }, "fg": "#AAAAAA", "bg": "#000000", "order": 2 }, "flags": [] }, { "id": "prop_hay", "name": "hay", - "renderable": { "glyph": "%", "sprite": "%", "fg": "#c7ad39", "bg": "#000000", "order": 2 }, + "renderable": { "glyph": "%", "sprite": { "id": "%" }, "fg": "#c7ad39", "bg": "#000000", "order": 2 }, "flags": [] }, { "id": "prop_statue", "name": "statue", - "renderable": { "glyph": "@", "sprite": "statue_warrior", "colour_sprite": false, "fg": "#ffffff", "bg": "#000000", "order": 2 }, + "renderable": { "glyph": "@", "sprite": { "id": "statue_warrior", "colour": false }, "fg": "#ffffff", "bg": "#000000", "order": 2 }, "flags": [] }, { "id": "prop_bed", "name": "bed", - "renderable": { "glyph": "=", "sprite": "bed", "colour_sprite": false, "fg": "#AAAAAA", "bg": "#000000", "order": 2 }, + "renderable": { "glyph": "=", "sprite": { "id": "bed", "colour": false }, "fg": "#AAAAAA", "bg": "#000000", "order": 2 }, "flags": [] }, { "id": "prop_chair", "name": "chair", - "renderable": { "glyph": "└", "sprite": "chair", "colour_sprite": false, "fg": "#AAAAAA", "bg": "#000000", "order": 2 }, + "renderable": { "glyph": "└", "sprite": { "id": "chair", "colour": false }, "fg": "#AAAAAA", "bg": "#000000", "order": 2 }, "flags": [] }, { "id": "prop_candle", "name": "candle", - "renderable": { "glyph": "Ä", "sprite": "candles_a1", "colour_sprite": false, "fg": "#FFA500", "bg": "#000000", "order": 2 }, + "renderable": { "glyph": "Ä", "sprite": { "id": "candles_a1", "colour": false }, "fg": "#FFA500", "bg": "#000000", "order": 2 }, "flags": [] }, { "id": "trap_bear", "name": "bear trap", - "renderable": { "glyph": "^", "sprite": "trap", "colour_sprite": false, "fg": "#e6e6e6", "bg": "#000000", "order": 2 }, + "renderable": { "glyph": "^", "sprite": { "id": "trap", "colour": false }, "fg": "#e6e6e6", "bg": "#000000", "order": 2 }, "flags": ["HIDDEN", "ENTRY_TRIGGER", "SINGLE_ACTIVATION"], "effects": { "damage": "2d4" } }, { "id": "trap_mini_mine", "name": "mini-mine", - "renderable": { "glyph": "^", "sprite": "^", "fg": "#ff1e00", "bg": "#000000", "order": 2 }, + "renderable": { "glyph": "^", "sprite": { "id": "^" }, "fg": "#ff1e00", "bg": "#000000", "order": 2 }, "flags": ["ENTRY_TRIGGER", "SINGLE_ACTIVATION"], "effects": { "damage": "2d4", "aoe": "3" } }, { "id": "trap_stonefall", "name": "stonefall trap", - "renderable": { "glyph": "^", "sprite": "^", "fg": "#beb5a7", "bg": "#000000", "order": 2 }, + "renderable": { "glyph": "^", "sprite": { "id": "^" }, "fg": "#beb5a7", "bg": "#000000", "order": 2 }, "flags": ["HIDDEN", "ENTRY_TRIGGER", "SINGLE_ACTIVATION"], "effects": { "damage": "2d10" } }, { "id": "trap_confusion", "name": "magic trap", - "renderable": { "glyph": "^", "sprite": "magic_e1", "colour_sprite": false, "fg": "#df07df", "bg": "#000000", "order": 2 }, + "renderable": { "glyph": "^", "sprite": { "id": "magic_e1", "colour": false }, "fg": "#df07df", "bg": "#000000", "order": 2 }, "flags": ["HIDDEN", "ENTRY_TRIGGER", "SINGLE_ACTIVATION"], "effects": { "confusion": "3" } } diff --git a/src/components.rs b/src/components.rs index bd9e4a1..ada13c5 100644 --- a/src/components.rs +++ b/src/components.rs @@ -38,11 +38,53 @@ pub struct OtherLevelPosition { pub id: i32, } +#[derive(Debug, Serialize, Deserialize, Clone)] +pub struct SpriteInfo { + pub id: String, + pub recolour: bool, + pub alt: Option, + pub offset: (f32, f32), + pub alt_offset: (f32, f32), +} + +impl SpriteInfo { + pub fn new(id: &str) -> Self { + Self { + id: id.to_string(), + recolour: false, + alt: None, + offset: (0.0, 0.0), + alt_offset: (0.0, 0.0), + } + } + pub fn colourable(id: &str) -> Self { + Self { + id: id.to_string(), + recolour: true, + alt: None, + offset: (0.0, 0.0), + alt_offset: (0.0, 0.0), + } + } + pub fn swap(&self) -> Self { + if let Some(alt_sprite) = &self.alt { + Self { + id: alt_sprite.clone(), + recolour: self.recolour, + alt: Some(self.id.clone()), + offset: self.alt_offset, + alt_offset: self.offset, + } + } else { + unreachable!("Tried to call .swap() on a sprite with no alt: {:?}", self); + } + } +} + #[derive(Component, ConvertSaveload, Clone)] pub struct Renderable { pub glyph: FontCharType, - pub sprite: Option, - pub colour_sprite: bool, + pub sprite: Option, pub fg: RGB, pub bg: RGB, pub render_order: i32, diff --git a/src/gui/character_creation.rs b/src/gui/character_creation.rs index a1f245d..55b0517 100644 --- a/src/gui/character_creation.rs +++ b/src/gui/character_creation.rs @@ -275,7 +275,6 @@ pub fn setup_player_ancestry(ecs: &mut World, ancestry: Ancestry) { .insert(*player, Renderable { glyph: to_cp437(DWARF_GLYPH), sprite: None, // TODO: Dwarf sprite - colour_sprite: true, fg: RGB::named(DWARF_COLOUR), bg: RGB::named(BLACK), render_order: 0, @@ -288,7 +287,6 @@ pub fn setup_player_ancestry(ecs: &mut World, ancestry: Ancestry) { .insert(*player, Renderable { glyph: to_cp437(ELF_GLYPH), sprite: None, // TODO: Elf sprite - colour_sprite: true, fg: RGB::named(ELF_COLOUR), bg: RGB::named(BLACK), render_order: 0, @@ -315,7 +313,6 @@ pub fn setup_player_ancestry(ecs: &mut World, ancestry: Ancestry) { .insert(*player, Renderable { glyph: to_cp437(CATFOLK_GLYPH), sprite: None, // TODO: Catfolk sprite - colour_sprite: true, fg: RGB::named(CATFOLK_COLOUR), bg: RGB::named(BLACK), render_order: 0, diff --git a/src/gui/mod.rs b/src/gui/mod.rs index 97b4c6a..4d719ff 100644 --- a/src/gui/mod.rs +++ b/src/gui/mod.rs @@ -126,7 +126,7 @@ fn draw_bar( let fill_width = (percent * (w as f32)) as i32; for x in 0..w { let suffix = if x == 0 { "1" } else if x == w - 1 { "3" } else { "2" }; - let fill = if x <= fill_width { "full" } else { "empty" }; + let fill = if x < fill_width { "full" } else { "empty" }; let sprite = if let Some(sprite) = atlas.get(&format!("{}_{}_{}", sprite, fill, suffix)) { sprite } else { diff --git a/src/main.rs b/src/main.rs index 06fc592..b904ffa 100644 --- a/src/main.rs +++ b/src/main.rs @@ -253,16 +253,19 @@ fn draw_camera( } // TODO: Use sprites here, not text drawing. Put bitmap font into atlas. let renderable = renderables.get(entry.1.e).unwrap(); - if let Some(sprite_id) = &renderable.sprite { - let sprite = if let Some(sprite) = atlas.get(sprite_id) { + if let Some(spriteinfo) = &renderable.sprite { + let id = if let Some(sprite) = atlas.get(&spriteinfo.id) { sprite } else { - panic!("No entity sprite found for ID: {}", sprite_id); + panic!("No entity sprite found for ID: {}", spriteinfo.id); }; - draw.image(sprite) - .position((entry.0.x as f32) * TILESIZE, (entry.0.y as f32) * TILESIZE) + draw.image(id) + .position( + ((entry.0.x as f32) + spriteinfo.offset.0) * TILESIZE, + ((entry.0.y as f32) + spriteinfo.offset.1) * TILESIZE + ) .color( - if renderable.colour_sprite { + if spriteinfo.recolour { Color::from_rgb( renderable.fg.r, renderable.fg.g, @@ -293,16 +296,19 @@ fn draw_camera( DrawType::VisibleAndRemember => { // TODO: PUT THIS INTO A FUNCTION! let renderable = renderables.get(entry.1.e).unwrap(); - if let Some(sprite_id) = &renderable.sprite { - let sprite = if let Some(sprite) = atlas.get(sprite_id) { + if let Some(spriteinfo) = &renderable.sprite { + let id = if let Some(sprite) = atlas.get(&spriteinfo.id) { sprite } else { - panic!("No entity sprite found for ID: {}", sprite_id); + panic!("No entity sprite found for ID: {}", spriteinfo.id); }; - draw.image(sprite) - .position((entry.0.x as f32) * TILESIZE, (entry.0.y as f32) * TILESIZE) + draw.image(id) + .position( + ((entry.0.x as f32) + spriteinfo.offset.0) * TILESIZE, + ((entry.0.y as f32) + spriteinfo.offset.1) * TILESIZE + ) .color( - if renderable.colour_sprite { + if spriteinfo.recolour { Color::from_rgb( renderable.fg.r, renderable.fg.g, diff --git a/src/map/themes.rs b/src/map/themes.rs index a5f1a00..2698eda 100644 --- a/src/map/themes.rs +++ b/src/map/themes.rs @@ -9,7 +9,7 @@ use notan::prelude::*; pub fn get_sprite_for_id(idx: usize, map: &Map, other_pos: Option) -> (&str, Color) { let f = map.colour_offset[idx].0.0; // Using offset as a source of random. let sprite = match map.tiles[idx] { - TileType::Wall => map.tiles[idx].sprite(check_if_base(idx, map), f), + TileType::Wall => map.tiles[idx].sprite(check_if_base(TileType::Wall, idx, map), f), _ => map.tiles[idx].sprite(false, f), }; let tint = if !map.visible_tiles[idx] { @@ -150,18 +150,23 @@ fn get_forest_theme_renderables(idx:usize, map: &Map, debug: Option) -> (F return (glyph, fg, bg, offsets, bg_offsets); } -fn is_revealed_and_wall(map: &Map, x: i32, y: i32, debug: Option) -> bool { +fn is_revealed_and(tt: TileType, map: &Map, x: i32, y: i32, debug: Option) -> bool { let idx = map.xy_idx(x, y); - map.tiles[idx] == TileType::Wall && - (if debug.is_none() { map.revealed_tiles[idx] } else { true }) + map.tiles[idx] == tt && (if debug.is_none() { map.revealed_tiles[idx] } else { true }) } -fn check_if_base(idx: usize, map: &Map) -> bool { +fn check_if_base(tt: TileType, idx: usize, map: &Map) -> bool { let x = (idx as i32) % map.width; let y = (idx as i32) / map.width; - if is_revealed_and_wall(map, x, y + 1, None) { + // If we're on the edge, it can only be a base sprite. + if y > map.height - 2 { + return true; + } + // If the tile below is a revealed wall, we're not the base. + if is_revealed_and(tt, map, x, y + 1, None) { return false; } + // If the tile below isn't a revealed wall, we're the base. return true; } @@ -179,37 +184,37 @@ fn wall_glyph(map: &Map, x: i32, y: i32, debug: Option) -> FontCharType { let mut mask: u8 = 0; let diagonals_matter: Vec = vec![7, 11, 13, 14, 15]; - if is_revealed_and_wall(map, x, y - 1, debug) { + if is_revealed_and(TileType::Wall, map, x, y - 1, debug) { // N mask += 1; } - if is_revealed_and_wall(map, x, y + 1, debug) { + if is_revealed_and(TileType::Wall, map, x, y + 1, debug) { // S mask += 2; } - if is_revealed_and_wall(map, x - 1, y, debug) { + if is_revealed_and(TileType::Wall, map, x - 1, y, debug) { // W mask += 4; } - if is_revealed_and_wall(map, x + 1, y, debug) { + if is_revealed_and(TileType::Wall, map, x + 1, y, debug) { // E mask += 8; } if diagonals_matter.contains(&mask) { - if is_revealed_and_wall(map, x + 1, y - 1, debug) { + if is_revealed_and(TileType::Wall, map, x + 1, y - 1, debug) { // Top right mask += 16; } - if is_revealed_and_wall(map, x - 1, y - 1, debug) { + if is_revealed_and(TileType::Wall, map, x - 1, y - 1, debug) { // Top left mask += 32; } - if is_revealed_and_wall(map, x + 1, y + 1, debug) { + if is_revealed_and(TileType::Wall, map, x + 1, y + 1, debug) { // Bottom right mask += 64; } - if is_revealed_and_wall(map, x - 1, y + 1, debug) { + if is_revealed_and(TileType::Wall, map, x - 1, y + 1, debug) { // Bottom left mask += 128; } diff --git a/src/particle_system.rs b/src/particle_system.rs index 0ff6baa..11e9ed7 100644 --- a/src/particle_system.rs +++ b/src/particle_system.rs @@ -83,7 +83,6 @@ fn create_delayed_particles(ecs: &mut World, ctx: &App) { renderables .insert(p, Renderable { sprite: None, // TODO: Particle sprite - colour_sprite: false, fg: handled.fg, bg: handled.bg, glyph: handled.glyph, @@ -309,8 +308,7 @@ impl<'a> System<'a> for ParticleSpawnSystem { .expect("Could not insert position"); renderables .insert(p, Renderable { - sprite: None, // TODO: Particle sprite - colour_sprite: false, + sprite: None, // TODO: Particle sprites fg: new_particle.fg, bg: new_particle.bg, glyph: new_particle.glyph, diff --git a/src/player.rs b/src/player.rs index b88bd48..9bb80d8 100644 --- a/src/player.rs +++ b/src/player.rs @@ -135,8 +135,9 @@ pub fn try_door(i: i32, j: i32, ecs: &mut World) -> RunState { std::mem::drop(renderables); let mut renderables = ecs.write_storage::(); let render_data = renderables.get_mut(potential_target).unwrap(); - render_data.glyph = to_cp437('+'); // Nethack open door, maybe just use '/' instead. - render_data.sprite = Some("door_wood_h_closed".to_string()); // TODO: Enum + if let Some(sprite) = &mut render_data.sprite { + *sprite = sprite.swap(); + } door_pos = Some(Point::new(pos.x + delta_x, pos.y + delta_y)); } result = RunState::Ticking; @@ -233,8 +234,9 @@ pub fn open(i: i32, j: i32, ecs: &mut World) -> RunState { std::mem::drop(renderables); let mut renderables = ecs.write_storage::(); let render_data = renderables.get_mut(potential_target).unwrap(); - render_data.glyph = to_cp437('▓'); // Nethack open door, maybe just use '/' instead. - render_data.sprite = Some("door_wood_h_open".to_string()); // TODO: Enum + if let Some(sprite) = &mut render_data.sprite { + *sprite = sprite.swap(); + } door_pos = Some(Point::new(pos.x + delta_x, pos.y + delta_y)); } result = RunState::Ticking; diff --git a/src/raws/item_structs.rs b/src/raws/item_structs.rs index ee74a69..d77034e 100644 --- a/src/raws/item_structs.rs +++ b/src/raws/item_structs.rs @@ -27,11 +27,21 @@ pub struct Equippable { pub to_hit: Option, } +#[derive(Deserialize, Debug)] +pub struct SpriteInfo { + pub id: String, + pub alt: Option, + pub colour: Option, + pub x: Option, + pub y: Option, + pub alt_x: Option, + pub alt_y: Option, +} + #[derive(Deserialize, Debug)] pub struct Renderable { pub glyph: String, - pub sprite: Option, - pub colour_sprite: Option, + pub sprite: Option, pub fg: String, pub bg: String, pub order: i32, diff --git a/src/raws/rawmaster.rs b/src/raws/rawmaster.rs index f9c9e37..7fbdeb9 100644 --- a/src/raws/rawmaster.rs +++ b/src/raws/rawmaster.rs @@ -691,11 +691,24 @@ fn get_renderable_component( ) -> crate::components::Renderable { crate::components::Renderable { glyph: to_cp437(renderable.glyph.chars().next().unwrap()), - sprite: renderable.sprite.clone(), - colour_sprite: if renderable.colour_sprite.is_some() { - renderable.colour_sprite.clone().unwrap() + sprite: if let Some(spriteinfo) = &renderable.sprite { + let x = spriteinfo.x.unwrap_or(0.0); + let y = spriteinfo.y.unwrap_or(0.0); + let alt_x = spriteinfo.alt_x.unwrap_or(0.0); + let alt_y = spriteinfo.alt_y.unwrap_or(0.0); + Some(SpriteInfo { + id: spriteinfo.id.clone(), + recolour: if let Some(colour) = spriteinfo.colour { + colour + } else { + false + }, + alt: spriteinfo.alt.clone(), + offset: (x, y), + alt_offset: (x, y), + }) } else { - true + None }, fg: RGB::from_hex(&renderable.fg).expect("Invalid RGB"), bg: RGB::from_hex(&renderable.bg).expect("Invalid RGB"), diff --git a/src/spawner.rs b/src/spawner.rs index 1340936..07add86 100644 --- a/src/spawner.rs +++ b/src/spawner.rs @@ -29,6 +29,7 @@ use super::{ Intrinsics, HasAncestry, HasClass, + SpriteInfo, }; use crate::gui::{ Ancestry, Class }; use crate::consts::entity; @@ -57,8 +58,7 @@ pub fn player(ecs: &mut World, player_x: i32, player_y: i32) -> Entity { .with(BlocksTile {}) .with(Renderable { glyph: to_cp437('@'), - sprite: Some("@".to_string()), // TODO: Player sprite - colour_sprite: true, + sprite: Some(SpriteInfo::colourable("@")), fg: RGB::named(YELLOW), bg: RGB::named(BLACK), render_order: 0,