the oryx-ening - zoom factor, and renderables refactor

currently extremely unfinished - half the sprites are gnomes, and tiles have no colours
This commit is contained in:
Llywelwyn 2023-10-06 09:22:11 +01:00
parent 8bb6a54a39
commit 44b0674b5a
30 changed files with 2150 additions and 650 deletions

View file

@ -2,7 +2,7 @@
{
"id": "potion_health",
"name": { "name": "potion of health", "plural": "potions of health" },
"renderable": { "glyph": "!", "fg": "#FF00FF", "bg": "#000000", "order": 4 },
"renderable": { "glyph": "!", "sprite": "potion", "fg": "#FF00FF", "order": 4 },
"class": "potion",
"weight": 1,
"value": 50,
@ -13,7 +13,7 @@
{
"id": "potion_health_weak",
"name": { "name": "potion of lesser health", "plural": "potions of lesser health" },
"renderable": { "glyph": "!", "fg": "#FF00FF", "bg": "#000000", "order": 4 },
"renderable": { "glyph": "!", "sprite": "potion", "fg": "#FF00FF", "order": 4 },
"class": "potion",
"weight": 1,
"value": 25,
@ -24,7 +24,7 @@
{
"id": "scroll_identify",
"name": { "name": "scroll of identify", "plural": "scrolls of identify" },
"renderable": { "glyph": "?", "sprite": { "id": "scroll", "colour": false }, "fg": "#0FFFFF", "bg": "#000000", "order": 4 },
"renderable": { "glyph": "?", "sprite": "scroll_writing", "fg": "#0FFFFF", "order": 4 },
"class": "scroll",
"weight": 0.5,
"value": 100,
@ -34,7 +34,7 @@
{
"id": "scroll_removecurse",
"name": { "name": "scroll of remove curse", "plural": "scrolls of remove curse" },
"renderable": { "glyph": "?", "sprite": { "id": "scroll", "colour": false }, "fg": "#0FFFFF", "bg": "#000000", "order": 4 },
"renderable": { "glyph": "?", "sprite": "scroll_writing", "fg": "#0FFFFF", "order": 4 },
"class": "scroll",
"weight": 0.5,
"value": 200,
@ -44,7 +44,7 @@
{
"id": "scroll_health",
"name": { "name": "scroll of healing word", "plural": "scrolls of healing word" },
"renderable": { "glyph": "?", "sprite": { "id": "scroll", "colour": false }, "fg": "#00FFFF", "bg": "#000000", "order": 4 },
"renderable": { "glyph": "?", "sprite": "scroll_writing", "fg": "#00FFFF", "order": 4 },
"class": "scroll",
"weight": 0.5,
"value": 50,
@ -55,7 +55,7 @@
{
"id": "scroll_mass_health",
"name": { "name": "scroll of mass healing word", "plural": "scrolls of mass healing word" },
"renderable": { "glyph": "?", "sprite": { "id": "scroll", "colour": false }, "fg": "#00FFFF", "bg": "#000000", "order": 4 },
"renderable": { "glyph": "?", "sprite": "scroll_writing", "fg": "#00FFFF", "order": 4 },
"class": "scroll",
"weight": 0.5,
"value": 200,
@ -66,7 +66,7 @@
{
"id": "scroll_magicmissile",
"name": { "name": "scroll of magic missile", "plural": "scrolls of magic missile" },
"renderable": { "glyph": "?", "sprite": { "id": "scroll", "colour": false }, "fg": "#00FFFF", "bg": "#000000", "order": 4 },
"renderable": { "glyph": "?", "sprite": "scroll_writing", "fg": "#00FFFF", "order": 4 },
"class": "scroll",
"weight": 0.5,
"value": 50,
@ -77,7 +77,7 @@
{
"id": "scroll_embers",
"name": { "name": "scroll of embers", "plural": "scrolls of embers" },
"renderable": { "glyph": "?", "sprite": { "id": "scroll", "colour": false }, "fg": "#00FFFF", "bg": "#000000", "order": 4 },
"renderable": { "glyph": "?", "sprite": "scroll_writing", "fg": "#00FFFF", "order": 4 },
"class": "scroll",
"weight": 0.5,
"value": 100,
@ -88,7 +88,7 @@
{
"id": "scroll_fireball",
"name": { "name": "scroll of fireball", "plural": "scrolls of fireball" },
"renderable": { "glyph": "?", "sprite": { "id": "scroll", "colour": false }, "fg": "#00FFFF", "bg": "#000000", "order": 4 },
"renderable": { "glyph": "?", "sprite": "scroll_writing", "fg": "#00FFFF", "order": 4 },
"class": "scroll",
"weight": 0.5,
"value": 200,
@ -104,7 +104,7 @@
{
"id": "scroll_confusion",
"name": { "name": "scroll of confusion", "plural": "scrolls of confusion" },
"renderable": { "glyph": "?", "sprite": { "id": "scroll", "colour": false }, "fg": "#00FFFF", "bg": "#000000", "order": 4 },
"renderable": { "glyph": "?", "sprite": "scroll_writing", "fg": "#00FFFF", "order": 4 },
"class": "scroll",
"weight": 0.5,
"value": 100,
@ -115,7 +115,7 @@
{
"id": "scroll_mass_confusion",
"name": { "name": "scroll of mass confusion", "plural": "scrolls of mass confusion" },
"renderable": { "glyph": "?", "sprite": { "id": "scroll", "colour": false }, "fg": "#00FFFF", "bg": "#000000", "order": 4 },
"renderable": { "glyph": "?", "sprite": "scroll_writing", "fg": "#00FFFF", "order": 4 },
"class": "scroll",
"weight": 0.5,
"value": 200,
@ -126,7 +126,7 @@
{
"id": "scroll_magicmap",
"name": { "name": "scroll of magic mapping", "plural": "scrolls of magic mapping" },
"renderable": { "glyph": "?", "sprite": { "id": "scroll", "colour": false }, "fg": "#00FFFF", "bg": "#000000", "order": 4 },
"renderable": { "glyph": "?", "sprite": "scroll_writing", "fg": "#00FFFF", "order": 4 },
"class": "scroll",
"weight": 0.5,
"value": 50,
@ -137,7 +137,7 @@
{
"id": "equip_dagger",
"name": { "name": "dagger", "plural": "daggers" },
"renderable": { "glyph": ")", "fg": "#808080", "bg": "#000000", "order": 4 },
"renderable": { "glyph": ")", "sprite": "dagger", "fg": "#808080", "order": 4 },
"class": "weapon",
"weight": 1,
"value": 2,
@ -147,7 +147,7 @@
{
"id": "equip_shortsword",
"name": { "name": "shortsword", "plural": "shortswords" },
"renderable": { "glyph": ")", "fg": "#C0C0C0", "bg": "#000000", "order": 4 },
"renderable": { "glyph": ")", "sprite": "shortsword", "fg": "#C0C0C0", "order": 4 },
"class": "weapon",
"weight": 2,
"value": 10,
@ -157,7 +157,7 @@
{
"id": "equip_rapier",
"name": { "name": "rapier", "plural": "rapiers" },
"renderable": { "glyph": ")", "fg": "#C0C0C0", "bg": "#000000", "order": 4 },
"renderable": { "glyph": ")", "sprite": "gnome", "fg": "#C0C0C0", "order": 4 },
"class": "weapon",
"weight": 2,
"value": 10,
@ -167,7 +167,7 @@
{
"id": "equip_pitchfork",
"name": { "name": "pitchfork", "plural": "pitchforks" },
"renderable": { "glyph": ")", "fg": "#C0C0C0", "bg": "#000000", "order": 4 },
"renderable": { "glyph": ")", "sprite": "trident", "fg": "#C0C0C0", "order": 4 },
"class": "weapon",
"weight": 2,
"value": 5,
@ -177,7 +177,7 @@
{
"id": "equip_sickle",
"name": { "name": "sickle", "plural": "sickles" },
"renderable": { "glyph": ")", "fg": "#C0C0C0", "bg": "#000000", "order": 4 },
"renderable": { "glyph": ")", "sprite": "gnome", "fg": "#C0C0C0", "order": 4 },
"class": "weapon",
"weight": 2,
"value": 5,
@ -187,7 +187,7 @@
{
"id": "equip_handaxe",
"name": { "name": "handaxe", "plural": "handaxes" },
"renderable": { "glyph": ")", "fg": "#C0C0C0", "bg": "#000000", "order": 4 },
"renderable": { "glyph": ")", "sprite": "handaxe", "fg": "#C0C0C0", "order": 4 },
"class": "weapon",
"weight": 2,
"value": 5,
@ -197,7 +197,7 @@
{
"id": "equip_longsword",
"name": { "name": "longsword", "plural": "longswords" },
"renderable": { "glyph": ")", "fg": "#FFF8DC", "bg": "#000000", "order": 4 },
"renderable": { "glyph": ")", "sprite": "longsword", "fg": "#FFF8DC", "order": 4 },
"class": "weapon",
"weight": 3,
"value": 15,
@ -207,7 +207,7 @@
{
"id": "artifact_icingdeath",
"name": { "name": "Icingdeath", "plural": "Icingdeath" },
"renderable": { "glyph": ")", "fg": "#37aecc", "bg": "#000000", "order": 4 },
"renderable": { "glyph": ")", "sprite": "scimitar", "fg": "#37aecc", "order": 4 },
"class": "weapon",
"weight": 3,
"value": 300,
@ -217,7 +217,7 @@
{
"id": "equip_smallshield",
"name": { "name": "buckler", "plural": "bucklers" },
"renderable": { "glyph": "[", "fg": "#808080", "bg": "#000000", "order": 4 },
"renderable": { "glyph": "[", "sprite": "shield_small", "fg": "#808080", "order": 4 },
"class": "armour",
"weight": 2,
"value": 5,
@ -227,7 +227,7 @@
{
"id": "equip_mediumshield",
"name": { "name": "medium shield", "plural": "medium shields" },
"renderable": { "glyph": "[", "fg": "#C0C0C0", "bg": "#000000", "order": 4 },
"renderable": { "glyph": "[", "sprite": "shield_round", "fg": "#C0C0C0", "order": 4 },
"class": "armour",
"weight": 6,
"value": 10,
@ -237,7 +237,7 @@
{
"id": "equip_largeshield",
"name": { "name": "large shield", "plural": "large shields" },
"renderable": { "glyph": "[", "fg": "#FFF8DC", "bg": "#000000", "order": 4 },
"renderable": { "glyph": "[", "sprite": "shield_large", "fg": "#FFF8DC", "order": 4 },
"class": "armour",
"weight": 12,
"value": 35,
@ -247,7 +247,7 @@
{
"id": "equip_body_weakleather",
"name": { "name": "leather jacket", "plural": "leather jackets" },
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 4 },
"renderable": { "glyph": "[", "sprite": "body_leather", "fg": "#aa6000", "order": 4 },
"class": "armour",
"weight": 8,
"value": 5,
@ -257,7 +257,7 @@
{
"id": "equip_body_leather",
"name": { "name": "leather chestpiece", "plural": "leather chestpiece" },
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 4 },
"renderable": { "glyph": "[", "sprite": "body_leather", "fg": "#aa6000", "order": 4 },
"class": "armour",
"weight": 10,
"value": 10,
@ -267,7 +267,7 @@
{
"id": "equip_body_studdedleather",
"name": { "name": "studded leather chestpiece", "plural": "studded leather chestpieces" },
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 4 },
"renderable": { "glyph": "[", "sprite": "body_leather", "fg": "#aa6000", "order": 4 },
"class": "armour",
"weight": 13,
"value": 45,
@ -277,7 +277,7 @@
{
"id": "equip_body_ringmail_o",
"name": { "name": "orcish ring mail", "plural": "orcish ring mail" },
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 4 },
"renderable": { "glyph": "[", "sprite": "body_leather", "fg": "#aa6000", "order": 4 },
"class": "armour",
"weight": 45,
"value": 50,
@ -287,7 +287,7 @@
{
"id": "equip_body_ringmail",
"name": { "name": "ring mail", "plural": "ring mail" },
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 4 },
"renderable": { "glyph": "[", "sprite": "body_leather", "fg": "#aa6000", "order": 4 },
"class": "armour",
"weight": 45,
"value": 70,
@ -297,7 +297,7 @@
{
"id": "equip_head_leather",
"name": { "name": "leather cap", "plural": "leather caps" },
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 4 },
"renderable": { "glyph": "[", "sprite": "body_leather", "fg": "#aa6000", "order": 4 },
"class": "armour",
"weight": 2,
"value": 10,
@ -307,7 +307,7 @@
{
"id": "equip_head_elvish",
"name": { "name": "elvish leather helm", "plural": "elvish leather helms" },
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 4 },
"renderable": { "glyph": "[", "sprite": "body_leather", "fg": "#aa6000", "order": 4 },
"class": "armour",
"weight": 2,
"value": 25,
@ -317,7 +317,7 @@
{
"id": "equip_head_o",
"name": { "name": "orcish helm", "plural": "orcish helm" },
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 4 },
"renderable": { "glyph": "[", "sprite": "body_leather", "fg": "#aa6000", "order": 4 },
"class": "armour",
"weight": 6,
"value": 25,
@ -327,7 +327,7 @@
{
"id": "equip_head_iron",
"name": { "name": "iron helm", "plural": "iron helm" },
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 4 },
"renderable": { "glyph": "[", "sprite": "body_leather", "fg": "#aa6000", "order": 4 },
"class": "armour",
"weight": 10,
"value": 45,
@ -337,7 +337,7 @@
{
"id": "equip_feet_leather",
"name": { "name": "leather shoes", "plural": "leather shoes" },
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 4 },
"renderable": { "glyph": "[", "sprite": "body_leather", "fg": "#aa6000", "order": 4 },
"class": "armour",
"weight": 2,
"value": 10,
@ -346,7 +346,7 @@
{
"id": "equip_feet_elvish",
"name": { "name": "elvish leather shoes", "plural": "elvish leather shoes" },
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 4 },
"renderable": { "glyph": "[", "sprite": "body_leather", "fg": "#aa6000", "order": 4 },
"class": "armour",
"weight": 2,
"value": 25,
@ -356,7 +356,7 @@
{
"id": "equip_feet_o",
"name": { "name": "orcish boots", "plural": "orcish boots" },
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 4 },
"renderable": { "glyph": "[", "sprite": "body_leather", "fg": "#aa6000", "order": 4 },
"class": "armour",
"weight": 6,
"value": 25,
@ -366,7 +366,7 @@
{
"id": "equip_feet_iron",
"name": { "name": "iron boots", "plural": "iron boots" },
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 4 },
"renderable": { "glyph": "[", "sprite": "body_leather", "fg": "#aa6000", "order": 4 },
"class": "armour",
"weight": 10,
"value": 45,
@ -376,7 +376,7 @@
{
"id": "equip_neck_protection",
"name": { "name": "amulet of protection", "plural": "amulets of protection" },
"renderable": { "glyph": "\"", "fg": "#aa6000", "bg": "#000000", "order": 4 },
"renderable": { "glyph": "\"", "sprite": "body_leather", "fg": "#aa6000", "order": 4 },
"class": "amulet",
"weight": 1,
"value": 200,
@ -386,7 +386,7 @@
{
"id": "equip_back_protection",
"name": { "name": "cloak of protection", "plural": "cloaks of protection" },
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 4 },
"renderable": { "glyph": "[", "sprite": "body_leather", "fg": "#aa6000", "order": 4 },
"class": "armour",
"weight": 1,
"value": 200,
@ -396,7 +396,7 @@
{
"id": "wand_magicmissile",
"name": { "name": "wand of magic missile", "plural": "wands of magic missile" },
"renderable": { "glyph": "/", "fg": "#00FFFF", "bg": "#000000", "order": 4 },
"renderable": { "glyph": "/", "sprite": "body_leather", "fg": "#00FFFF", "order": 4 },
"class": "wand",
"weight": 2,
"value": 100,
@ -407,7 +407,7 @@
{
"id": "wand_fireball",
"name": { "name": "wand of fireball", "plural": "wands of fireball" },
"renderable": { "glyph": "/", "fg": "#00FFFF", "bg": "#000000", "order": 4 },
"renderable": { "glyph": "/", "sprite": "body_leather", "fg": "#00FFFF", "order": 4 },
"class": "wand",
"weight": 2,
"value": 300,
@ -418,7 +418,7 @@
{
"id": "wand_confusion",
"name": { "name": "wand of confusion", "plural": "wands of confusion" },
"renderable": { "glyph": "/", "fg": "#00FFFF", "bg": "#000000", "order": 4 },
"renderable": { "glyph": "/", "sprite": "body_leather", "fg": "#00FFFF", "order": 4 },
"class": "wand",
"weight": 2,
"value": 200,
@ -429,7 +429,7 @@
{
"id": "wand_digging",
"name": { "name": "wand of digging", "plural": "wands of digging" },
"renderable": { "glyph": "/", "fg": "#00FFFF", "bg": "#000000", "order": 4 },
"renderable": { "glyph": "/", "sprite": "body_leather", "fg": "#00FFFF", "order": 4 },
"class": "wand",
"weight": 2,
"value": 300,
@ -440,7 +440,7 @@
{
"id": "food_rations",
"name": { "name": "rations", "plural": "rations" },
"renderable": { "glyph": "%", "fg": "#FFA07A", "bg": "#000000", "order": 4 },
"renderable": { "glyph": "%", "sprite": "meat", "fg": "#FFA07A", "order": 4 },
"class": "comestible",
"weight": 1,
"value": 1,
@ -449,7 +449,7 @@
{
"id": "food_apple",
"name": { "name": "apple", "plural": "apples" },
"renderable": { "glyph": "%", "fg": "#00FF00", "bg": "#000000", "order": 4 },
"renderable": { "glyph": "%", "sprite": "body_leather", "fg": "#00FF00", "order": 4 },
"class": "comestible",
"weight": 0.5,
"value": 1,

View file

@ -2,7 +2,7 @@
{
"id": "npc_barkeep",
"name": "barkeep",
"renderable": { "glyph": "@", "sprite": { "id": "@" }, "fg": "#EE82EE", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "@", "sprite": "gnome", "fg": "#EE82EE", "order": 3 },
"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": { "id": "@" }, "fg": "#9fa86c", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "@", "sprite": "gnome", "fg": "#9fa86c", "order": 3 },
"flags": ["NEUTRAL", "RANDOM_PATH", "IS_HUMAN"],
"vision_range": 4,
"quips": ["Hello!", "Good morning.", "<a quiet complaint about chores>"]
@ -18,7 +18,7 @@
{
"id": "npc_drunk",
"name": "drunk",
"renderable": { "glyph": "@", "sprite": { "id": "@" }, "fg": "#a0a83c", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "@", "sprite": "gnome", "fg": "#a0a83c", "order": 3 },
"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": { "id": "@" }, "fg": "#3ca3a8", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "@", "sprite": "gnome", "fg": "#3ca3a8", "order": 3 },
"flags": ["NEUTRAL", "IS_HUMAN"],
"vision_range": 4,
"quips": ["Hey."]
@ -34,7 +34,7 @@
{
"id": "npc_dockworker",
"name": "dock worker",
"renderable": { "glyph": "@", "sprite": { "id": "@" }, "fg": "#68d8de", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "@", "sprite": "gnome", "fg": "#68d8de", "order": 3 },
"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": { "id": "@" }, "fg": "#FFFFFF", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "@", "sprite": "gnome", "fg": "#FFFFFF", "order": 3 },
"flags": ["NEUTRAL", "IS_HUMAN"],
"vision_range": 4,
"quips": ["Light's givings.", "<a quiet prayer>", "Bless you."]
@ -50,7 +50,7 @@
{
"id": "npc_miner",
"name": "miner",
"renderable": { "glyph": "@", "sprite": { "id": "@" }, "fg": "#946123", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "@", "sprite": "gnome", "fg": "#946123", "order": 3 },
"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": { "id": "@" }, "fg": "#034efc", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "@", "sprite": "gnome", "fg": "#034efc", "order": 3 },
"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": { "id": "r" }, "fg": "#aa6000", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "r", "sprite": "rat", "fg": "#aa6000", "order": 3 },
"flags": [],
"bac": 6,
"attacks": [{ "name": "bites", "hit_bonus": 0, "damage": "1d2" }],
@ -78,7 +78,7 @@
{
"id": "chicken",
"name": "chicken",
"renderable": { "glyph": "c", "sprite": { "id": "c" }, "fg": "#BB6000", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "c", "sprite": "gnome", "fg": "#BB6000", "order": 3 },
"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": { "id": "q" }, "fg": "#a57037", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "q", "sprite": "gnome", "fg": "#a57037", "order": 3 },
"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": { "id": "q" }, "fg": "#e7e7e7", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "q", "sprite": "gnome", "fg": "#e7e7e7", "order": 3 },
"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": { "id": "c" }, "fg": "#fae478", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "c", "sprite": "gnome", "fg": "#fae478", "order": 3 },
"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": { "id": "u" }, "fg": "#b36c29", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "u", "sprite": "horse", "fg": "#b36c29", "order": 3 },
"flags": ["HERBIVORE", "MULTIATTACK"],
"level": 3,
"bac": 6,
@ -124,7 +124,7 @@
{
"id": "horse",
"name": "horse",
"renderable": { "glyph": "u", "sprite": { "id": "u" }, "fg": "#744d29", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "u", "sprite": "horse", "fg": "#744d29", "order": 3 },
"flags": ["MULTIATTACK"],
"level": 5,
"bac": 5,
@ -137,7 +137,7 @@
{
"id": "horse_large",
"name": "warhorse",
"renderable": { "glyph": "u", "sprite": { "id": "u" }, "fg": "#8a3520", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "u", "sprite": "horse", "fg": "#8a3520", "order": 3 },
"flags": ["MULTIATTACK"],
"level": 7,
"bac": 4,
@ -150,7 +150,7 @@
{
"id": "rat_giant",
"name": "giant rat",
"renderable": { "glyph": "r", "sprite": { "id": "r" }, "fg": "#bb8000", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "r", "sprite": "rat_large", "fg": "#bb8000", "order": 3 },
"flags": ["SMALL_GROUP"],
"level": 1,
"bac": 7,
@ -160,7 +160,7 @@
{
"id": "dog_little",
"name": "little dog",
"renderable": { "glyph": "d", "sprite": { "id": "d" }, "fg": "#FFFFFF", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "d", "sprite": "dog", "fg": "#FFFFFF", "order": 3 },
"flags": ["NEUTRAL"],
"level": 2,
"bac": 6,
@ -171,7 +171,7 @@
{
"id": "dog",
"name": "dog",
"renderable": { "glyph": "d", "sprite": { "id": "d" }, "fg": "#EEEEEE", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "d", "sprite": "dog", "fg": "#EEEEEE", "order": 3 },
"flags": [],
"level": 4,
"bac": 5,
@ -181,7 +181,7 @@
{
"id": "dog_large",
"name": "large dog",
"renderable": { "glyph": "d", "sprite": { "id": "d" }, "fg": "#DDDDDD", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "d", "sprite": "dog", "fg": "#DDDDDD", "order": 3 },
"flags": [],
"level": 6,
"bac": 4,
@ -191,7 +191,7 @@
{
"id": "gnome",
"name": "gnome",
"renderable": { "glyph": "G", "sprite": { "id": "g2" }, "fg": "#AA5500", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "G", "sprite": "gnome", "fg": "#AA5500", "order": 3 },
"flags": ["SMALL_GROUP", "IS_GNOME"],
"level": 1,
"speed": 6,
@ -201,7 +201,7 @@
{
"id": "zombie_gnome",
"name": "gnome zombie",
"renderable": { "glyph": "z", "sprite": { "id": "z" }, "fg": "#AA5500", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "z", "sprite": "gnome", "fg": "#AA5500", "order": 3 },
"flags": ["MINDLESS"],
"level": 1,
"speed": 6,
@ -212,7 +212,7 @@
{
"id": "goblin",
"name": "goblin",
"renderable": { "glyph": "g", "sprite": { "id": "g" }, "fg": "#00FF00", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "g", "sprite": "goblin", "fg": "#00FF00", "order": 3 },
"flags": [],
"level": 1,
"speed": 9,
@ -221,7 +221,7 @@
{
"id": "kobold",
"name": "kobold",
"renderable": { "glyph": "k", "sprite": { "id": "k" }, "fg": "#AA5500", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "k", "sprite": "kobold", "fg": "#AA5500", "order": 3 },
"flags": [],
"level": 1,
"speed": 6,
@ -231,7 +231,7 @@
{
"id": "zombie_kobold",
"name": "kobold zombie",
"renderable": { "glyph": "z", "sprite": { "id": "z" }, "fg": "#AA5500", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "z", "sprite": "kobold", "fg": "#AA5500", "order": 3 },
"flags": ["MINDLESS"],
"level": 1,
"speed": 6,
@ -242,7 +242,7 @@
{
"id": "kobold_large",
"name": "large kobold",
"renderable": { "glyph": "k", "sprite": { "id": "k" }, "fg": "#70461b", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "k", "sprite": "kobold_large", "fg": "#70461b", "order": 3 },
"flags": [],
"level": 1,
"speed": 6,
@ -253,7 +253,7 @@
{
"id": "zombie_orc",
"name": "orc zombie",
"renderable": { "glyph": "z", "sprite": { "id": "z" }, "fg": "#dbd830", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "z", "sprite": "orc", "fg": "#dbd830", "order": 3 },
"flags": ["MINDLESS"],
"level": 2,
"bac": 9,
@ -265,7 +265,7 @@
{
"id": "dwarf",
"name": "dwarf",
"renderable": { "glyph": "h", "sprite": { "id": "h" }, "fg": "#d61b1b", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "h", "sprite": "dwarf", "fg": "#d61b1b", "order": 3 },
"flags": ["IS_DWARF"],
"level": 2,
"bac": 10,
@ -277,7 +277,7 @@
{
"id": "zombie_dwarf",
"name": "dwarf zombie",
"renderable": { "glyph": "z", "sprite": { "id": "z" }, "fg": "#d61b1b", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "z", "sprite": "dwarf", "fg": "#d61b1b", "order": 3 },
"flags": ["MINDLESS"],
"level": 2,
"bac": 9,
@ -289,7 +289,7 @@
{
"id": "kobold_captain",
"name": "kobold captain",
"renderable": { "glyph": "k", "sprite": { "id": "k" }, "fg": "#9331ac", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "k", "sprite": "kobold_c", "fg": "#9331ac", "order": 3 },
"flags": [],
"level": 2,
"speed": 6,
@ -300,7 +300,7 @@
{
"id": "spider_cave",
"name": "cave spider",
"renderable": { "glyph": "s", "sprite": { "id": "s" }, "fg": "#6b6b6b", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "s", "sprite": "spider", "fg": "#6b6b6b", "order": 3 },
"flags": ["SMALL_GROUP"],
"level": 1,
"bac": 3,
@ -311,7 +311,7 @@
{
"id": "ant_worker",
"name": "worker ant",
"renderable": { "glyph": "a", "sprite": { "id": "a" }, "fg": "#ca7631", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "a", "sprite": "ant", "fg": "#ca7631", "order": 3 },
"flags": ["SMALL_GROUP"],
"level": 2,
"bac": 3,
@ -322,7 +322,7 @@
{
"id": "ant_soldier",
"name": "soldier ant",
"renderable": { "glyph": "a", "sprite": { "id": "a" }, "fg": "#ca3f26", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "a", "sprite": "ant", "fg": "#ca3f26", "order": 3 },
"flags": ["SMALL_GROUP", "POISON_RES"],
"level": 3,
"bac": 3,
@ -336,7 +336,7 @@
{
"id": "caterpillar_cave",
"name": "caterpillar",
"renderable": { "glyph": "a", "sprite": { "id": "a" }, "fg": "#6b6b6b", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "a", "sprite": "caterpillar", "fg": "#6b6b6b", "order": 3 },
"flags": ["SMALL_GROUP"],
"level": 1,
"bac": 3,
@ -347,7 +347,7 @@
{
"id": "caterpillar_giant",
"name": "giant caterpillar",
"renderable": { "glyph": "a", "sprite": { "id": "a" }, "fg": "#b9aeae", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "a", "sprite": "caterpillar", "fg": "#b9aeae", "order": 3 },
"flags": ["SMALL_GROUP"],
"level": 2,
"bac": 7,
@ -358,7 +358,7 @@
{
"id": "jackal",
"name": "jackal",
"renderable": { "glyph": "d", "sprite": { "id": "d" }, "fg": "#AA5500", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "d", "sprite": "dog", "fg": "#AA5500", "order": 3 },
"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": { "id": "d" }, "fg": "#FF0000", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "d", "sprite": "dog", "fg": "#FF0000", "order": 3 },
"flags": ["CARNIVORE"],
"bac": 7,
"attacks": [{ "name": "bites", "hit_bonus": 0, "damage": "1d3" }]
@ -374,7 +374,7 @@
{
"id": "coyote",
"name": "coyote",
"renderable": { "glyph": "d", "sprite": { "id": "d" }, "fg": "#6E3215", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "d", "sprite": "dog", "fg": "#6E3215", "order": 3 },
"flags": ["CARNIVORE", "SMALL_GROUP"],
"level": 1,
"bac": 7,
@ -383,7 +383,7 @@
{
"id": "wolf",
"name": "wolf",
"renderable": { "glyph": "d", "sprite": { "id": "d" }, "fg": "#5E4225", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "d", "sprite": "dog", "fg": "#5E4225", "order": 3 },
"flags": ["CARNIVORE"],
"level": 5,
"bac": 4,
@ -392,7 +392,7 @@
{
"id": "goblin_chieftain",
"name": "goblin chieftain",
"renderable": { "glyph": "g", "sprite": { "id": "g" }, "fg": "#9331ac", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "g", "sprite": "goblin_c", "fg": "#9331ac", "order": 3 },
"flags": [],
"level": 2,
"speed": 9,
@ -402,7 +402,7 @@
{
"id": "orc",
"name": "orc",
"renderable": { "glyph": "o", "sprite": { "id": "o" }, "fg": "#00FF00", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "o", "sprite": "orc", "fg": "#00FF00", "order": 3 },
"flags": ["SMALL_GROUP"],
"level": 1,
"speed": 9,
@ -412,7 +412,7 @@
{
"id": "orc_hill",
"name": "hill orc",
"renderable": { "glyph": "o", "sprite": { "id": "o" }, "fg": "#dbd830", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "o", "sprite": "orc", "fg": "#dbd830", "order": 3 },
"flags": ["LARGE_GROUP"],
"level": 2,
"speed": 9,
@ -422,7 +422,7 @@
{
"id": "orc_captain",
"name": "orc captain",
"renderable": { "glyph": "o", "sprite": { "id": "o" }, "fg": "#9331ac", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "o", "sprite": "orc", "fg": "#9331ac", "order": 3 },
"flags": ["MULTIATTACK"],
"level": 5,
"speed": 5,
@ -435,7 +435,7 @@
{
"id": "warg",
"name": "warg",
"renderable": { "glyph": "d", "sprite": { "id": "d" }, "fg": "#8b7164", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "d", "sprite": "dog", "fg": "#8b7164", "order": 3 },
"flags": ["SMALL_GROUP"],
"level": 7,
"bac": 4,
@ -446,7 +446,7 @@
{
"id": "jaguar",
"name": "jaguar",
"renderable": { "glyph": "f", "sprite": { "id": "f" }, "fg": "#d3b947", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "f", "sprite": "cat_large", "fg": "#d3b947", "order": 3 },
"flags": ["MULTIATTACK"],
"level": 4,
"bac": 6,
@ -461,7 +461,7 @@
{
"id": "lynx",
"name": "lynx",
"renderable": { "glyph": "f", "sprite": { "id": "f" }, "fg": "#b5d347", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "f", "sprite": "cat_large", "fg": "#b5d347", "order": 3 },
"flags": ["MULTIATTACK"],
"level": 5,
"bac": 6,
@ -476,7 +476,7 @@
{
"id": "panther",
"name": "panther",
"renderable": { "glyph": "f", "sprite": { "id": "f" }, "fg": "#58554e", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "f", "sprite": "cat_large", "fg": "#58554e", "order": 3 },
"flags": ["MULTIATTACK"],
"level": 5,
"bac": 6,
@ -491,7 +491,7 @@
{
"id": "ogre",
"name": "ogre",
"renderable": { "glyph": "O", "sprite": { "id": "o2" }, "fg": "#10A70d", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "O", "sprite": "ogre", "fg": "#10A70d", "order": 3 },
"flags": ["SMALL_GROUP"],
"level": 5,
"bac": 5,
@ -502,7 +502,7 @@
{
"id": "treant_small",
"name": "treant sapling",
"renderable": { "glyph": "♠️", "sprite": { "id": "spade" }, "fg": "#10570d", "bg": "#000000", "order": 3 },
"renderable": { "glyph": "♠️", "sprite": "gnome", "fg": "#10570d", "order": 3 },
"flags": ["LARGE_GROUP", "GREEN_BLOOD", "FIRE_WEAK"],
"level": 2,
"bac": 12,

View file

@ -2,89 +2,89 @@
{
"id": "door",
"name": "door",
"renderable": { "glyph": "+", "sprite": { "id": "door_wood_h_closed", "alt": "door_wood_h_open", "colour": false }, "fg": "#00FFFF", "bg": "#000000", "order": 5 },
"renderable": { "glyph": "+", "sprite": "door", "alt": "door_open", "fg": "#00FFFF", "order": 5 },
"door": { "open": false, "locked": false, "blocks_vis": true, "blocks_move": true }
},
{
"id": "trapdoor",
"name": "trapdoor",
"renderable": { "glyph": "+", "sprite": { "id": "trapdoor_closed", "alt": "trapdoor_open2", "colour": false, "alt_y": 1.0 }, "fg": "#00FFFF", "bg": "#000000", "order": 5, "alt_order": 1 },
"renderable": { "glyph": "+", "sprite": "trapdoor", "alt": "trapdoor_open", "fg": "#00FFFF", "order": 5, "alt_order": 1 },
"door": { "open": false, "locked": false, "blocks_vis": false, "blocks_move": false }
},
{
"id": "prop_altar",
"name": "altar",
"renderable": { "glyph": "_", "sprite": { "id": "tombstone", "colour": false }, "fg": "#FFFFFF", "bg": "#000000", "order": 5 },
"renderable": { "glyph": "_", "sprite": "altar", "fg": "#FFFFFF", "order": 5 },
"flags": ["ENTRY_TRIGGER"],
"effects": { "heal": "8d8" }
},
{
"id": "prop_keg",
"name": "keg",
"renderable": { "glyph": "φ", "fg": "#AAAAAA", "bg": "#000000", "order": 5 },
"renderable": { "glyph": "φ", "sprite": "gnome", "fg": "#AAAAAA", "order": 5 },
"flags": []
},
{
"id": "prop_table",
"name": "table",
"renderable": { "glyph": "-", "sprite": { "id": "table", "colour": false }, "fg": "#AAAAAA", "bg": "#000000", "order": 5 },
"renderable": { "glyph": "-", "sprite": "table", "fg": "#a76d3d", "order": 5 },
"flags": []
},
{
"id": "prop_hay",
"name": "hay",
"renderable": { "glyph": "%", "sprite": { "id": "%" }, "fg": "#c7ad39", "bg": "#000000", "order": 5 },
"renderable": { "glyph": "%", "sprite": "plants", "fg": "#e2b82f", "order": 5 },
"flags": []
},
{
"id": "prop_statue",
"name": "statue",
"renderable": { "glyph": "@", "sprite": { "id": "statue_warrior", "colour": false }, "fg": "#ffffff", "bg": "#000000", "order": 5 },
"renderable": { "glyph": "@", "sprite": "altar", "fg": "#ffffff", "order": 5 },
"flags": []
},
{
"id": "prop_bed",
"name": "bed",
"renderable": { "glyph": "=", "sprite": { "id": "bed", "colour": false }, "fg": "#AAAAAA", "bg": "#000000", "order": 5 },
"renderable": { "glyph": "=", "sprite": "bed", "fg": "#a55d33", "order": 5 },
"flags": []
},
{
"id": "prop_chair",
"name": "chair",
"renderable": { "glyph": "└", "sprite": { "id": "chair", "colour": false }, "fg": "#AAAAAA", "bg": "#000000", "order": 5 },
"renderable": { "glyph": "└", "sprite": "chair_r", "fg": "#a76d3d", "order": 5 },
"flags": []
},
{
"id": "prop_candle",
"name": "candle",
"renderable": { "glyph": "Ä", "sprite": { "id": "candles_a1", "colour": false }, "fg": "#FFA500", "bg": "#000000", "order": 4 },
"renderable": { "glyph": "Ä", "sprite": "candelabra", "fg": "#FFA500", "order": 4 },
"flags": []
},
{
"id": "trap_bear",
"name": "bear trap",
"renderable": { "glyph": "^", "sprite": { "id": "trap", "colour": false }, "fg": "#e6e6e6", "bg": "#000000", "order": 5 },
"renderable": { "glyph": "^", "sprite": "beartrap", "fg": "#e6e6e6", "order": 5 },
"flags": ["HIDDEN", "ENTRY_TRIGGER", "SINGLE_ACTIVATION"],
"effects": { "damage": "2d4" }
},
{
"id": "trap_mini_mine",
"name": "mini-mine",
"renderable": { "glyph": "^", "sprite": { "id": "^" }, "fg": "#ff1e00", "bg": "#000000", "order": 5 },
"renderable": { "glyph": "^", "sprite": "minimine", "fg": "#ff1e00", "order": 5 },
"flags": ["ENTRY_TRIGGER", "SINGLE_ACTIVATION"],
"effects": { "damage": "2d4", "aoe": "3" }
},
{
"id": "trap_stonefall",
"name": "stonefall trap",
"renderable": { "glyph": "^", "sprite": { "id": "^" }, "fg": "#beb5a7", "bg": "#000000", "order": 5 },
"renderable": { "glyph": "^", "sprite": "stones", "fg": "#beb5a7", "order": 5 },
"flags": ["HIDDEN", "ENTRY_TRIGGER", "SINGLE_ACTIVATION"],
"effects": { "damage": "2d10" }
},
{
"id": "trap_confusion",
"name": "magic trap",
"renderable": { "glyph": "^", "sprite": { "id": "magic_e1", "colour": false }, "fg": "#df07df", "bg": "#000000", "order": 5 },
"renderable": { "glyph": "^", "sprite": "magic_trap", "fg": "#df07df", "order": 5 },
"flags": ["HIDDEN", "ENTRY_TRIGGER", "SINGLE_ACTIVATION"],
"effects": { "confusion": "3" }
}

1596
resources/atlas.json Normal file

File diff suppressed because it is too large Load diff

BIN
resources/atlas.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View file

@ -83,8 +83,8 @@ impl<'a> System<'a> for TurnStatusSystem {
None,
EffectType::Particle {
glyph: to_cp437('!'),
sprite: "gnome".to_string(), // FIXME: REMOVE THE GNOMES
fg: RGB::named(LIGHT_BLUE),
bg: RGB::named(BLACK),
lifespan: 200.0,
delay: 0.0,
},
@ -113,8 +113,8 @@ impl<'a> System<'a> for TurnStatusSystem {
None,
EffectType::Particle {
glyph: to_cp437('?'),
sprite: "gnome".to_string(), // FIXME: REMOVE THE GNOMES
fg: RGB::named(MAGENTA),
bg: RGB::named(BLACK),
lifespan: 200.0,
delay: 0.0,
},

View file

@ -2,7 +2,7 @@ use super::{ Hidden, Map, Mind, Position, Prop, Renderable, Pools };
use bracket_lib::prelude::*;
use specs::prelude::*;
use std::ops::Mul;
use super::consts::visuals::{ VIEWPORT_W, VIEWPORT_H };
use super::consts::visuals::{ TILES_IN_VIEWPORT_H, TILES_IN_VIEWPORT_W };
use super::consts::prelude::*;
const SHOW_BOUNDARIES: bool = false;
@ -25,6 +25,28 @@ pub struct ScreenBounds {
pub y_offset: i32,
}
pub struct ScreenBoundsf32 {
pub min_x: f32,
pub max_x: f32,
pub min_y: f32,
pub max_y: f32,
pub x_offset: f32,
pub y_offset: f32,
}
impl ScreenBounds {
pub fn to_px(&self) -> ScreenBoundsf32 {
ScreenBoundsf32 {
min_x: (self.min_x as f32) * TILESIZE.sprite_x,
max_x: (self.max_x as f32) * TILESIZE.sprite_x,
min_y: (self.min_y as f32) * TILESIZE.sprite_y,
max_y: (self.max_y as f32) * TILESIZE.sprite_y,
x_offset: (self.x_offset as f32) * TILESIZE.x,
y_offset: (self.y_offset as f32) * TILESIZE.x,
}
}
}
pub fn get_screen_bounds(ecs: &World, debug: bool) -> ScreenBounds {
let map = ecs.fetch::<Map>();
let player_pos = if !debug {
@ -33,7 +55,12 @@ pub fn get_screen_bounds(ecs: &World, debug: bool) -> ScreenBounds {
Point::new(map.width / 2, map.height / 2)
};
let (x_chars, y_chars, mut x_offset, mut y_offset) = (VIEWPORT_W, VIEWPORT_H, 1, 10);
let (x_chars, y_chars, mut x_offset, mut y_offset) = (
TILES_IN_VIEWPORT_W,
TILES_IN_VIEWPORT_H,
1,
10,
);
let centre_x = (x_chars / 2) as i32;
let centre_y = (y_chars / 2) as i32;
@ -56,6 +83,8 @@ pub fn get_screen_bounds(ecs: &World, debug: bool) -> ScreenBounds {
ScreenBounds { min_x, max_x, min_y, max_y, x_offset, y_offset }
}
use crate::consts::TILESIZE;
pub fn in_bounds(x: i32, y: i32, min_x: i32, min_y: i32, upper_x: i32, upper_y: i32) -> bool {
x >= min_x && x < upper_x && y >= min_y && y < upper_y
}

View file

@ -38,57 +38,17 @@ pub struct OtherLevelPosition {
pub id: i32,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct SpriteInfo {
pub id: String,
pub recolour: bool,
pub alt: Option<String>,
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),
}
}
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(Debug, Component, ConvertSaveload, Clone)]
pub struct Renderable {
pub glyph: FontCharType,
pub sprite: Option<SpriteInfo>,
pub glyph: FontCharType, // Legacy, and for drawing the morgue map.
pub sprite: String,
pub sprite_alt: Option<String>,
pub fg: RGB,
pub bg: RGB,
pub fg_alt: Option<RGB>,
pub render_order: i32,
pub alt_render_order: Option<i32>,
pub render_order_alt: Option<i32>,
pub offset: (f32, f32),
pub offset_alt: Option<(f32, f32)>,
// 0 = always on top: particle effects
// 1 = things that should appear infront of the player: railings, etc.
// 2 = the player
@ -98,16 +58,25 @@ pub struct Renderable {
}
impl Renderable {
pub fn new(glyph: FontCharType, sprite: String, fg: RGB, render_order: i32) -> Self {
Self {
glyph,
sprite,
sprite_alt: None,
fg,
fg_alt: None,
render_order,
render_order_alt: None,
offset: (0.0, 0.0),
offset_alt: None,
}
}
pub fn swap(&mut self) {
let mut did_something = false;
if let Some(alt_render_order) = &mut self.alt_render_order {
std::mem::swap(&mut self.render_order, alt_render_order);
did_something = true;
}
if let Some(sprite) = &mut self.sprite {
*sprite = sprite.swap();
did_something = true;
}
let sprite = self.swap_sprite();
let fg = self.swap_fg();
let render_order = self.swap_render_order();
let offset = self.swap_offset();
let did_something = sprite || fg || render_order || offset;
if !did_something {
unreachable!(
".swap() was called on a Renderable component, but nothing happened. {:?}",
@ -115,6 +84,34 @@ impl Renderable {
);
}
}
pub fn swap_sprite(&mut self) -> bool {
if let Some(sprite_alt) = &mut self.sprite_alt {
std::mem::swap(&mut self.sprite, sprite_alt);
return true;
}
false
}
pub fn swap_fg(&mut self) -> bool {
if let Some(fg_alt) = &mut self.fg_alt {
std::mem::swap(&mut self.fg, fg_alt);
return true;
}
false
}
pub fn swap_render_order(&mut self) -> bool {
if let Some(render_order_alt) = &mut self.render_order_alt {
std::mem::swap(&mut self.render_order, render_order_alt);
return true;
}
false
}
pub fn swap_offset(&mut self) -> bool {
if let Some(offset_alt) = &mut self.offset_alt {
std::mem::swap(&mut self.offset, offset_alt);
return true;
}
false
}
}
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
@ -793,7 +790,9 @@ pub struct Charges {
#[derive(Component, Serialize, Deserialize, Clone)]
pub struct SpawnParticleLine {
pub glyph: FontCharType,
pub sprite: String,
pub tail_glyph: FontCharType,
pub tail_sprite: String,
pub colour: RGB,
pub lifetime_ms: f32,
pub trail_colour: RGB,
@ -803,6 +802,7 @@ pub struct SpawnParticleLine {
#[derive(Component, Serialize, Deserialize, Clone)]
pub struct SpawnParticleSimple {
pub glyph: FontCharType,
pub sprite: String,
pub colour: RGB,
pub lifetime_ms: f32,
}
@ -810,8 +810,11 @@ pub struct SpawnParticleSimple {
#[derive(Component, Serialize, Deserialize, Clone)]
pub struct SpawnParticleBurst {
pub glyph: FontCharType,
pub sprite: String,
pub head_glyph: FontCharType,
pub head_sprite: String,
pub tail_glyph: FontCharType,
pub tail_sprite: String,
pub colour: RGB,
pub lerp: RGB,
pub lifetime_ms: f32,

View file

@ -12,7 +12,20 @@ pub mod prelude {
pub use super::visuals::{ VIEWPORT_H, VIEWPORT_W };
}
pub const TILESIZE: f32 = 16.0;
pub struct Spritesize {
pub x: f32,
pub y: f32,
pub sprite_x: f32,
pub sprite_y: f32,
}
pub const TILESIZE: Spritesize = Spritesize {
x: 16.0,
y: 24.0,
sprite_x: 16.0 * ZOOM_FACTOR,
sprite_y: 24.0 * ZOOM_FACTOR,
};
pub const ZOOM_FACTOR: f32 = 2.0;
pub const FONTSIZE: f32 = 16.0;
pub const DISPLAYWIDTH: u32 = 100;
pub const DISPLAYHEIGHT: u32 = 56;
pub const DISPLAYHEIGHT: u32 = 57;

View file

@ -1,9 +1,17 @@
use bracket_lib::prelude::*;
use super::ZOOM_FACTOR;
// POST-PROCESSING
pub const WITH_DARKEN_BY_DISTANCE: bool = true; // If further away tiles should get darkened, instead of a harsh transition to non-visible.
pub const VIEWPORT_W: i32 = 69;
pub const VIEWPORT_H: i32 = 41;
// Counted in 16x16 tiles, because that's how most of the screen is drawn. However,
// the viewport itself uses 16x24 sprites - so this translates to 70x28 tiles drawn.
// It also works nicely for zooming in, displaying 35x14 tiles cleanly onscreen.
pub const VIEWPORT_W: i32 = 70;
pub const VIEWPORT_H: i32 = 42;
pub const TILES_IN_VIEWPORT_W: i32 = 70 / (ZOOM_FACTOR as i32);
pub const TILES_IN_VIEWPORT_H: i32 = 28 / (ZOOM_FACTOR as i32);
pub const TILE_LAYER: usize = 1;
pub const ENTITY_LAYER: usize = 2;

View file

@ -49,8 +49,8 @@ pub fn inflict_damage(ecs: &mut World, damage: &EffectSpawner, target: Entity) {
None,
EffectType::Particle {
glyph: to_cp437('‼'),
sprite: "gnome".to_string(), // FIXME: REMOVE THE GNOMES
fg: RGB::named(ORANGE),
bg: RGB::named(BLACK),
lifespan: DEFAULT_PARTICLE_LIFETIME,
delay: 0.0,
},
@ -83,10 +83,10 @@ pub fn heal_damage(ecs: &mut World, heal: &EffectSpawner, target: Entity) {
}
add_effect(
None,
EffectType::Particle {
EffectType::Particle { // GNOMES
glyph: to_cp437('♥'),
sprite: "gnome".to_string(),
fg: RGB::named(BLUE),
bg: RGB::named(BLACK),
lifespan: DEFAULT_PARTICLE_LIFETIME,
delay: 0.0,
},
@ -266,11 +266,11 @@ pub fn entity_death(ecs: &mut World, effect: &EffectSpawner, target: Entity) {
for i in 0..5 {
if player_pos.y - i > 1 {
add_effect(
None,
None, // FIXME: REMOVE THE GNOMES
EffectType::Particle {
glyph: to_cp437('░'),
sprite: "gnome".to_string(),
fg: RGB::named(GOLD),
bg: RGB::named(BLACK),
lifespan: LONG_PARTICLE_LIFETIME,
delay: (i as f32) * 100.0,
},
@ -281,8 +281,8 @@ pub fn entity_death(ecs: &mut World, effect: &EffectSpawner, target: Entity) {
None,
EffectType::Particle {
glyph: to_cp437('░'),
sprite: "gnome".to_string(),
fg: RGB::named(GOLD),
bg: RGB::named(BLACK),
lifespan: LONG_PARTICLE_LIFETIME,
delay: (i as f32) * 100.0,
},
@ -297,8 +297,8 @@ pub fn entity_death(ecs: &mut World, effect: &EffectSpawner, target: Entity) {
None,
EffectType::Particle {
glyph: to_cp437('░'),
sprite: "gnome".to_string(),
fg: RGB::named(GOLD),
bg: RGB::named(BLACK),
lifespan: LONG_PARTICLE_LIFETIME,
delay: (i as f32) * 100.0,
},

View file

@ -45,8 +45,8 @@ pub enum EffectType {
},
Particle {
glyph: FontCharType,
sprite: String,
fg: RGB,
bg: RGB,
lifespan: f32,
delay: f32,
},

View file

@ -4,27 +4,27 @@ use bracket_lib::prelude::*;
use specs::prelude::*;
pub fn particle_to_tile(ecs: &mut World, target: i32, effect: &EffectSpawner) {
if let EffectType::Particle { glyph, fg, bg, lifespan, delay } = effect.effect_type {
if let EffectType::Particle { glyph, sprite, fg, lifespan, delay } = &effect.effect_type {
let map = ecs.fetch::<Map>();
let mut particle_builder = ecs.fetch_mut::<ParticleBuilder>();
if delay <= 0.0 {
if delay <= &0.0 {
particle_builder.request(
target % map.width,
target / map.width,
fg,
bg,
glyph,
lifespan
*fg,
*glyph,
sprite.clone(),
*lifespan
);
} else {
particle_builder.delay(
target % map.width,
target / map.width,
fg,
bg,
glyph,
lifespan,
delay
*fg,
*glyph,
sprite.clone(),
*lifespan,
*delay
);
}
}
@ -36,8 +36,8 @@ pub fn handle_simple_particles(ecs: &World, entity: Entity, target: &Targets) {
None,
EffectType::Particle {
glyph: part.glyph,
sprite: part.sprite.clone(),
fg: part.colour,
bg: RGB::named(BLACK),
lifespan: part.lifetime_ms,
delay: 0.0,
},
@ -56,7 +56,9 @@ pub fn handle_burst_particles(ecs: &World, entity: Entity, target: &Targets) {
end_pos,
&(SpawnParticleLine {
glyph: part.head_glyph,
sprite: part.head_sprite.clone(),
tail_glyph: part.tail_glyph,
tail_sprite: part.tail_sprite.clone(),
colour: part.colour,
trail_colour: part.trail_colour,
lifetime_ms: part.trail_lifetime_ms, // 75.0 is good here.
@ -75,8 +77,8 @@ pub fn handle_burst_particles(ecs: &World, entity: Entity, target: &Targets) {
None,
EffectType::Particle {
glyph: part.glyph,
sprite: part.sprite.clone(),
fg: part.colour.lerp(part.lerp, (i as f32) * 0.1),
bg: RGB::named(BLACK),
lifespan: part.lifetime_ms / 10.0, // ~50-80 is good here.
delay: burst_delay + ((i as f32) * part.lifetime_ms) / 10.0, // above + burst_delay
},
@ -163,8 +165,8 @@ fn spawn_line_particles(ecs: &World, start: i32, end: i32, part: &SpawnParticleL
None,
EffectType::Particle {
glyph: part.glyph,
sprite: part.sprite.clone(),
fg: part.colour,
bg: RGB::named(BLACK),
lifespan: part.lifetime_ms,
delay: (i as f32) * part.lifetime_ms,
},
@ -175,8 +177,8 @@ fn spawn_line_particles(ecs: &World, start: i32, end: i32, part: &SpawnParticleL
None,
EffectType::Particle {
glyph: part.tail_glyph,
sprite: part.tail_sprite.clone(),
fg: part.trail_colour,
bg: RGB::named(BLACK),
lifespan: part.trail_lifetime_ms,
delay: (i as f32) * part.lifetime_ms,
},

View file

@ -18,8 +18,8 @@ pub fn render(draw: bool, gfx: &mut Graphics, font: &Fonts) {
render_log(
gfx,
&font,
&(TILESIZE, TILESIZE * 8.0 + 4.0),
(VIEWPORT_W as f32) * TILESIZE,
&(TILESIZE.x, TILESIZE.x * 8.0 + 4.0),
(VIEWPORT_W as f32) * TILESIZE.x,
7
);
}

View file

@ -118,8 +118,8 @@ pub enum CharCreateResult {
}
use notan::prelude::*;
use notan::draw::{ Draw, CreateDraw, DrawTextSection, Font };
use super::{ FONTSIZE, DISPLAYWIDTH, TILESIZE, MainMenuSelection };
use notan::draw::{ Draw, DrawTextSection };
use super::{ FONTSIZE, TILESIZE };
use crate::consts::DISPLAYHEIGHT;
use crate::Fonts;
@ -134,8 +134,8 @@ pub fn draw_charcreation(
RunState::CharacterCreation { class, ancestry } => (class, ancestry),
_ => unreachable!("draw_charcreation() called outside of CharacterCreation runstate."),
};
let (mut x, mut y) = (2.0 * TILESIZE, ((DISPLAYHEIGHT as f32) * TILESIZE) / 4.0);
const COLUMN_WIDTH: f32 = 20.0 * TILESIZE;
let (mut x, mut y) = (2.0 * TILESIZE.x, ((DISPLAYHEIGHT as f32) * TILESIZE.x) / 4.0);
const COLUMN_WIDTH: f32 = 20.0 * TILESIZE.x;
draw.text(&font.ib(), "Who are you?")
.size(FONTSIZE * 2.0)
.position(x, y)
@ -178,7 +178,7 @@ pub fn draw_charcreation(
draw.text(font.n(), line).size(FONTSIZE).position(x, y).h_align_left();
y = draw.last_text_bounds().max_y();
}
y += TILESIZE;
y += TILESIZE.x;
for line in CLASSDATA.get(&class).unwrap().iter() {
draw.text(font.n(), line).size(FONTSIZE).position(x, y).h_align_left();
y = draw.last_text_bounds().max_y();
@ -256,27 +256,29 @@ pub fn setup_player_ancestry(ecs: &mut World, ancestry: Ancestry) {
Ancestry::Human => {}
Ancestry::Dwarf => {
renderables
.insert(*player, Renderable {
glyph: to_cp437(DWARF_GLYPH),
sprite: None, // TODO: Dwarf sprite
fg: RGB::named(DWARF_COLOUR),
bg: RGB::named(BLACK),
render_order: 0,
alt_render_order: None,
})
.insert(
*player,
Renderable::new(
to_cp437(DWARF_GLYPH),
"gnome".to_string(),
RGB::named(DWARF_COLOUR),
2
)
)
.expect("Unable to insert renderable component");
*player_skills.skills.entry(Skill::Defence).or_insert(0) += DWARF_DEFENCE_MOD;
}
Ancestry::Elf => {
renderables
.insert(*player, Renderable {
glyph: to_cp437(ELF_GLYPH),
sprite: None, // TODO: Elf sprite
fg: RGB::named(ELF_COLOUR),
bg: RGB::named(BLACK),
render_order: 0,
alt_render_order: None,
})
.insert(
*player,
Renderable::new(
to_cp437(ELF_GLYPH),
"gnome".to_string(),
RGB::named(ELF_COLOUR),
2
)
)
.expect("Unable to insert renderable component");
let mut telepaths = ecs.write_storage::<Telepath>();
telepaths
@ -296,14 +298,15 @@ pub fn setup_player_ancestry(ecs: &mut World, ancestry: Ancestry) {
}
Ancestry::Catfolk => {
renderables
.insert(*player, Renderable {
glyph: to_cp437(CATFOLK_GLYPH),
sprite: None, // TODO: Catfolk sprite
fg: RGB::named(CATFOLK_COLOUR),
bg: RGB::named(BLACK),
render_order: 0,
alt_render_order: None,
})
.insert(
*player,
Renderable::new(
to_cp437(CATFOLK_GLYPH),
"gnome".to_string(),
RGB::named(CATFOLK_COLOUR),
2
)
)
.expect("Unable to insert renderable component");
let mut speeds = ecs.write_storage::<Energy>();
speeds

View file

@ -59,7 +59,7 @@ pub fn draw_cheat_menu(
m - MAGIC MAP REVEAL
g - GOD MODE"#;
draw.text(&font.n(), DEBUG_MENU)
.position((1.0 + (offsets.x as f32)) * TILESIZE, (1.0 + (offsets.y as f32)) * TILESIZE)
.position((1.0 + (offsets.x as f32)) * TILESIZE.x, (1.0 + (offsets.y as f32)) * TILESIZE.x)
.color(Color::RED)
.size(FONTSIZE);
}

View file

@ -63,7 +63,7 @@ pub fn show_farlook(gs: &mut State, ctx: &mut App) -> FarlookResult {
pub fn draw_farlook(x: i32, y: i32, draw: &mut Draw, atlas: &HashMap<String, Texture>) {
draw.image(atlas.get("ui_select_c1").unwrap()).position(
(x as f32) * TILESIZE,
(y as f32) * TILESIZE
(x as f32) * TILESIZE.x,
(y as f32) * TILESIZE.x
);
}

View file

@ -47,8 +47,8 @@ pub fn draw_items(
continue;
}
draw.text(&font.b(), itemtype.string()).position(x, y).color(Color::WHITE);
y += TILESIZE;
y = print_options(ecs, draw, font, &inv, x, y) + TILESIZE;
y += TILESIZE.x;
y = print_options(ecs, draw, font, &inv, x, y) + TILESIZE.x;
}
} else {
let filter = match loc {
@ -60,7 +60,7 @@ pub fn draw_items(
if inv.is_empty() {
return;
}
y = print_options(ecs, draw, font, &inv, x, y) + TILESIZE;
y = print_options(ecs, draw, font, &inv, x, y) + TILESIZE.x;
}
}

View file

@ -13,9 +13,9 @@ pub fn draw_mainmenu(ecs: &World, draw: &mut Draw, atlas: &HashMap<String, Textu
_ => unreachable!("draw_mainmenu() called outside of MainMenu runstate."),
};
let save_exists = crate::saveload_system::does_save_exist();
const MID_X: f32 = ((DISPLAYWIDTH as f32) * TILESIZE) / 2.0;
const MID_X: f32 = ((DISPLAYWIDTH as f32) * TILESIZE.x) / 2.0;
let (x, mut y) = (MID_X, ((DISPLAYHEIGHT as f32) * TILESIZE) / 4.0);
let (x, mut y) = (MID_X, ((DISPLAYHEIGHT as f32) * TILESIZE.x) / 4.0);
draw.text(&font.ib(), "RUST-RL")
.size(FONTSIZE * 2.0)
.position(x, y)

View file

@ -142,7 +142,7 @@ fn draw_bar_sprite(
} else {
panic!("No sprite found in atlas: {}_{}_{}", sprite, fill, suffix)
};
draw.image(sprite).position(sx + (x as f32) * TILESIZE, y);
draw.image(sprite).position(sx + (x as f32) * TILESIZE.x, y);
}
}
@ -160,10 +160,10 @@ pub fn draw_bar(
empty: Color
) {
let fill: f32 = (f32::max(current as f32, 0.0) / (max as f32)) * width;
draw.line((x * TILESIZE, y * TILESIZE), ((x + fill) * TILESIZE, y * TILESIZE))
draw.line((x * TILESIZE.x, y * TILESIZE.x), ((x + fill) * TILESIZE.x, y * TILESIZE.x))
.color(full)
.width(height);
draw.line(((x + fill) * TILESIZE, y * TILESIZE), ((x + width) * TILESIZE, y * TILESIZE))
draw.line(((x + fill) * TILESIZE.x, y * TILESIZE.x), ((x + width) * TILESIZE.x, y * TILESIZE.x))
.color(empty)
.width(height);
}
@ -187,9 +187,9 @@ pub fn draw_ui2(ecs: &World, draw: &mut Draw, atlas: &HashMap<String, Texture>,
draw_bar(
draw,
BAR_X,
53.5,
54.5,
BAR_WIDTH,
TILESIZE,
TILESIZE.x,
stats.hit_points.current,
stats.hit_points.max,
Color::GREEN,
@ -198,18 +198,18 @@ pub fn draw_ui2(ecs: &World, draw: &mut Draw, atlas: &HashMap<String, Texture>,
draw_bar(
draw,
BAR_X,
54.5,
55.5,
BAR_WIDTH,
TILESIZE,
TILESIZE.x,
stats.mana.current,
stats.mana.max,
Color::BLUE,
Color::BLACK
);
let initial_x = 24.0 * TILESIZE;
let initial_x = 24.0 * TILESIZE.x;
let mut x = initial_x;
let row1 = 53.0 * TILESIZE;
let row2 = row1 + TILESIZE;
let row1 = 54.0 * TILESIZE.x;
let row2 = row1 + TILESIZE.x;
let hp_colours: (RGB, RGB, RGB) = (
RGB::named(GREEN),
RGB::named(RED),
@ -262,7 +262,7 @@ pub fn draw_ui2(ecs: &World, draw: &mut Draw, atlas: &HashMap<String, Texture>,
armour_ac_bonus += ac.amount;
}
}
x = draw.last_text_bounds().max_x() + 2.0 * TILESIZE;
x = draw.last_text_bounds().max_x() + 2.0 * TILESIZE.x;
let armour_class =
stats.bac - attributes.dexterity.modifier() / 2 - skill_ac_bonus - armour_ac_bonus;
draw.text(&font.b(), "AC").position(x, row1).color(Color::PINK).size(FONTSIZE);
@ -273,19 +273,19 @@ pub fn draw_ui2(ecs: &World, draw: &mut Draw, atlas: &HashMap<String, Texture>,
draw.text(&font.n(), &format!("{}/{}", stats.level, stats.xp))
.position(last_x, row2)
.size(FONTSIZE);
let attribute_x = draw.last_text_bounds().max_x() + 2.0 * TILESIZE;
let attribute_x = draw.last_text_bounds().max_x() + 2.0 * TILESIZE.x;
draw.text(&font.b(), "STR").position(attribute_x, row1).color(Color::RED).size(FONTSIZE);
x = draw.last_text_bounds().max_x();
draw.text(&font.n(), &format!("{:<2}", attributes.strength.base))
.position(x, row1)
.size(FONTSIZE);
x = draw.last_text_bounds().max_x() + TILESIZE;
x = draw.last_text_bounds().max_x() + TILESIZE.x;
draw.text(&font.b(), "DEX").position(x, row1).color(Color::GREEN).size(FONTSIZE);
x = draw.last_text_bounds().max_x();
draw.text(&font.n(), &format!("{:<2}", attributes.dexterity.base))
.position(x, row1)
.size(FONTSIZE);
x = draw.last_text_bounds().max_x() + TILESIZE;
x = draw.last_text_bounds().max_x() + TILESIZE.x;
draw.text(&font.b(), "CON").position(x, row1).color(Color::ORANGE).size(FONTSIZE);
x = draw.last_text_bounds().max_x();
draw.text(&font.n(), &format!("{:<2}", attributes.constitution.base))
@ -296,13 +296,13 @@ pub fn draw_ui2(ecs: &World, draw: &mut Draw, atlas: &HashMap<String, Texture>,
draw.text(&font.n(), &format!("{:<2}", attributes.intelligence.base))
.position(x, row2)
.size(FONTSIZE);
x = draw.last_text_bounds().max_x() + TILESIZE;
x = draw.last_text_bounds().max_x() + TILESIZE.x;
draw.text(&font.b(), "WIS").position(x, row2).color(Color::YELLOW).size(FONTSIZE);
x = draw.last_text_bounds().max_x();
draw.text(&font.n(), &format!("{:<2}", attributes.wisdom.base))
.position(x, row2)
.size(FONTSIZE);
x = draw.last_text_bounds().max_x() + TILESIZE;
x = draw.last_text_bounds().max_x() + TILESIZE.x;
draw.text(&font.b(), "CHA").position(x, row2).color(Color::PURPLE).size(FONTSIZE);
x = draw.last_text_bounds().max_x();
draw.text(&font.n(), &format!("{:<2}", attributes.charisma.base))
@ -321,7 +321,7 @@ pub fn draw_ui2(ecs: &World, draw: &mut Draw, atlas: &HashMap<String, Texture>,
_ => {
let col = get_hunger_colour(hunger.state);
draw.text(&font.n(), hungertxt)
.position(((VIEWPORT_W + 1) as f32) * TILESIZE, row1)
.position(((VIEWPORT_W + 1) as f32) * TILESIZE.x, row1)
.color(Color::from_bytes(col.0, col.1, col.2, 255))
.size(FONTSIZE)
.h_align_right();
@ -334,12 +334,12 @@ pub fn draw_ui2(ecs: &World, draw: &mut Draw, atlas: &HashMap<String, Texture>,
format!("{}", map.short_name)
};
draw.text(&font.n(), &id)
.position(((VIEWPORT_W + 1) as f32) * TILESIZE, row2)
.position(((VIEWPORT_W + 1) as f32) * TILESIZE.x, row2)
.color(Color::WHITE) // get_local_col()
.size(FONTSIZE)
.h_align_right();
let turns = crate::gamelog::get_event_count(EVENT::COUNT_TURN);
x = draw.last_text_bounds().min_x() - TILESIZE;
x = draw.last_text_bounds().min_x() - TILESIZE.x;
draw.text(&font.n(), &format!("T{}", turns))
.position(x, row2)
.color(Color::YELLOW)
@ -353,19 +353,19 @@ pub fn draw_ui2(ecs: &World, draw: &mut Draw, atlas: &HashMap<String, Texture>,
BurdenLevel::Overloaded => ("Overloaded", RGB::named(RED)),
};
draw.text(&font.n(), &text)
.position((VIEWPORT_W as f32) * TILESIZE, 50.0 * TILESIZE)
.position((VIEWPORT_W as f32) * TILESIZE.x, 50.0 * TILESIZE.x)
.color(Color::from_rgb(colour.r, colour.g, colour.b))
.size(FONTSIZE)
.h_align_right();
}
if stats.god {
draw.text(&font.n(), "--- GODMODE: ON ---")
.position(20.0 * TILESIZE, 20.0 * TILESIZE)
.position(20.0 * TILESIZE.x, 20.0 * TILESIZE.x)
.color(Color::YELLOW)
.size(FONTSIZE);
}
// Equipment
draw_all_items(ecs, draw, font, ((VIEWPORT_W + 3) as f32) * TILESIZE, TILESIZE);
draw_all_items(ecs, draw, font, ((VIEWPORT_W + 3) as f32) * TILESIZE.x, TILESIZE.x);
/*let renderables = ecs.read_storage::<Renderable>();
let mut equipment: Vec<(String, RGB, RGB, FontCharType)> = Vec::new();
let entities = ecs.entities();
@ -383,40 +383,40 @@ pub fn draw_ui2(ecs: &World, draw: &mut Draw, atlas: &HashMap<String, Texture>,
// TODO: Fix all of this to work with notan colours, and sprites.
if !equipment.is_empty() {
draw.text(&font.b(), "Equipment")
.position(((VIEWPORT_W + 3) as f32) * TILESIZE, (y as f32) * TILESIZE)
.position(((VIEWPORT_W + 3) as f32) * TILESIZE.x, (y as f32) * TILESIZE.x)
.size(FONTSIZE);
let mut j: u8 = 0;
for item in equipment {
y += 1;
x = ((VIEWPORT_W + 3) as f32) * TILESIZE;
x = ((VIEWPORT_W + 3) as f32) * TILESIZE.x;
draw.text(&font.b(), &format!("{} ", (97 + j) as char))
.position(x, (y as f32) * TILESIZE)
.position(x, (y as f32) * TILESIZE.x)
.color(Color::YELLOW)
.size(FONTSIZE);
j += 1;
x = draw.last_text_bounds().max_x();
let mut col = item.2;
draw.text(&font.n(), &format!("{} ", item.3 as u8 as char))
.position(x, (y as f32) * TILESIZE)
.position(x, (y as f32) * TILESIZE.x)
.size(FONTSIZE)
.color(Color::from_rgb(col.r, col.g, col.b)); // Colours here - and below.
x = draw.last_text_bounds().max_x();
col = item.1;
draw.text(&font.n(), &item.0)
.position(x, (y as f32) * TILESIZE)
.position(x, (y as f32) * TILESIZE.x)
.size(FONTSIZE)
.color(Color::from_rgb(col.r, col.g, col.b));
x = draw.last_text_bounds().max_x();
draw.text(&font.n(), " (worn)")
.position(x, (y as f32) * TILESIZE)
.position(x, (y as f32) * TILESIZE.x)
.size(FONTSIZE);
}
y += 2;
}
// Backpack
x = ((VIEWPORT_W + 3) as f32) * TILESIZE;
x = ((VIEWPORT_W + 3) as f32) * TILESIZE.x;
draw.text(&font.b(), "Backpack")
.position(x, (y as f32) * TILESIZE)
.position(x, (y as f32) * TILESIZE.x)
.size(FONTSIZE);
draw.text(
&font.b(),
@ -427,7 +427,7 @@ pub fn draw_ui2(ecs: &World, draw: &mut Draw, atlas: &HashMap<String, Texture>,
CARRY_CAPACITY_PER_STRENGTH
)
)
.position(((DISPLAYWIDTH - 1) as f32) * TILESIZE, (y as f32) * TILESIZE)
.position(((DISPLAYWIDTH - 1) as f32) * TILESIZE.x, (y as f32) * TILESIZE.x)
.size(FONTSIZE)
.h_align_right();*/
//let player_inventory = get_player_inventory(&ecs);
@ -987,7 +987,7 @@ pub fn print_options(
.size(FONTSIZE);
};
}
y += TILESIZE;
y += TILESIZE.x;
}
return y;
}
@ -1651,7 +1651,7 @@ pub fn draw_targeting(
}
for (k, v) in needs_draw {
let pos = ((k.x as f32) * TILESIZE, (k.y as f32) * TILESIZE);
let pos = ((k.x as f32) * TILESIZE.x, (k.y as f32) * TILESIZE.x);
let tex = atlas.get("217").unwrap();
if (v & CURSOR_UNAVAILABLE) != 0 {
draw.image(tex).position(pos.0, pos.1).alpha(0.5).color(Color::RED);

View file

@ -12,7 +12,7 @@ use crate::states::state::Fonts;
#[notan_main]
fn main() -> Result<(), String> {
let win_config = WindowConfig::new()
.set_size(DISPLAYWIDTH * (TILESIZE as u32), DISPLAYHEIGHT * (TILESIZE as u32))
.set_size(DISPLAYWIDTH * (TILESIZE.x as u32), DISPLAYHEIGHT * (TILESIZE.x as u32))
.set_title("RUST-RL")
.set_resizable(false)
.set_taskbar_icon_data(Some(include_bytes!("../resources/icon.png")))
@ -27,13 +27,20 @@ fn main() -> Result<(), String> {
}
fn setup(gfx: &mut Graphics) -> State {
let texture = gfx
.create_texture()
.from_image(include_bytes!("../resources/atlas.png"))
.build()
.unwrap();
let data = include_bytes!("../resources/atlas.json");
let atlas = create_textures_from_atlas(data, &texture).unwrap();
let texture = gfx
.create_texture()
.from_image(include_bytes!("../resources/td.png"))
.build()
.unwrap();
let data = include_bytes!("../resources/td.json");
let atlas = create_textures_from_atlas(data, &texture).unwrap();
let interface = create_textures_from_atlas(data, &texture).unwrap();
let font = Fonts::new(
gfx.create_font(include_bytes!("../resources/fonts/Greybeard-16px.ttf")).unwrap(),
Some(
@ -45,8 +52,8 @@ fn setup(gfx: &mut Graphics) -> State {
);
let mut gs = State {
ecs: World::new(),
base_texture: texture,
atlas,
interface,
font,
mapgen_next_state: Some(RunState::MainMenu {
menu_selection: gui::MainMenuSelection::NewGame,
@ -192,6 +199,9 @@ fn draw_entities(
) {
{
let bounds = crate::camera::get_screen_bounds(ecs, false);
let bounds_to_px = bounds.to_px();
let offset_x = bounds_to_px.x_offset - bounds_to_px.min_x;
let offset_y = bounds_to_px.y_offset - bounds_to_px.min_y;
let positions = ecs.read_storage::<Position>();
let renderables = ecs.read_storage::<Renderable>();
let hidden = ecs.read_storage::<Hidden>();
@ -202,8 +212,6 @@ fn draw_entities(
let mut to_draw: HashMap<DrawKey, DrawInfo> = HashMap::new();
for (pos, render, e, _h) in data.iter() {
let idx = map.xy_idx(pos.x, pos.y);
let offset_x = pos.x - bounds.min_x + bounds.x_offset;
let offset_y = pos.y - bounds.min_y + bounds.y_offset;
if
crate::camera::in_bounds(
pos.x,
@ -236,7 +244,7 @@ fn draw_entities(
DrawType::None => {}
_ => {
to_draw.insert(
DrawKey { x: offset_x, y: offset_y, render_order: render.render_order },
DrawKey { x: pos.x, y: pos.y, render_order: render.render_order },
DrawInfo { e: *e, draw_type }
);
}
@ -250,25 +258,14 @@ fn draw_entities(
match entry.1.draw_type {
DrawType::Visible | DrawType::Telepathy => {
let renderable = renderables.get(entry.1.e).unwrap();
if let Some(spriteinfo) = &renderable.sprite {
let id = if let Some(sprite) = atlas.get(&spriteinfo.id) {
let id = if let Some(sprite) = atlas.get(&renderable.sprite) {
sprite
} else {
panic!("No entity sprite found for ID: {}", spriteinfo.id);
panic!("No entity sprite found for ID: {}", &renderable.sprite);
};
draw.image(id)
.position(
((entry.0.x as f32) + spriteinfo.offset.0) * TILESIZE,
((entry.0.y as f32) + spriteinfo.offset.1) * TILESIZE
)
.color(
if spriteinfo.recolour {
Color::from_rgb(
renderable.fg.r,
renderable.fg.g,
renderable.fg.b
)
} else {
console::log(&format!("offset_x: {}, offset_y: {}", offset_x, offset_y));
let x_pos = (entry.0.x as f32) * TILESIZE.sprite_x + offset_x;
let y_pos = (entry.0.y as f32) * TILESIZE.sprite_y + offset_y;
let mul = themes::darken_by_distance(
Point::new(
entry.0.x + bounds.min_x - bounds.x_offset,
@ -276,15 +273,24 @@ fn draw_entities(
),
*ecs.fetch::<Point>()
);
Color::from_rgb(mul, mul, mul)
}
let col = Color::from_rgb(
renderable.fg.r * mul,
renderable.fg.g * mul,
renderable.fg.b * mul
);
draw.image(id)
.position(
x_pos + renderable.offset.0 * TILESIZE.sprite_x,
y_pos + renderable.offset.1 * TILESIZE.sprite_y
)
.color(col)
.size(TILESIZE.sprite_x, TILESIZE.sprite_y);
if let Some(pool) = pools.get(entry.1.e) {
if pool.hit_points.current < pool.hit_points.max {
gui::draw_bar(
draw,
entry.0.x as f32,
entry.0.y as f32,
x_pos,
y_pos,
1.0,
1.0,
pool.hit_points.current,
@ -294,23 +300,6 @@ fn draw_entities(
);
}
}
} else {
// Fallback to drawing text.
draw.text(
&font.b(),
&format!("{}", bracket_lib::terminal::to_char(renderable.glyph as u8))
)
.position(
((entry.0.x as f32) + 0.5) * TILESIZE,
((entry.0.y as f32) + 0.5) * TILESIZE
)
.color(
Color::from_rgb(renderable.fg.r, renderable.fg.g, renderable.fg.b)
)
.size(FONTSIZE)
.h_align_center()
.v_align_middle();
}
}
_ => {}
}
@ -333,6 +322,10 @@ fn render_map_in_view(
if crate::camera::in_bounds(tile_x, tile_y, 0, 0, map.width, map.height) {
let idx = map.xy_idx(tile_x, tile_y);
if map.revealed_tiles[idx] || mapgen {
let draw_x =
(x as f32) * TILESIZE.sprite_x + (bounds.x_offset as f32) * TILESIZE.x;
let draw_y =
(y as f32) * TILESIZE.sprite_y + (bounds.y_offset as f32) * TILESIZE.x;
if ASCII_MODE {
let (glyph, fg, bg) = crate::map::themes::get_tile_renderables_for_id(
idx,
@ -353,11 +346,9 @@ fn render_map_in_view(
panic!("No sprite found for ID: {}", id);
};
draw.image(sprite)
.position(
((x + bounds.x_offset) as f32) * TILESIZE,
((y + bounds.y_offset) as f32) * TILESIZE
)
.color(tint);
.position(draw_x, draw_y)
.color(tint)
.size(TILESIZE.sprite_x, TILESIZE.sprite_y);
}
if !map.visible_tiles[idx] {
// Recall map memory. TODO: Improve this? Optimize? Do we need to remember more fields?
@ -365,6 +356,12 @@ fn render_map_in_view(
let mut sorted: Vec<_> = memories.iter().collect();
sorted.sort_by(|a, b| a.render_order.cmp(&b.render_order));
for memory in sorted.iter() {
let mult = 0.3;
let col = Color::from_rgb(
memory.fg.r * mult,
memory.fg.g * mult,
memory.fg.b * mult
);
let sprite = if let Some(sprite) = atlas.get(&memory.sprite) {
sprite
} else {
@ -372,19 +369,11 @@ fn render_map_in_view(
};
draw.image(sprite)
.position(
(((x + bounds.x_offset) as f32) + memory.offset.0) *
TILESIZE,
(((y + bounds.y_offset) as f32) + memory.offset.1) *
TILESIZE
draw_x + memory.offset.0 * TILESIZE.sprite_x,
draw_y + memory.offset.1 * TILESIZE.sprite_y
)
.color(
if memory.recolour {
Color::from_rgb(memory.fg.r, memory.fg.g, memory.fg.b)
} else {
let mult = 0.3;
Color::from_rgb(mult, mult, mult)
}
);
.color(col)
.size(TILESIZE.sprite_x, TILESIZE.sprite_y);
}
}
}
@ -408,54 +397,54 @@ struct BoxDraw {
}
fn draw_spritebox(panel: BoxDraw, draw: &mut Draw, atlas: &HashMap<String, Texture>) {
draw.image(atlas.get(&format!("{}_1", panel.frame)).unwrap()).position(
(panel.top_left.0 as f32) * TILESIZE,
(panel.top_left.1 as f32) * TILESIZE
(panel.top_left.0 as f32) * TILESIZE.x,
(panel.top_left.1 as f32) * TILESIZE.x
);
for i in panel.top_left.0 + 1..panel.top_right.0 {
draw.image(atlas.get(&format!("{}_2", panel.frame)).unwrap()).position(
(i as f32) * TILESIZE,
(panel.top_left.1 as f32) * TILESIZE
(i as f32) * TILESIZE.x,
(panel.top_left.1 as f32) * TILESIZE.x
);
}
draw.image(atlas.get(&format!("{}_3", panel.frame)).unwrap()).position(
(panel.top_right.0 as f32) * TILESIZE,
(panel.top_right.1 as f32) * TILESIZE
(panel.top_right.0 as f32) * TILESIZE.x,
(panel.top_right.1 as f32) * TILESIZE.x
);
for i in panel.top_left.1 + 1..panel.bottom_left.1 {
draw.image(atlas.get(&format!("{}_4", panel.frame)).unwrap()).position(
(panel.top_left.0 as f32) * TILESIZE,
(i as f32) * TILESIZE
(panel.top_left.0 as f32) * TILESIZE.x,
(i as f32) * TILESIZE.x
);
}
if panel.fill {
for i in panel.top_left.0 + 1..panel.top_right.0 {
for j in panel.top_left.1 + 1..panel.bottom_left.1 {
draw.image(atlas.get(&format!("{}_5", panel.frame)).unwrap()).position(
(i as f32) * TILESIZE,
(j as f32) * TILESIZE
(i as f32) * TILESIZE.x,
(j as f32) * TILESIZE.x
);
}
}
}
for i in panel.top_right.1 + 1..panel.bottom_right.1 {
draw.image(atlas.get(&format!("{}_6", panel.frame)).unwrap()).position(
(panel.top_right.0 as f32) * TILESIZE,
(i as f32) * TILESIZE
(panel.top_right.0 as f32) * TILESIZE.x,
(i as f32) * TILESIZE.x
);
}
draw.image(atlas.get(&format!("{}_7", panel.frame)).unwrap()).position(
(panel.bottom_left.0 as f32) * TILESIZE,
(panel.bottom_left.1 as f32) * TILESIZE
(panel.bottom_left.0 as f32) * TILESIZE.x,
(panel.bottom_left.1 as f32) * TILESIZE.x
);
for i in panel.bottom_left.0 + 1..panel.bottom_right.0 {
draw.image(atlas.get(&format!("{}_8", panel.frame)).unwrap()).position(
(i as f32) * TILESIZE,
(panel.bottom_left.1 as f32) * TILESIZE
(i as f32) * TILESIZE.x,
(panel.bottom_left.1 as f32) * TILESIZE.x
);
}
draw.image(atlas.get(&format!("{}_9", panel.frame)).unwrap()).position(
(panel.bottom_right.0 as f32) * TILESIZE,
(panel.bottom_right.1 as f32) * TILESIZE
(panel.bottom_right.0 as f32) * TILESIZE.x,
(panel.bottom_right.1 as f32) * TILESIZE.x
);
}
@ -514,7 +503,7 @@ fn draw(_app: &mut App, gfx: &mut Graphics, gs: &mut State) {
}
RunState::PreRun { .. } => {}
RunState::MapGeneration => {
draw_bg(&gs.ecs, &mut draw, &gs.atlas);
draw_bg(&gs.ecs, &mut draw, &gs.interface);
if config::CONFIG.logging.show_mapgen && gs.mapgen_history.len() > 0 {
render_map_in_view(
&gs.mapgen_history[gs.mapgen_index],
@ -528,7 +517,7 @@ fn draw(_app: &mut App, gfx: &mut Graphics, gs: &mut State) {
}
_ => {
let map = gs.ecs.fetch::<Map>();
draw_bg(&gs.ecs, &mut draw, &gs.atlas);
draw_bg(&gs.ecs, &mut draw, &gs.interface);
render_map_in_view(&*map, &gs.ecs, &mut draw, &gs.atlas, false);
// Special case: targeting needs to be drawn *below* entities, but above tiles.
if let RunState::ShowTargeting { range, item: _, x, y, aoe } = runstate {
@ -556,19 +545,28 @@ fn draw(_app: &mut App, gfx: &mut Graphics, gs: &mut State) {
RunState::ShowInventory => {
corner_text("Use what? [aA-zZ]/[Esc.]", &mut draw, &gs.font);
let offset = crate::camera::get_offset();
let (x, y) = (((1 + offset.x) as f32) * TILESIZE, ((3 + offset.y) as f32) * TILESIZE);
let (x, y) = (
((1 + offset.x) as f32) * TILESIZE.x,
((3 + offset.y) as f32) * TILESIZE.x,
);
gui::draw_backpack_items(&gs.ecs, &mut draw, &gs.font, x, y);
}
RunState::ShowDropItem => {
corner_text("Drop what? [aA-zZ]/[Esc.]", &mut draw, &gs.font);
let offset = crate::camera::get_offset();
let (x, y) = (((1 + offset.x) as f32) * TILESIZE, ((3 + offset.y) as f32) * TILESIZE);
let (x, y) = (
((1 + offset.x) as f32) * TILESIZE.x,
((3 + offset.y) as f32) * TILESIZE.x,
);
gui::draw_backpack_items(&gs.ecs, &mut draw, &gs.font, x, y);
}
RunState::ShowRemoveItem => {
corner_text("Unequip which item? [aA-zZ]/[Esc.]", &mut draw, &gs.font);
let offset = crate::camera::get_offset();
let (x, y) = (((1 + offset.x) as f32) * TILESIZE, ((3 + offset.y) as f32) * TILESIZE);
let (x, y) = (
((1 + offset.x) as f32) * TILESIZE.x,
((3 + offset.y) as f32) * TILESIZE.x,
);
gui::draw_items(&gs.ecs, &mut draw, &gs.font, x, y, gui::Location::Equipped, None);
}
RunState::ShowTargeting { .. } => {
@ -587,6 +585,6 @@ fn update(ctx: &mut App, state: &mut State) {
fn corner_text(text: &str, draw: &mut Draw, font: &Fonts) {
let offset = crate::camera::get_offset();
draw.text(&font.b(), &text)
.position(((offset.x + 1) as f32) * TILESIZE, ((offset.y + 1) as f32) * TILESIZE)
.position(((offset.x + 1) as f32) * TILESIZE.x, ((offset.y + 1) as f32) * TILESIZE.x)
.size(FONTSIZE);
}

View file

@ -32,7 +32,6 @@ use super::consts::visuals::{
pub struct MapMemory {
pub sprite: String,
pub fg: RGB,
pub recolour: bool,
pub offset: (f32, f32),
pub render_order: i32,
}

View file

@ -37,74 +37,32 @@ impl TileType {
}
fn h(&self, float: f32) -> &str {
let options = match self {
TileType::Wall =>
vec![
"wall_cave_h_a",
"wall_cave_h_b",
"wall_cave_h_c",
"wall_cave_h_d",
"wall_cave_h_crack"
],
TileType::Wall => vec!["wall_b"],
_ => unreachable!("Tried to get a h (base) sprite for a non-wall tile."),
};
return options[(float * (options.len() as f32)) as usize];
}
fn v(&self, float: f32) -> &str {
let options = match self {
TileType::ImpassableMountain => vec!["statue_warrior"],
TileType::Wall =>
vec![
"wall_cave_v_a",
"wall_cave_v_b",
"wall_cave_v_c",
"wall_cave_v_d",
"wall_cave_v_crack"
],
TileType::DeepWater => vec!["water", "water_a1", "water_a2"],
TileType::Fence => vec!["wall_cave_h_a"],
TileType::Bars => vec!["wall_cave_h_a"],
TileType::Floor =>
vec![
"floor_cobble_a",
"floor_cobble_b",
"floor_cobble_c",
"floor_cobble_d",
"floor_cobble_e",
"floor_cobble_f"
],
TileType::WoodFloor =>
vec!["floor_wood_a", "floor_wood_b", "floor_wood_c", "floor_wood_d"],
TileType::Gravel => vec!["floor_cobble_b"],
TileType::Road =>
vec![
"floor_tile_a",
"floor_tile_b",
"floor_tile_c",
"floor_tile_d",
"floor_mossy_a",
"floor_mossy_b",
"floor_mossy_c",
"floor_mossy_d",
"floor_mossy_e"
],
TileType::Grass =>
vec![
"floor_grass_a",
"floor_grass_b",
"floor_grass_c",
"floor_grass_d",
"floor_grass_e",
"floor_grass_f"
],
TileType::Foliage => vec!["floor_grass_b"],
TileType::HeavyFoliage => vec!["floor_grass_c"],
TileType::Sand => vec!["floor_cobble_c"],
TileType::ShallowWater => vec!["water"],
TileType::Bridge => vec!["floor_cobble_a"],
TileType::DownStair => vec!["wall_cave_stair_down"],
TileType::UpStair => vec!["wall_cave_stair_up"],
TileType::ToLocal(_) => vec!["wall_crypt_stair_down"],
TileType::ToOvermap(_) => vec!["wall_crypt_stair_up"],
TileType::ImpassableMountain => vec!["wall_b"],
TileType::Wall => vec!["wall_top"],
TileType::DeepWater => vec!["water", "water2"],
TileType::Fence => vec!["wall_b"],
TileType::Bars => vec!["wall_b"],
TileType::Floor => vec!["fluff", "fluff2"],
TileType::WoodFloor => vec!["fluff", "fluff2"],
TileType::Gravel => vec!["fluff", "fluff2"],
TileType::Road => vec!["fluff", "fluff2"],
TileType::Grass => vec!["fluff", "fluff2"],
TileType::Foliage => vec!["fluff", "fluff2"],
TileType::HeavyFoliage => vec!["fluff", "fluff2"],
TileType::Sand => vec!["fluff", "fluff2"],
TileType::ShallowWater => vec!["water", "water2"],
TileType::Bridge => vec!["wall_b"],
TileType::DownStair => vec!["wall_b"],
TileType::UpStair => vec!["wall_b"],
TileType::ToLocal(_) => vec!["wall_b"],
TileType::ToOvermap(_) => vec!["wall_b"],
};
return options[(float * (options.len() as f32)) as usize];
}

View file

@ -50,8 +50,8 @@ fn create_delayed_particles(ecs: &mut World, ctx: &App) {
x: delayed_particle.particle.x,
y: delayed_particle.particle.y,
fg: delayed_particle.particle.fg,
bg: delayed_particle.particle.bg,
glyph: delayed_particle.particle.glyph,
sprite: delayed_particle.particle.sprite.clone(),
lifetime: delayed_particle.particle.lifetime,
});
}
@ -81,14 +81,7 @@ fn create_delayed_particles(ecs: &mut World, ctx: &App) {
.insert(p, Position { x: handled.x, y: handled.y })
.expect("Could not insert position");
renderables
.insert(p, Renderable {
sprite: None, // TODO: Particle sprite
fg: handled.fg,
bg: handled.bg,
glyph: handled.glyph,
render_order: 0,
alt_render_order: None,
})
.insert(p, Renderable::new(handled.glyph, handled.sprite, handled.fg, 0))
.expect("Could not insert renderables");
particles
.insert(p, ParticleLifetime { lifetime_ms: handled.lifetime })
@ -101,8 +94,8 @@ pub struct ParticleRequest {
x: i32,
y: i32,
fg: RGB,
bg: RGB,
glyph: FontCharType,
sprite: String,
lifetime: f32,
}
@ -129,11 +122,11 @@ impl ParticleBuilder {
x: i32,
y: i32,
fg: RGB,
bg: RGB,
glyph: FontCharType,
sprite: String,
lifetime: f32
) {
self.requests.push(ParticleRequest { x, y, fg, bg, glyph, lifetime });
self.requests.push(ParticleRequest { x, y, fg, glyph, sprite, lifetime });
}
pub fn delay(
@ -141,150 +134,43 @@ impl ParticleBuilder {
x: i32,
y: i32,
fg: RGB,
bg: RGB,
glyph: FontCharType,
sprite: String,
lifetime: f32,
delay: f32
) {
self.delayed_requests.push(DelayedParticleRequest {
delay: delay,
particle: ParticleRequest { x, y, fg, bg, glyph, lifetime },
particle: ParticleRequest { x, y, fg, glyph, sprite, lifetime },
});
}
// MASSIVE TODO: Animate these, or make them random. PLACEHOLDER.
pub fn damage_taken(&mut self, x: i32, y: i32) {
self.request(
x,
y,
RGB::named(ORANGE),
RGB::named(BLACK),
to_cp437('‼'),
DEFAULT_PARTICLE_LIFETIME
);
self.request(x, y, RGB::named(RED), to_cp437('‼'), "slash1".to_string(), 75.0);
self.delay(x, y, RGB::named(RED), to_cp437('‼'), "slash2".to_string(), 75.0, 75.0);
self.delay(x, y, RGB::named(RED), to_cp437('‼'), "slash3".to_string(), 75.0, 150.0);
}
pub fn attack_miss(&mut self, x: i32, y: i32) {
self.request(
x,
y,
RGB::named(CYAN),
RGB::named(BLACK),
to_cp437('‼'),
"slash1".to_string(),
DEFAULT_PARTICLE_LIFETIME
);
}
pub fn kick(&mut self, x: i32, y: i32) {
self.request(
x,
y,
RGB::named(CHOCOLATE),
RGB::named(BLACK),
to_cp437('‼'),
"kick".to_string(),
SHORT_PARTICLE_LIFETIME
);
}
// Makes a particle request in the shape of an 'x'. Sort of.
#[allow(dead_code)]
pub fn request_star(
&mut self,
x: i32,
y: i32,
fg: RGB,
bg: RGB,
glyph: FontCharType,
lifetime: f32,
secondary_fg: RGB
) {
let eighth_l = lifetime / 8.0;
let quarter_l = eighth_l * 2.0;
self.request(x, y, fg, bg, glyph, lifetime);
self.delay(
x + 1,
y + 1,
secondary_fg.lerp(bg, 0.8),
bg,
to_cp437('/'),
quarter_l,
eighth_l
);
self.delay(
x + 1,
y - 1,
secondary_fg.lerp(bg, 0.6),
bg,
to_cp437('\\'),
quarter_l,
quarter_l
);
self.delay(
x - 1,
y - 1,
secondary_fg.lerp(bg, 0.2),
bg,
to_cp437('/'),
quarter_l,
eighth_l * 3.0
);
self.delay(
x - 1,
y + 1,
secondary_fg.lerp(bg, 0.4),
bg,
to_cp437('\\'),
quarter_l,
lifetime
);
}
// Makes a rainbow particle request in the shape of an 'x'. Sort of.
#[allow(dead_code)]
pub fn request_rainbow_star(&mut self, x: i32, y: i32, glyph: FontCharType, lifetime: f32) {
let bg = RGB::named(BLACK);
let eighth_l = lifetime / 8.0;
let quarter_l = eighth_l * 2.0;
let half_l = quarter_l * 2.0;
self.request(x, y, RGB::named(CYAN), bg, glyph, lifetime);
self.delay(x + 1, y + 1, RGB::named(RED), bg, to_cp437('\\'), half_l, eighth_l);
self.delay(x + 1, y - 1, RGB::named(ORANGE), bg, to_cp437('/'), half_l, quarter_l);
self.delay(x - 1, y - 1, RGB::named(GREEN), bg, to_cp437('\\'), half_l, eighth_l * 3.0);
self.delay(x - 1, y + 1, RGB::named(YELLOW), bg, to_cp437('/'), half_l, half_l);
}
// Makes a rainbow particle request. Sort of.
#[allow(dead_code)]
pub fn request_rainbow(&mut self, x: i32, y: i32, glyph: FontCharType, lifetime: f32) {
let bg = RGB::named(BLACK);
let eighth_l = lifetime / 8.0;
self.request(x, y, RGB::named(RED), bg, glyph, eighth_l);
self.delay(x, y, RGB::named(ORANGE), bg, glyph, eighth_l, eighth_l);
self.delay(x, y, RGB::named(YELLOW), bg, glyph, eighth_l, eighth_l * 2.0);
self.delay(x, y, RGB::named(GREEN), bg, glyph, eighth_l, eighth_l * 3.0);
self.delay(x, y, RGB::named(BLUE), bg, glyph, eighth_l, eighth_l * 4.0);
self.delay(x, y, RGB::named(INDIGO), bg, glyph, eighth_l, eighth_l * 5.0);
self.delay(x, y, RGB::named(VIOLET), bg, glyph, eighth_l, eighth_l * 6.0);
}
/// Makes a particle request in the shape of a +.
#[allow(dead_code)]
pub fn request_plus(
&mut self,
x: i32,
y: i32,
fg: RGB,
bg: RGB,
glyph: FontCharType,
lifetime: f32
) {
self.request(x, y, fg, bg, glyph, lifetime * 2.0);
self.request(x + 1, y, fg, bg, to_cp437('─'), lifetime);
self.request(x - 1, y, fg, bg, to_cp437('─'), lifetime);
self.request(x, y + 1, fg, bg, to_cp437('│'), lifetime);
self.request(x, y - 1, fg, bg, to_cp437('│'), lifetime);
}
}
pub struct ParticleSpawnSystem {}
@ -308,14 +194,15 @@ impl<'a> System<'a> for ParticleSpawnSystem {
.insert(p, Position { x: new_particle.x, y: new_particle.y })
.expect("Could not insert position");
renderables
.insert(p, Renderable {
sprite: None, // TODO: Particle sprites
fg: new_particle.fg,
bg: new_particle.bg,
glyph: new_particle.glyph,
render_order: 0,
alt_render_order: None,
})
.insert(
p,
Renderable::new(
new_particle.glyph,
new_particle.sprite.clone(),
new_particle.fg,
0
)
)
.expect("Could not insert renderables");
particles
.insert(p, ParticleLifetime { lifetime_ms: new_particle.lifetime })

View file

@ -338,8 +338,8 @@ pub fn kick(i: i32, j: i32, ecs: &mut World) -> RunState {
None,
EffectType::Particle {
glyph: to_cp437('‼'),
sprite: "gnome".to_string(), // FIXME: REMOVE THE GNOMES
fg: RGB::named(CHOCOLATE),
bg: RGB::named(BLACK),
lifespan: 150.0,
delay: 0.0,
},
@ -398,8 +398,8 @@ pub fn kick(i: i32, j: i32, ecs: &mut World) -> RunState {
None,
EffectType::Particle {
glyph: to_cp437('‼'),
sprite: "gnome".to_string(), // FIXME: REMOVE THE GNOMES
fg: RGB::named(CHOCOLATE),
bg: RGB::named(BLACK),
lifespan: 150.0,
delay: 0.0,
},

View file

@ -28,25 +28,19 @@ pub struct Equippable {
pub to_hit: Option<i32>,
}
#[derive(Deserialize, Debug)]
pub struct SpriteInfo {
pub id: String,
pub alt: Option<String>,
pub colour: Option<bool>,
pub x: Option<f32>,
pub y: Option<f32>,
pub alt_x: Option<f32>,
pub alt_y: Option<f32>,
}
#[derive(Deserialize, Debug)]
pub struct Renderable {
pub glyph: String,
pub sprite: Option<SpriteInfo>,
pub sprite: String,
pub alt: Option<String>,
pub fg: String,
pub bg: String,
pub fg_alt: Option<String>,
pub order: i32,
pub alt_order: Option<i32>,
pub order_alt: Option<i32>,
pub x: Option<f32>,
pub x_alt: Option<f32>,
pub y: Option<f32>,
pub y_alt: Option<f32>,
}
#[derive(Deserialize, Debug)]

View file

@ -740,35 +740,50 @@ fn is_player_owned(player: &Entity, pos: &SpawnType) -> bool {
fn get_renderable_component(
renderable: &super::item_structs::Renderable
) -> crate::components::Renderable {
let glyph = to_cp437(renderable.glyph.chars().next().unwrap());
let sprite = renderable.sprite.clone();
let sprite_alt = if let Some(sprite_alt) = &renderable.alt {
Some(sprite_alt.clone())
} else {
None
};
let fg = RGB::from_hex(&renderable.fg).expect("Invalid RGB");
let fg_alt = if let Some(fg_alt) = &renderable.fg_alt {
Some(RGB::from_hex(&fg_alt).expect("Invalid RGB"))
} else {
None
};
let render_order = renderable.order;
let render_order_alt = if let Some(order_alt) = renderable.order_alt {
Some(order_alt)
} else {
None
};
let offset_x = if let Some(x) = renderable.x { x } else { 0.0 };
let offset_y = if let Some(y) = renderable.y { -y } else { 0.0 };
let offset_alt: Option<(f32, f32)> = if
renderable.x_alt.is_some() ||
renderable.y_alt.is_some()
{
Some((
if let Some(x) = renderable.x_alt { x } else { 0.0 },
if let Some(y) = renderable.y_alt { -y } else { 0.0 },
))
} else {
None
};
crate::components::Renderable {
glyph: to_cp437(renderable.glyph.chars().next().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 {
true
},
alt: spriteinfo.alt.clone(),
offset: (x, -y), // Invert y so that positive y = move upwards.
alt_offset: (alt_x, -alt_y),
})
} else {
None
},
fg: RGB::from_hex(&renderable.fg).expect("Invalid RGB"),
bg: RGB::from_hex(&renderable.bg).expect("Invalid RGB"),
render_order: renderable.order,
alt_render_order: if let Some(alt_order) = renderable.alt_order {
Some(alt_order)
} else {
None
},
glyph,
sprite,
sprite_alt,
fg,
fg_alt,
render_order,
render_order_alt,
offset: (offset_x, offset_y),
offset_alt,
}
}
@ -1101,35 +1116,41 @@ fn get_ancestry_string(ancestry: Ancestry) -> &'static str {
fn parse_particle_line(n: &str) -> SpawnParticleLine {
let tokens: Vec<_> = n.split(';').collect();
SpawnParticleLine {
glyph: to_cp437(tokens[0].chars().next().unwrap()),
tail_glyph: to_cp437(tokens[1].chars().next().unwrap()),
colour: RGB::from_hex(tokens[2]).expect("Invalid RGB"),
lifetime_ms: tokens[3].parse::<f32>().unwrap(),
trail_colour: RGB::from_hex(tokens[4]).expect("Invalid trail RGB"),
trail_lifetime_ms: tokens[5].parse::<f32>().unwrap(),
sprite: tokens[0].to_string(),
tail_sprite: tokens[1].to_string(),
glyph: to_cp437(tokens[2].chars().next().unwrap()),
tail_glyph: to_cp437(tokens[3].chars().next().unwrap()),
colour: RGB::from_hex(tokens[4]).expect("Invalid RGB"),
lifetime_ms: tokens[5].parse::<f32>().unwrap(),
trail_colour: RGB::from_hex(tokens[6]).expect("Invalid trail RGB"),
trail_lifetime_ms: tokens[7].parse::<f32>().unwrap(),
}
}
fn parse_particle(n: &str) -> SpawnParticleSimple {
let tokens: Vec<_> = n.split(';').collect();
SpawnParticleSimple {
glyph: to_cp437(tokens[0].chars().next().unwrap()),
colour: RGB::from_hex(tokens[1]).expect("Invalid RGB"),
lifetime_ms: tokens[2].parse::<f32>().unwrap(),
sprite: tokens[0].to_string(),
glyph: to_cp437(tokens[1].chars().next().unwrap()),
colour: RGB::from_hex(tokens[2]).expect(&format!("Invalid RGB: {}", n)),
lifetime_ms: tokens[3].parse::<f32>().unwrap(),
}
}
fn parse_particle_burst(n: &str) -> SpawnParticleBurst {
let tokens: Vec<_> = n.split(';').collect();
SpawnParticleBurst {
glyph: to_cp437(tokens[0].chars().next().unwrap()),
head_glyph: to_cp437(tokens[1].chars().next().unwrap()),
tail_glyph: to_cp437(tokens[2].chars().next().unwrap()),
colour: RGB::from_hex(tokens[3]).expect("Invalid RGB"),
lerp: RGB::from_hex(tokens[4]).expect("Invalid LERP RGB"),
lifetime_ms: tokens[5].parse::<f32>().unwrap(),
trail_colour: RGB::from_hex(tokens[6]).expect("Invalid trail RGB"),
trail_lifetime_ms: tokens[7].parse::<f32>().unwrap(),
sprite: tokens[0].to_string(),
head_sprite: tokens[1].to_string(),
tail_sprite: tokens[2].to_string(),
glyph: to_cp437(tokens[3].chars().next().unwrap()),
head_glyph: to_cp437(tokens[4].chars().next().unwrap()),
tail_glyph: to_cp437(tokens[5].chars().next().unwrap()),
colour: RGB::from_hex(tokens[6]).expect("Invalid RGB"),
lerp: RGB::from_hex(tokens[7]).expect("Invalid LERP RGB"),
lifetime_ms: tokens[8].parse::<f32>().unwrap(),
trail_colour: RGB::from_hex(tokens[9]).expect("Invalid trail RGB"),
trail_lifetime_ms: tokens[10].parse::<f32>().unwrap(),
}
}

View file

@ -29,7 +29,6 @@ use super::{
Intrinsics,
HasAncestry,
HasClass,
SpriteInfo,
};
use crate::gui::{ Ancestry, Class };
use crate::consts::entity;
@ -55,15 +54,8 @@ pub fn player(ecs: &mut World, player_x: i32, player_y: i32) -> Entity {
let player = ecs
.create_entity()
.with(Position { x: player_x, y: player_y })
.with(BlocksTile {})
.with(Renderable {
glyph: to_cp437('@'),
sprite: Some(SpriteInfo::colourable("@")),
fg: RGB::named(YELLOW),
bg: RGB::named(BLACK),
render_order: 2,
alt_render_order: None,
})
.with(BlocksTile {}) // FIXME: Put in actual player sprite
.with(Renderable::new(to_cp437('@'), "gnome".to_string(), RGB::named(YELLOW), 2))
.with(Bleeds { colour: RGB::named(BLOODSTAIN_COLOUR) })
.with(Player {})
.with(Mind {})

View file

@ -61,8 +61,8 @@ impl Fonts {
#[derive(AppState)]
pub struct State {
pub ecs: World,
pub base_texture: Texture,
pub atlas: HashMap<String, Texture>,
pub interface: HashMap<String, Texture>,
pub font: Fonts,
pub mapgen_next_state: Option<RunState>,
pub mapgen_history: Vec<Map>,

View file

@ -165,12 +165,10 @@ impl<'a> System<'a> for VisibilitySystem {
if prop.get(e).is_some() || item.get(e).is_some() {
let idx = map.xy_idx(p.x, p.y);
if map.visible_tiles[idx] {
if let Some(spriteinfo) = &r.sprite {
map.memory.entry(idx).or_insert(Vec::new()).push(crate::MapMemory {
sprite: spriteinfo.id.clone(),
sprite: r.sprite.clone(),
fg: r.fg,
recolour: spriteinfo.recolour,
offset: spriteinfo.offset,
offset: r.offset,
render_order: r.render_order,
});
}
@ -178,7 +176,6 @@ impl<'a> System<'a> for VisibilitySystem {
}
}
}
}
}
pub fn fast_fov(p_x: i32, p_y: i32, r: i32, map: &WriteExpect<Map>) -> Vec<Point> {