Use element names, hex colors for under
This commit is contained in:
@@ -274,3 +274,70 @@ pub fn element_name(id: u8) -> String {
|
|||||||
None => format!("unknown ({})", id),
|
None => format!("unknown ({})", id),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convert an element name back to its ID.
|
||||||
|
/// Handles "unknown_N" format for unknown element IDs.
|
||||||
|
pub fn element_id_from_name(name: &str) -> Option<u8> {
|
||||||
|
// Handle "unknown_N" format first
|
||||||
|
if let Some(suffix) = name.strip_prefix("unknown_") {
|
||||||
|
return suffix.parse().ok();
|
||||||
|
}
|
||||||
|
// Match all known element names to their IDs
|
||||||
|
match name {
|
||||||
|
"empty" => Some(0),
|
||||||
|
"board_edge" => Some(1),
|
||||||
|
"messenger" => Some(2),
|
||||||
|
"monitor" => Some(3),
|
||||||
|
"player" => Some(4),
|
||||||
|
"ammo" => Some(5),
|
||||||
|
"torch" => Some(6),
|
||||||
|
"gem" => Some(7),
|
||||||
|
"key" => Some(8),
|
||||||
|
"door" => Some(9),
|
||||||
|
"scroll" => Some(10),
|
||||||
|
"passage" => Some(11),
|
||||||
|
"duplicator" => Some(12),
|
||||||
|
"bomb" => Some(13),
|
||||||
|
"energizer" => Some(14),
|
||||||
|
"star" => Some(15),
|
||||||
|
"clockwise" => Some(16),
|
||||||
|
"counter" => Some(17),
|
||||||
|
"bullet" => Some(18),
|
||||||
|
"water" => Some(19),
|
||||||
|
"forest" => Some(20),
|
||||||
|
"solid" => Some(21),
|
||||||
|
"normal" => Some(22),
|
||||||
|
"breakable" => Some(23),
|
||||||
|
"boulder" => Some(24),
|
||||||
|
"sliderns" => Some(25),
|
||||||
|
"sliderew" => Some(26),
|
||||||
|
"fake" => Some(27),
|
||||||
|
"invisible" => Some(28),
|
||||||
|
"blinkwall" => Some(29),
|
||||||
|
"transporter" => Some(30),
|
||||||
|
"line" => Some(31),
|
||||||
|
"ricochet" => Some(32),
|
||||||
|
"blink_ray_h" => Some(33),
|
||||||
|
"bear" => Some(34),
|
||||||
|
"ruffian" => Some(35),
|
||||||
|
"object" => Some(36),
|
||||||
|
"slime" => Some(37),
|
||||||
|
"shark" => Some(38),
|
||||||
|
"spinninggun" => Some(39),
|
||||||
|
"pusher" => Some(40),
|
||||||
|
"lion" => Some(41),
|
||||||
|
"tiger" => Some(42),
|
||||||
|
"blink_ray_v" => Some(43),
|
||||||
|
"head" => Some(44),
|
||||||
|
"segment" => Some(45),
|
||||||
|
// 46 is unused
|
||||||
|
"text_blue" => Some(47),
|
||||||
|
"text_green" => Some(48),
|
||||||
|
"text_cyan" => Some(49),
|
||||||
|
"text_red" => Some(50),
|
||||||
|
"text_purple" => Some(51),
|
||||||
|
"text_brown" => Some(52),
|
||||||
|
"text_black" => Some(53),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+37
-7
@@ -11,7 +11,7 @@ use nom::{
|
|||||||
sequence::pair,
|
sequence::pair,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::elements::{Element, element_name, resolve_alias};
|
use super::elements::{Element, element_id_from_name, element_name, resolve_alias};
|
||||||
use super::error::ParseError;
|
use super::error::ParseError;
|
||||||
use super::parse::{Board, Program, Stat, Tile, World};
|
use super::parse::{Board, Program, Stat, Tile, World};
|
||||||
|
|
||||||
@@ -206,10 +206,14 @@ fn write_stat(output: &mut String, index: usize, stat: &Stat, element: Option<u8
|
|||||||
kv!(output, "y_step", stat.y_step, 0);
|
kv!(output, "y_step", stat.y_step, 0);
|
||||||
|
|
||||||
if stat.under.element != Element::Empty as u8 || stat.under.color != 0x0f {
|
if stat.under.element != Element::Empty as u8 || stat.under.color != 0x0f {
|
||||||
|
let elem_name = match Element::from_u8(stat.under.element) {
|
||||||
|
Some(e) => e.name().to_string(),
|
||||||
|
None => format!("unknown_{}", stat.under.element),
|
||||||
|
};
|
||||||
writeln!(
|
writeln!(
|
||||||
output,
|
output,
|
||||||
"under = ({}, {})",
|
"under = ({}, 0x{:02x})",
|
||||||
stat.under.element, stat.under.color
|
elem_name, stat.under.color
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
@@ -374,18 +378,44 @@ fn boolean(input: &str) -> IResult<&str, bool> {
|
|||||||
alt((value(true, tag("true")), value(false, tag("false")))).parse(input)
|
alt((value(true, tag("true")), value(false, tag("false")))).parse(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a tuple like (element, color).
|
/// Parse a hex number like 0x0f or 0x1F.
|
||||||
|
fn hex_u8(input: &str) -> IResult<&str, u8> {
|
||||||
|
let (input, _) = tag("0x").parse(input)?;
|
||||||
|
let (input, hex_str) = take_while1(|c: char| c.is_ascii_hexdigit()).parse(input)?;
|
||||||
|
match u8::from_str_radix(hex_str, 16) {
|
||||||
|
Ok(n) => Ok((input, n)),
|
||||||
|
Err(_) => Err(nom::Err::Error(nom::error::Error::new(
|
||||||
|
input,
|
||||||
|
nom::error::ErrorKind::HexDigit,
|
||||||
|
))),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Parse a tuple like (element_name, 0xNN) or legacy (element_id, color).
|
||||||
|
/// Supports both new format: (empty, 0x0f) and legacy: (0, 15).
|
||||||
fn tuple2(input: &str) -> IResult<&str, (u8, u8)> {
|
fn tuple2(input: &str) -> IResult<&str, (u8, u8)> {
|
||||||
let (input, _) = char('(').parse(input)?;
|
let (input, _) = char('(').parse(input)?;
|
||||||
let (input, _) = multispace0.parse(input)?;
|
let (input, _) = multispace0.parse(input)?;
|
||||||
let (input, a) = map_res(digit1, |s: &str| s.parse::<u8>()).parse(input)?;
|
|
||||||
|
// First value: element name (identifier) or decimal number
|
||||||
|
let (input, element_id) = alt((
|
||||||
|
// Element name (identifier) -> convert to ID
|
||||||
|
map(identifier, |name| element_id_from_name(name).unwrap_or(0)),
|
||||||
|
// Legacy: decimal element ID
|
||||||
|
map_res(digit1, |s: &str| s.parse::<u8>()),
|
||||||
|
))
|
||||||
|
.parse(input)?;
|
||||||
|
|
||||||
let (input, _) = multispace0.parse(input)?;
|
let (input, _) = multispace0.parse(input)?;
|
||||||
let (input, _) = char(',').parse(input)?;
|
let (input, _) = char(',').parse(input)?;
|
||||||
let (input, _) = multispace0.parse(input)?;
|
let (input, _) = multispace0.parse(input)?;
|
||||||
let (input, b) = map_res(digit1, |s: &str| s.parse::<u8>()).parse(input)?;
|
|
||||||
|
// Second value: hex color (0xNN) or decimal color
|
||||||
|
let (input, color) = alt((hex_u8, map_res(digit1, |s: &str| s.parse::<u8>()))).parse(input)?;
|
||||||
|
|
||||||
let (input, _) = multispace0.parse(input)?;
|
let (input, _) = multispace0.parse(input)?;
|
||||||
let (input, _) = char(')').parse(input)?;
|
let (input, _) = char(')').parse(input)?;
|
||||||
Ok((input, (a, b)))
|
Ok((input, (element_id, color)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a string array like ["foo", "bar", ""].
|
/// Parse a string array like ["foo", "bar", ""].
|
||||||
|
|||||||
Reference in New Issue
Block a user