Compare commits
14 commits
master
...
switching_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2d55f83bb3 | ||
|
|
670b365def | ||
|
|
d58614b106 | ||
|
|
cee4d02ce2 | ||
|
|
8337f202cf | ||
|
|
141d4b63d2 | ||
|
|
ddcfd72318 | ||
|
|
441b22439f | ||
|
|
a29a7f5be4 | ||
|
|
ae3e061ce8 | ||
|
|
ebcce3183b | ||
|
|
1bea2c0026 | ||
|
|
4e0ed95a22 | ||
|
|
2a3c59ad33 |
2
.github/workflows/cargo-build-test.yml
vendored
|
|
@ -12,7 +12,7 @@ env:
|
|||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "rust-rl"
|
||||
version = "0.1.4"
|
||||
version = "0.1.1"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
|
|
|||
11
README.md
|
|
@ -2,18 +2,18 @@
|
|||
|
||||
#### using _rltk/bracket-lib_, and _specs_
|
||||
|
||||
[](https://github.com/Llywelwyn/rust-rl/actions/workflows/cargo-build-test.yml)
|
||||
|
||||
check out the page in the header for the wasm version, pick [a release](https://github.com/Llywelwyn/rust-rl/releases), or build manually with:
|
||||
check out the page in the header for the wasm version, pick [a release of your choice](https://github.com/Llywelwyn/rust-rl/releases), or build manually with:
|
||||
|
||||
`git clone https://github.com/Llywelwyn/rust-rl/ && cd rust-rl && cargo build --release`,
|
||||
|
||||

|
||||
|
||||
this year for roguelikedev does the complete tutorial, i followed along with thebracket's [_roguelike tutorial - in rust_](https://bfnightly.bracketproductions.com). the notes i made during the sprint are being kept below for posterity - further changes since then are noted in [changelog.txt](https://github.com/Llywelwyn/rust-rl/blob/9150ed39e45bee536060cdc769d274e639021012/changelog.txt), and in the release notes.
|
||||
|
||||
i'm also working on translating over my progress into blog entries on my site @ [llyw.co.uk](https://llyw.co.uk/), with a larger focus on some of the more interesting implementation details.
|
||||
|
||||
---
|
||||
|
||||
<details>
|
||||
<summary>boring details about the sprint where this project started</summary>
|
||||
<details>
|
||||
<summary>week 1</summary>
|
||||
|
||||
|
|
@ -157,4 +157,3 @@ check out the page in the header for the wasm version, pick [a release](https://
|
|||

|
||||
|
||||
</details>
|
||||
</details>
|
||||
|
|
|
|||
|
|
@ -49,7 +49,3 @@ Complex example, with negative AC:
|
|||
bloodstains: if starts on bloodied tile, remove blood + heal, gain xp, grow (little dog -> dog), etc.
|
||||
- You have negative AC, so you roll 1d14 for damage reduction, and get an 8.
|
||||
- The total damage is 6 - 8 = -2, but damage can't be negative, so you take 1 point of damage.
|
||||
|
||||
tl;dr
|
||||
1. Lower AC is better
|
||||
2. Aim for 0 AC - it's an important breakpoint. Every point of AC before 0 counts for a lot.
|
||||
|
|
|
|||
|
|
@ -3,10 +3,9 @@
|
|||
"id": "potion_health",
|
||||
"name": { "name": "potion of health", "plural": "potions of health" },
|
||||
"renderable": { "glyph": "!", "fg": "#FF00FF", "bg": "#000000", "order": 2 },
|
||||
"class": "potion",
|
||||
"weight": 1,
|
||||
"value": 50,
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE", "STACKABLE"],
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE"],
|
||||
"effects": { "heal": "4d4+2" },
|
||||
"magic": { "class": "uncommon", "naming": "potion" }
|
||||
},
|
||||
|
|
@ -14,10 +13,9 @@
|
|||
"id": "potion_health_weak",
|
||||
"name": { "name": "potion of lesser health", "plural": "potions of lesser health" },
|
||||
"renderable": { "glyph": "!", "fg": "#FF00FF", "bg": "#000000", "order": 2 },
|
||||
"class": "potion",
|
||||
"weight": 1,
|
||||
"value": 25,
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE", "STACKABLE"],
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE"],
|
||||
"effects": { "heal": "2d4+2" },
|
||||
"magic": { "class": "uncommon", "naming": "potion" }
|
||||
},
|
||||
|
|
@ -25,30 +23,27 @@
|
|||
"id": "scroll_identify",
|
||||
"name": { "name": "scroll of identify", "plural": "scrolls of identify" },
|
||||
"renderable": { "glyph": "?", "fg": "#0FFFFF", "bg": "#000000", "order": 2 },
|
||||
"class": "scroll",
|
||||
"weight": 0.5,
|
||||
"value": 100,
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE", "STACKABLE", "IDENTIFY"],
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE", "IDENTIFY"],
|
||||
"magic": { "class": "uncommon", "naming": "scroll" }
|
||||
},
|
||||
{
|
||||
"id": "scroll_removecurse",
|
||||
"name": { "name": "scroll of remove curse", "plural": "scrolls of remove curse" },
|
||||
"renderable": { "glyph": "?", "fg": "#0FFFFF", "bg": "#000000", "order": 2 },
|
||||
"class": "scroll",
|
||||
"weight": 0.5,
|
||||
"value": 200,
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE", "STACKABLE", "REMOVE_CURSE"],
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE", "REMOVE_CURSE"],
|
||||
"magic": { "class": "rare", "naming": "scroll" }
|
||||
},
|
||||
{
|
||||
"id": "scroll_health",
|
||||
"name": { "name": "scroll of healing word", "plural": "scrolls of healing word" },
|
||||
"renderable": { "glyph": "?", "fg": "#00FFFF", "bg": "#000000", "order": 2 },
|
||||
"class": "scroll",
|
||||
"weight": 0.5,
|
||||
"value": 50,
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE", "STACKABLE"],
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE"],
|
||||
"effects": { "particle_line": "*;-;#53f06d;75.0;#f9ff9f;100.0", "ranged": "12", "heal": "1d4+2" },
|
||||
"magic": { "class": "uncommon", "naming": "scroll" }
|
||||
},
|
||||
|
|
@ -56,10 +51,9 @@
|
|||
"id": "scroll_mass_health",
|
||||
"name": { "name": "scroll of mass healing word", "plural": "scrolls of mass healing word" },
|
||||
"renderable": { "glyph": "?", "fg": "#00FFFF", "bg": "#000000", "order": 2 },
|
||||
"class": "scroll",
|
||||
"weight": 0.5,
|
||||
"value": 200,
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE", "STACKABLE"],
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE"],
|
||||
"effects": { "particle": "*;#53f06d;200.0", "ranged": "12", "aoe": "3", "heal": "1d4+2" },
|
||||
"magic": { "class": "rare", "naming": "scroll" }
|
||||
},
|
||||
|
|
@ -67,10 +61,9 @@
|
|||
"id": "scroll_magicmissile",
|
||||
"name": { "name": "scroll of magic missile", "plural": "scrolls of magic missile" },
|
||||
"renderable": { "glyph": "?", "fg": "#00FFFF", "bg": "#000000", "order": 2 },
|
||||
"class": "scroll",
|
||||
"weight": 0.5,
|
||||
"value": 50,
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE", "STACKABLE"],
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE"],
|
||||
"effects": { "particle_line": "*;-;#00b7ff;75.0;#f4fc83;100.0", "ranged": "12", "damage": "3d4+3;magic" },
|
||||
"magic": { "class": "uncommon", "naming": "scroll" }
|
||||
},
|
||||
|
|
@ -78,10 +71,9 @@
|
|||
"id": "scroll_embers",
|
||||
"name": { "name": "scroll of embers", "plural": "scrolls of embers" },
|
||||
"renderable": { "glyph": "?", "fg": "#00FFFF", "bg": "#000000", "order": 2 },
|
||||
"class": "scroll",
|
||||
"weight": 0.5,
|
||||
"value": 100,
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE", "STACKABLE"],
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE"],
|
||||
"effects": { "particle": "*;#FFA500;200.0", "ranged": "10", "damage": "4d6;fire", "aoe": "2" },
|
||||
"magic": { "class": "uncommon", "naming": "scroll" }
|
||||
},
|
||||
|
|
@ -89,10 +81,9 @@
|
|||
"id": "scroll_fireball",
|
||||
"name": { "name": "scroll of fireball", "plural": "scrolls of fireball" },
|
||||
"renderable": { "glyph": "?", "fg": "#00FFFF", "bg": "#000000", "order": 2 },
|
||||
"class": "scroll",
|
||||
"weight": 0.5,
|
||||
"value": 200,
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE", "STACKABLE"],
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE"],
|
||||
"effects": {
|
||||
"particle_burst": "▓;*;~;#FFA500;#000000;500.0;#ffd381;60.0",
|
||||
"ranged": "10",
|
||||
|
|
@ -105,10 +96,9 @@
|
|||
"id": "scroll_confusion",
|
||||
"name": { "name": "scroll of confusion", "plural": "scrolls of confusion" },
|
||||
"renderable": { "glyph": "?", "fg": "#00FFFF", "bg": "#000000", "order": 2 },
|
||||
"class": "scroll",
|
||||
"weight": 0.5,
|
||||
"value": 100,
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE", "STACKABLE"],
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE"],
|
||||
"effects": { "particle_line": "*;-;#ad56a6;75.0;#cacaca;100.0", "ranged": "10", "confusion": "4" },
|
||||
"magic": { "class": "uncommon", "naming": "scroll" }
|
||||
},
|
||||
|
|
@ -116,10 +106,9 @@
|
|||
"id": "scroll_mass_confusion",
|
||||
"name": { "name": "scroll of mass confusion", "plural": "scrolls of mass confusion" },
|
||||
"renderable": { "glyph": "?", "fg": "#00FFFF", "bg": "#000000", "order": 2 },
|
||||
"class": "scroll",
|
||||
"weight": 0.5,
|
||||
"value": 200,
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE", "STACKABLE"],
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE"],
|
||||
"effects": { "particle": "*;#ad56a6;200.0", "ranged": "10", "aoe": "3", "confusion": "3" },
|
||||
"magic": { "class": "veryrare", "naming": "scroll" }
|
||||
},
|
||||
|
|
@ -127,10 +116,9 @@
|
|||
"id": "scroll_magicmap",
|
||||
"name": { "name": "scroll of magic mapping", "plural": "scrolls of magic mapping" },
|
||||
"renderable": { "glyph": "?", "fg": "#00FFFF", "bg": "#000000", "order": 2 },
|
||||
"class": "scroll",
|
||||
"weight": 0.5,
|
||||
"value": 50,
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE", "STACKABLE", "MAGICMAP"],
|
||||
"flags": ["CONSUMABLE", "DESTRUCTIBLE", "MAGICMAP"],
|
||||
"effects": {},
|
||||
"magic": { "class": "common", "naming": "scroll" }
|
||||
},
|
||||
|
|
@ -138,7 +126,6 @@
|
|||
"id": "equip_dagger",
|
||||
"name": { "name": "dagger", "plural": "daggers" },
|
||||
"renderable": { "glyph": ")", "fg": "#808080", "bg": "#000000", "order": 2 },
|
||||
"class": "weapon",
|
||||
"weight": 1,
|
||||
"value": 2,
|
||||
"flags": ["EQUIP_MELEE"],
|
||||
|
|
@ -148,7 +135,6 @@
|
|||
"id": "equip_shortsword",
|
||||
"name": { "name": "shortsword", "plural": "shortswords" },
|
||||
"renderable": { "glyph": ")", "fg": "#C0C0C0", "bg": "#000000", "order": 2 },
|
||||
"class": "weapon",
|
||||
"weight": 2,
|
||||
"value": 10,
|
||||
"flags": ["EQUIP_MELEE"],
|
||||
|
|
@ -158,7 +144,6 @@
|
|||
"id": "equip_rapier",
|
||||
"name": { "name": "rapier", "plural": "rapiers" },
|
||||
"renderable": { "glyph": ")", "fg": "#C0C0C0", "bg": "#000000", "order": 2 },
|
||||
"class": "weapon",
|
||||
"weight": 2,
|
||||
"value": 10,
|
||||
"flags": ["EQUIP_MELEE"],
|
||||
|
|
@ -168,7 +153,6 @@
|
|||
"id": "equip_pitchfork",
|
||||
"name": { "name": "pitchfork", "plural": "pitchforks" },
|
||||
"renderable": { "glyph": ")", "fg": "#C0C0C0", "bg": "#000000", "order": 2 },
|
||||
"class": "weapon",
|
||||
"weight": 2,
|
||||
"value": 5,
|
||||
"flags": ["EQUIP_MELEE"],
|
||||
|
|
@ -178,7 +162,6 @@
|
|||
"id": "equip_sickle",
|
||||
"name": { "name": "sickle", "plural": "sickles" },
|
||||
"renderable": { "glyph": ")", "fg": "#C0C0C0", "bg": "#000000", "order": 2 },
|
||||
"class": "weapon",
|
||||
"weight": 2,
|
||||
"value": 5,
|
||||
"flags": ["EQUIP_MELEE"],
|
||||
|
|
@ -188,7 +171,6 @@
|
|||
"id": "equip_handaxe",
|
||||
"name": { "name": "handaxe", "plural": "handaxes" },
|
||||
"renderable": { "glyph": ")", "fg": "#C0C0C0", "bg": "#000000", "order": 2 },
|
||||
"class": "weapon",
|
||||
"weight": 2,
|
||||
"value": 5,
|
||||
"flags": ["EQUIP_MELEE"],
|
||||
|
|
@ -198,7 +180,6 @@
|
|||
"id": "equip_longsword",
|
||||
"name": { "name": "longsword", "plural": "longswords" },
|
||||
"renderable": { "glyph": ")", "fg": "#FFF8DC", "bg": "#000000", "order": 2 },
|
||||
"class": "weapon",
|
||||
"weight": 3,
|
||||
"value": 15,
|
||||
"flags": ["EQUIP_MELEE"],
|
||||
|
|
@ -208,7 +189,6 @@
|
|||
"id": "equip_smallshield",
|
||||
"name": { "name": "buckler", "plural": "bucklers" },
|
||||
"renderable": { "glyph": "[", "fg": "#808080", "bg": "#000000", "order": 2 },
|
||||
"class": "armour",
|
||||
"weight": 2,
|
||||
"value": 5,
|
||||
"flags": ["EQUIP_SHIELD"],
|
||||
|
|
@ -218,7 +198,6 @@
|
|||
"id": "equip_mediumshield",
|
||||
"name": { "name": "medium shield", "plural": "medium shields" },
|
||||
"renderable": { "glyph": "[", "fg": "#C0C0C0", "bg": "#000000", "order": 2 },
|
||||
"class": "armour",
|
||||
"weight": 6,
|
||||
"value": 10,
|
||||
"flags": ["EQUIP_SHIELD"],
|
||||
|
|
@ -228,7 +207,6 @@
|
|||
"id": "equip_largeshield",
|
||||
"name": { "name": "large shield", "plural": "large shields" },
|
||||
"renderable": { "glyph": "[", "fg": "#FFF8DC", "bg": "#000000", "order": 2 },
|
||||
"class": "armour",
|
||||
"weight": 12,
|
||||
"value": 35,
|
||||
"flags": ["EQUIP_SHIELD"],
|
||||
|
|
@ -238,7 +216,6 @@
|
|||
"id": "equip_body_weakleather",
|
||||
"name": { "name": "leather jacket", "plural": "leather jackets" },
|
||||
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 2 },
|
||||
"class": "armour",
|
||||
"weight": 8,
|
||||
"value": 5,
|
||||
"flags": ["EQUIP_BODY"],
|
||||
|
|
@ -248,7 +225,6 @@
|
|||
"id": "equip_body_leather",
|
||||
"name": { "name": "leather chestpiece", "plural": "leather chestpiece" },
|
||||
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 2 },
|
||||
"class": "armour",
|
||||
"weight": 10,
|
||||
"value": 10,
|
||||
"flags": ["EQUIP_BODY"],
|
||||
|
|
@ -258,7 +234,6 @@
|
|||
"id": "equip_body_studdedleather",
|
||||
"name": { "name": "studded leather chestpiece", "plural": "studded leather chestpieces" },
|
||||
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 2 },
|
||||
"class": "armour",
|
||||
"weight": 13,
|
||||
"value": 45,
|
||||
"flags": ["EQUIP_BODY"],
|
||||
|
|
@ -268,7 +243,6 @@
|
|||
"id": "equip_body_ringmail_o",
|
||||
"name": { "name": "orcish ring mail", "plural": "orcish ring mail" },
|
||||
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 2 },
|
||||
"class": "armour",
|
||||
"weight": 45,
|
||||
"value": 50,
|
||||
"flags": ["EQUIP_BODY"],
|
||||
|
|
@ -278,7 +252,6 @@
|
|||
"id": "equip_body_ringmail",
|
||||
"name": { "name": "ring mail", "plural": "ring mail" },
|
||||
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 2 },
|
||||
"class": "armour",
|
||||
"weight": 45,
|
||||
"value": 70,
|
||||
"flags": ["EQUIP_BODY"],
|
||||
|
|
@ -288,7 +261,6 @@
|
|||
"id": "equip_head_leather",
|
||||
"name": { "name": "leather cap", "plural": "leather caps" },
|
||||
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 2 },
|
||||
"class": "armour",
|
||||
"weight": 2,
|
||||
"value": 10,
|
||||
"flags": ["EQUIP_HEAD"],
|
||||
|
|
@ -298,7 +270,6 @@
|
|||
"id": "equip_head_elvish",
|
||||
"name": { "name": "elvish leather helm", "plural": "elvish leather helms" },
|
||||
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 2 },
|
||||
"class": "armour",
|
||||
"weight": 2,
|
||||
"value": 25,
|
||||
"flags": ["EQUIP_HEAD"],
|
||||
|
|
@ -308,7 +279,6 @@
|
|||
"id": "equip_head_o",
|
||||
"name": { "name": "orcish helm", "plural": "orcish helm" },
|
||||
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 2 },
|
||||
"class": "armour",
|
||||
"weight": 6,
|
||||
"value": 25,
|
||||
"flags": ["EQUIP_HEAD"],
|
||||
|
|
@ -318,7 +288,6 @@
|
|||
"id": "equip_head_iron",
|
||||
"name": { "name": "iron helm", "plural": "iron helm" },
|
||||
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 2 },
|
||||
"class": "armour",
|
||||
"weight": 10,
|
||||
"value": 45,
|
||||
"flags": ["EQUIP_HEAD"],
|
||||
|
|
@ -328,7 +297,6 @@
|
|||
"id": "equip_feet_leather",
|
||||
"name": { "name": "leather shoes", "plural": "leather shoes" },
|
||||
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 2 },
|
||||
"class": "armour",
|
||||
"weight": 2,
|
||||
"value": 10,
|
||||
"flags": ["EQUIP_FEET"]
|
||||
|
|
@ -337,7 +305,6 @@
|
|||
"id": "equip_feet_elvish",
|
||||
"name": { "name": "elvish leather shoes", "plural": "elvish leather shoes" },
|
||||
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 2 },
|
||||
"class": "armour",
|
||||
"weight": 2,
|
||||
"value": 25,
|
||||
"flags": ["EQUIP_FEET"],
|
||||
|
|
@ -347,7 +314,6 @@
|
|||
"id": "equip_feet_o",
|
||||
"name": { "name": "orcish boots", "plural": "orcish boots" },
|
||||
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 2 },
|
||||
"class": "armour",
|
||||
"weight": 6,
|
||||
"value": 25,
|
||||
"flags": ["EQUIP_FEET"],
|
||||
|
|
@ -357,7 +323,6 @@
|
|||
"id": "equip_feet_iron",
|
||||
"name": { "name": "iron boots", "plural": "iron boots" },
|
||||
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 2 },
|
||||
"class": "armour",
|
||||
"weight": 10,
|
||||
"value": 45,
|
||||
"flags": ["EQUIP_FEET"],
|
||||
|
|
@ -367,7 +332,6 @@
|
|||
"id": "equip_neck_protection",
|
||||
"name": { "name": "amulet of protection", "plural": "amulets of protection" },
|
||||
"renderable": { "glyph": "\"", "fg": "#aa6000", "bg": "#000000", "order": 2 },
|
||||
"class": "amulet",
|
||||
"weight": 1,
|
||||
"value": 200,
|
||||
"flags": ["EQUIP_NECK"],
|
||||
|
|
@ -377,7 +341,6 @@
|
|||
"id": "equip_back_protection",
|
||||
"name": { "name": "cloak of protection", "plural": "cloaks of protection" },
|
||||
"renderable": { "glyph": "[", "fg": "#aa6000", "bg": "#000000", "order": 2 },
|
||||
"class": "armour",
|
||||
"weight": 1,
|
||||
"value": 200,
|
||||
"flags": ["EQUIP_BACK"],
|
||||
|
|
@ -387,7 +350,6 @@
|
|||
"id": "wand_magicmissile",
|
||||
"name": { "name": "wand of magic missile", "plural": "wands of magic missile" },
|
||||
"renderable": { "glyph": "/", "fg": "#00FFFF", "bg": "#000000", "order": 2 },
|
||||
"class": "wand",
|
||||
"weight": 2,
|
||||
"value": 100,
|
||||
"flags": ["CHARGES"],
|
||||
|
|
@ -398,7 +360,6 @@
|
|||
"id": "wand_fireball",
|
||||
"name": { "name": "wand of fireball", "plural": "wands of fireball" },
|
||||
"renderable": { "glyph": "/", "fg": "#00FFFF", "bg": "#000000", "order": 2 },
|
||||
"class": "wand",
|
||||
"weight": 2,
|
||||
"value": 300,
|
||||
"flags": ["CHARGES"],
|
||||
|
|
@ -409,7 +370,6 @@
|
|||
"id": "wand_confusion",
|
||||
"name": { "name": "wand of confusion", "plural": "wands of confusion" },
|
||||
"renderable": { "glyph": "/", "fg": "#00FFFF", "bg": "#000000", "order": 2 },
|
||||
"class": "wand",
|
||||
"weight": 2,
|
||||
"value": 200,
|
||||
"flags": ["CHARGES"],
|
||||
|
|
@ -420,7 +380,6 @@
|
|||
"id": "wand_digging",
|
||||
"name": { "name": "wand of digging", "plural": "wands of digging" },
|
||||
"renderable": { "glyph": "/", "fg": "#00FFFF", "bg": "#000000", "order": 2 },
|
||||
"class": "wand",
|
||||
"weight": 2,
|
||||
"value": 300,
|
||||
"flags": ["CHARGES", "DIGGER"],
|
||||
|
|
@ -431,18 +390,16 @@
|
|||
"id": "food_rations",
|
||||
"name": { "name": "rations", "plural": "rations" },
|
||||
"renderable": { "glyph": "%", "fg": "#FFA07A", "bg": "#000000", "order": 2 },
|
||||
"class": "comestible",
|
||||
"weight": 1,
|
||||
"value": 1,
|
||||
"flags": ["FOOD", "CONSUMABLE", "STACKABLE"]
|
||||
"flags": ["FOOD", "CONSUMABLE"]
|
||||
},
|
||||
{
|
||||
"id": "food_apple",
|
||||
"name": { "name": "apple", "plural": "apples" },
|
||||
"renderable": { "glyph": "%", "fg": "#00FF00", "bg": "#000000", "order": 2 },
|
||||
"class": "comestible",
|
||||
"weight": 0.5,
|
||||
"value": 1,
|
||||
"flags": ["FOOD", "CONSUMABLE", "STACKABLE"]
|
||||
"flags": ["FOOD", "CONSUMABLE"]
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
{
|
||||
"id": "door",
|
||||
"name": "door",
|
||||
"renderable": { "glyph": "+", "fg": "#00FFFF", "bg": "#000000", "order": 2 },
|
||||
"renderable": { "glyph": "+", "sprite": 17, "fg": "#00FFFF", "bg": "#000000", "order": 2 },
|
||||
"flags": ["DOOR"]
|
||||
},
|
||||
{
|
||||
|
|
@ -21,7 +21,7 @@
|
|||
{
|
||||
"id": "prop_table",
|
||||
"name": "table",
|
||||
"renderable": { "glyph": "-", "fg": "#AAAAAA", "bg": "#000000", "order": 2 },
|
||||
"renderable": { "glyph": "-", "sprite": 52, "fg": "#AAAAAA", "bg": "#000000", "order": 2 },
|
||||
"flags": []
|
||||
},
|
||||
{
|
||||
|
|
@ -33,25 +33,25 @@
|
|||
{
|
||||
"id": "prop_statue",
|
||||
"name": "statue",
|
||||
"renderable": { "glyph": "@", "fg": "#ffffff", "bg": "#000000", "order": 2 },
|
||||
"renderable": { "glyph": "@", "sprite": 29, "fg": "#ffffff", "bg": "#000000", "order": 2 },
|
||||
"flags": []
|
||||
},
|
||||
{
|
||||
"id": "prop_bed",
|
||||
"name": "bed",
|
||||
"renderable": { "glyph": "=", "fg": "#AAAAAA", "bg": "#000000", "order": 2 },
|
||||
"renderable": { "glyph": "=", "sprite": 50, "fg": "#AAAAAA", "bg": "#000000", "order": 2 },
|
||||
"flags": []
|
||||
},
|
||||
{
|
||||
"id": "prop_chair",
|
||||
"name": "chair",
|
||||
"renderable": { "glyph": "└", "fg": "#AAAAAA", "bg": "#000000", "order": 2 },
|
||||
"renderable": { "glyph": "└", "sprite": 51, "fg": "#AAAAAA", "bg": "#000000", "order": 2 },
|
||||
"flags": []
|
||||
},
|
||||
{
|
||||
"id": "prop_candle",
|
||||
"name": "candle",
|
||||
"renderable": { "glyph": "Ä", "fg": "#FFA500", "bg": "#000000", "order": 2 },
|
||||
"renderable": { "glyph": "Ä", "sprite": 3, "fg": "#FFA500", "bg": "#000000", "order": 2 },
|
||||
"flags": []
|
||||
},
|
||||
{
|
||||
|
|
|
|||
BIN
resources/curses11x20.png
Normal file
|
After Width: | Height: | Size: 6.8 KiB |
BIN
resources/curses12x24.png
Normal file
|
After Width: | Height: | Size: 7.9 KiB |
BIN
resources/curses16x16.pdn
Normal file
BIN
resources/curses16x16.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
resources/curses8x16.pdn
Normal file
BIN
resources/curses8x16.png
Normal file
|
After Width: | Height: | Size: 6.3 KiB |
BIN
resources/healthbar11x2.png
Normal file
|
After Width: | Height: | Size: 406 B |
BIN
resources/healthbar22x2.png
Normal file
|
After Width: | Height: | Size: 337 B |
BIN
resources/nagidal22x20_centred.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
resources/nagidal22x22_centred.png
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
resources/nagidal24x24.png
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
resources/terminal10x10_gs_tc.png
Normal file
|
After Width: | Height: | Size: 8.6 KiB |
BIN
resources/vga8x16.png
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
resources/world16x16.png
Normal file
|
After Width: | Height: | Size: 50 KiB |
|
|
@ -45,6 +45,7 @@ impl<'a> System<'a> for ApproachAI {
|
|||
continue;
|
||||
};
|
||||
let mut path: Option<NavigationPath> = None;
|
||||
let mut curr_abs_diff = 100;
|
||||
let idx = map.xy_idx(pos.x, pos.y);
|
||||
for tar_idx in target_idxs {
|
||||
let potential_path = a_star_search(idx, tar_idx, &mut *map);
|
||||
|
|
@ -54,6 +55,17 @@ impl<'a> System<'a> for ApproachAI {
|
|||
potential_path.steps.len() < path.as_ref().unwrap().steps.len()
|
||||
{
|
||||
path = Some(potential_path);
|
||||
let (x1, y1) = (pos.x, pos.y);
|
||||
let (x2, y2) = ((tar_idx as i32) % map.width, (tar_idx as i32) / map.width);
|
||||
curr_abs_diff = i32::abs(x2 - x1) + i32::abs(y2 - y1);
|
||||
} else if potential_path.steps.len() == path.as_ref().unwrap().steps.len() {
|
||||
let (x1, y1) = (pos.x, pos.y);
|
||||
let (x2, y2) = ((tar_idx as i32) % map.width, (tar_idx as i32) / map.width);
|
||||
let abs_diff = i32::abs(x2 - x1) + i32::abs(y2 - y1);
|
||||
if abs_diff < curr_abs_diff {
|
||||
path = Some(potential_path);
|
||||
curr_abs_diff = abs_diff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,7 +65,9 @@ impl<'a> System<'a> for TurnStatusSystem {
|
|||
not_confused.push(entity);
|
||||
if entity == *player_entity {
|
||||
logger = logger
|
||||
.colour(renderable_colour(&renderables, entity))
|
||||
.append("You")
|
||||
.colour(WHITE)
|
||||
.append("snap out of it.");
|
||||
log = true;
|
||||
} else {
|
||||
|
|
@ -92,7 +94,9 @@ impl<'a> System<'a> for TurnStatusSystem {
|
|||
not_my_turn.push(entity);
|
||||
if entity == *player_entity {
|
||||
logger = logger
|
||||
.colour(renderable_colour(&renderables, entity))
|
||||
.append("You")
|
||||
.colour(WHITE)
|
||||
.append("are confused!");
|
||||
log = true;
|
||||
gamelog::record_event(EVENT::PlayerConfused(1));
|
||||
|
|
|
|||
|
|
@ -1,14 +1,16 @@
|
|||
use super::{ Hidden, Map, Mind, Position, Prop, Renderable };
|
||||
use super::{ Hidden, Map, Mind, Position, Prop, Renderable, Pools };
|
||||
use bracket_lib::prelude::*;
|
||||
use specs::prelude::*;
|
||||
use std::ops::Mul;
|
||||
use super::data::visuals::{ VIEWPORT_W, VIEWPORT_H };
|
||||
use super::data::prelude::*;
|
||||
|
||||
const SHOW_BOUNDARIES: bool = false;
|
||||
|
||||
pub fn get_screen_bounds(ecs: &World, _ctx: &mut BTerm) -> (i32, i32, i32, i32, i32, i32) {
|
||||
let player_pos = ecs.fetch::<Point>();
|
||||
let map = ecs.fetch::<Map>();
|
||||
let (x_chars, y_chars, mut x_offset, mut y_offset) = (69, 41, 1, 10);
|
||||
let (x_chars, y_chars, mut x_offset, mut y_offset) = (VIEWPORT_W, VIEWPORT_H, 1, 10);
|
||||
|
||||
let centre_x = (x_chars / 2) as i32;
|
||||
let centre_y = (y_chars / 2) as i32;
|
||||
|
|
@ -43,13 +45,29 @@ pub fn render_camera(ecs: &World, ctx: &mut BTerm) {
|
|||
if t_x >= 0 && t_x < map.width && t_y >= 0 && t_y < map.height {
|
||||
let idx = map.xy_idx(t_x, t_y);
|
||||
if map.revealed_tiles[idx] {
|
||||
let (glyph, fg, bg) = crate::map::themes::get_tile_renderables_for_id(
|
||||
idx,
|
||||
&*map,
|
||||
Some(*ecs.fetch::<Point>()),
|
||||
None
|
||||
);
|
||||
ctx.set(x + x_offset, y + y_offset, fg, bg, glyph);
|
||||
if 1 == 2 {
|
||||
let (glyph, fg, bg) = crate::map::themes::get_tile_renderables_for_id(
|
||||
idx,
|
||||
&*map,
|
||||
Some(*ecs.fetch::<Point>()),
|
||||
None
|
||||
);
|
||||
ctx.set(x + x_offset, y + y_offset, fg, bg, glyph);
|
||||
} else {
|
||||
ctx.set_active_console(0);
|
||||
let (id, tint) = crate::map::themes::get_sprite_for_id(
|
||||
idx,
|
||||
&*map,
|
||||
Some(*ecs.fetch::<Point>())
|
||||
);
|
||||
ctx.add_sprite(
|
||||
Rect::with_size(x * 16 + x_offset * 16, y * 16 + y_offset * 16, 16, 16),
|
||||
0,
|
||||
tint,
|
||||
id
|
||||
);
|
||||
ctx.set_active_console(TILE_LAYER);
|
||||
}
|
||||
}
|
||||
} else if SHOW_BOUNDARIES {
|
||||
ctx.set(
|
||||
|
|
@ -67,8 +85,11 @@ pub fn render_camera(ecs: &World, ctx: &mut BTerm) {
|
|||
|
||||
// Render entities
|
||||
{
|
||||
ctx.set_active_console(ENTITY_LAYER);
|
||||
|
||||
let positions = ecs.read_storage::<Position>();
|
||||
let renderables = ecs.read_storage::<Renderable>();
|
||||
let pools = ecs.read_storage::<Pools>();
|
||||
let minds = ecs.read_storage::<Mind>();
|
||||
let hidden = ecs.read_storage::<Hidden>();
|
||||
let props = ecs.write_storage::<Prop>();
|
||||
|
|
@ -84,12 +105,7 @@ pub fn render_camera(ecs: &World, ctx: &mut BTerm) {
|
|||
if pos.x < max_x && pos.y < max_y && pos.x >= min_x && pos.y >= min_y {
|
||||
let mut draw = false;
|
||||
let mut fg = render.fg;
|
||||
let mut bg = crate::map::themes::get_tile_renderables_for_id(
|
||||
idx,
|
||||
&*map,
|
||||
Some(*ecs.fetch::<Point>()),
|
||||
None
|
||||
).2;
|
||||
let bg = BLACK;
|
||||
// Draw entities on visible tiles
|
||||
if map.visible_tiles[idx] {
|
||||
draw = true;
|
||||
|
|
@ -104,9 +120,6 @@ pub fn render_camera(ecs: &World, ctx: &mut BTerm) {
|
|||
let has_mind = minds.get(*ent);
|
||||
if let Some(_) = has_mind {
|
||||
draw = true;
|
||||
if !map.revealed_tiles[idx] {
|
||||
bg = RGB::named(BLACK);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -118,16 +131,51 @@ pub fn render_camera(ecs: &World, ctx: &mut BTerm) {
|
|||
}
|
||||
}
|
||||
if draw {
|
||||
ctx.set(
|
||||
entity_offset_x + x_offset,
|
||||
entity_offset_y + y_offset,
|
||||
fg,
|
||||
bg,
|
||||
render.glyph
|
||||
);
|
||||
if let Some(sprite) = render.sprite {
|
||||
ctx.set_active_console(0);
|
||||
ctx.add_sprite(
|
||||
Rect::with_size(
|
||||
entity_offset_x * 16 + x_offset * 16,
|
||||
entity_offset_y * 16 + y_offset * 16,
|
||||
16,
|
||||
16
|
||||
),
|
||||
render.render_order,
|
||||
RGBA::named(WHITE),
|
||||
sprite
|
||||
);
|
||||
ctx.set_active_console(ENTITY_LAYER);
|
||||
} else {
|
||||
ctx.set(
|
||||
entity_offset_x + x_offset,
|
||||
entity_offset_y + y_offset,
|
||||
fg,
|
||||
bg,
|
||||
render.glyph
|
||||
);
|
||||
}
|
||||
if let Some(pool) = pools.get(*ent) {
|
||||
if pool.hit_points.current < pool.hit_points.max {
|
||||
ctx.set_active_console(HP_BAR_LAYER);
|
||||
crate::gui::draw_lerping_bar(
|
||||
ctx,
|
||||
(entity_offset_x + x_offset) * 16 + 2,
|
||||
(entity_offset_y + y_offset) * 16 - 1,
|
||||
14,
|
||||
pool.hit_points.current,
|
||||
pool.hit_points.max,
|
||||
RGB::named(GREEN),
|
||||
RGB::named(RED),
|
||||
false,
|
||||
false
|
||||
);
|
||||
ctx.set_active_console(ENTITY_LAYER);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ctx.set_active_console(TILE_LAYER);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ pub struct OtherLevelPosition {
|
|||
#[derive(Component, ConvertSaveload, Clone)]
|
||||
pub struct Renderable {
|
||||
pub glyph: FontCharType,
|
||||
pub sprite: Option<usize>,
|
||||
pub fg: RGB,
|
||||
pub bg: RGB,
|
||||
pub render_order: i32,
|
||||
|
|
@ -243,55 +244,16 @@ pub enum BUC {
|
|||
Blessed,
|
||||
}
|
||||
|
||||
impl BUC {
|
||||
pub fn noncursed(&self) -> bool {
|
||||
match self {
|
||||
BUC::Cursed => false,
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Component, Debug, Serialize, Deserialize, Eq, PartialEq, Hash, Clone)]
|
||||
pub struct Beatitude {
|
||||
pub buc: BUC,
|
||||
pub known: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum ItemType {
|
||||
Amulet,
|
||||
Weapon,
|
||||
Armour,
|
||||
Comestible,
|
||||
Scroll,
|
||||
Spellbook,
|
||||
Potion,
|
||||
Ring,
|
||||
Wand,
|
||||
}
|
||||
|
||||
impl ItemType {
|
||||
pub fn string(&self) -> &str {
|
||||
match self {
|
||||
ItemType::Amulet => "Amulets",
|
||||
ItemType::Weapon => "Weapons",
|
||||
ItemType::Armour => "Armour",
|
||||
ItemType::Comestible => "Comestibles",
|
||||
ItemType::Scroll => "Scrolls",
|
||||
ItemType::Spellbook => "Spellbooks",
|
||||
ItemType::Potion => "Potions",
|
||||
ItemType::Ring => "Rings",
|
||||
ItemType::Wand => "Wands",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct Item {
|
||||
pub weight: f32, // in lbs
|
||||
pub value: f32, // base
|
||||
pub category: ItemType,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq, Hash)]
|
||||
|
|
@ -466,45 +428,11 @@ pub enum Intrinsic {
|
|||
Speed, // 4/3x speed multiplier
|
||||
}
|
||||
|
||||
impl Intrinsic {
|
||||
pub fn describe(&self) -> &str {
|
||||
match self {
|
||||
Intrinsic::Regeneration => "regenerates health",
|
||||
Intrinsic::Speed => "is hasted",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Component, Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct Intrinsics {
|
||||
pub list: HashSet<Intrinsic>,
|
||||
}
|
||||
|
||||
impl Intrinsics {
|
||||
pub fn describe(&self) -> String {
|
||||
let mut descriptions = Vec::new();
|
||||
for intrinsic in &self.list {
|
||||
descriptions.push(intrinsic.describe());
|
||||
}
|
||||
match descriptions.len() {
|
||||
0 =>
|
||||
unreachable!("describe() should never be called on an empty Intrinsics component."),
|
||||
1 => format!("It {}.", descriptions[0]),
|
||||
_ => {
|
||||
let last = descriptions.pop().unwrap();
|
||||
let joined = descriptions.join(", ");
|
||||
format!("It {}, and {}.", joined, last)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Component, Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct IntrinsicChanged {
|
||||
pub gained: HashSet<Intrinsic>,
|
||||
pub lost: HashSet<Intrinsic>,
|
||||
}
|
||||
|
||||
#[derive(Component, Debug, ConvertSaveload, Clone)]
|
||||
pub struct InflictsDamage {
|
||||
pub damage_type: DamageType,
|
||||
|
|
@ -648,20 +576,3 @@ pub struct EntityMoved {}
|
|||
|
||||
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct MultiAttack {}
|
||||
|
||||
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct Stackable {}
|
||||
|
||||
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct WantsToRemoveKey {}
|
||||
|
||||
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct WantsToDelete {}
|
||||
|
||||
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct Key {
|
||||
pub idx: usize,
|
||||
}
|
||||
|
||||
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct WantsToAssignKey {}
|
||||
|
|
|
|||
|
|
@ -11,8 +11,6 @@ use super::{
|
|||
Position,
|
||||
Renderable,
|
||||
RunState,
|
||||
WantsToRemoveKey,
|
||||
WantsToDelete,
|
||||
};
|
||||
use bracket_lib::prelude::*;
|
||||
use specs::prelude::*;
|
||||
|
|
@ -67,17 +65,7 @@ pub fn delete_the_dead(ecs: &mut World) {
|
|||
}
|
||||
}
|
||||
}
|
||||
let (mut items_to_delete, loot_to_spawn) = handle_dead_entity_items(ecs, &dead);
|
||||
{
|
||||
let entities = ecs.entities();
|
||||
let removekeys = ecs.read_storage::<WantsToRemoveKey>();
|
||||
let delete = ecs.read_storage::<WantsToDelete>();
|
||||
// Add items marked for deletion to the list, but only if they've already had their
|
||||
// key assignments handled, to ensurew we don't leave any dangling references behind.
|
||||
for (e, _d, _r) in (&entities, &delete, !&removekeys).join() {
|
||||
items_to_delete.push(e);
|
||||
}
|
||||
}
|
||||
let (items_to_delete, loot_to_spawn) = handle_dead_entity_items(ecs, &dead);
|
||||
for loot in loot_to_spawn {
|
||||
crate::raws::spawn_named_entity(
|
||||
&crate::raws::RAWS.lock().unwrap(),
|
||||
|
|
@ -94,7 +82,6 @@ pub fn delete_the_dead(ecs: &mut World) {
|
|||
// For everything that died, increment the event log, and delete.
|
||||
for victim in dead {
|
||||
gamelog::record_event(events::EVENT::Turn(1));
|
||||
// TODO: Delete stuff from inventory? This should be handled elsewhere.
|
||||
ecs.delete_entity(victim).expect("Unable to delete.");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ pub const NUTRITION_BLESSED: &str = "Delicious";
|
|||
|
||||
pub const LEVELUP_PLAYER: &str = "Welcome to experience level";
|
||||
pub const YOU_PICKUP_ITEM: &str = "You pick up the";
|
||||
pub const NO_MORE_KEYS: &str = "Your backpack cannot accomodate any more items";
|
||||
pub const YOU_DROP_ITEM: &str = "You drop the";
|
||||
pub const YOU_EQUIP_ITEM: &str = "You equip the";
|
||||
pub const YOU_REMOVE_ITEM: &str = "You unequip your";
|
||||
|
|
|
|||
|
|
@ -5,3 +5,8 @@ pub mod char_create;
|
|||
pub mod events;
|
||||
pub mod ids;
|
||||
pub mod names;
|
||||
pub mod sprites;
|
||||
|
||||
pub mod prelude {
|
||||
pub use super::visuals::{ TILE_LAYER, ENTITY_LAYER, TEXT_LAYER, HP_BAR_LAYER };
|
||||
}
|
||||
|
|
|
|||
119
src/data/sprites.rs
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
// Row 1
|
||||
pub const UNKN: usize = 0;
|
||||
pub const UNKN2: usize = 1;
|
||||
pub const UNKN3: usize = 2;
|
||||
pub const CANDLE: usize = 3;
|
||||
pub const CANDLE2: usize = 4;
|
||||
pub const CANDLE3: usize = 5;
|
||||
pub const CANDLE4: usize = 6;
|
||||
pub const CANDLE5: usize = 7;
|
||||
pub const CANDLE6: usize = 8;
|
||||
pub const CAULDRON: usize = 9;
|
||||
pub const CAULDRON2: usize = 10;
|
||||
pub const POTS: usize = 11;
|
||||
pub const POTS2: usize = 12;
|
||||
pub const POT: usize = 13;
|
||||
pub const SPIKES: usize = 14;
|
||||
pub const SPIKES2: usize = 15;
|
||||
// Row 2
|
||||
pub const WINDOW: usize = 16;
|
||||
pub const DOOR: usize = 17;
|
||||
pub const DOOR_OPEN: usize = 18;
|
||||
pub const ROOF_BASE: usize = 19;
|
||||
pub const ROOF_BASE2: usize = 20;
|
||||
pub const ROOF: usize = 21;
|
||||
pub const ROOF2: usize = 22;
|
||||
pub const ROOF_CHIMNEY: usize = 23;
|
||||
pub const SIGN: usize = 24;
|
||||
pub const SIGN_BLACKSMITH: usize = 25;
|
||||
pub const SIGN_POTION: usize = 26;
|
||||
pub const SIGN_FURNITURE: usize = 27;
|
||||
pub const WINDOW_LIT: usize = 28;
|
||||
pub const STATUE_ANGEL: usize = 29;
|
||||
pub const STATUE: usize = 30;
|
||||
pub const STATUE_SPIDER: usize = 31;
|
||||
// Row 3
|
||||
pub const UNKN4: usize = 32;
|
||||
pub const UNKN5: usize = 33;
|
||||
pub const UNKN6: usize = 34;
|
||||
pub const UNKN7: usize = 35;
|
||||
pub const UNKN8: usize = 36;
|
||||
pub const TREE: usize = 37;
|
||||
pub const TREE2: usize = 38;
|
||||
pub const PATH_GRASS: usize = 39;
|
||||
pub const PATH_GRASS_QUAD: usize = 40;
|
||||
pub const PATH_GRASS_QUAD2: usize = 41;
|
||||
pub const PATH_GRASS_QUAD3: usize = 42;
|
||||
pub const CAMPFIRE: usize = 43;
|
||||
pub const CAMPFIRE_LIT: usize = 44;
|
||||
pub const CAMPFIRE_LIT2: usize = 45; // ANIMATE WITH % 2 AND SOMETHING TO DO WITH FRAME TIME
|
||||
pub const THRONE: usize = 46;
|
||||
pub const THRONE2: usize = 47;
|
||||
// Row 4
|
||||
pub const BOOKSHELF: usize = 48;
|
||||
pub const BOOKSHELF_EMPTY: usize = 49;
|
||||
pub const BED: usize = 50;
|
||||
pub const CHAIR: usize = 51;
|
||||
pub const TABLE: usize = 52;
|
||||
pub const TABLE_L: usize = 53;
|
||||
pub const TABLE_M: usize = 54;
|
||||
pub const TABLE_R: usize = 55;
|
||||
pub const CHAIR_AT_TABLE_L: usize = 56;
|
||||
pub const TABLE_M_PARCHMENT: usize = 57;
|
||||
pub const CHAIR_AT_TABLE_R: usize = 58;
|
||||
pub const TABLE_DARK: usize = 59;
|
||||
pub const TABLE_DARK_SKULL: usize = 60;
|
||||
pub const TABLE_DARK_L: usize = 61;
|
||||
pub const TABLE_DARK_M: usize = 62;
|
||||
pub const TABLE_DARK_R: usize = 63;
|
||||
// Row 5
|
||||
pub const GRASS: usize = 64;
|
||||
pub const GRASS2: usize = 65;
|
||||
pub const GRASS3: usize = 66;
|
||||
pub const GRASS4: usize = 67;
|
||||
pub const GRASS5: usize = 68;
|
||||
pub const MUSHROOM: usize = 69;
|
||||
pub const MUSHROOM_PURPLE: usize = 70;
|
||||
pub const MUSHROOM_ORANGE: usize = 71;
|
||||
pub const LILYPAD: usize = 72;
|
||||
pub const LILYPAD2: usize = 73;
|
||||
pub const LILYPAD3: usize = 74;
|
||||
pub const LILYPAD4: usize = 75;
|
||||
pub const LILYPAD5: usize = 76;
|
||||
pub const LILYPAD6: usize = 77;
|
||||
pub const LILYPAD7: usize = 78;
|
||||
pub const LILYPAD8: usize = 79;
|
||||
// Row 6 (80-95)
|
||||
// Row 7 (96-111)
|
||||
// Row 8 (112-127)
|
||||
pub const FLOOR_WOOD: usize = 124;
|
||||
// Row 9 (128-143)
|
||||
// Row 10 (144-159)
|
||||
// Row 11 (160-175)
|
||||
pub const WATER_DEEP: usize = 164;
|
||||
// Row 12 (176-191)
|
||||
// Row 13 (192-207)
|
||||
// Row 14 (208-223)
|
||||
pub const FLOOR_GRASS: usize = 216;
|
||||
// Row 15 (224-239)
|
||||
pub const FLOOR: usize = 224;
|
||||
// Row 16 (240-255)
|
||||
// Row 17 (256-271)
|
||||
// Row 18 (272-287)
|
||||
// Row 19 (288-303)
|
||||
pub const WALL_BASE: usize = 288;
|
||||
pub const WALL_BASE2: usize = 289;
|
||||
pub const WALL_BASE3: usize = 290;
|
||||
pub const WALL_BASE4: usize = 291;
|
||||
pub const WALL_CLOTH_BASE: usize = 292;
|
||||
pub const WALL_CRACKED_BASE: usize = 293;
|
||||
pub const WALL: usize = 294;
|
||||
pub const WALL2: usize = 295;
|
||||
pub const WALL3: usize = 296;
|
||||
pub const WALL4: usize = 297;
|
||||
pub const WALL_CRACKED: usize = 298;
|
||||
pub const WALL_CLOTH_H: usize = 299;
|
||||
pub const STAIR_D: usize = 300;
|
||||
pub const STAIR_A: usize = 301;
|
||||
pub const BASIN: usize = 302;
|
||||
pub const BASIN_EMPTY: usize = 303;
|
||||
|
|
@ -2,6 +2,13 @@ use bracket_lib::prelude::*;
|
|||
|
||||
// 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;
|
||||
|
||||
pub const TILE_LAYER: usize = 1;
|
||||
pub const ENTITY_LAYER: usize = 2;
|
||||
pub const TEXT_LAYER: usize = 3;
|
||||
pub const HP_BAR_LAYER: usize = 4;
|
||||
|
||||
pub const BRIGHTEN_FG_COLOUR_BY: i32 = 16;
|
||||
pub const GLOBAL_OFFSET_MIN_CLAMP: f32 = -0.5;
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ fn get_death_message(ecs: &World, source: Entity) -> String {
|
|||
result.push_str(format!("{}", PLAYER_DIED_SUICIDE).as_str());
|
||||
} else if let Some(name) = ecs.read_storage::<Name>().get(source) {
|
||||
result.push_str(
|
||||
format!("{} {}", PLAYER_DIED_NAMED_ATTACKER, with_article(name.name.clone())).as_str()
|
||||
format!("{} {}", PLAYER_DIED_NAMED_ATTACKER, with_article(&name.name)).as_str()
|
||||
);
|
||||
} else {
|
||||
result.push_str(format!("{}", PLAYER_DIED_UNKNOWN).as_str());
|
||||
|
|
|
|||
|
|
@ -1,11 +0,0 @@
|
|||
use super::{ EffectSpawner, EffectType };
|
||||
use specs::prelude::*;
|
||||
|
||||
pub fn add_intrinsic(ecs: &mut World, effect: &EffectSpawner, target: Entity) {
|
||||
let intrinsic = if let EffectType::AddIntrinsic { intrinsic } = &effect.effect_type {
|
||||
intrinsic
|
||||
} else {
|
||||
unreachable!("add_intrinsic() called with the wrong EffectType")
|
||||
};
|
||||
add_intr!(ecs, target, *intrinsic);
|
||||
}
|
||||
|
|
@ -4,14 +4,13 @@ use bracket_lib::prelude::*;
|
|||
use specs::prelude::*;
|
||||
use std::collections::VecDeque;
|
||||
use std::sync::Mutex;
|
||||
use crate::components::*;
|
||||
use crate::components::DamageType;
|
||||
|
||||
mod damage;
|
||||
mod hunger;
|
||||
mod particles;
|
||||
mod targeting;
|
||||
mod triggers;
|
||||
mod intrinsics;
|
||||
|
||||
pub use targeting::aoe_tiles;
|
||||
|
||||
|
|
@ -52,9 +51,6 @@ pub enum EffectType {
|
|||
ModifyNutrition {
|
||||
amount: i32,
|
||||
},
|
||||
AddIntrinsic {
|
||||
intrinsic: Intrinsic,
|
||||
},
|
||||
TriggerFire {
|
||||
trigger: Entity,
|
||||
},
|
||||
|
|
@ -157,7 +153,6 @@ fn tile_effect_hits_entities(effect: &EffectType) -> bool {
|
|||
EffectType::Healing { .. } => true,
|
||||
EffectType::ModifyNutrition { .. } => true,
|
||||
EffectType::Confusion { .. } => true,
|
||||
EffectType::AddIntrinsic { .. } => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
@ -180,7 +175,6 @@ fn affect_entity(ecs: &mut World, effect: &EffectSpawner, target: Entity) {
|
|||
}
|
||||
EffectType::EntityDeath => damage::entity_death(ecs, effect, target),
|
||||
EffectType::ModifyNutrition { .. } => hunger::modify_nutrition(ecs, effect, target),
|
||||
EffectType::AddIntrinsic { .. } => intrinsics::add_intrinsic(ecs, effect, target),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use super::{ add_effect, particles, spatial, EffectType, Entity, Targets, World };
|
||||
use super::{ add_effect, get_noncursed, particles, spatial, EffectType, Entity, Targets, World };
|
||||
use crate::{
|
||||
gamelog,
|
||||
gui::item_colour_ecs,
|
||||
|
|
@ -33,8 +33,6 @@ use crate::{
|
|||
KnownSpells,
|
||||
Position,
|
||||
Viewshed,
|
||||
WantsToRemoveKey,
|
||||
WantsToDelete,
|
||||
};
|
||||
use crate::data::messages::*;
|
||||
use bracket_lib::prelude::*;
|
||||
|
|
@ -59,10 +57,7 @@ pub fn item_trigger(source: Option<Entity>, item: Entity, target: &Targets, ecs:
|
|||
let did_something = event_trigger(source, item, target, ecs);
|
||||
// If it's a consumable, delete it
|
||||
if did_something && ecs.read_storage::<Consumable>().get(item).is_some() {
|
||||
let mut removekey = ecs.write_storage::<WantsToRemoveKey>();
|
||||
removekey.insert(item, WantsToRemoveKey {}).expect("Unable to insert WantsToRemoveKey");
|
||||
let mut delete = ecs.write_storage::<WantsToDelete>();
|
||||
delete.insert(item, WantsToDelete {}).expect("Unable to insert WantsToDelete");
|
||||
ecs.entities().delete(item).expect("Failed to delete item");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -210,7 +205,7 @@ fn handle_healing(
|
|||
healing_item.modifier;
|
||||
add_effect(
|
||||
event.source,
|
||||
EffectType::Healing { amount: roll, increment_max: event.buc.noncursed() },
|
||||
EffectType::Healing { amount: roll, increment_max: get_noncursed(&event.buc) },
|
||||
event.target.clone()
|
||||
);
|
||||
for target in get_entity_targets(&event.target) {
|
||||
|
|
@ -223,7 +218,9 @@ fn handle_healing(
|
|||
let renderables = ecs.read_storage::<Renderable>();
|
||||
if ecs.read_storage::<Player>().get(target).is_some() {
|
||||
logger = logger
|
||||
.colour(renderable_colour(&renderables, target))
|
||||
.append("You")
|
||||
.colour(WHITE)
|
||||
.append(HEAL_PLAYER_HIT)
|
||||
.buc(event.buc.clone(), None, Some(HEAL_PLAYER_HIT_BLESSED));
|
||||
} else {
|
||||
|
|
@ -265,7 +262,9 @@ fn handle_damage(
|
|||
let player_viewshed = viewsheds.get(*ecs.fetch::<Entity>()).unwrap();
|
||||
if ecs.read_storage::<Player>().get(target).is_some() {
|
||||
logger = logger
|
||||
.colour(renderable_colour(&renderables, target))
|
||||
.append("You")
|
||||
.colour(WHITE)
|
||||
.append(DAMAGE_PLAYER_HIT);
|
||||
event.log = true;
|
||||
} else if
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ pub fn record_event(event: EVENT) {
|
|||
new_event = format!("Discovered {}", name);
|
||||
}
|
||||
EVENT::Identified(name) => {
|
||||
new_event = format!("Identified {}", crate::gui::with_article(name));
|
||||
new_event = format!("Identified {}", name);
|
||||
}
|
||||
EVENT::PlayerDied(str) => {
|
||||
// Generating the String is handled in the death effect, to avoid passing the ecs here.
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ use bracket_lib::prelude::*;
|
|||
use serde::{ Deserialize, Serialize };
|
||||
use specs::prelude::*;
|
||||
use std::collections::HashMap;
|
||||
use crate::data::prelude::*;
|
||||
|
||||
#[derive(Serialize, Deserialize, Copy, Clone, PartialEq)]
|
||||
pub enum Ancestry {
|
||||
|
|
@ -112,6 +113,7 @@ pub enum CharCreateResult {
|
|||
|
||||
/// Handles the player character creation screen.
|
||||
pub fn character_creation(gs: &mut State, ctx: &mut BTerm) -> CharCreateResult {
|
||||
ctx.set_active_console(TEXT_LAYER);
|
||||
let runstate = gs.ecs.fetch::<RunState>();
|
||||
|
||||
let mut x = 2;
|
||||
|
|
@ -245,6 +247,7 @@ pub fn character_creation(gs: &mut State, ctx: &mut BTerm) -> CharCreateResult {
|
|||
}
|
||||
}
|
||||
}
|
||||
ctx.set_active_console(TILE_LAYER);
|
||||
return CharCreateResult::NoSelection { ancestry: Ancestry::Human, class: Class::Fighter };
|
||||
}
|
||||
|
||||
|
|
@ -270,6 +273,7 @@ pub fn setup_player_ancestry(ecs: &mut World, ancestry: Ancestry) {
|
|||
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,
|
||||
|
|
@ -281,6 +285,7 @@ pub fn setup_player_ancestry(ecs: &mut World, ancestry: Ancestry) {
|
|||
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,
|
||||
|
|
@ -306,6 +311,7 @@ pub fn setup_player_ancestry(ecs: &mut World, ancestry: Ancestry) {
|
|||
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,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,11 @@
|
|||
use super::{ State, RunState, tooltip::draw_tooltips, camera::get_screen_bounds };
|
||||
use super::{
|
||||
State,
|
||||
RunState,
|
||||
tooltip::draw_tooltips,
|
||||
camera::get_screen_bounds,
|
||||
VIEWPORT_H,
|
||||
VIEWPORT_W,
|
||||
};
|
||||
use bracket_lib::prelude::*;
|
||||
|
||||
#[derive(PartialEq, Copy, Clone)]
|
||||
|
|
@ -23,9 +30,8 @@ pub fn show_farlook(gs: &mut State, ctx: &mut BTerm) -> FarlookResult {
|
|||
);
|
||||
|
||||
if let RunState::Farlook { x, y } = *runstate {
|
||||
let (screen_x, screen_y) = (69, 41);
|
||||
let x = x.clamp(x_offset, x_offset - 1 + (screen_x as i32));
|
||||
let y = y.clamp(y_offset, y_offset - 1 + (screen_y as i32));
|
||||
let x = x.clamp(x_offset, x_offset - 1 + VIEWPORT_W);
|
||||
let y = y.clamp(y_offset, y_offset - 1 + VIEWPORT_H);
|
||||
|
||||
ctx.set(x, y, RGB::named(WHITE), RGB::named(BLACK), to_cp437('X'));
|
||||
draw_tooltips(&gs.ecs, ctx, Some((x, y)));
|
||||
|
|
|
|||
|
|
@ -3,10 +3,10 @@ use super::{
|
|||
item_colour_ecs,
|
||||
obfuscate_name_ecs,
|
||||
print_options,
|
||||
unique_ecs,
|
||||
check_key,
|
||||
letter_to_option,
|
||||
renderable_colour,
|
||||
ItemMenuResult,
|
||||
UniqueInventoryItem,
|
||||
BUC,
|
||||
};
|
||||
use crate::{
|
||||
gamelog,
|
||||
|
|
@ -19,12 +19,11 @@ use crate::{
|
|||
Name,
|
||||
ObfuscatedName,
|
||||
Renderable,
|
||||
Key,
|
||||
states::state::*,
|
||||
};
|
||||
use bracket_lib::prelude::*;
|
||||
use specs::prelude::*;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
/// Handles the Identify menu.
|
||||
pub fn identify(gs: &mut State, ctx: &mut BTerm) -> (ItemMenuResult, Option<Entity>) {
|
||||
|
|
@ -38,41 +37,38 @@ pub fn identify(gs: &mut State, ctx: &mut BTerm) -> (ItemMenuResult, Option<Enti
|
|||
let names = gs.ecs.read_storage::<Name>();
|
||||
let renderables = gs.ecs.read_storage::<Renderable>();
|
||||
let beatitudes = gs.ecs.read_storage::<Beatitude>();
|
||||
let keys = gs.ecs.read_storage::<Key>();
|
||||
|
||||
let build_identify_iterator = || {
|
||||
(&entities, &items, &renderables, &names, &keys)
|
||||
.join()
|
||||
.filter(|(item_entity, _i, _r, n, _k)| {
|
||||
// If not owned by the player, return false.
|
||||
let mut keep = false;
|
||||
if let Some(bp) = backpack.get(*item_entity) {
|
||||
if bp.owner == *player_entity {
|
||||
keep = true;
|
||||
}
|
||||
(&entities, &items, &renderables, &names).join().filter(|(item_entity, _i, _r, n)| {
|
||||
// If not owned by the player, return false.
|
||||
let mut keep = false;
|
||||
if let Some(bp) = backpack.get(*item_entity) {
|
||||
if bp.owner == *player_entity {
|
||||
keep = true;
|
||||
}
|
||||
// If not equipped by the player, return false.
|
||||
if let Some(equip) = equipped.get(*item_entity) {
|
||||
if equip.owner == *player_entity {
|
||||
keep = true;
|
||||
}
|
||||
}
|
||||
// If not equipped by the player, return false.
|
||||
if let Some(equip) = equipped.get(*item_entity) {
|
||||
if equip.owner == *player_entity {
|
||||
keep = true;
|
||||
}
|
||||
if !keep {
|
||||
return false;
|
||||
}
|
||||
// If not obfuscated, or already identified, return false.
|
||||
if
|
||||
(!obfuscated.get(*item_entity).is_some() ||
|
||||
dm.identified_items.contains(&n.name)) &&
|
||||
beatitudes
|
||||
.get(*item_entity)
|
||||
.map(|beatitude| beatitude.known)
|
||||
.unwrap_or(true)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
})
|
||||
}
|
||||
if !keep {
|
||||
return false;
|
||||
}
|
||||
// If not obfuscated, or already identified, return false.
|
||||
if
|
||||
(!obfuscated.get(*item_entity).is_some() ||
|
||||
dm.identified_items.contains(&n.name)) &&
|
||||
beatitudes
|
||||
.get(*item_entity)
|
||||
.map(|beatitude| beatitude.known)
|
||||
.unwrap_or(true)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
})
|
||||
};
|
||||
|
||||
// Build list of items to display
|
||||
|
|
@ -95,15 +91,34 @@ pub fn identify(gs: &mut State, ctx: &mut BTerm) -> (ItemMenuResult, Option<Enti
|
|||
.log();
|
||||
return (ItemMenuResult::Selected, Some(build_identify_iterator().nth(0).unwrap().0));
|
||||
}
|
||||
let mut player_inventory: super::PlayerInventory = HashMap::new();
|
||||
for (entity, _i, _r, _n, key) in build_identify_iterator() {
|
||||
let unique_item = unique_ecs(&gs.ecs, entity);
|
||||
let mut player_inventory: super::PlayerInventory = BTreeMap::new();
|
||||
for (entity, _i, renderable, name) in build_identify_iterator() {
|
||||
let (singular, plural) = obfuscate_name_ecs(&gs.ecs, entity);
|
||||
let beatitude_status = if
|
||||
let Some(beatitude) = gs.ecs.read_storage::<Beatitude>().get(entity)
|
||||
{
|
||||
match beatitude.buc {
|
||||
BUC::Blessed => 1,
|
||||
BUC::Uncursed => 2,
|
||||
BUC::Cursed => 3,
|
||||
}
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let unique_item = UniqueInventoryItem {
|
||||
display_name: super::DisplayName { singular: singular.clone(), plural: plural.clone() },
|
||||
rgb: item_colour_ecs(&gs.ecs, entity),
|
||||
renderables: renderable_colour(&renderables, entity),
|
||||
glyph: renderable.glyph,
|
||||
beatitude_status: beatitude_status,
|
||||
name: name.name.clone(),
|
||||
};
|
||||
player_inventory
|
||||
.entry(unique_item)
|
||||
.and_modify(|slot| {
|
||||
slot.count += 1;
|
||||
.and_modify(|(_e, count)| {
|
||||
*count += 1;
|
||||
})
|
||||
.or_insert(super::InventorySlot { item: entity, count: 1, idx: key.idx });
|
||||
.or_insert((entity, 1));
|
||||
}
|
||||
// Get display args
|
||||
let width = get_max_inventory_width(&player_inventory);
|
||||
|
|
@ -118,7 +133,7 @@ pub fn identify(gs: &mut State, ctx: &mut BTerm) -> (ItemMenuResult, Option<Enti
|
|||
"Identify which item? [aA-zZ][Esc.]"
|
||||
);
|
||||
ctx.draw_box(x, y, width + 2, count + 1, RGB::named(WHITE), RGB::named(BLACK));
|
||||
print_options(&gs.ecs, &player_inventory, x + 1, y + 1, ctx);
|
||||
print_options(&player_inventory, x + 1, y + 1, ctx);
|
||||
// Input
|
||||
match ctx.key {
|
||||
None => (ItemMenuResult::NoResponse, None),
|
||||
|
|
@ -126,17 +141,21 @@ pub fn identify(gs: &mut State, ctx: &mut BTerm) -> (ItemMenuResult, Option<Enti
|
|||
match key {
|
||||
VirtualKeyCode::Escape => (ItemMenuResult::Cancel, None),
|
||||
_ => {
|
||||
let selection = letter_to_option::letter_to_option(key, ctx.shift);
|
||||
if selection != -1 && check_key(selection as usize) {
|
||||
// Get the first entity with a Key {} component that has an idx matching "selection".
|
||||
let entities = gs.ecs.entities();
|
||||
let keyed_items = gs.ecs.read_storage::<Key>();
|
||||
let backpack = gs.ecs.read_storage::<InBackpack>();
|
||||
for (e, key, _b) in (&entities, &keyed_items, &backpack).join() {
|
||||
if key.idx == (selection as usize) {
|
||||
return (ItemMenuResult::Selected, Some(e));
|
||||
}
|
||||
}
|
||||
let selection = letter_to_option(key);
|
||||
if selection > -1 && selection < (count as i32) {
|
||||
let item = player_inventory
|
||||
.iter()
|
||||
.nth(selection as usize)
|
||||
.unwrap().1.0;
|
||||
gamelog::Logger
|
||||
::new()
|
||||
.append("You identify the")
|
||||
.colour(item_colour_ecs(&gs.ecs, item))
|
||||
.append_n(obfuscate_name_ecs(&gs.ecs, item).0)
|
||||
.colour(WHITE)
|
||||
.append("!")
|
||||
.log();
|
||||
return (ItemMenuResult::Selected, Some(item));
|
||||
}
|
||||
(ItemMenuResult::NoResponse, None)
|
||||
}
|
||||
|
|
|
|||
798
src/gui/mod.rs
|
|
@ -3,11 +3,9 @@ use super::{
|
|||
item_colour_ecs,
|
||||
obfuscate_name_ecs,
|
||||
print_options,
|
||||
unique_ecs,
|
||||
check_key,
|
||||
letter_to_option,
|
||||
renderable_colour,
|
||||
ItemMenuResult,
|
||||
InventorySlot,
|
||||
UniqueInventoryItem,
|
||||
};
|
||||
use crate::{
|
||||
gamelog,
|
||||
|
|
@ -20,11 +18,10 @@ use crate::{
|
|||
Renderable,
|
||||
states::state::*,
|
||||
BUC,
|
||||
Key,
|
||||
};
|
||||
use bracket_lib::prelude::*;
|
||||
use specs::prelude::*;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
/// Handles the Remove Curse menu.
|
||||
pub fn remove_curse(gs: &mut State, ctx: &mut BTerm) -> (ItemMenuResult, Option<Entity>) {
|
||||
|
|
@ -36,12 +33,11 @@ pub fn remove_curse(gs: &mut State, ctx: &mut BTerm) -> (ItemMenuResult, Option<
|
|||
let beatitudes = gs.ecs.read_storage::<Beatitude>();
|
||||
let names = gs.ecs.read_storage::<Name>();
|
||||
let renderables = gs.ecs.read_storage::<Renderable>();
|
||||
let keys = gs.ecs.read_storage::<Key>();
|
||||
|
||||
let build_cursed_iterator = || {
|
||||
(&entities, &items, &beatitudes, &renderables, &names, &keys)
|
||||
(&entities, &items, &beatitudes, &renderables, &names)
|
||||
.join()
|
||||
.filter(|(item_entity, _i, b, _r, _n, _k)| {
|
||||
.filter(|(item_entity, _i, b, _r, _n)| {
|
||||
// Set all items to FALSE initially.
|
||||
let mut keep = false;
|
||||
// If found in the player's backpack, set to TRUE
|
||||
|
|
@ -90,19 +86,34 @@ pub fn remove_curse(gs: &mut State, ctx: &mut BTerm) -> (ItemMenuResult, Option<
|
|||
.log();
|
||||
return (ItemMenuResult::Selected, Some(item));
|
||||
}
|
||||
let mut player_inventory: super::PlayerInventory = HashMap::new();
|
||||
for (entity, _i, _b, _r, _n, key) in build_cursed_iterator() {
|
||||
let unique_item = unique_ecs(&gs.ecs, entity);
|
||||
let mut player_inventory: super::PlayerInventory = BTreeMap::new();
|
||||
for (entity, _i, _b, renderable, name) in build_cursed_iterator() {
|
||||
let (singular, plural) = obfuscate_name_ecs(&gs.ecs, entity);
|
||||
let beatitude_status = if
|
||||
let Some(beatitude) = gs.ecs.read_storage::<Beatitude>().get(entity)
|
||||
{
|
||||
match beatitude.buc {
|
||||
BUC::Blessed => 1,
|
||||
BUC::Uncursed => 2,
|
||||
BUC::Cursed => 3,
|
||||
}
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let unique_item = UniqueInventoryItem {
|
||||
display_name: super::DisplayName { singular: singular.clone(), plural: plural.clone() },
|
||||
rgb: item_colour_ecs(&gs.ecs, entity),
|
||||
renderables: renderable_colour(&renderables, entity),
|
||||
glyph: renderable.glyph,
|
||||
beatitude_status: beatitude_status,
|
||||
name: name.name.clone(),
|
||||
};
|
||||
player_inventory
|
||||
.entry(unique_item)
|
||||
.and_modify(|slot| {
|
||||
slot.count += 1;
|
||||
.and_modify(|(_e, count)| {
|
||||
*count += 1;
|
||||
})
|
||||
.or_insert(InventorySlot {
|
||||
item: entity,
|
||||
count: 1,
|
||||
idx: key.idx,
|
||||
});
|
||||
.or_insert((entity, 1));
|
||||
}
|
||||
// Get display args
|
||||
let width = get_max_inventory_width(&player_inventory);
|
||||
|
|
@ -117,7 +128,7 @@ pub fn remove_curse(gs: &mut State, ctx: &mut BTerm) -> (ItemMenuResult, Option<
|
|||
"Decurse which item? [aA-zZ][Esc.]"
|
||||
);
|
||||
ctx.draw_box(x, y, width + 2, count + 1, RGB::named(WHITE), RGB::named(BLACK));
|
||||
print_options(&gs.ecs, &player_inventory, x + 1, y + 1, ctx);
|
||||
print_options(&player_inventory, x + 1, y + 1, ctx);
|
||||
// Input
|
||||
match ctx.key {
|
||||
None => (ItemMenuResult::NoResponse, None),
|
||||
|
|
@ -125,17 +136,21 @@ pub fn remove_curse(gs: &mut State, ctx: &mut BTerm) -> (ItemMenuResult, Option<
|
|||
match key {
|
||||
VirtualKeyCode::Escape => (ItemMenuResult::Cancel, None),
|
||||
_ => {
|
||||
let selection = letter_to_option::letter_to_option(key, ctx.shift);
|
||||
if selection != -1 && check_key(selection as usize) {
|
||||
// Get the first entity with a Key {} component that has an idx matching "selection".
|
||||
let entities = gs.ecs.entities();
|
||||
let keyed_items = gs.ecs.read_storage::<Key>();
|
||||
let backpack = gs.ecs.read_storage::<InBackpack>();
|
||||
for (e, key, _b) in (&entities, &keyed_items, &backpack).join() {
|
||||
if key.idx == (selection as usize) {
|
||||
return (ItemMenuResult::Selected, Some(e));
|
||||
}
|
||||
}
|
||||
let selection = letter_to_option(key);
|
||||
if selection > -1 && selection < (count as i32) {
|
||||
let item = player_inventory
|
||||
.iter()
|
||||
.nth(selection as usize)
|
||||
.unwrap().1.0;
|
||||
gamelog::Logger
|
||||
::new()
|
||||
.append("You decurse the")
|
||||
.colour(item_colour_ecs(&gs.ecs, item))
|
||||
.append_n(obfuscate_name_ecs(&gs.ecs, item).0)
|
||||
.colour(WHITE)
|
||||
.append("!")
|
||||
.log();
|
||||
return (ItemMenuResult::Selected, Some(item));
|
||||
}
|
||||
(ItemMenuResult::NoResponse, None)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ use super::{
|
|||
};
|
||||
use crate::TileType;
|
||||
use crate::data::ids::*;
|
||||
use crate::data::prelude::*;
|
||||
use bracket_lib::prelude::*;
|
||||
use specs::prelude::*;
|
||||
|
||||
|
|
@ -45,6 +46,7 @@ impl Tooltip {
|
|||
return (self.lines.len() as i32) + 2i32;
|
||||
}
|
||||
fn render(&self, ctx: &mut BTerm, x: i32, y: i32) {
|
||||
ctx.set_active_console(TEXT_LAYER);
|
||||
ctx.draw_box(
|
||||
x,
|
||||
y,
|
||||
|
|
@ -56,6 +58,7 @@ impl Tooltip {
|
|||
for (i, s) in self.lines.iter().enumerate() {
|
||||
ctx.print_color(x + 1, y + (i as i32) + 1, s.1, RGB::named(BLACK), &s.0);
|
||||
}
|
||||
ctx.set_active_console(TILE_LAYER);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -111,12 +114,6 @@ pub fn draw_tooltips(ecs: &World, ctx: &mut BTerm, xy: Option<(i32, i32)>) {
|
|||
if position.x == mouse_pos_adjusted.0 && position.y == mouse_pos_adjusted.1 {
|
||||
let mut tip = Tooltip::new();
|
||||
tip.add(crate::gui::obfuscate_name_ecs(ecs, entity).0, renderable.fg);
|
||||
let intrinsics = ecs.read_storage::<crate::components::Intrinsics>();
|
||||
if let Some(intrinsics) = intrinsics.get(entity) {
|
||||
if !intrinsics.list.is_empty() {
|
||||
tip.add(intrinsics.describe(), RGB::named(WHITE));
|
||||
}
|
||||
}
|
||||
// Attributes
|
||||
let attr = attributes.get(entity);
|
||||
if let Some(a) = attr {
|
||||
|
|
@ -175,13 +172,15 @@ pub fn draw_tooltips(ecs: &World, ctx: &mut BTerm, xy: Option<(i32, i32)>) {
|
|||
if mouse_pos.0 > 35 {
|
||||
// Render to the left
|
||||
arrow = to_cp437('→');
|
||||
arrow_x = mouse_pos.0 - 1;
|
||||
arrow_x = mouse_pos.0 * 2 - 1;
|
||||
} else {
|
||||
// Render to the right
|
||||
arrow = to_cp437('←');
|
||||
arrow_x = mouse_pos.0 + 1;
|
||||
arrow_x = (mouse_pos.0 + 1) * 2;
|
||||
}
|
||||
ctx.set_active_console(TEXT_LAYER);
|
||||
ctx.set(arrow_x, arrow_y, white, RGB::named(BLACK), arrow);
|
||||
ctx.set_active_console(TILE_LAYER);
|
||||
|
||||
let mut total_height = 0;
|
||||
for t in tooltips.iter() {
|
||||
|
|
@ -195,9 +194,9 @@ pub fn draw_tooltips(ecs: &World, ctx: &mut BTerm, xy: Option<(i32, i32)>) {
|
|||
|
||||
for t in tooltips.iter() {
|
||||
let x = if mouse_pos.0 > 35 {
|
||||
mouse_pos.0 - (1 + t.width())
|
||||
(mouse_pos.0 * 2) - (1 + t.width())
|
||||
} else {
|
||||
mouse_pos.0 + (1 + 1)
|
||||
(mouse_pos.0 * 2) + 2 + 1
|
||||
};
|
||||
t.render(ctx, x, y);
|
||||
y += t.height();
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ use crate::{
|
|||
ObfuscatedName,
|
||||
Position,
|
||||
WantsToPickupItem,
|
||||
WantsToAssignKey,
|
||||
};
|
||||
use specs::prelude::*;
|
||||
use crate::data::messages;
|
||||
|
|
@ -34,7 +33,6 @@ impl<'a> System<'a> for ItemCollectionSystem {
|
|||
ReadStorage<'a, Beatitude>,
|
||||
ReadExpect<'a, MasterDungeonMap>,
|
||||
ReadStorage<'a, Charges>,
|
||||
ReadStorage<'a, WantsToAssignKey>,
|
||||
);
|
||||
|
||||
fn run(&mut self, data: Self::SystemData) {
|
||||
|
|
@ -50,11 +48,17 @@ impl<'a> System<'a> for ItemCollectionSystem {
|
|||
beatitudes,
|
||||
dm,
|
||||
wands,
|
||||
wants_key,
|
||||
) = data;
|
||||
let mut to_remove: Vec<Entity> = Vec::new();
|
||||
// For every item that wants to be picked up that *isn't* waiting on a key assignment.
|
||||
for (pickup, _key) in (&wants_pickup, !&wants_key).join() {
|
||||
|
||||
for pickup in wants_pickup.join() {
|
||||
positions.remove(pickup.item);
|
||||
backpack
|
||||
.insert(pickup.item, InBackpack { owner: pickup.collected_by })
|
||||
.expect("Unable to pickup item.");
|
||||
equipment_changed
|
||||
.insert(pickup.collected_by, EquipmentChanged {})
|
||||
.expect("Unable to insert EquipmentChanged.");
|
||||
|
||||
if pickup.collected_by == *player_entity {
|
||||
gamelog::Logger
|
||||
::new()
|
||||
|
|
@ -78,17 +82,8 @@ impl<'a> System<'a> for ItemCollectionSystem {
|
|||
.period()
|
||||
.log();
|
||||
}
|
||||
positions.remove(pickup.item);
|
||||
backpack
|
||||
.insert(pickup.item, InBackpack { owner: pickup.collected_by })
|
||||
.expect("Unable to pickup item");
|
||||
equipment_changed
|
||||
.insert(pickup.collected_by, EquipmentChanged {})
|
||||
.expect("Unable to insert EquipmentChanged");
|
||||
to_remove.push(pickup.collected_by);
|
||||
}
|
||||
for item in to_remove.iter() {
|
||||
wants_pickup.remove(*item);
|
||||
}
|
||||
|
||||
wants_pickup.clear();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ use crate::{
|
|||
ObfuscatedName,
|
||||
Position,
|
||||
WantsToDropItem,
|
||||
WantsToRemoveKey,
|
||||
};
|
||||
use specs::prelude::*;
|
||||
use crate::data::messages;
|
||||
|
|
@ -35,7 +34,6 @@ impl<'a> System<'a> for ItemDropSystem {
|
|||
ReadStorage<'a, ObfuscatedName>,
|
||||
ReadExpect<'a, MasterDungeonMap>,
|
||||
ReadStorage<'a, Charges>,
|
||||
WriteStorage<'a, WantsToRemoveKey>,
|
||||
);
|
||||
|
||||
fn run(&mut self, data: Self::SystemData) {
|
||||
|
|
@ -52,7 +50,6 @@ impl<'a> System<'a> for ItemDropSystem {
|
|||
obfuscated_names,
|
||||
dm,
|
||||
wands,
|
||||
mut keys,
|
||||
) = data;
|
||||
|
||||
for (entity, to_drop) in (&entities, &wants_drop).join() {
|
||||
|
|
@ -71,9 +68,6 @@ impl<'a> System<'a> for ItemDropSystem {
|
|||
backpack.remove(to_drop.item);
|
||||
|
||||
if entity == *player_entity {
|
||||
keys.insert(to_drop.item, WantsToRemoveKey {}).expect(
|
||||
"Unable to insert WantsToRemoveKey"
|
||||
);
|
||||
gamelog::Logger
|
||||
::new()
|
||||
.append(messages::YOU_DROP_ITEM)
|
||||
|
|
|
|||
|
|
@ -1,153 +0,0 @@
|
|||
use crate::{
|
||||
gamelog,
|
||||
gui::unique,
|
||||
Beatitude,
|
||||
Charges,
|
||||
MagicItem,
|
||||
MasterDungeonMap,
|
||||
Name,
|
||||
ObfuscatedName,
|
||||
Stackable,
|
||||
Renderable,
|
||||
WantsToAssignKey,
|
||||
WantsToRemoveKey,
|
||||
Key,
|
||||
};
|
||||
use specs::prelude::*;
|
||||
use crate::data::messages;
|
||||
use bracket_lib::prelude::*;
|
||||
use crate::invkeys::*;
|
||||
|
||||
pub struct KeyHandling {}
|
||||
|
||||
const DEBUG_KEYHANDLING: bool = true;
|
||||
|
||||
impl<'a> System<'a> for KeyHandling {
|
||||
#[allow(clippy::type_complexity)]
|
||||
type SystemData = (
|
||||
Entities<'a>,
|
||||
WriteStorage<'a, WantsToAssignKey>,
|
||||
WriteStorage<'a, WantsToRemoveKey>,
|
||||
WriteStorage<'a, Key>,
|
||||
ReadStorage<'a, Stackable>,
|
||||
ReadStorage<'a, Name>,
|
||||
ReadStorage<'a, ObfuscatedName>,
|
||||
ReadStorage<'a, Renderable>,
|
||||
ReadStorage<'a, Beatitude>,
|
||||
ReadStorage<'a, MagicItem>,
|
||||
ReadStorage<'a, Charges>,
|
||||
ReadExpect<'a, MasterDungeonMap>,
|
||||
);
|
||||
|
||||
fn run(&mut self, data: Self::SystemData) {
|
||||
let (
|
||||
entities,
|
||||
mut wants_keys,
|
||||
mut wants_removekey,
|
||||
mut keys,
|
||||
stackable,
|
||||
names,
|
||||
obfuscated_names,
|
||||
renderables,
|
||||
beatitudes,
|
||||
magic_items,
|
||||
wands,
|
||||
dm,
|
||||
) = data;
|
||||
|
||||
// For every entity that wants to be picked up, that still needs a key assigned.
|
||||
for (e, _wants_key) in (&entities, &wants_keys).join() {
|
||||
if DEBUG_KEYHANDLING {
|
||||
console::log(&format!("KEYHANDLING: Assigning key to {:?}", e));
|
||||
}
|
||||
let (stacks, mut handled, unique) = (
|
||||
if let Some(_) = stackable.get(e) { true } else { false },
|
||||
false,
|
||||
unique(
|
||||
e,
|
||||
&names,
|
||||
&obfuscated_names,
|
||||
&renderables,
|
||||
&beatitudes,
|
||||
&magic_items,
|
||||
Some(&wands),
|
||||
&dm
|
||||
),
|
||||
);
|
||||
if stacks {
|
||||
console::log(&format!("KEYHANDLING: Item is stackable."));
|
||||
let maybe_key = item_exists(&unique);
|
||||
if maybe_key.is_some() {
|
||||
console::log(&format!("KEYHANDLING: Existing stack found for this item."));
|
||||
let key = maybe_key.unwrap();
|
||||
keys.insert(e, Key { idx: key }).expect("Unable to insert Key.");
|
||||
console::log(&format!("KEYHANDLING: Assigned key idx {} to item.", key));
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
if !handled {
|
||||
console::log(
|
||||
&format!("KEYHANDLING: Item is not stackable, or no existing stack found.")
|
||||
);
|
||||
if let Some(idx) = assign_next_available() {
|
||||
console::log(
|
||||
&format!("KEYHANDLING: Assigned next available index {} to item.", idx)
|
||||
);
|
||||
keys.insert(e, Key { idx }).expect("Unable to insert Key.");
|
||||
register_stackable(stacks, unique, idx);
|
||||
} else {
|
||||
console::log(&format!("KEYHANDLING: No more keys available."));
|
||||
gamelog::Logger
|
||||
::new()
|
||||
.append(messages::NO_MORE_KEYS)
|
||||
.colour(WHITE)
|
||||
.period()
|
||||
.log();
|
||||
}
|
||||
}
|
||||
}
|
||||
for (e, _wants_key) in (&entities, &wants_removekey).join() {
|
||||
let idx = keys.get(e).unwrap().idx;
|
||||
if DEBUG_KEYHANDLING {
|
||||
console::log(&format!("KEYHANDLING: Removing key from {:?}", e));
|
||||
}
|
||||
// If the item is *not* stackable, then we can just remove the key and clear the index.
|
||||
if let None = stackable.get(e) {
|
||||
console::log(
|
||||
&format!("KEYHANDLING: Item is not stackable, clearing index {}.", idx)
|
||||
);
|
||||
clear_idx(idx);
|
||||
keys.remove(e);
|
||||
continue;
|
||||
}
|
||||
// If the item *is* stackable, then we need to check if there are any other items that
|
||||
// share this key assignment, before clearing the index.
|
||||
console::log(
|
||||
&format!(
|
||||
"KEYHANDLING: Item is stackable, checking if any other items share this key."
|
||||
)
|
||||
);
|
||||
let mut sole_item_with_key = true;
|
||||
for (entity, key) in (&entities, &keys).join() {
|
||||
if entity != e && key.idx == idx {
|
||||
console::log(&format!("KEYHANDLING: Another item shares index {}", idx));
|
||||
sole_item_with_key = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If no other items shared this key, free up the index.
|
||||
if sole_item_with_key {
|
||||
console::log(
|
||||
&format!("KEYHANDLING: No other items found, clearing index {}.", idx)
|
||||
);
|
||||
clear_idx(idx);
|
||||
}
|
||||
// Either way, remove the key component from this item, because we're dropping it.
|
||||
console::log(&format!("KEYHANDLING: Removing key component from item."));
|
||||
keys.remove(e);
|
||||
}
|
||||
|
||||
wants_removekey.clear();
|
||||
wants_keys.clear();
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,6 @@ mod equip_system;
|
|||
mod identification_system;
|
||||
mod remove_system;
|
||||
mod use_system;
|
||||
mod keyhandling;
|
||||
|
||||
pub use self::{
|
||||
collection_system::ItemCollectionSystem,
|
||||
|
|
@ -13,5 +12,4 @@ pub use self::{
|
|||
identification_system::ItemIdentificationSystem,
|
||||
remove_system::ItemRemoveSystem,
|
||||
use_system::ItemUseSystem,
|
||||
keyhandling::KeyHandling,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,59 +0,0 @@
|
|||
use std::sync::Mutex;
|
||||
use std::collections::HashMap;
|
||||
use crate::gui::UniqueInventoryItem;
|
||||
|
||||
lazy_static! {
|
||||
pub static ref INVKEYS: Mutex<HashMap<UniqueInventoryItem, usize>> = Mutex::new(HashMap::new());
|
||||
pub static ref ASSIGNEDKEYS: Mutex<Vec<bool>> = Mutex::new(vec![false; 52]);
|
||||
}
|
||||
|
||||
/// For (de)serialization.
|
||||
pub fn clone_invkeys() -> HashMap<UniqueInventoryItem, usize> {
|
||||
let invkeys = INVKEYS.lock().unwrap();
|
||||
invkeys.clone()
|
||||
}
|
||||
pub fn restore_invkeys(invkeys: HashMap<UniqueInventoryItem, usize>) {
|
||||
INVKEYS.lock().unwrap().clear();
|
||||
INVKEYS.lock().unwrap().extend(invkeys);
|
||||
}
|
||||
|
||||
pub fn check_key(idx: usize) -> bool {
|
||||
let lock = ASSIGNEDKEYS.lock().unwrap();
|
||||
lock[idx]
|
||||
}
|
||||
|
||||
pub fn item_exists(item: &UniqueInventoryItem) -> Option<usize> {
|
||||
let invkeys = INVKEYS.lock().unwrap();
|
||||
use bracket_lib::prelude::*;
|
||||
console::log(&format!("{:?}", item));
|
||||
if invkeys.contains_key(item) {
|
||||
Some(*invkeys.get(item).unwrap())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn assign_next_available() -> Option<usize> {
|
||||
let mut lock = ASSIGNEDKEYS.lock().unwrap();
|
||||
for (i, key) in lock.iter_mut().enumerate() {
|
||||
if !*key {
|
||||
*key = true;
|
||||
return Some(i);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn register_stackable(stacks: bool, item: UniqueInventoryItem, idx: usize) {
|
||||
if stacks {
|
||||
let mut invkeys = INVKEYS.lock().unwrap();
|
||||
invkeys.insert(item, idx);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clear_idx(idx: usize) {
|
||||
let mut lock = ASSIGNEDKEYS.lock().unwrap();
|
||||
lock[idx] = false;
|
||||
let mut invkeys = INVKEYS.lock().unwrap();
|
||||
invkeys.retain(|_k, v| *v != idx);
|
||||
}
|
||||
|
|
@ -8,9 +8,6 @@ extern crate serde;
|
|||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
|
||||
#[macro_use]
|
||||
pub mod macros;
|
||||
|
||||
pub mod camera;
|
||||
pub mod components;
|
||||
pub mod raws;
|
||||
|
|
@ -38,7 +35,6 @@ pub mod rex_assets;
|
|||
pub mod spatial;
|
||||
pub mod morgue;
|
||||
pub mod states;
|
||||
pub mod invkeys;
|
||||
|
||||
pub use components::*;
|
||||
use particle_system::ParticleBuilder;
|
||||
|
|
|
|||
|
|
@ -1,93 +0,0 @@
|
|||
// macros/mod.rs
|
||||
|
||||
#[macro_export]
|
||||
/// Used to check if the player has a given component.
|
||||
macro_rules! player_has_component {
|
||||
($ecs:expr, $component:ty) => {
|
||||
{
|
||||
let player = $ecs.fetch::<Entity>();
|
||||
let component = $ecs.read_storage::<$component>();
|
||||
if let Some(player_component) = component.get(*player) {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
/// Used to check if a given entity has a given Intrinsic.
|
||||
macro_rules! has {
|
||||
($ecs:expr, $entity:expr, $intrinsic:expr) => {
|
||||
{
|
||||
let intrinsics = $ecs.read_storage::<crate::Intrinsics>();
|
||||
if let Some(has_intrinsics) = intrinsics.get($entity) {
|
||||
has_intrinsics.list.contains(&$intrinsic)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
/// Used to check if the player has a given Intrinsic.
|
||||
macro_rules! player_has {
|
||||
($ecs:expr, $intrinsic:expr) => {
|
||||
{
|
||||
let player = $ecs.fetch::<Entity>();
|
||||
let intrinsics = $ecs.read_storage::<crate::Intrinsics>();
|
||||
if let Some(player_intrinsics) = intrinsics.get(*player) {
|
||||
player_intrinsics.list.contains(&$intrinsic)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
/// Handles adding an Intrinsic to the player, and adding it to the IntrinsicChanged component.
|
||||
macro_rules! add_intr {
|
||||
($ecs:expr, $entity:expr, $intrinsic:expr) => {
|
||||
{
|
||||
let mut intrinsics = $ecs.write_storage::<crate::Intrinsics>();
|
||||
if let Some(player_intrinsics) = intrinsics.get_mut($entity) {
|
||||
if !player_intrinsics.list.contains(&$intrinsic) {
|
||||
player_intrinsics.list.insert($intrinsic);
|
||||
let mut intrinsic_changed = $ecs.write_storage::<crate::IntrinsicChanged>();
|
||||
if let Some(this_intrinsic_changed) = intrinsic_changed.get_mut($entity) {
|
||||
this_intrinsic_changed.gained.insert($intrinsic);
|
||||
} else {
|
||||
intrinsic_changed.insert($entity, crate::IntrinsicChanged {
|
||||
gained: {
|
||||
let mut m = std::collections::HashSet::new();
|
||||
m.insert($intrinsic);
|
||||
m
|
||||
},
|
||||
lost: std::collections::HashSet::new()
|
||||
}).expect("Failed to insert IntrinsicChanged component.");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
intrinsics.insert($entity, crate::Intrinsics {
|
||||
list: {
|
||||
let mut m = std::collections::HashSet::new();
|
||||
m.insert($intrinsic);
|
||||
m
|
||||
}
|
||||
}).expect("Failed to insert Intrinsics component.");
|
||||
let mut intrinsic_changed = $ecs.write_storage::<crate::IntrinsicChanged>();
|
||||
intrinsic_changed.insert($entity, crate::IntrinsicChanged {
|
||||
gained: {
|
||||
let mut m = std::collections::HashSet::new();
|
||||
m.insert($intrinsic);
|
||||
m
|
||||
},
|
||||
lost: std::collections::HashSet::new()
|
||||
}).expect("Failed to insert IntrinsicChanged component.");
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
53
src/main.rs
|
|
@ -3,22 +3,43 @@ use specs::prelude::*;
|
|||
use specs::saveload::{ SimpleMarker, SimpleMarkerAllocator };
|
||||
use bracket_lib::prelude::*;
|
||||
|
||||
const DISPLAYWIDTH: i32 = 105;
|
||||
const DISPLAYWIDTH: i32 = 100;
|
||||
const DISPLAYHEIGHT: i32 = 56;
|
||||
|
||||
fn main() -> BError {
|
||||
// Embedded resources for use in wasm build
|
||||
const CURSES_14_16_BYTES: &[u8] = include_bytes!("../resources/curses14x16.png");
|
||||
EMBED.lock().add_resource("resources/curses14x16.png".to_string(), CURSES_14_16_BYTES);
|
||||
{
|
||||
const WORLD_16_16_BYTES: &[u8] = include_bytes!("../resources/world16x16.png");
|
||||
const CURSES_16_16_BYTES: &[u8] = include_bytes!("../resources/curses16x16.png");
|
||||
const CURSES_8_16_BYTES: &[u8] = include_bytes!("../resources/curses8x16.png");
|
||||
const SINGLE_1_1_BYTES: &[u8] = include_bytes!("../resources/healthbar22x2.png");
|
||||
let mut lock = bracket_lib::terminal::EMBED.lock();
|
||||
lock.add_resource("resources/world16x16.png".to_string(), WORLD_16_16_BYTES);
|
||||
lock.add_resource("resources/curses16x16.png".to_string(), CURSES_16_16_BYTES);
|
||||
lock.add_resource("resources/curses8x16.png".to_string(), CURSES_8_16_BYTES);
|
||||
lock.add_resource("resources/healthbar22x2.png".to_string(), SINGLE_1_1_BYTES);
|
||||
}
|
||||
|
||||
//link_resource!(CURSES14X16, "../resources/curses_14x16.png");
|
||||
let world_sheet = SpriteSheet {
|
||||
filename: "resources/world16x16.png".to_string(),
|
||||
sprites: register_spritesheet(16, 16, 19, 16),
|
||||
backing: None,
|
||||
};
|
||||
|
||||
let mut context = BTermBuilder::new()
|
||||
.with_title("rust-rl")
|
||||
.with_dimensions(DISPLAYWIDTH, DISPLAYHEIGHT)
|
||||
.with_font("curses14x16.png", 14, 16)
|
||||
.with_tile_dimensions(14, 16)
|
||||
.with_simple_console(DISPLAYWIDTH, DISPLAYHEIGHT, "curses14x16.png")
|
||||
.with_font("curses16x16.png", 16, 16)
|
||||
.with_font("curses8x16.png", 8, 16)
|
||||
.with_font("healthbar22x2.png", 1, 1)
|
||||
.with_tile_dimensions(16, 16)
|
||||
.with_gutter(2)
|
||||
.with_sprite_console(DISPLAYWIDTH * 16, DISPLAYHEIGHT * 16, 0)
|
||||
.with_sprite_sheet(world_sheet)
|
||||
.with_simple_console_no_bg(DISPLAYWIDTH, DISPLAYHEIGHT, "curses16x16.png")
|
||||
.with_simple_console_no_bg(DISPLAYWIDTH, DISPLAYHEIGHT, "curses16x16.png")
|
||||
.with_sparse_console(DISPLAYWIDTH * 2, DISPLAYHEIGHT, "curses8x16.png")
|
||||
.with_sparse_console(DISPLAYWIDTH * 16, DISPLAYHEIGHT * 16, "healthbar22x2.png")
|
||||
.build()?;
|
||||
if config::CONFIG.visuals.with_scanlines {
|
||||
context.with_post_scanlines(config::CONFIG.visuals.with_screen_burn);
|
||||
|
|
@ -111,12 +132,6 @@ fn main() -> BError {
|
|||
gs.ecs.register::<SpawnParticleLine>();
|
||||
gs.ecs.register::<HasDamageModifiers>();
|
||||
gs.ecs.register::<Intrinsics>();
|
||||
gs.ecs.register::<IntrinsicChanged>();
|
||||
gs.ecs.register::<Stackable>();
|
||||
gs.ecs.register::<WantsToAssignKey>();
|
||||
gs.ecs.register::<Key>();
|
||||
gs.ecs.register::<WantsToRemoveKey>();
|
||||
gs.ecs.register::<WantsToDelete>();
|
||||
gs.ecs.register::<SimpleMarker<SerializeMe>>();
|
||||
gs.ecs.register::<SerializationHelper>();
|
||||
gs.ecs.register::<DMSerializationHelper>();
|
||||
|
|
@ -142,3 +157,15 @@ fn main() -> BError {
|
|||
|
||||
main_loop(context, gs)
|
||||
}
|
||||
|
||||
fn register_spritesheet(width: i32, height: i32, rows: i32, columns: i32) -> Vec<Sprite> {
|
||||
let mut sprites: Vec<Sprite> = Vec::new();
|
||||
for y in 0..rows {
|
||||
for x in 0..columns {
|
||||
sprites.push(
|
||||
Sprite::new(Rect::with_size(x * width + 1, y * height + 1, width, height))
|
||||
);
|
||||
}
|
||||
}
|
||||
sprites
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,26 +112,7 @@ fn make_scroll_name(rng: &mut RandomNumberGenerator) -> String {
|
|||
return name;
|
||||
}
|
||||
|
||||
const POTION_COLOURS: &[&str] = &[
|
||||
"red",
|
||||
"orange",
|
||||
"yellow",
|
||||
"green",
|
||||
"blue",
|
||||
"indigo",
|
||||
"violet",
|
||||
"black",
|
||||
"white",
|
||||
"silver",
|
||||
"gold",
|
||||
"rainbow",
|
||||
"blood",
|
||||
"purple",
|
||||
"cyan",
|
||||
"brown",
|
||||
"grey",
|
||||
"octarine",
|
||||
];
|
||||
const POTION_COLOURS: &[&str] = &["blue", "red", "green", "yellow", "black"];
|
||||
const POTION_ADJECTIVES: &[&str] = &[
|
||||
"swirling",
|
||||
"viscous",
|
||||
|
|
|
|||
|
|
@ -2,7 +2,15 @@ use bracket_lib::prelude::*;
|
|||
use serde::{ Deserialize, Serialize };
|
||||
use std::collections::{ HashSet, HashMap };
|
||||
mod tiletype;
|
||||
pub use tiletype::{ tile_cost, tile_opaque, tile_walkable, TileType, get_dest, Destination };
|
||||
pub use tiletype::{
|
||||
tile_cost,
|
||||
tile_opaque,
|
||||
tile_walkable,
|
||||
tile_blocks_telepathy,
|
||||
TileType,
|
||||
get_dest,
|
||||
Destination,
|
||||
};
|
||||
mod interval_spawning_system;
|
||||
pub use interval_spawning_system::{ maybe_map_message, try_spawn_interval };
|
||||
pub mod dungeon;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,22 @@ use crate::data::ids::*;
|
|||
use bracket_lib::prelude::*;
|
||||
use std::ops::{ Add, Mul };
|
||||
|
||||
pub fn get_sprite_for_id(idx: usize, map: &Map, other_pos: Option<Point>) -> (usize, RGBA) {
|
||||
let x = (idx as i32) % map.width;
|
||||
let y = (idx as i32) / map.width;
|
||||
let tile = map.tiles[idx];
|
||||
let base = match tile {
|
||||
TileType::Wall => wall_sprite(tile.sprite(), map, x, y),
|
||||
_ => tile.sprite(),
|
||||
};
|
||||
let sprite_id = pick_variant(base, tile.variants(), idx, map);
|
||||
let tint = if !map.visible_tiles[idx] {
|
||||
RGBA::from_f32(0.75, 0.75, 0.75, 1.0)
|
||||
} else {
|
||||
RGBA::named(WHITE)
|
||||
};
|
||||
return (sprite_id, tint);
|
||||
}
|
||||
/// Gets the renderables for a tile, with darkening/offset/post-processing/etc. Passing a val for "debug" will ignore viewshed.
|
||||
pub fn get_tile_renderables_for_id(
|
||||
idx: usize,
|
||||
|
|
@ -142,6 +158,20 @@ fn is_revealed_and_wall(map: &Map, x: i32, y: i32, debug: Option<bool>) -> bool
|
|||
(if debug.is_none() { map.revealed_tiles[idx] } else { true })
|
||||
}
|
||||
|
||||
fn wall_sprite(id: usize, map: &Map, x: i32, y: i32) -> usize {
|
||||
if y > map.height - (2 as i32) {
|
||||
return id;
|
||||
}
|
||||
if is_revealed_and_wall(map, x, y + 1, None) {
|
||||
return id + 6;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
fn pick_variant(base: usize, variants: usize, idx: usize, map: &Map) -> usize {
|
||||
return base + ((map.colour_offset[idx].0.0 * (variants as f32)) as usize);
|
||||
}
|
||||
|
||||
fn wall_glyph(map: &Map, x: i32, y: i32, debug: Option<bool>) -> FontCharType {
|
||||
if
|
||||
x < 1 ||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use serde::{ Deserialize, Serialize };
|
||||
use crate::data::sprites::*;
|
||||
|
||||
#[derive(PartialEq, Eq, Hash, Copy, Clone, Serialize, Deserialize, Debug)]
|
||||
pub enum TileType {
|
||||
|
|
@ -27,9 +28,64 @@ pub enum TileType {
|
|||
ToOvermap(i32),
|
||||
ToLocal(i32),
|
||||
}
|
||||
|
||||
impl TileType {
|
||||
pub fn sprite(&self) -> usize {
|
||||
match self {
|
||||
TileType::ImpassableMountain => STATUE,
|
||||
TileType::Wall => WALL_BASE,
|
||||
TileType::DeepWater => WATER_DEEP,
|
||||
TileType::Fence => WALL_BASE,
|
||||
TileType::Bars => WALL_BASE,
|
||||
TileType::Floor => FLOOR,
|
||||
TileType::WoodFloor => FLOOR_WOOD,
|
||||
TileType::Gravel => FLOOR,
|
||||
TileType::Road => PATH_GRASS,
|
||||
TileType::Grass => FLOOR_GRASS,
|
||||
TileType::Foliage => FLOOR_GRASS,
|
||||
TileType::HeavyFoliage => FLOOR_GRASS,
|
||||
TileType::Sand => FLOOR,
|
||||
TileType::ShallowWater => WATER_DEEP,
|
||||
TileType::Bridge => FLOOR,
|
||||
TileType::DownStair => STAIR_D,
|
||||
TileType::UpStair => STAIR_A,
|
||||
TileType::ToLocal(_) => MUSHROOM,
|
||||
TileType::ToOvermap(_) => MUSHROOM_ORANGE,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn variants(&self) -> usize {
|
||||
match self {
|
||||
TileType::ImpassableMountain => 1,
|
||||
TileType::Wall => 4,
|
||||
TileType::DeepWater => 2,
|
||||
TileType::Fence => 1,
|
||||
TileType::Bars => 1,
|
||||
TileType::Floor => 6,
|
||||
TileType::WoodFloor => 3,
|
||||
TileType::Gravel => 1,
|
||||
TileType::Road => 4,
|
||||
TileType::Grass => 6,
|
||||
TileType::Foliage => 1,
|
||||
TileType::HeavyFoliage => 1,
|
||||
TileType::Sand => 1,
|
||||
TileType::ShallowWater => 2,
|
||||
TileType::Bridge => 1,
|
||||
TileType::DownStair => 1,
|
||||
TileType::UpStair => 1,
|
||||
TileType::ToLocal(_) => 1,
|
||||
TileType::ToOvermap(_) => 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tile_walkable(tt: TileType) -> bool {
|
||||
match tt {
|
||||
TileType::ImpassableMountain | TileType::Wall | TileType::DeepWater | TileType::Fence | TileType::Bars => false,
|
||||
| TileType::ImpassableMountain
|
||||
| TileType::Wall
|
||||
| TileType::DeepWater
|
||||
| TileType::Fence
|
||||
| TileType::Bars => false,
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
|
|
@ -40,6 +96,11 @@ pub fn tile_opaque(tt: TileType) -> bool {
|
|||
_ => false,
|
||||
}
|
||||
}
|
||||
pub fn tile_blocks_telepathy(tt: TileType) -> bool {
|
||||
match tt {
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
pub fn tile_cost(tt: TileType) -> f32 {
|
||||
match tt {
|
||||
TileType::Road => 0.75,
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ fn create_delayed_particles(ecs: &mut World, ctx: &BTerm) {
|
|||
.expect("Could not insert position");
|
||||
renderables
|
||||
.insert(p, Renderable {
|
||||
sprite: None, // TODO: Particle sprite
|
||||
fg: handled.fg,
|
||||
bg: handled.bg,
|
||||
glyph: handled.glyph,
|
||||
|
|
@ -306,6 +307,7 @@ impl<'a> System<'a> for ParticleSpawnSystem {
|
|||
.expect("Could not insert position");
|
||||
renderables
|
||||
.insert(p, Renderable {
|
||||
sprite: None, // TODO: Particle sprite
|
||||
fg: new_particle.fg,
|
||||
bg: new_particle.bg,
|
||||
glyph: new_particle.glyph,
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ use super::{
|
|||
Viewshed,
|
||||
WantsToMelee,
|
||||
WantsToPickupItem,
|
||||
WantsToAssignKey,
|
||||
get_dest,
|
||||
Destination,
|
||||
DamageType,
|
||||
|
|
@ -40,6 +39,7 @@ use specs::prelude::*;
|
|||
use std::cmp::{ max, min };
|
||||
use crate::data::events::*;
|
||||
use crate::data::ids::*;
|
||||
use crate::gui::with_article;
|
||||
|
||||
pub fn try_door(i: i32, j: i32, ecs: &mut World) -> RunState {
|
||||
let mut positions = ecs.write_storage::<Position>();
|
||||
|
|
@ -134,6 +134,7 @@ pub fn try_door(i: i32, j: i32, ecs: &mut World) -> RunState {
|
|||
let mut renderables = ecs.write_storage::<Renderable>();
|
||||
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(17); // TODO: Enum
|
||||
door_pos = Some(Point::new(pos.x + delta_x, pos.y + delta_y));
|
||||
}
|
||||
result = RunState::Ticking;
|
||||
|
|
@ -231,6 +232,7 @@ pub fn open(i: i32, j: i32, ecs: &mut World) -> RunState {
|
|||
let mut renderables = ecs.write_storage::<Renderable>();
|
||||
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(18); // TODO: Enum
|
||||
door_pos = Some(Point::new(pos.x + delta_x, pos.y + delta_y));
|
||||
}
|
||||
result = RunState::Ticking;
|
||||
|
|
@ -561,11 +563,11 @@ pub fn try_move_player(delta_x: i32, delta_y: i32, ecs: &mut World) -> RunState
|
|||
let mut logger = gamelog::Logger::new().append("You see");
|
||||
for i in 0..seen_items.len() {
|
||||
if i > 0 && i < seen_items.len() {
|
||||
logger = logger.append(", a");
|
||||
logger = logger.append(", ");
|
||||
}
|
||||
logger = logger
|
||||
.colour(seen_items[i].1)
|
||||
.append_n(&seen_items[i].0)
|
||||
.append_n(with_article(&seen_items[i].0))
|
||||
.colour(WHITE);
|
||||
}
|
||||
logger.period().log();
|
||||
|
|
@ -634,9 +636,7 @@ fn get_item(ecs: &mut World) -> RunState {
|
|||
return RunState::AwaitingInput;
|
||||
}
|
||||
Some(item) => {
|
||||
let mut assignkey = ecs.write_storage::<WantsToAssignKey>();
|
||||
let mut pickup = ecs.write_storage::<WantsToPickupItem>();
|
||||
assignkey.insert(item, WantsToAssignKey {}).expect("Unable to insert WantsToAssignKey");
|
||||
pickup
|
||||
.insert(*player_entity, WantsToPickupItem { collected_by: *player_entity, item })
|
||||
.expect("Unable to insert want to pickup item.");
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ pub struct Item {
|
|||
pub id: String,
|
||||
pub name: Name,
|
||||
pub renderable: Option<Renderable>,
|
||||
pub class: String,
|
||||
pub weight: Option<f32>,
|
||||
pub value: Option<f32>,
|
||||
pub equip: Option<Equippable>,
|
||||
|
|
@ -31,6 +30,7 @@ pub struct Equippable {
|
|||
#[derive(Deserialize, Debug)]
|
||||
pub struct Renderable {
|
||||
pub glyph: String,
|
||||
pub sprite: Option<usize>,
|
||||
pub fg: String,
|
||||
pub bg: String,
|
||||
pub order: i32,
|
||||
|
|
|
|||
|
|
@ -66,7 +66,6 @@ macro_rules! apply_flags {
|
|||
"IDENTIFY" => $eb = $eb.with(ProvidesIdentify {}),
|
||||
"DIGGER" => $eb = $eb.with(Digger {}),
|
||||
"MAGICMAP" => $eb = $eb.with(MagicMapper {}),
|
||||
"STACKABLE" => $eb = $eb.with(Stackable {}),
|
||||
// CAN BE DESTROYED BY DAMAGE
|
||||
"DESTRUCTIBLE" => $eb = $eb.with(Destructible {}),
|
||||
// --- EQUIP SLOTS ---
|
||||
|
|
@ -282,7 +281,6 @@ pub fn spawn_named_item(
|
|||
if known_beatitude && !identified_items.contains(&item_template.name.name) {
|
||||
dm.identified_items.insert(item_template.name.name.clone());
|
||||
}
|
||||
let needs_key = is_player_owned(&player_entity, &pos);
|
||||
std::mem::drop(player_entity);
|
||||
std::mem::drop(dm);
|
||||
// -- DROP EVERYTHING THAT INVOLVES THE ECS BEFORE THIS POINT ---
|
||||
|
|
@ -295,23 +293,9 @@ pub fn spawn_named_item(
|
|||
eb = eb.with(Item {
|
||||
weight: item_template.weight.unwrap_or(0.0),
|
||||
value: item_template.value.unwrap_or(0.0),
|
||||
category: match item_template.class.as_str() {
|
||||
"amulet" => ItemType::Amulet,
|
||||
"weapon" => ItemType::Weapon,
|
||||
"armour" => ItemType::Armour,
|
||||
"comestible" => ItemType::Comestible,
|
||||
"scroll" => ItemType::Scroll,
|
||||
"spellbook" => ItemType::Spellbook,
|
||||
"potion" => ItemType::Potion,
|
||||
"ring" => ItemType::Ring,
|
||||
"wand" => ItemType::Wand,
|
||||
_ => unreachable!("Unknown item type."),
|
||||
},
|
||||
});
|
||||
eb = spawn_position(pos, eb, key, raws);
|
||||
if needs_key {
|
||||
eb = eb.with(WantsToAssignKey {});
|
||||
}
|
||||
|
||||
if let Some(renderable) = &item_template.renderable {
|
||||
eb = eb.with(get_renderable_component(renderable));
|
||||
}
|
||||
|
|
@ -408,7 +392,6 @@ pub fn spawn_named_mob(
|
|||
if raws.mob_index.contains_key(key) {
|
||||
let mob_template = &raws.raws.mobs[raws.mob_index[key]];
|
||||
let mut player_level = 1;
|
||||
let needs_key;
|
||||
{
|
||||
let pools = ecs.read_storage::<Pools>();
|
||||
let player_entity = ecs.fetch::<Entity>();
|
||||
|
|
@ -416,15 +399,12 @@ pub fn spawn_named_mob(
|
|||
if let Some(pool) = player_pool {
|
||||
player_level = pool.level;
|
||||
}
|
||||
needs_key = is_player_owned(&player_entity, &pos);
|
||||
}
|
||||
|
||||
let mut eb;
|
||||
// New entity with a position, name, combatstats, and viewshed
|
||||
eb = ecs.create_entity().marked::<SimpleMarker<SerializeMe>>();
|
||||
eb = spawn_position(pos, eb, key, raws);
|
||||
if needs_key {
|
||||
eb = eb.with(WantsToAssignKey {});
|
||||
}
|
||||
eb = eb.with(Name { name: mob_template.name.clone(), plural: mob_template.name.clone() });
|
||||
eb = eb.with(Viewshed {
|
||||
visible_tiles: Vec::new(),
|
||||
|
|
@ -652,18 +632,10 @@ pub fn spawn_named_prop(
|
|||
pos: SpawnType
|
||||
) -> Option<Entity> {
|
||||
if raws.prop_index.contains_key(key) {
|
||||
let needs_key;
|
||||
{
|
||||
let player_entity = ecs.fetch::<Entity>();
|
||||
needs_key = is_player_owned(&player_entity, &pos);
|
||||
}
|
||||
// ENTITY BUILDER PREP
|
||||
let prop_template = &raws.raws.props[raws.prop_index[key]];
|
||||
let mut eb = ecs.create_entity().marked::<SimpleMarker<SerializeMe>>();
|
||||
eb = spawn_position(pos, eb, key, raws);
|
||||
if needs_key {
|
||||
eb = eb.with(WantsToAssignKey {});
|
||||
}
|
||||
// APPLY MANDATORY COMPONENTS FOR A PROP:
|
||||
// - Name
|
||||
// - Prop {}
|
||||
|
|
@ -714,28 +686,16 @@ fn spawn_position<'a>(
|
|||
eb
|
||||
}
|
||||
|
||||
fn is_player_owned(player: &Entity, pos: &SpawnType) -> bool {
|
||||
match pos {
|
||||
SpawnType::Carried { by } => {
|
||||
if by == player {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
SpawnType::Equipped { by } => {
|
||||
if by == player {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn get_renderable_component(
|
||||
renderable: &super::item_structs::Renderable
|
||||
) -> crate::components::Renderable {
|
||||
crate::components::Renderable {
|
||||
glyph: to_cp437(renderable.glyph.chars().next().unwrap()),
|
||||
sprite: if let Some(sprite) = &renderable.sprite {
|
||||
Some(sprite.clone())
|
||||
} else {
|
||||
None
|
||||
},
|
||||
fg: RGB::from_hex(&renderable.fg).expect("Invalid RGB"),
|
||||
bg: RGB::from_hex(&renderable.bg).expect("Invalid RGB"),
|
||||
render_order: renderable.order,
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ use specs::saveload::{
|
|||
SimpleMarker,
|
||||
SimpleMarkerAllocator,
|
||||
};
|
||||
|
||||
use std::fs;
|
||||
use std::fs::File;
|
||||
use std::path::Path;
|
||||
|
|
@ -96,10 +95,8 @@ pub fn save_game(ecs: &mut World) {
|
|||
IdentifiedItem,
|
||||
InBackpack,
|
||||
InflictsDamage,
|
||||
IntrinsicChanged,
|
||||
Intrinsics,
|
||||
Item,
|
||||
Key,
|
||||
KnownSpells,
|
||||
LootTable,
|
||||
MagicItem,
|
||||
|
|
@ -129,21 +126,17 @@ pub fn save_game(ecs: &mut World) {
|
|||
SpawnParticleBurst,
|
||||
SpawnParticleLine,
|
||||
SpawnParticleSimple,
|
||||
Stackable,
|
||||
TakingTurn,
|
||||
Telepath,
|
||||
ToHitBonus,
|
||||
Viewshed,
|
||||
Charges,
|
||||
WantsToApproach,
|
||||
WantsToAssignKey,
|
||||
WantsToDelete,
|
||||
WantsToDropItem,
|
||||
WantsToFlee,
|
||||
WantsToMelee,
|
||||
WantsToPickupItem,
|
||||
WantsToRemoveItem,
|
||||
WantsToRemoveKey,
|
||||
WantsToUseItem,
|
||||
SerializationHelper,
|
||||
DMSerializationHelper
|
||||
|
|
@ -234,10 +227,8 @@ pub fn load_game(ecs: &mut World) {
|
|||
IdentifiedItem,
|
||||
InBackpack,
|
||||
InflictsDamage,
|
||||
IntrinsicChanged,
|
||||
Intrinsics,
|
||||
Item,
|
||||
Key,
|
||||
KnownSpells,
|
||||
LootTable,
|
||||
MagicItem,
|
||||
|
|
@ -267,21 +258,17 @@ pub fn load_game(ecs: &mut World) {
|
|||
SpawnParticleBurst,
|
||||
SpawnParticleLine,
|
||||
SpawnParticleSimple,
|
||||
Stackable,
|
||||
TakingTurn,
|
||||
Telepath,
|
||||
ToHitBonus,
|
||||
Viewshed,
|
||||
Charges,
|
||||
WantsToApproach,
|
||||
WantsToAssignKey,
|
||||
WantsToDelete,
|
||||
WantsToDropItem,
|
||||
WantsToFlee,
|
||||
WantsToMelee,
|
||||
WantsToPickupItem,
|
||||
WantsToRemoveItem,
|
||||
WantsToRemoveKey,
|
||||
WantsToUseItem,
|
||||
SerializationHelper,
|
||||
DMSerializationHelper
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ pub fn player(ecs: &mut World, player_x: i32, player_y: i32) -> Entity {
|
|||
.with(BlocksTile {})
|
||||
.with(Renderable {
|
||||
glyph: to_cp437('@'),
|
||||
sprite: None, // TODO: Player sprite
|
||||
fg: RGB::named(YELLOW),
|
||||
bg: RGB::named(BLACK),
|
||||
render_order: 0,
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ use crate::camera;
|
|||
use crate::saveload_system;
|
||||
use crate::morgue;
|
||||
use crate::damage_system;
|
||||
use crate::data::prelude::*;
|
||||
|
||||
pub struct State {
|
||||
pub ecs: World,
|
||||
|
|
@ -64,13 +65,12 @@ impl State {
|
|||
|
||||
fn resolve_entity_decisions(&mut self) {
|
||||
let mut trigger_system = trigger_system::TriggerSystem {};
|
||||
let mut inventory_system = inventory::ItemCollectionSystem {};
|
||||
let mut item_equip_system = inventory::ItemEquipSystem {};
|
||||
let mut item_use_system = inventory::ItemUseSystem {};
|
||||
let mut item_drop_system = inventory::ItemDropSystem {};
|
||||
let mut item_remove_system = inventory::ItemRemoveSystem {};
|
||||
let mut inventory_system = inventory::ItemCollectionSystem {};
|
||||
let mut item_id_system = inventory::ItemIdentificationSystem {};
|
||||
let mut key_system = inventory::KeyHandling {};
|
||||
let mut melee_system = MeleeCombatSystem {};
|
||||
trigger_system.run_now(&self.ecs);
|
||||
inventory_system.run_now(&self.ecs);
|
||||
|
|
@ -79,7 +79,6 @@ impl State {
|
|||
item_drop_system.run_now(&self.ecs);
|
||||
item_remove_system.run_now(&self.ecs);
|
||||
item_id_system.run_now(&self.ecs);
|
||||
key_system.run_now(&self.ecs);
|
||||
melee_system.run_now(&self.ecs);
|
||||
|
||||
effects::run_effects_queue(&mut self.ecs);
|
||||
|
|
@ -166,6 +165,15 @@ impl GameState for State {
|
|||
new_runstate = *runstate;
|
||||
}
|
||||
// Clear screen
|
||||
ctx.set_active_console(0);
|
||||
ctx.cls();
|
||||
ctx.set_active_console(HP_BAR_LAYER);
|
||||
ctx.cls();
|
||||
ctx.set_active_console(TEXT_LAYER);
|
||||
ctx.cls();
|
||||
ctx.set_active_console(ENTITY_LAYER);
|
||||
ctx.cls();
|
||||
ctx.set_active_console(TILE_LAYER);
|
||||
ctx.cls();
|
||||
particle_system::particle_ticker(&mut self.ecs, ctx);
|
||||
|
||||
|
|
@ -344,11 +352,7 @@ impl GameState for State {
|
|||
gui::ItemMenuResult::NoResponse => {}
|
||||
gui::ItemMenuResult::Selected => {
|
||||
let item_entity = result.1.unwrap();
|
||||
let mut removekey = self.ecs.write_storage::<WantsToRemoveKey>();
|
||||
let mut intent = self.ecs.write_storage::<WantsToDropItem>();
|
||||
removekey
|
||||
.insert(item_entity, WantsToRemoveKey {})
|
||||
.expect("Unable to insert WantsToRemoveKey");
|
||||
intent
|
||||
.insert(*self.ecs.fetch::<Entity>(), WantsToDropItem {
|
||||
item: item_entity,
|
||||
|
|
@ -565,6 +569,15 @@ impl GameState for State {
|
|||
new_runstate = self.mapgen_next_state.unwrap();
|
||||
}
|
||||
if self.mapgen_history.len() != 0 {
|
||||
ctx.set_active_console(0);
|
||||
ctx.cls();
|
||||
ctx.set_active_console(HP_BAR_LAYER);
|
||||
ctx.cls();
|
||||
ctx.set_active_console(TEXT_LAYER);
|
||||
ctx.cls();
|
||||
ctx.set_active_console(ENTITY_LAYER);
|
||||
ctx.cls();
|
||||
ctx.set_active_console(TILE_LAYER);
|
||||
ctx.cls();
|
||||
camera::render_debug_map(&self.mapgen_history[self.mapgen_index], ctx);
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ use super::{
|
|||
Viewshed,
|
||||
Renderable,
|
||||
gui::renderable_colour,
|
||||
tile_blocks_telepathy,
|
||||
};
|
||||
use bracket_lib::prelude::*;
|
||||
use bracket_lib::pathfinding::FieldOfViewAlg::SymmetricShadowcasting;
|
||||
|
|
@ -120,7 +121,7 @@ impl<'a> System<'a> for VisibilitySystem {
|
|||
if let Some(_is_blind) = blind_entities.get(ent) {
|
||||
range *= BLIND_TELEPATHY_RANGE_MULTIPLIER;
|
||||
}
|
||||
telepath.telepath_tiles = fast_fov(pos.x, pos.y, range);
|
||||
telepath.telepath_tiles = fast_fov(pos.x, pos.y, range, &map);
|
||||
telepath.telepath_tiles.retain(
|
||||
|p| p.x >= 0 && p.x < map.width && p.y >= 0 && p.y < map.height
|
||||
);
|
||||
|
|
@ -141,7 +142,7 @@ impl<'a> System<'a> for VisibilitySystem {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn fast_fov(p_x: i32, p_y: i32, r: i32) -> Vec<Point> {
|
||||
pub fn fast_fov(p_x: i32, p_y: i32, r: i32, map: &WriteExpect<Map>) -> Vec<Point> {
|
||||
let mut visible_tiles: Vec<Point> = Vec::new();
|
||||
|
||||
let mut i = 0;
|
||||
|
|
@ -152,7 +153,17 @@ pub fn fast_fov(p_x: i32, p_y: i32, r: i32) -> Vec<Point> {
|
|||
let mut ox: f32 = (p_x as f32) + (0.5 as f32);
|
||||
let mut oy: f32 = (p_y as f32) + (0.5 as f32);
|
||||
for _i in 0..r {
|
||||
visible_tiles.push(Point::new(ox as i32, oy as i32));
|
||||
let (ox_i32, oy_i32) = (ox as i32, oy as i32);
|
||||
visible_tiles.push(Point::new(ox_i32, oy_i32));
|
||||
if
|
||||
ox_i32 >= 0 &&
|
||||
ox_i32 < map.width &&
|
||||
oy_i32 >= 0 &&
|
||||
oy_i32 < map.height &&
|
||||
tile_blocks_telepathy(map.tiles[map.xy_idx(ox_i32, oy_i32)])
|
||||
{
|
||||
break;
|
||||
}
|
||||
ox += x;
|
||||
oy += y;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -212,11 +212,11 @@ function makeMutClosure(arg0, arg1, dtor, f) {
|
|||
return real;
|
||||
}
|
||||
function __wbg_adapter_20(arg0, arg1) {
|
||||
wasm._dyn_core__ops__function__FnMut_____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hb6c6b1cd103d974c(arg0, arg1);
|
||||
wasm._dyn_core__ops__function__FnMut_____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h66b665bcfa5ccc10(arg0, arg1);
|
||||
}
|
||||
|
||||
function __wbg_adapter_23(arg0, arg1, arg2) {
|
||||
wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h02b9f16709be0849(arg0, arg1, addHeapObject(arg2));
|
||||
wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h7f980deb71f217f3(arg0, arg1, addHeapObject(arg2));
|
||||
}
|
||||
|
||||
function handleError(f, args) {
|
||||
|
|
@ -817,16 +817,16 @@ function __wbg_get_imports() {
|
|||
const ret = wasm.memory;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_closure_wrapper258 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 15, __wbg_adapter_20);
|
||||
imports.wbg.__wbindgen_closure_wrapper257 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 14, __wbg_adapter_20);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_closure_wrapper2954 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 696, __wbg_adapter_23);
|
||||
imports.wbg.__wbindgen_closure_wrapper2960 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 698, __wbg_adapter_23);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_closure_wrapper2956 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 696, __wbg_adapter_23);
|
||||
imports.wbg.__wbindgen_closure_wrapper2962 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 698, __wbg_adapter_23);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
|
||||
|
|
|
|||
887
web/rust-rl.js
Normal file
|
|
@ -0,0 +1,887 @@
|
|||
let wasm_bindgen;
|
||||
(function() {
|
||||
const __exports = {};
|
||||
let script_src;
|
||||
if (typeof document !== 'undefined' && document.currentScript !== null) {
|
||||
script_src = new URL(document.currentScript.src, location.href).toString();
|
||||
}
|
||||
let wasm = undefined;
|
||||
|
||||
const heap = new Array(128).fill(undefined);
|
||||
|
||||
heap.push(undefined, null, true, false);
|
||||
|
||||
function getObject(idx) { return heap[idx]; }
|
||||
|
||||
let heap_next = heap.length;
|
||||
|
||||
function dropObject(idx) {
|
||||
if (idx < 132) return;
|
||||
heap[idx] = heap_next;
|
||||
heap_next = idx;
|
||||
}
|
||||
|
||||
function takeObject(idx) {
|
||||
const ret = getObject(idx);
|
||||
dropObject(idx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
function addHeapObject(obj) {
|
||||
if (heap_next === heap.length) heap.push(heap.length + 1);
|
||||
const idx = heap_next;
|
||||
heap_next = heap[idx];
|
||||
|
||||
heap[idx] = obj;
|
||||
return idx;
|
||||
}
|
||||
|
||||
let WASM_VECTOR_LEN = 0;
|
||||
|
||||
let cachedUint8Memory0 = null;
|
||||
|
||||
function getUint8Memory0() {
|
||||
if (cachedUint8Memory0 === null || cachedUint8Memory0.byteLength === 0) {
|
||||
cachedUint8Memory0 = new Uint8Array(wasm.memory.buffer);
|
||||
}
|
||||
return cachedUint8Memory0;
|
||||
}
|
||||
|
||||
const cachedTextEncoder = (typeof TextEncoder !== 'undefined' ? new TextEncoder('utf-8') : { encode: () => { throw Error('TextEncoder not available') } } );
|
||||
|
||||
const encodeString = (typeof cachedTextEncoder.encodeInto === 'function'
|
||||
? function (arg, view) {
|
||||
return cachedTextEncoder.encodeInto(arg, view);
|
||||
}
|
||||
: function (arg, view) {
|
||||
const buf = cachedTextEncoder.encode(arg);
|
||||
view.set(buf);
|
||||
return {
|
||||
read: arg.length,
|
||||
written: buf.length
|
||||
};
|
||||
});
|
||||
|
||||
function passStringToWasm0(arg, malloc, realloc) {
|
||||
|
||||
if (realloc === undefined) {
|
||||
const buf = cachedTextEncoder.encode(arg);
|
||||
const ptr = malloc(buf.length, 1) >>> 0;
|
||||
getUint8Memory0().subarray(ptr, ptr + buf.length).set(buf);
|
||||
WASM_VECTOR_LEN = buf.length;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
let len = arg.length;
|
||||
let ptr = malloc(len, 1) >>> 0;
|
||||
|
||||
const mem = getUint8Memory0();
|
||||
|
||||
let offset = 0;
|
||||
|
||||
for (; offset < len; offset++) {
|
||||
const code = arg.charCodeAt(offset);
|
||||
if (code > 0x7F) break;
|
||||
mem[ptr + offset] = code;
|
||||
}
|
||||
|
||||
if (offset !== len) {
|
||||
if (offset !== 0) {
|
||||
arg = arg.slice(offset);
|
||||
}
|
||||
ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
|
||||
const view = getUint8Memory0().subarray(ptr + offset, ptr + len);
|
||||
const ret = encodeString(arg, view);
|
||||
|
||||
offset += ret.written;
|
||||
}
|
||||
|
||||
WASM_VECTOR_LEN = offset;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
function isLikeNone(x) {
|
||||
return x === undefined || x === null;
|
||||
}
|
||||
|
||||
let cachedInt32Memory0 = null;
|
||||
|
||||
function getInt32Memory0() {
|
||||
if (cachedInt32Memory0 === null || cachedInt32Memory0.byteLength === 0) {
|
||||
cachedInt32Memory0 = new Int32Array(wasm.memory.buffer);
|
||||
}
|
||||
return cachedInt32Memory0;
|
||||
}
|
||||
|
||||
function debugString(val) {
|
||||
// primitive types
|
||||
const type = typeof val;
|
||||
if (type == 'number' || type == 'boolean' || val == null) {
|
||||
return `${val}`;
|
||||
}
|
||||
if (type == 'string') {
|
||||
return `"${val}"`;
|
||||
}
|
||||
if (type == 'symbol') {
|
||||
const description = val.description;
|
||||
if (description == null) {
|
||||
return 'Symbol';
|
||||
} else {
|
||||
return `Symbol(${description})`;
|
||||
}
|
||||
}
|
||||
if (type == 'function') {
|
||||
const name = val.name;
|
||||
if (typeof name == 'string' && name.length > 0) {
|
||||
return `Function(${name})`;
|
||||
} else {
|
||||
return 'Function';
|
||||
}
|
||||
}
|
||||
// objects
|
||||
if (Array.isArray(val)) {
|
||||
const length = val.length;
|
||||
let debug = '[';
|
||||
if (length > 0) {
|
||||
debug += debugString(val[0]);
|
||||
}
|
||||
for(let i = 1; i < length; i++) {
|
||||
debug += ', ' + debugString(val[i]);
|
||||
}
|
||||
debug += ']';
|
||||
return debug;
|
||||
}
|
||||
// Test for built-in
|
||||
const builtInMatches = /\[object ([^\]]+)\]/.exec(toString.call(val));
|
||||
let className;
|
||||
if (builtInMatches.length > 1) {
|
||||
className = builtInMatches[1];
|
||||
} else {
|
||||
// Failed to match the standard '[object ClassName]'
|
||||
return toString.call(val);
|
||||
}
|
||||
if (className == 'Object') {
|
||||
// we're a user defined class or Object
|
||||
// JSON.stringify avoids problems with cycles, and is generally much
|
||||
// easier than looping through ownProperties of `val`.
|
||||
try {
|
||||
return 'Object(' + JSON.stringify(val) + ')';
|
||||
} catch (_) {
|
||||
return 'Object';
|
||||
}
|
||||
}
|
||||
// errors
|
||||
if (val instanceof Error) {
|
||||
return `${val.name}: ${val.message}\n${val.stack}`;
|
||||
}
|
||||
// TODO we could test for more things here, like `Set`s and `Map`s.
|
||||
return className;
|
||||
}
|
||||
|
||||
const cachedTextDecoder = (typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }) : { decode: () => { throw Error('TextDecoder not available') } } );
|
||||
|
||||
if (typeof TextDecoder !== 'undefined') { cachedTextDecoder.decode(); };
|
||||
|
||||
function getStringFromWasm0(ptr, len) {
|
||||
ptr = ptr >>> 0;
|
||||
return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));
|
||||
}
|
||||
|
||||
function makeMutClosure(arg0, arg1, dtor, f) {
|
||||
const state = { a: arg0, b: arg1, cnt: 1, dtor };
|
||||
const real = (...args) => {
|
||||
// First up with a closure we increment the internal reference
|
||||
// count. This ensures that the Rust closure environment won't
|
||||
// be deallocated while we're invoking it.
|
||||
state.cnt++;
|
||||
const a = state.a;
|
||||
state.a = 0;
|
||||
try {
|
||||
return f(a, state.b, ...args);
|
||||
} finally {
|
||||
if (--state.cnt === 0) {
|
||||
wasm.__wbindgen_export_2.get(state.dtor)(a, state.b);
|
||||
|
||||
} else {
|
||||
state.a = a;
|
||||
}
|
||||
}
|
||||
};
|
||||
real.original = state;
|
||||
|
||||
return real;
|
||||
}
|
||||
function __wbg_adapter_20(arg0, arg1) {
|
||||
wasm._dyn_core__ops__function__FnMut_____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h66b665bcfa5ccc10(arg0, arg1);
|
||||
}
|
||||
|
||||
function __wbg_adapter_23(arg0, arg1, arg2) {
|
||||
wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h7f980deb71f217f3(arg0, arg1, addHeapObject(arg2));
|
||||
}
|
||||
|
||||
function handleError(f, args) {
|
||||
try {
|
||||
return f.apply(this, args);
|
||||
} catch (e) {
|
||||
wasm.__wbindgen_exn_store(addHeapObject(e));
|
||||
}
|
||||
}
|
||||
|
||||
function getArrayU8FromWasm0(ptr, len) {
|
||||
ptr = ptr >>> 0;
|
||||
return getUint8Memory0().subarray(ptr / 1, ptr / 1 + len);
|
||||
}
|
||||
|
||||
async function __wbg_load(module, imports) {
|
||||
if (typeof Response === 'function' && module instanceof Response) {
|
||||
if (typeof WebAssembly.instantiateStreaming === 'function') {
|
||||
try {
|
||||
return await WebAssembly.instantiateStreaming(module, imports);
|
||||
|
||||
} catch (e) {
|
||||
if (module.headers.get('Content-Type') != 'application/wasm') {
|
||||
console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e);
|
||||
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const bytes = await module.arrayBuffer();
|
||||
return await WebAssembly.instantiate(bytes, imports);
|
||||
|
||||
} else {
|
||||
const instance = await WebAssembly.instantiate(module, imports);
|
||||
|
||||
if (instance instanceof WebAssembly.Instance) {
|
||||
return { instance, module };
|
||||
|
||||
} else {
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function __wbg_get_imports() {
|
||||
const imports = {};
|
||||
imports.wbg = {};
|
||||
imports.wbg.__wbindgen_cb_drop = function(arg0) {
|
||||
const obj = takeObject(arg0).original;
|
||||
if (obj.cnt-- == 1) {
|
||||
obj.a = 0;
|
||||
return true;
|
||||
}
|
||||
const ret = false;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbindgen_object_drop_ref = function(arg0) {
|
||||
takeObject(arg0);
|
||||
};
|
||||
imports.wbg.__wbg_log_0e24d345b14995ec = function(arg0, arg1) {
|
||||
console.log(getStringFromWasm0(arg0, arg1));
|
||||
};
|
||||
imports.wbg.__wbindgen_object_clone_ref = function(arg0) {
|
||||
const ret = getObject(arg0);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_new_abda76e883ba8a5f = function() {
|
||||
const ret = new Error();
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_stack_658279fe44541cf6 = function(arg0, arg1) {
|
||||
const ret = getObject(arg1).stack;
|
||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
const len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
};
|
||||
imports.wbg.__wbg_error_f851667af71bcfc6 = function(arg0, arg1) {
|
||||
let deferred0_0;
|
||||
let deferred0_1;
|
||||
try {
|
||||
deferred0_0 = arg0;
|
||||
deferred0_1 = arg1;
|
||||
console.error(getStringFromWasm0(arg0, arg1));
|
||||
} finally {
|
||||
wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
|
||||
}
|
||||
};
|
||||
imports.wbg.__wbindgen_string_get = function(arg0, arg1) {
|
||||
const obj = getObject(arg1);
|
||||
const ret = typeof(obj) === 'string' ? obj : undefined;
|
||||
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
var len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
};
|
||||
imports.wbg.__wbindgen_boolean_get = function(arg0) {
|
||||
const v = getObject(arg0);
|
||||
const ret = typeof(v) === 'boolean' ? (v ? 1 : 0) : 2;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_instanceof_WebGl2RenderingContext_f921526c513bf717 = function(arg0) {
|
||||
let result;
|
||||
try {
|
||||
result = getObject(arg0) instanceof WebGL2RenderingContext;
|
||||
} catch {
|
||||
result = false;
|
||||
}
|
||||
const ret = result;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_bindVertexArray_8863a216d7b0a339 = function(arg0, arg1) {
|
||||
getObject(arg0).bindVertexArray(getObject(arg1));
|
||||
};
|
||||
imports.wbg.__wbg_bufferData_21334671c4ba6004 = function(arg0, arg1, arg2, arg3) {
|
||||
getObject(arg0).bufferData(arg1 >>> 0, getObject(arg2), arg3 >>> 0);
|
||||
};
|
||||
imports.wbg.__wbg_createVertexArray_51d51e1e1e13e9f6 = function(arg0) {
|
||||
const ret = getObject(arg0).createVertexArray();
|
||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_texImage2D_07240affd06971e9 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) {
|
||||
getObject(arg0).texImage2D(arg1 >>> 0, arg2, arg3, arg4, arg5, arg6, arg7 >>> 0, arg8 >>> 0, getObject(arg9));
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_attachShader_47256b6b3d42a22e = function(arg0, arg1, arg2) {
|
||||
getObject(arg0).attachShader(getObject(arg1), getObject(arg2));
|
||||
};
|
||||
imports.wbg.__wbg_bindBuffer_24f6010e273fa400 = function(arg0, arg1, arg2) {
|
||||
getObject(arg0).bindBuffer(arg1 >>> 0, getObject(arg2));
|
||||
};
|
||||
imports.wbg.__wbg_bindFramebuffer_a9573e340dab20fe = function(arg0, arg1, arg2) {
|
||||
getObject(arg0).bindFramebuffer(arg1 >>> 0, getObject(arg2));
|
||||
};
|
||||
imports.wbg.__wbg_bindTexture_92d6d7f8bff9531e = function(arg0, arg1, arg2) {
|
||||
getObject(arg0).bindTexture(arg1 >>> 0, getObject(arg2));
|
||||
};
|
||||
imports.wbg.__wbg_blendFunc_533de6de45b80a09 = function(arg0, arg1, arg2) {
|
||||
getObject(arg0).blendFunc(arg1 >>> 0, arg2 >>> 0);
|
||||
};
|
||||
imports.wbg.__wbg_clear_2db2efe323bfdf68 = function(arg0, arg1) {
|
||||
getObject(arg0).clear(arg1 >>> 0);
|
||||
};
|
||||
imports.wbg.__wbg_clearColor_7a7d04702f7e38e5 = function(arg0, arg1, arg2, arg3, arg4) {
|
||||
getObject(arg0).clearColor(arg1, arg2, arg3, arg4);
|
||||
};
|
||||
imports.wbg.__wbg_compileShader_6bf78b425d5c98e1 = function(arg0, arg1) {
|
||||
getObject(arg0).compileShader(getObject(arg1));
|
||||
};
|
||||
imports.wbg.__wbg_createBuffer_323425af422748ac = function(arg0) {
|
||||
const ret = getObject(arg0).createBuffer();
|
||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_createFramebuffer_1684a99697ac9563 = function(arg0) {
|
||||
const ret = getObject(arg0).createFramebuffer();
|
||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_createProgram_4eaf3b97b5747a62 = function(arg0) {
|
||||
const ret = getObject(arg0).createProgram();
|
||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_createShader_429776c9dd6fb87b = function(arg0, arg1) {
|
||||
const ret = getObject(arg0).createShader(arg1 >>> 0);
|
||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_createTexture_1bf4d6fec570124b = function(arg0) {
|
||||
const ret = getObject(arg0).createTexture();
|
||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_disable_e02106ca6c7002d6 = function(arg0, arg1) {
|
||||
getObject(arg0).disable(arg1 >>> 0);
|
||||
};
|
||||
imports.wbg.__wbg_drawArrays_c91ce3f736bf1f2a = function(arg0, arg1, arg2, arg3) {
|
||||
getObject(arg0).drawArrays(arg1 >>> 0, arg2, arg3);
|
||||
};
|
||||
imports.wbg.__wbg_drawElements_a9529eefaf2008bd = function(arg0, arg1, arg2, arg3, arg4) {
|
||||
getObject(arg0).drawElements(arg1 >>> 0, arg2, arg3 >>> 0, arg4);
|
||||
};
|
||||
imports.wbg.__wbg_enable_195891416c520019 = function(arg0, arg1) {
|
||||
getObject(arg0).enable(arg1 >>> 0);
|
||||
};
|
||||
imports.wbg.__wbg_enableVertexAttribArray_8804480c2ea0bb72 = function(arg0, arg1) {
|
||||
getObject(arg0).enableVertexAttribArray(arg1 >>> 0);
|
||||
};
|
||||
imports.wbg.__wbg_framebufferTexture2D_e88fcbd7f8523bb8 = function(arg0, arg1, arg2, arg3, arg4, arg5) {
|
||||
getObject(arg0).framebufferTexture2D(arg1 >>> 0, arg2 >>> 0, arg3 >>> 0, getObject(arg4), arg5);
|
||||
};
|
||||
imports.wbg.__wbg_getError_7191ad6ea53607fe = function(arg0) {
|
||||
const ret = getObject(arg0).getError();
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_getExtension_77909f6d51d49d4d = function() { return handleError(function (arg0, arg1, arg2) {
|
||||
const ret = getObject(arg0).getExtension(getStringFromWasm0(arg1, arg2));
|
||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_getParameter_55b36a787dbbfb74 = function() { return handleError(function (arg0, arg1) {
|
||||
const ret = getObject(arg0).getParameter(arg1 >>> 0);
|
||||
return addHeapObject(ret);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_getProgramInfoLog_b81bc53188e286fa = function(arg0, arg1, arg2) {
|
||||
const ret = getObject(arg1).getProgramInfoLog(getObject(arg2));
|
||||
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
var len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
};
|
||||
imports.wbg.__wbg_getProgramParameter_35522a0bfdfaad27 = function(arg0, arg1, arg2) {
|
||||
const ret = getObject(arg0).getProgramParameter(getObject(arg1), arg2 >>> 0);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_getShaderInfoLog_968b93e75477d725 = function(arg0, arg1, arg2) {
|
||||
const ret = getObject(arg1).getShaderInfoLog(getObject(arg2));
|
||||
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
var len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
};
|
||||
imports.wbg.__wbg_getShaderParameter_ac2727ae4fe7648e = function(arg0, arg1, arg2) {
|
||||
const ret = getObject(arg0).getShaderParameter(getObject(arg1), arg2 >>> 0);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_getSupportedExtensions_fafc31aab913037d = function(arg0) {
|
||||
const ret = getObject(arg0).getSupportedExtensions();
|
||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_getUniformLocation_9f6eb60c560a347b = function(arg0, arg1, arg2, arg3) {
|
||||
const ret = getObject(arg0).getUniformLocation(getObject(arg1), getStringFromWasm0(arg2, arg3));
|
||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_linkProgram_33998194075d71fb = function(arg0, arg1) {
|
||||
getObject(arg0).linkProgram(getObject(arg1));
|
||||
};
|
||||
imports.wbg.__wbg_shaderSource_1cb7c64dc7d1a500 = function(arg0, arg1, arg2, arg3) {
|
||||
getObject(arg0).shaderSource(getObject(arg1), getStringFromWasm0(arg2, arg3));
|
||||
};
|
||||
imports.wbg.__wbg_texParameteri_85dad939f62a15aa = function(arg0, arg1, arg2, arg3) {
|
||||
getObject(arg0).texParameteri(arg1 >>> 0, arg2 >>> 0, arg3);
|
||||
};
|
||||
imports.wbg.__wbg_uniform1i_d2e61a6a43889648 = function(arg0, arg1, arg2) {
|
||||
getObject(arg0).uniform1i(getObject(arg1), arg2);
|
||||
};
|
||||
imports.wbg.__wbg_uniform3f_8364a0959b6c1570 = function(arg0, arg1, arg2, arg3, arg4) {
|
||||
getObject(arg0).uniform3f(getObject(arg1), arg2, arg3, arg4);
|
||||
};
|
||||
imports.wbg.__wbg_useProgram_3683cf6f60939dcd = function(arg0, arg1) {
|
||||
getObject(arg0).useProgram(getObject(arg1));
|
||||
};
|
||||
imports.wbg.__wbg_vertexAttribPointer_316ffe2f0458fde7 = function(arg0, arg1, arg2, arg3, arg4, arg5, arg6) {
|
||||
getObject(arg0).vertexAttribPointer(arg1 >>> 0, arg2, arg3 >>> 0, arg4 !== 0, arg5, arg6);
|
||||
};
|
||||
imports.wbg.__wbg_getElementById_cc0e0d931b0d9a28 = function(arg0, arg1, arg2) {
|
||||
const ret = getObject(arg0).getElementById(getStringFromWasm0(arg1, arg2));
|
||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_instanceof_HtmlCanvasElement_da5f9efa0688cf6d = function(arg0) {
|
||||
let result;
|
||||
try {
|
||||
result = getObject(arg0) instanceof HTMLCanvasElement;
|
||||
} catch {
|
||||
result = false;
|
||||
}
|
||||
const ret = result;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_setwidth_a667a942dba6656e = function(arg0, arg1) {
|
||||
getObject(arg0).width = arg1 >>> 0;
|
||||
};
|
||||
imports.wbg.__wbg_setheight_a747d440760fe5aa = function(arg0, arg1) {
|
||||
getObject(arg0).height = arg1 >>> 0;
|
||||
};
|
||||
imports.wbg.__wbg_getContext_7c5944ea807bf5d3 = function() { return handleError(function (arg0, arg1, arg2) {
|
||||
const ret = getObject(arg0).getContext(getStringFromWasm0(arg1, arg2));
|
||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_offsetX_5a58f16f6c3a41b6 = function(arg0) {
|
||||
const ret = getObject(arg0).offsetX;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_offsetY_c45b4956f6429a95 = function(arg0) {
|
||||
const ret = getObject(arg0).offsetY;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_now_0cfdc90c97d0c24b = function(arg0) {
|
||||
const ret = getObject(arg0).now();
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_instanceof_Window_9029196b662bc42a = function(arg0) {
|
||||
let result;
|
||||
try {
|
||||
result = getObject(arg0) instanceof Window;
|
||||
} catch {
|
||||
result = false;
|
||||
}
|
||||
const ret = result;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_charCode_75cea1a3a6d66388 = function(arg0) {
|
||||
const ret = getObject(arg0).charCode;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_keyCode_dfa86be31f5ef90c = function(arg0) {
|
||||
const ret = getObject(arg0).keyCode;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_code_96d6322b968b2d17 = function(arg0, arg1) {
|
||||
const ret = getObject(arg1).code;
|
||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
const len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
};
|
||||
imports.wbg.__wbg_getModifierState_5102ee8843516d2f = function(arg0, arg1, arg2) {
|
||||
const ret = getObject(arg0).getModifierState(getStringFromWasm0(arg1, arg2));
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_document_f7ace2b956f30a4f = function(arg0) {
|
||||
const ret = getObject(arg0).document;
|
||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_performance_2c295061c8b01e0b = function(arg0) {
|
||||
const ret = getObject(arg0).performance;
|
||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_setonkeydown_933cca3c9000a932 = function(arg0, arg1) {
|
||||
getObject(arg0).onkeydown = getObject(arg1);
|
||||
};
|
||||
imports.wbg.__wbg_setonkeyup_0dfb23e81d0afdde = function(arg0, arg1) {
|
||||
getObject(arg0).onkeyup = getObject(arg1);
|
||||
};
|
||||
imports.wbg.__wbg_requestAnimationFrame_d082200514b6674d = function() { return handleError(function (arg0, arg1) {
|
||||
const ret = getObject(arg0).requestAnimationFrame(getObject(arg1));
|
||||
return ret;
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_setonmousedown_4f38d9c057bbfcbd = function(arg0, arg1) {
|
||||
getObject(arg0).onmousedown = getObject(arg1);
|
||||
};
|
||||
imports.wbg.__wbg_setonmousemove_c0b17753786f3544 = function(arg0, arg1) {
|
||||
getObject(arg0).onmousemove = getObject(arg1);
|
||||
};
|
||||
imports.wbg.__wbg_setonmouseup_4b447fa380e33802 = function(arg0, arg1) {
|
||||
getObject(arg0).onmouseup = getObject(arg1);
|
||||
};
|
||||
imports.wbg.__wbg_bufferData_a11a9f65f31e7256 = function(arg0, arg1, arg2, arg3) {
|
||||
getObject(arg0).bufferData(arg1 >>> 0, getObject(arg2), arg3 >>> 0);
|
||||
};
|
||||
imports.wbg.__wbg_texImage2D_6175916e58c59bc7 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) {
|
||||
getObject(arg0).texImage2D(arg1 >>> 0, arg2, arg3, arg4, arg5, arg6, arg7 >>> 0, arg8 >>> 0, getObject(arg9));
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_attachShader_b65b695055670cb5 = function(arg0, arg1, arg2) {
|
||||
getObject(arg0).attachShader(getObject(arg1), getObject(arg2));
|
||||
};
|
||||
imports.wbg.__wbg_bindBuffer_313561e5bc0e533f = function(arg0, arg1, arg2) {
|
||||
getObject(arg0).bindBuffer(arg1 >>> 0, getObject(arg2));
|
||||
};
|
||||
imports.wbg.__wbg_bindFramebuffer_56bf6536a4ced0ec = function(arg0, arg1, arg2) {
|
||||
getObject(arg0).bindFramebuffer(arg1 >>> 0, getObject(arg2));
|
||||
};
|
||||
imports.wbg.__wbg_bindTexture_9cb5c770d1ba2cca = function(arg0, arg1, arg2) {
|
||||
getObject(arg0).bindTexture(arg1 >>> 0, getObject(arg2));
|
||||
};
|
||||
imports.wbg.__wbg_blendFunc_fbe9d3a688fe71c3 = function(arg0, arg1, arg2) {
|
||||
getObject(arg0).blendFunc(arg1 >>> 0, arg2 >>> 0);
|
||||
};
|
||||
imports.wbg.__wbg_clear_2ccea1f65b510c97 = function(arg0, arg1) {
|
||||
getObject(arg0).clear(arg1 >>> 0);
|
||||
};
|
||||
imports.wbg.__wbg_clearColor_de587608b28bc7ed = function(arg0, arg1, arg2, arg3, arg4) {
|
||||
getObject(arg0).clearColor(arg1, arg2, arg3, arg4);
|
||||
};
|
||||
imports.wbg.__wbg_compileShader_d88d0a8cd9b72b4d = function(arg0, arg1) {
|
||||
getObject(arg0).compileShader(getObject(arg1));
|
||||
};
|
||||
imports.wbg.__wbg_createBuffer_59051f4461e7c5e2 = function(arg0) {
|
||||
const ret = getObject(arg0).createBuffer();
|
||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_createFramebuffer_223c1212ad76affc = function(arg0) {
|
||||
const ret = getObject(arg0).createFramebuffer();
|
||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_createProgram_88dbe21c0b682e1a = function(arg0) {
|
||||
const ret = getObject(arg0).createProgram();
|
||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_createShader_9d7d388633caad18 = function(arg0, arg1) {
|
||||
const ret = getObject(arg0).createShader(arg1 >>> 0);
|
||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_createTexture_9d0bb4d741b8ad76 = function(arg0) {
|
||||
const ret = getObject(arg0).createTexture();
|
||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_disable_5cf2070641fa2ed7 = function(arg0, arg1) {
|
||||
getObject(arg0).disable(arg1 >>> 0);
|
||||
};
|
||||
imports.wbg.__wbg_drawArrays_d5c7dc2b2376c85a = function(arg0, arg1, arg2, arg3) {
|
||||
getObject(arg0).drawArrays(arg1 >>> 0, arg2, arg3);
|
||||
};
|
||||
imports.wbg.__wbg_drawElements_3316ee0cd1117c2a = function(arg0, arg1, arg2, arg3, arg4) {
|
||||
getObject(arg0).drawElements(arg1 >>> 0, arg2, arg3 >>> 0, arg4);
|
||||
};
|
||||
imports.wbg.__wbg_enable_8965e69c596f0a94 = function(arg0, arg1) {
|
||||
getObject(arg0).enable(arg1 >>> 0);
|
||||
};
|
||||
imports.wbg.__wbg_enableVertexAttribArray_2b0475db43533cf2 = function(arg0, arg1) {
|
||||
getObject(arg0).enableVertexAttribArray(arg1 >>> 0);
|
||||
};
|
||||
imports.wbg.__wbg_framebufferTexture2D_953e69a8bec22fa9 = function(arg0, arg1, arg2, arg3, arg4, arg5) {
|
||||
getObject(arg0).framebufferTexture2D(arg1 >>> 0, arg2 >>> 0, arg3 >>> 0, getObject(arg4), arg5);
|
||||
};
|
||||
imports.wbg.__wbg_getError_1e5ec1ec9e58b323 = function(arg0) {
|
||||
const ret = getObject(arg0).getError();
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_getProgramInfoLog_0b7af4ad85fa52a4 = function(arg0, arg1, arg2) {
|
||||
const ret = getObject(arg1).getProgramInfoLog(getObject(arg2));
|
||||
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
var len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
};
|
||||
imports.wbg.__wbg_getProgramParameter_2a3735278367f8bc = function(arg0, arg1, arg2) {
|
||||
const ret = getObject(arg0).getProgramParameter(getObject(arg1), arg2 >>> 0);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_getShaderInfoLog_979aafa403ffb252 = function(arg0, arg1, arg2) {
|
||||
const ret = getObject(arg1).getShaderInfoLog(getObject(arg2));
|
||||
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
var len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
};
|
||||
imports.wbg.__wbg_getShaderParameter_e8054f1d9026fb70 = function(arg0, arg1, arg2) {
|
||||
const ret = getObject(arg0).getShaderParameter(getObject(arg1), arg2 >>> 0);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_getUniformLocation_688976233799a45a = function(arg0, arg1, arg2, arg3) {
|
||||
const ret = getObject(arg0).getUniformLocation(getObject(arg1), getStringFromWasm0(arg2, arg3));
|
||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_linkProgram_9a2d12d120d99917 = function(arg0, arg1) {
|
||||
getObject(arg0).linkProgram(getObject(arg1));
|
||||
};
|
||||
imports.wbg.__wbg_shaderSource_f435f9b74440bb54 = function(arg0, arg1, arg2, arg3) {
|
||||
getObject(arg0).shaderSource(getObject(arg1), getStringFromWasm0(arg2, arg3));
|
||||
};
|
||||
imports.wbg.__wbg_texParameteri_1f17358e51eb8069 = function(arg0, arg1, arg2, arg3) {
|
||||
getObject(arg0).texParameteri(arg1 >>> 0, arg2 >>> 0, arg3);
|
||||
};
|
||||
imports.wbg.__wbg_uniform1i_9f94ef0ba6b3cc66 = function(arg0, arg1, arg2) {
|
||||
getObject(arg0).uniform1i(getObject(arg1), arg2);
|
||||
};
|
||||
imports.wbg.__wbg_uniform3f_c682f4b32f713d1a = function(arg0, arg1, arg2, arg3, arg4) {
|
||||
getObject(arg0).uniform3f(getObject(arg1), arg2, arg3, arg4);
|
||||
};
|
||||
imports.wbg.__wbg_useProgram_019eb6df066fabf5 = function(arg0, arg1) {
|
||||
getObject(arg0).useProgram(getObject(arg1));
|
||||
};
|
||||
imports.wbg.__wbg_vertexAttribPointer_ca11984ee8843c0a = function(arg0, arg1, arg2, arg3, arg4, arg5, arg6) {
|
||||
getObject(arg0).vertexAttribPointer(arg1 >>> 0, arg2, arg3 >>> 0, arg4 !== 0, arg5, arg6);
|
||||
};
|
||||
imports.wbg.__wbg_bindVertexArrayOES_b7d9da7e073aa6b5 = function(arg0, arg1) {
|
||||
getObject(arg0).bindVertexArrayOES(getObject(arg1));
|
||||
};
|
||||
imports.wbg.__wbg_createVertexArrayOES_6a3c3a5a68201f8f = function(arg0) {
|
||||
const ret = getObject(arg0).createVertexArrayOES();
|
||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_self_1c2814d86e6e51e3 = function() { return handleError(function () {
|
||||
const ret = self.self;
|
||||
return addHeapObject(ret);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_crypto_70532d614bc7e028 = function(arg0) {
|
||||
const ret = getObject(arg0).crypto;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_msCrypto_4e9b4dd0e1abade6 = function(arg0) {
|
||||
const ret = getObject(arg0).msCrypto;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_is_undefined = function(arg0) {
|
||||
const ret = getObject(arg0) === undefined;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_static_accessor_MODULE_7781e47b50010688 = function() {
|
||||
const ret = module;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_require_9ace3ae680954e98 = function() { return handleError(function (arg0, arg1, arg2) {
|
||||
const ret = getObject(arg0).require(getStringFromWasm0(arg1, arg2));
|
||||
return addHeapObject(ret);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_getRandomValues_f6c9b08ef5448767 = function() { return handleError(function (arg0, arg1) {
|
||||
getObject(arg0).getRandomValues(getObject(arg1));
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_randomFillSync_bf67eeddb65b346b = function() { return handleError(function (arg0, arg1, arg2) {
|
||||
getObject(arg0).randomFillSync(getArrayU8FromWasm0(arg1, arg2));
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_get_44be0491f933a435 = function(arg0, arg1) {
|
||||
const ret = getObject(arg0)[arg1 >>> 0];
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_length_fff51ee6522a1a18 = function(arg0) {
|
||||
const ret = getObject(arg0).length;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_newnoargs_581967eacc0e2604 = function(arg0, arg1) {
|
||||
const ret = new Function(getStringFromWasm0(arg0, arg1));
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_call_cb65541d95d71282 = function() { return handleError(function (arg0, arg1) {
|
||||
const ret = getObject(arg0).call(getObject(arg1));
|
||||
return addHeapObject(ret);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_self_1ff1d729e9aae938 = function() { return handleError(function () {
|
||||
const ret = self.self;
|
||||
return addHeapObject(ret);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_window_5f4faef6c12b79ec = function() { return handleError(function () {
|
||||
const ret = window.window;
|
||||
return addHeapObject(ret);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_globalThis_1d39714405582d3c = function() { return handleError(function () {
|
||||
const ret = globalThis.globalThis;
|
||||
return addHeapObject(ret);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_global_651f05c6a0944d1c = function() { return handleError(function () {
|
||||
const ret = global.global;
|
||||
return addHeapObject(ret);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_now_9c5990bda04c7e53 = function() {
|
||||
const ret = Date.now();
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_buffer_085ec1f694018c4f = function(arg0) {
|
||||
const ret = getObject(arg0).buffer;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_newwithbyteoffsetandlength_828b952f0e692245 = function(arg0, arg1, arg2) {
|
||||
const ret = new Int8Array(getObject(arg0), arg1 >>> 0, arg2 >>> 0);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_newwithbyteoffsetandlength_735ed5ea2ae07fe9 = function(arg0, arg1, arg2) {
|
||||
const ret = new Int16Array(getObject(arg0), arg1 >>> 0, arg2 >>> 0);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_newwithbyteoffsetandlength_9f43b22ab631d1d6 = function(arg0, arg1, arg2) {
|
||||
const ret = new Int32Array(getObject(arg0), arg1 >>> 0, arg2 >>> 0);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_newwithbyteoffsetandlength_6da8e527659b86aa = function(arg0, arg1, arg2) {
|
||||
const ret = new Uint8Array(getObject(arg0), arg1 >>> 0, arg2 >>> 0);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_new_8125e318e6245eed = function(arg0) {
|
||||
const ret = new Uint8Array(getObject(arg0));
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_set_5cf90238115182c3 = function(arg0, arg1, arg2) {
|
||||
getObject(arg0).set(getObject(arg1), arg2 >>> 0);
|
||||
};
|
||||
imports.wbg.__wbg_length_72e2208bbc0efc61 = function(arg0) {
|
||||
const ret = getObject(arg0).length;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_newwithbyteoffsetandlength_31ff1024ef0c63c7 = function(arg0, arg1, arg2) {
|
||||
const ret = new Uint16Array(getObject(arg0), arg1 >>> 0, arg2 >>> 0);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_newwithbyteoffsetandlength_6df0e8c3efd2a5d3 = function(arg0, arg1, arg2) {
|
||||
const ret = new Uint32Array(getObject(arg0), arg1 >>> 0, arg2 >>> 0);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_newwithbyteoffsetandlength_69193e31c844b792 = function(arg0, arg1, arg2) {
|
||||
const ret = new Float32Array(getObject(arg0), arg1 >>> 0, arg2 >>> 0);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_newwithlength_e5d69174d6984cd7 = function(arg0) {
|
||||
const ret = new Uint8Array(arg0 >>> 0);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_subarray_13db269f57aa838d = function(arg0, arg1, arg2) {
|
||||
const ret = getObject(arg0).subarray(arg1 >>> 0, arg2 >>> 0);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_debug_string = function(arg0, arg1) {
|
||||
const ret = debugString(getObject(arg1));
|
||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
const len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
};
|
||||
imports.wbg.__wbindgen_throw = function(arg0, arg1) {
|
||||
throw new Error(getStringFromWasm0(arg0, arg1));
|
||||
};
|
||||
imports.wbg.__wbindgen_memory = function() {
|
||||
const ret = wasm.memory;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_closure_wrapper257 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 14, __wbg_adapter_20);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_closure_wrapper2960 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 698, __wbg_adapter_23);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_closure_wrapper2962 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 698, __wbg_adapter_23);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
|
||||
return imports;
|
||||
}
|
||||
|
||||
function __wbg_init_memory(imports, maybe_memory) {
|
||||
|
||||
}
|
||||
|
||||
function __wbg_finalize_init(instance, module) {
|
||||
wasm = instance.exports;
|
||||
__wbg_init.__wbindgen_wasm_module = module;
|
||||
cachedInt32Memory0 = null;
|
||||
cachedUint8Memory0 = null;
|
||||
|
||||
wasm.__wbindgen_start();
|
||||
return wasm;
|
||||
}
|
||||
|
||||
function initSync(module) {
|
||||
if (wasm !== undefined) return wasm;
|
||||
|
||||
const imports = __wbg_get_imports();
|
||||
|
||||
__wbg_init_memory(imports);
|
||||
|
||||
if (!(module instanceof WebAssembly.Module)) {
|
||||
module = new WebAssembly.Module(module);
|
||||
}
|
||||
|
||||
const instance = new WebAssembly.Instance(module, imports);
|
||||
|
||||
return __wbg_finalize_init(instance, module);
|
||||
}
|
||||
|
||||
async function __wbg_init(input) {
|
||||
if (wasm !== undefined) return wasm;
|
||||
|
||||
if (typeof input === 'undefined' && script_src !== 'undefined') {
|
||||
input = script_src.replace(/\.js$/, '_bg.wasm');
|
||||
}
|
||||
const imports = __wbg_get_imports();
|
||||
|
||||
if (typeof input === 'string' || (typeof Request === 'function' && input instanceof Request) || (typeof URL === 'function' && input instanceof URL)) {
|
||||
input = fetch(input);
|
||||
}
|
||||
|
||||
__wbg_init_memory(imports);
|
||||
|
||||
const { instance, module } = await __wbg_load(await input, imports);
|
||||
|
||||
return __wbg_finalize_init(instance, module);
|
||||
}
|
||||
|
||||
wasm_bindgen = Object.assign(__wbg_init, { initSync }, __exports);
|
||||
|
||||
})();
|
||||