basic wands and wresting

This commit is contained in:
Llywelwyn 2023-07-12 11:40:56 +01:00
parent 4cd4b638ec
commit 24417fbb05
5 changed files with 96 additions and 22 deletions

View file

@ -200,6 +200,12 @@ pub struct WantsToUseItem {
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
pub struct Consumable {}
#[derive(Component, Debug, ConvertSaveload)]
pub struct Wand {
pub uses: i32,
pub max_uses: i32,
}
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
pub struct Destructible {}

View file

@ -1,8 +1,8 @@
use super::{
gamelog, CombatStats, Confusion, Consumable, Cursed, Destructible, Equippable, Equipped, HungerClock, HungerState,
InBackpack, InflictsDamage, MagicMapper, Map, Name, ParticleBuilder, Point, Position, ProvidesHealing,
ProvidesNutrition, RunState, SufferDamage, WantsToDropItem, WantsToPickupItem, WantsToRemoveItem, WantsToUseItem,
AOE, DEFAULT_PARTICLE_LIFETIME, LONG_PARTICLE_LIFETIME,
ProvidesNutrition, RandomNumberGenerator, RunState, SufferDamage, Wand, WantsToDropItem, WantsToPickupItem,
WantsToRemoveItem, WantsToUseItem, AOE, DEFAULT_PARTICLE_LIFETIME, LONG_PARTICLE_LIFETIME,
};
use specs::prelude::*;
@ -44,10 +44,12 @@ impl<'a> System<'a> for ItemUseSystem {
type SystemData = (
ReadExpect<'a, Entity>,
ReadExpect<'a, Map>,
WriteExpect<'a, RandomNumberGenerator>,
Entities<'a>,
WriteStorage<'a, WantsToUseItem>,
ReadStorage<'a, Name>,
ReadStorage<'a, Consumable>,
WriteStorage<'a, Consumable>,
WriteStorage<'a, Wand>,
ReadStorage<'a, Destructible>,
ReadStorage<'a, Cursed>,
ReadStorage<'a, ProvidesHealing>,
@ -71,10 +73,12 @@ impl<'a> System<'a> for ItemUseSystem {
let (
player_entity,
map,
mut rng,
entities,
mut wants_to_use,
names,
consumables,
mut consumables,
mut wands,
destructibles,
cursed_items,
provides_healing,
@ -95,13 +99,29 @@ impl<'a> System<'a> for ItemUseSystem {
) = data;
for (entity, wants_to_use) in (&entities, &wants_to_use).join() {
let mut verb = "use";
let mut used_item = true;
let mut aoe_item = false;
let item_being_used = names.get(wants_to_use.item).unwrap();
let is_cursed = cursed_items.get(wants_to_use.item);
let mut verb = "use";
let wand = wands.get_mut(wants_to_use.item);
if let Some(wand) = wand {
// If want has no uses, roll 1d121. On a 121, wrest the wand, then delete it.
if wand.uses == 0 {
if rng.roll_dice(1, 121) != 121 {
gamelog::Logger::new().append("The wand does nothing.").log();
break;
}
gamelog::Logger::new()
.colour(rltk::YELLOW)
.append("You wrest one last charge from the worn-out wand.")
.log();
consumables.insert(wants_to_use.item, Consumable {}).expect("Could not insert consumable");
}
verb = "zap";
wand.uses -= 1;
}
let is_edible = provides_nutrition.get(wants_to_use.item);
if let Some(_) = is_edible {

View file

@ -283,13 +283,11 @@ impl GameState for State {
}
RunState::AwaitingInput => {
new_runstate = player_input(self, ctx);
if new_runstate != RunState::AwaitingInput {
gamelog::record_event("Turn", 1);
}
}
RunState::PlayerTurn => {
self.run_systems();
self.ecs.maintain();
gamelog::record_event("Turn", 1);
match *self.ecs.fetch::<RunState>() {
RunState::MagicMapReveal { row, cursed } => {
new_runstate = RunState::MagicMapReveal { row: row, cursed: cursed }
@ -508,6 +506,7 @@ fn main() -> rltk::BError {
gs.ecs.register::<WantsToRemoveItem>();
gs.ecs.register::<WantsToUseItem>();
gs.ecs.register::<Consumable>();
gs.ecs.register::<Wand>();
gs.ecs.register::<ProvidesNutrition>();
gs.ecs.register::<Destructible>();
gs.ecs.register::<ParticleLifetime>();

View file

@ -76,6 +76,7 @@ pub fn save_game(ecs: &mut World) {
SufferDamage,
Telepath,
Viewshed,
Wand,
WantsToDropItem,
WantsToMelee,
WantsToPickupItem,
@ -163,6 +164,7 @@ pub fn load_game(ecs: &mut World) {
SufferDamage,
Telepath,
Viewshed,
Wand,
WantsToDropItem,
WantsToMelee,
WantsToPickupItem,

View file

@ -2,7 +2,7 @@ use super::{
random_table::RandomTable, BlocksTile, CombatStats, Confusion, Consumable, Cursed, DefenceBonus, Destructible,
EquipmentSlot, Equippable, HungerClock, HungerState, InflictsDamage, Item, MagicMapper, MeleePowerBonus, Mind,
Monster, Name, Player, Position, ProvidesHealing, ProvidesNutrition, Ranged, Rect, Renderable, SerializeMe,
Viewshed, AOE, MAPWIDTH,
Viewshed, Wand, AOE, MAPWIDTH,
};
use rltk::{console, RandomNumberGenerator, RGB};
use specs::prelude::*;
@ -135,6 +135,9 @@ pub fn spawn_room(ecs: &mut World, room: &Rect, map_depth: i32) {
"magic missile scroll" => magic_missile_scroll(ecs, x, y),
"magic map scroll" => magic_map_scroll(ecs, x, y),
"cursed magic map scroll" => cursed_magic_map_scroll(ecs, x, y),
// Wands
"magic missile wand" => magic_missile_wand(ecs, x, y),
"fireball wand" => fireball_wand(ecs, x, y),
// Food
"rations" => rations(ecs, x, y),
_ => console::log("Tried to spawn nothing. Bugfix needed!"),
@ -164,20 +167,23 @@ fn mob_table(map_depth: i32) -> RandomTable {
fn item_table(_map_depth: i32) -> RandomTable {
return RandomTable::new()
// Equipment
.add("dagger", 2)
.add("shortsword", 2)
.add("buckler", 2)
.add("shield", 1)
.add("dagger", 4)
.add("shortsword", 4)
.add("buckler", 4)
.add("shield", 2)
// Potions
.add("weak health potion", 7)
.add("health potion", 3)
.add("weak health potion", 14)
.add("health potion", 6)
// Scrolls
.add("fireball scroll", 1)
.add("cursed fireball scroll", 1)
.add("confusion scroll", 2)
.add("magic missile scroll", 5)
.add("magic map scroll", 2)
.add("cursed magic map scroll", 1);
.add("fireball scroll", 2)
.add("cursed fireball scroll", 2)
.add("confusion scroll", 4)
.add("magic missile scroll", 10)
.add("magic map scroll", 4)
.add("cursed magic map scroll", 2)
// Wands
.add("magic missile wand", 1)
.add("fireball wand", 1);
}
fn food_table(_map_depth: i32) -> RandomTable {
@ -445,3 +451,44 @@ fn rations(ecs: &mut World, x: i32, y: i32) {
.marked::<SimpleMarker<SerializeMe>>()
.build();
}
// WANDS
fn fireball_wand(ecs: &mut World, x: i32, y: i32) {
ecs.create_entity()
.with(Position { x, y })
.with(Renderable {
glyph: rltk::to_cp437('/'),
fg: RGB::named(rltk::ORANGE),
bg: RGB::named(rltk::BLACK),
render_order: 2,
})
.with(Name { name: "wand of fireball".to_string() })
.with(Item {})
.with(Wand { uses: 3, max_uses: 3 })
.with(Destructible {})
.with(Ranged { range: 10 })
.with(InflictsDamage { amount: 20 })
.with(AOE { radius: 3 })
.marked::<SimpleMarker<SerializeMe>>()
.build();
}
fn magic_missile_wand(ecs: &mut World, x: i32, y: i32) {
ecs.create_entity()
.with(Position { x, y })
.with(Renderable {
glyph: rltk::to_cp437('?'),
fg: RGB::named(rltk::BLUE),
bg: RGB::named(rltk::BLACK),
render_order: 2,
})
.with(Name { name: "wand of magic missile".to_string() })
.with(Item {})
.with(Wand { uses: 3, max_uses: 3 })
.with(Destructible {})
.with(Ranged { range: 12 }) // Long range - as far as default vision range
.with(InflictsDamage { amount: 10 }) // Low~ damage
.marked::<SimpleMarker<SerializeMe>>()
.build();
}