diff --git a/src/gamelog/logstore.rs b/src/gamelog/logstore.rs index c4ae0fc..0627aa5 100644 --- a/src/gamelog/logstore.rs +++ b/src/gamelog/logstore.rs @@ -19,34 +19,57 @@ pub fn clear_log() { LOG.lock().unwrap().clear(); } -pub fn print_log(console: &mut Box, pos: Point, descending: bool, len: usize, maximum_len: i32) { +pub fn print_log(console: &mut Box, pos: Point, _descending: bool, len: usize, maximum_len: i32) { + // Start at x, y let mut y = pos.y; let mut x = pos.x; + // Reverse the log, take the number we want to show, and iterate through them LOG.lock().unwrap().iter().rev().take(len).for_each(|log| { let mut len_so_far: i32 = 0; let mut entry_len = 0; + // Iterate through each message fragment, and get the total length + // in lines, by adding the length of every fragment and dividing it + // by the maximum length we desire. log.iter().for_each(|frag| { entry_len += frag.text.len() as i32; }); let lines = entry_len / maximum_len; + // If the fragment is more than one line long, move our y-value up + // by this much. y -= lines; + // Iterate through each fragment now, for the draw loop log.iter().for_each(|frag| { - if len_so_far + frag.text.len() as i32 > maximum_len { - y += 1; - x = pos.x; - len_so_far = 0; + // Split every fragment up into single characters + let parts = frag.text.split(""); + // For every character, check if the length will exceed + // the maximum length we're looking for. If it will, go + // down 1 in the y-axis, return us to the start of the line, + // and reset our length counter to 0. + for part in parts { + if len_so_far + part.len() as i32 > maximum_len { + y += 1; + x = pos.x; + len_so_far = 0; + } + // If we're still within our "range" (we haven't gone up + // further in the y-axis than our desired amount), then + // print the next character. Otherwise, just skip it. + // -- this makes sure we don't continue drawing outside of + // the bounds of our message box. + if y > pos.y - len as i32 { + console.print_color(x, y, frag.colour.into(), RGB::named(rltk::BLACK).into(), part); + } + // Move across by 1 in the x-axis, and add the length to our counter. + x += part.len() as i32; + len_so_far += part.len() as i32; } - if y > pos.y - len as i32 { - console.print_color(x, y, frag.colour.into(), RGB::named(rltk::BLACK).into(), &frag.text); - } - x += frag.text.len() as i32; - len_so_far += frag.text.len() as i32; }); - if descending { - y += 1; - } else { - y -= 1 + lines; - } + // Descending is deprecated for now, so we always ascending upwards. + // Take away one from the y-axis, because we want to start each entry + // on a new line, and go up an additional amount depending on how many + // lines our *previous* entry took. + y -= 1 + lines; + // Go back to the start of the new line. x = pos.x; }); } diff --git a/src/inventory_system.rs b/src/inventory_system.rs index 98e0fce..0fd6776 100644 --- a/src/inventory_system.rs +++ b/src/inventory_system.rs @@ -110,6 +110,8 @@ impl<'a> System<'a> for ItemUseSystem { let mut used_item = true; let mut aoe_item = false; + let mut logger = gamelog::Logger::new(); + let is_cursed = cursed_items.get(wants_to_use.item); let wand = wands.get_mut(wants_to_use.item); if let Some(wand) = wand { @@ -120,10 +122,7 @@ impl<'a> System<'a> for ItemUseSystem { 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(); + logger = logger.colour(rltk::YELLOW).append("You wrest one last charge from the worn-out wand."); consumables.insert(wants_to_use.item, Consumable {}).expect("Could not insert consumable"); } verb = "zap"; @@ -144,11 +143,8 @@ impl<'a> System<'a> for ItemUseSystem { verb = "equip" } - gamelog::Logger::new() - .append(format!("You {} the", verb)) - .item_name_n(format!("{}", &item_being_used.name)) - .period() - .log(); + logger = + logger.append(format!("You {} the", verb)).item_name_n(format!("{}", &item_being_used.name)).period(); // TARGETING let mut targets: Vec = Vec::new(); @@ -182,7 +178,7 @@ impl<'a> System<'a> for ItemUseSystem { if let Some(pos) = pos { target = Point::new(pos.x, pos.y); } - gamelog::Logger::new() + logger = logger .append("The") .item_name(&item_being_used.name) .colour(rltk::WHITE) @@ -244,11 +240,7 @@ impl<'a> System<'a> for ItemUseSystem { equipped.remove(*item); backpack.insert(*item, InBackpack { owner: target }).expect("Unable to insert backpack"); if target == *player_entity { - gamelog::Logger::new() - .append("You remove your") - .item_name_n(&item_being_used.name) - .period() - .log(); + logger = logger.append("You remove your").item_name_n(&item_being_used.name).period(); } } @@ -271,7 +263,7 @@ impl<'a> System<'a> for ItemUseSystem { stats.hit_points.current = i32::min(stats.hit_points.max, stats.hit_points.current + heal.amount); if entity == *player_entity { - gamelog::Logger::new().append("Quaffing, you recover some vigour.").log(); + logger = logger.append("You recover some vigour."); } let pos = positions.get(entity); if let Some(pos) = pos { @@ -282,6 +274,9 @@ impl<'a> System<'a> for ItemUseSystem { } } + let mut damage_logger = gamelog::Logger::new(); + let mut needs_damage_log = false; + // DAMAGING ITEM let item_damages = inflicts_damage.get(wants_to_use.item); match item_damages { @@ -305,7 +300,7 @@ impl<'a> System<'a> for ItemUseSystem { None => { SufferDamage::new_damage(&mut suffer_damage, *mob, damage.amount); if entity == *player_entity { - gamelog::Logger::new() + damage_logger = damage_logger .append("The") .npc_name(&entity_name.name) .colour(rltk::WHITE) @@ -314,17 +309,17 @@ impl<'a> System<'a> for ItemUseSystem { .colour(rltk::WHITE) .append("damage from the") .item_name_n(format!("{}", &item_being_used.name)) - .period() - .log(); + .period(); + needs_damage_log = true; } } Some(_destructible) => { - gamelog::Logger::new() + damage_logger = damage_logger .append("The") .item_name(&entity_name.name) .colour(rltk::WHITE) - .append("is destroyed!") - .log(); + .append("is destroyed!"); + needs_damage_log = true; entities.delete(*mob).expect("Delete failed"); } } @@ -360,19 +355,14 @@ impl<'a> System<'a> for ItemUseSystem { used_item = true; match is_cursed { None => { - gamelog::Logger::new() + logger = logger .append("You feel") .colour(rltk::GREEN) - .append("a sense of acuity towards your surroundings.") - .log(); + .append("a sense of acuity towards your surroundings."); *runstate = RunState::MagicMapReveal { row: 0, cursed: false }; } Some(_) => { - gamelog::Logger::new() - .append("You") - .colour(rltk::RED) - .append("forget where you last were.") - .log(); + logger = logger.append("You").colour(rltk::RED).append("forget where you last were."); *runstate = RunState::MagicMapReveal { row: 0, cursed: true }; } } @@ -410,6 +400,11 @@ impl<'a> System<'a> for ItemUseSystem { } } } + + logger.log(); + if needs_damage_log { + damage_logger.log(); + } } wants_to_use.clear(); }