Compare commits
7 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c29b93337c | ||
|
|
0584d07a1f | ||
|
|
45b9b33039 | ||
|
|
bdcd55c8a5 | ||
|
|
99c17f8521 | ||
|
|
6324449c16 | ||
|
|
d465592c0f |
5 changed files with 107 additions and 118 deletions
2
.github/workflows/cargo-build-test.yml
vendored
2
.github/workflows/cargo-build-test.yml
vendored
|
|
@ -12,7 +12,7 @@ env:
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-22.04
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|
|
||||||
11
README.md
11
README.md
|
|
@ -2,18 +2,18 @@
|
||||||
|
|
||||||
#### using _rltk/bracket-lib_, and _specs_
|
#### using _rltk/bracket-lib_, and _specs_
|
||||||
|
|
||||||
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:
|
[](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:
|
||||||
|
|
||||||
`git clone https://github.com/Llywelwyn/rust-rl/ && cd rust-rl && cargo build --release`,
|
`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>
|
<details>
|
||||||
<summary>week 1</summary>
|
<summary>week 1</summary>
|
||||||
|
|
||||||
|
|
@ -157,3 +157,4 @@ i'm also working on translating over my progress into blog entries on my site @
|
||||||

|

|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
</details>
|
||||||
|
|
|
||||||
|
|
@ -65,9 +65,7 @@ impl<'a> System<'a> for TurnStatusSystem {
|
||||||
not_confused.push(entity);
|
not_confused.push(entity);
|
||||||
if entity == *player_entity {
|
if entity == *player_entity {
|
||||||
logger = logger
|
logger = logger
|
||||||
.colour(renderable_colour(&renderables, entity))
|
|
||||||
.append("You")
|
.append("You")
|
||||||
.colour(WHITE)
|
|
||||||
.append("snap out of it.");
|
.append("snap out of it.");
|
||||||
log = true;
|
log = true;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -94,9 +92,7 @@ impl<'a> System<'a> for TurnStatusSystem {
|
||||||
not_my_turn.push(entity);
|
not_my_turn.push(entity);
|
||||||
if entity == *player_entity {
|
if entity == *player_entity {
|
||||||
logger = logger
|
logger = logger
|
||||||
.colour(renderable_colour(&renderables, entity))
|
|
||||||
.append("You")
|
.append("You")
|
||||||
.colour(WHITE)
|
|
||||||
.append("are confused!");
|
.append("are confused!");
|
||||||
log = true;
|
log = true;
|
||||||
gamelog::record_event(EVENT::PlayerConfused(1));
|
gamelog::record_event(EVENT::PlayerConfused(1));
|
||||||
|
|
|
||||||
|
|
@ -223,9 +223,7 @@ fn handle_healing(
|
||||||
let renderables = ecs.read_storage::<Renderable>();
|
let renderables = ecs.read_storage::<Renderable>();
|
||||||
if ecs.read_storage::<Player>().get(target).is_some() {
|
if ecs.read_storage::<Player>().get(target).is_some() {
|
||||||
logger = logger
|
logger = logger
|
||||||
.colour(renderable_colour(&renderables, target))
|
|
||||||
.append("You")
|
.append("You")
|
||||||
.colour(WHITE)
|
|
||||||
.append(HEAL_PLAYER_HIT)
|
.append(HEAL_PLAYER_HIT)
|
||||||
.buc(event.buc.clone(), None, Some(HEAL_PLAYER_HIT_BLESSED));
|
.buc(event.buc.clone(), None, Some(HEAL_PLAYER_HIT_BLESSED));
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -267,9 +265,7 @@ fn handle_damage(
|
||||||
let player_viewshed = viewsheds.get(*ecs.fetch::<Entity>()).unwrap();
|
let player_viewshed = viewsheds.get(*ecs.fetch::<Entity>()).unwrap();
|
||||||
if ecs.read_storage::<Player>().get(target).is_some() {
|
if ecs.read_storage::<Player>().get(target).is_some() {
|
||||||
logger = logger
|
logger = logger
|
||||||
.colour(renderable_colour(&renderables, target))
|
|
||||||
.append("You")
|
.append("You")
|
||||||
.colour(WHITE)
|
|
||||||
.append(DAMAGE_PLAYER_HIT);
|
.append(DAMAGE_PLAYER_HIT);
|
||||||
event.log = true;
|
event.log = true;
|
||||||
} else if
|
} else if
|
||||||
|
|
|
||||||
204
src/gui/mod.rs
204
src/gui/mod.rs
|
|
@ -106,6 +106,101 @@ pub fn draw_lerping_bar(
|
||||||
ctx.print(sx + width, sy, "]");
|
ctx.print(sx + width, sy, "]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn draw_xp(ctx: &mut BTerm, pt: Point, pool: &Pools) {
|
||||||
|
ctx.print_color(
|
||||||
|
pt.x,
|
||||||
|
pt.y,
|
||||||
|
RGB::named(WHITE),
|
||||||
|
RGB::named(BLACK),
|
||||||
|
format!("XP{}/{}", pool.level, pool.xp)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn calc_ac(ecs: &World, skills: &Skills, stats: &Pools, attr: &Attributes) -> i32 {
|
||||||
|
let skill_ac_bonus = gamesystem::skill_bonus(Skill::Defence, skills);
|
||||||
|
let mut armour_ac_bonus = 0;
|
||||||
|
let equipped = ecs.read_storage::<Equipped>();
|
||||||
|
let ac = ecs.read_storage::<ArmourClassBonus>();
|
||||||
|
let player_entity = ecs.fetch::<Entity>();
|
||||||
|
for (wielded, ac) in (&equipped, &ac).join() {
|
||||||
|
if wielded.owner == *player_entity {
|
||||||
|
armour_ac_bonus += ac.amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stats.bac - attr.dexterity.bonus / 2 - skill_ac_bonus - armour_ac_bonus
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_ac(ctx: &mut BTerm, pt: Point, ac: i32) {
|
||||||
|
ctx.print_color(pt.x, pt.y, RGB::named(PINK), RGB::named(BLACK), "AC");
|
||||||
|
ctx.print_color(pt.x + 2, pt.y, RGB::named(WHITE), RGB::named(BLACK), ac);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_attributes(ctx: &mut BTerm, pt: Point, a: &Attributes) {
|
||||||
|
ctx.print_color(pt.x, pt.y, RGB::named(RED), RGB::named(BLACK), "STR");
|
||||||
|
ctx.print_color(pt.x + 3, pt.y, RGB::named(WHITE), RGB::named(BLACK), a.strength.base);
|
||||||
|
ctx.print_color(pt.x + 7, pt.y, RGB::named(GREEN), RGB::named(BLACK), "DEX");
|
||||||
|
ctx.print_color(pt.x + 10, pt.y, RGB::named(WHITE), RGB::named(BLACK), a.dexterity.base);
|
||||||
|
ctx.print_color(pt.x + 14, pt.y, RGB::named(ORANGE), RGB::named(BLACK), "CON");
|
||||||
|
ctx.print_color(pt.x + 17, pt.y, RGB::named(WHITE), RGB::named(BLACK), a.constitution.base);
|
||||||
|
ctx.print_color(pt.x, 54, RGB::named(CYAN), RGB::named(BLACK), "INT");
|
||||||
|
ctx.print_color(pt.x + 3, pt.y + 1, RGB::named(WHITE), RGB::named(BLACK), a.intelligence.base);
|
||||||
|
ctx.print_color(pt.x + 7, pt.y + 1, RGB::named(YELLOW), RGB::named(BLACK), "WIS");
|
||||||
|
ctx.print_color(pt.x + 10, pt.y + 1, RGB::named(WHITE), RGB::named(BLACK), a.wisdom.base);
|
||||||
|
ctx.print_color(pt.x + 14, pt.y + 1, RGB::named(PURPLE), RGB::named(BLACK), "CHA");
|
||||||
|
ctx.print_color(pt.x + 17, pt.y + 1, RGB::named(WHITE), RGB::named(BLACK), a.charisma.base);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_hunger(ctx: &mut BTerm, pt: Point, hunger: &HungerClock) {
|
||||||
|
match hunger.state {
|
||||||
|
HungerState::Satiated => {
|
||||||
|
ctx.print_color_right(
|
||||||
|
pt.x,
|
||||||
|
pt.y,
|
||||||
|
get_hunger_colour(hunger.state),
|
||||||
|
RGB::named(BLACK),
|
||||||
|
"Satiated"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
HungerState::Normal => {}
|
||||||
|
HungerState::Hungry => {
|
||||||
|
ctx.print_color_right(
|
||||||
|
pt.x,
|
||||||
|
pt.y,
|
||||||
|
get_hunger_colour(hunger.state),
|
||||||
|
RGB::named(BLACK),
|
||||||
|
"Hungry"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
HungerState::Weak => {
|
||||||
|
ctx.print_color_right(
|
||||||
|
pt.x,
|
||||||
|
pt.y,
|
||||||
|
get_hunger_colour(hunger.state),
|
||||||
|
RGB::named(BLACK),
|
||||||
|
"Weak"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
HungerState::Fainting => {
|
||||||
|
ctx.print_color_right(
|
||||||
|
pt.x,
|
||||||
|
pt.y,
|
||||||
|
get_hunger_colour(hunger.state),
|
||||||
|
RGB::named(BLACK),
|
||||||
|
"Fainting"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
HungerState::Starving => {
|
||||||
|
ctx.print_color_right(
|
||||||
|
pt.x,
|
||||||
|
pt.y,
|
||||||
|
get_hunger_colour(hunger.state),
|
||||||
|
RGB::named(BLACK),
|
||||||
|
"Starving"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn draw_ui(ecs: &World, ctx: &mut BTerm) {
|
pub fn draw_ui(ecs: &World, ctx: &mut BTerm) {
|
||||||
// Render stats
|
// Render stats
|
||||||
let pools = ecs.read_storage::<Pools>();
|
let pools = ecs.read_storage::<Pools>();
|
||||||
|
|
@ -142,111 +237,12 @@ pub fn draw_ui(ecs: &World, ctx: &mut BTerm) {
|
||||||
RGB::named(BLUE),
|
RGB::named(BLUE),
|
||||||
RGB::named(BLACK)
|
RGB::named(BLACK)
|
||||||
);
|
);
|
||||||
// Draw AC
|
draw_ac(ctx, Point::new(26, 53), calc_ac(ecs, skills, stats, attributes));
|
||||||
let skill_ac_bonus = gamesystem::skill_bonus(Skill::Defence, &*skills);
|
draw_xp(ctx, Point::new(26, 54), stats);
|
||||||
let mut armour_ac_bonus = 0;
|
draw_attributes(ctx, Point::new(38, 53), attributes);
|
||||||
let equipped = ecs.read_storage::<Equipped>();
|
draw_hunger(ctx, Point::new(70, 53), hunger);
|
||||||
let ac = ecs.read_storage::<ArmourClassBonus>();
|
|
||||||
let player_entity = ecs.fetch::<Entity>();
|
|
||||||
for (wielded, ac) in (&equipped, &ac).join() {
|
|
||||||
if wielded.owner == *player_entity {
|
|
||||||
armour_ac_bonus += ac.amount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let armour_class =
|
|
||||||
stats.bac - attributes.dexterity.bonus / 2 - skill_ac_bonus - armour_ac_bonus;
|
|
||||||
ctx.print_color(26, 53, RGB::named(PINK), RGB::named(BLACK), "AC");
|
|
||||||
ctx.print_color(28, 53, RGB::named(WHITE), RGB::named(BLACK), armour_class);
|
|
||||||
// Draw level
|
|
||||||
ctx.print_color(
|
|
||||||
26,
|
|
||||||
54,
|
|
||||||
RGB::named(WHITE),
|
|
||||||
RGB::named(BLACK),
|
|
||||||
format!("XP{}/{}", stats.level, stats.xp)
|
|
||||||
);
|
|
||||||
// Draw attributes
|
|
||||||
let x = 38;
|
|
||||||
ctx.print_color(x, 53, RGB::named(RED), RGB::named(BLACK), "STR");
|
|
||||||
ctx.print_color(x + 3, 53, RGB::named(WHITE), RGB::named(BLACK), attributes.strength.base);
|
|
||||||
ctx.print_color(x + 7, 53, RGB::named(GREEN), RGB::named(BLACK), "DEX");
|
|
||||||
ctx.print_color(
|
|
||||||
x + 10,
|
|
||||||
53,
|
|
||||||
RGB::named(WHITE),
|
|
||||||
RGB::named(BLACK),
|
|
||||||
attributes.dexterity.base
|
|
||||||
);
|
|
||||||
ctx.print_color(x + 14, 53, RGB::named(ORANGE), RGB::named(BLACK), "CON");
|
|
||||||
ctx.print_color(
|
|
||||||
x + 17,
|
|
||||||
53,
|
|
||||||
RGB::named(WHITE),
|
|
||||||
RGB::named(BLACK),
|
|
||||||
attributes.constitution.base
|
|
||||||
);
|
|
||||||
ctx.print_color(x, 54, RGB::named(CYAN), RGB::named(BLACK), "INT");
|
|
||||||
ctx.print_color(
|
|
||||||
x + 3,
|
|
||||||
54,
|
|
||||||
RGB::named(WHITE),
|
|
||||||
RGB::named(BLACK),
|
|
||||||
attributes.intelligence.base
|
|
||||||
);
|
|
||||||
ctx.print_color(x + 7, 54, RGB::named(YELLOW), RGB::named(BLACK), "WIS");
|
|
||||||
ctx.print_color(x + 10, 54, RGB::named(WHITE), RGB::named(BLACK), attributes.wisdom.base);
|
|
||||||
ctx.print_color(x + 14, 54, RGB::named(PURPLE), RGB::named(BLACK), "CHA");
|
|
||||||
ctx.print_color(x + 17, 54, RGB::named(WHITE), RGB::named(BLACK), attributes.charisma.base);
|
|
||||||
// Draw hunger
|
|
||||||
match hunger.state {
|
|
||||||
HungerState::Satiated => {
|
|
||||||
ctx.print_color_right(
|
|
||||||
70,
|
|
||||||
53,
|
|
||||||
get_hunger_colour(hunger.state),
|
|
||||||
RGB::named(BLACK),
|
|
||||||
"Satiated"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
HungerState::Normal => {}
|
|
||||||
HungerState::Hungry => {
|
|
||||||
ctx.print_color_right(
|
|
||||||
70,
|
|
||||||
53,
|
|
||||||
get_hunger_colour(hunger.state),
|
|
||||||
RGB::named(BLACK),
|
|
||||||
"Hungry"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
HungerState::Weak => {
|
|
||||||
ctx.print_color_right(
|
|
||||||
70,
|
|
||||||
53,
|
|
||||||
get_hunger_colour(hunger.state),
|
|
||||||
RGB::named(BLACK),
|
|
||||||
"Weak"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
HungerState::Fainting => {
|
|
||||||
ctx.print_color_right(
|
|
||||||
70,
|
|
||||||
53,
|
|
||||||
get_hunger_colour(hunger.state),
|
|
||||||
RGB::named(BLACK),
|
|
||||||
"Fainting"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
HungerState::Starving => {
|
|
||||||
ctx.print_color_right(
|
|
||||||
70,
|
|
||||||
53,
|
|
||||||
get_hunger_colour(hunger.state),
|
|
||||||
RGB::named(BLACK),
|
|
||||||
"Starving"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Burden
|
// Burden
|
||||||
|
let player_entity = ecs.fetch::<Entity>();
|
||||||
if let Some(burden) = burden.get(*player_entity) {
|
if let Some(burden) = burden.get(*player_entity) {
|
||||||
match burden.level {
|
match burden.level {
|
||||||
crate::BurdenLevel::Burdened => {
|
crate::BurdenLevel::Burdened => {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue