handle game segments better

This commit is contained in:
Max Bradbury 2020-04-24 21:51:31 +01:00
parent 408e46ef7e
commit 9e8d032ced
1 changed files with 47 additions and 75 deletions

View File

@ -1,4 +1,4 @@
use crate::{Avatar, Dialogue, Ending, Font, Item, Palette, Room, Sprite, TextDirection, Tile, ToBase36, Variable, transform_line_endings}; use crate::{Avatar, Dialogue, Ending, Font, Item, Palette, Room, Sprite, TextDirection, Tile, ToBase36, Variable, transform_line_endings, segments_from_string};
use std::error::Error; use std::error::Error;
use loe::TransformMode; use loe::TransformMode;
@ -94,64 +94,30 @@ impl Game {
string = transform_line_endings(string, TransformMode::LF) string = transform_line_endings(string, TransformMode::LF)
} }
let mut string = format!("{}\n\n", string.trim_matches('\n')); let string = string.trim_start_matches("\n").to_string();
let segments = segments_from_string(string);
if string.starts_with("# BITSY VERSION") { let mut name = "".to_string();
string = format!("\n\n{}", string);
if
! segments[0].starts_with("# BITSY VERSION")
&&
! segments[0].starts_with("! ROOM_FORMAT")
&&
! segments[0].starts_with("PAL")
&&
! segments[0].starts_with("DEFAULT_FONT")
&&
! segments[0].starts_with("TEXT_DIRECTION") {
name = segments[0].to_string();
} }
let string = string; let name = name;
// dialogues and endings can have 2+ line breaks inside, so deal with these separately
// otherwise, everything can be split on a double line break (\n\n)
let mut dialogues: Vec<Dialogue> = Vec::new(); let mut dialogues: Vec<Dialogue> = Vec::new();
let mut endings: Vec<Ending> = Vec::new(); let mut endings: Vec<Ending> = Vec::new();
let mut variables: Vec<Variable> = Vec::new(); let mut variables: Vec<Variable> = Vec::new();
let mut font_data: Option<String> = None; let mut font_data: Option<String> = None;
let main_split: Vec<&str> = string.split("\n\nDLG").collect();
let main = main_split[0].to_string();
let mut extra: String = main_split[1..].join("\n\nDLG");
if extra.contains("\n\nFONT") {
let parts = extra.clone();
let parts: Vec<&str> = parts.split("\n\nFONT").collect();
font_data = Some(format!("FONT{}", parts[1]));
}
let variable_segments = extra.clone();
let variable_segments: Vec<&str> = variable_segments.split("\n\nVAR").collect();
if variable_segments.len() > 0 {
extra = variable_segments[0].to_string();
let variable_segments = variable_segments[1..].to_owned();
for segment in variable_segments {
let segment = format!("VAR{}", segment);
variables.push(Variable::from(segment));
}
}
let ending_segments = extra.clone();
let ending_segments: Vec<&str> = ending_segments.split("\n\nEND").collect();
if ending_segments.len() > 0 {
extra = ending_segments[0].to_string();
let ending_segments = ending_segments[1..].to_owned();
for segment in ending_segments {
let segment = format!("END{}", segment);
endings.push(Ending::from(segment));
}
}
let dialogue_segments = format!("\n\nDLG{}", extra.trim_matches('\n'));
let dialogue_segments: Vec<&str> = dialogue_segments.split("\n\nDLG").collect();
for segment in dialogue_segments[1..].to_owned() {
let segment = format!("DLG{}", segment);
dialogues.push(Dialogue::from(segment));
}
let segments: Vec<&str> = main.split("\n\n").collect();
let name = segments[0].to_string();
let mut version = None; let mut version = None;
let mut room_format = None; let mut room_format = None;
let mut room_type = RoomType::Room; let mut room_type = RoomType::Room;
@ -165,11 +131,7 @@ impl Game {
let mut sprites: Vec<Sprite> = Vec::new(); let mut sprites: Vec<Sprite> = Vec::new();
let mut items: Vec<Item> = Vec::new(); let mut items: Vec<Item> = Vec::new();
let segments = segments[1..].to_owned();
for segment in segments { for segment in segments {
let segment = segment.to_string();
if segment.starts_with("# BITSY VERSION") { if segment.starts_with("# BITSY VERSION") {
let segment = segment.replace("# BITSY VERSION ", ""); let segment = segment.replace("# BITSY VERSION ", "");
version = Some(Version::from(&segment)); version = Some(Version::from(&segment));
@ -201,32 +163,42 @@ impl Game {
sprites.push(Sprite::from(segment)); sprites.push(Sprite::from(segment));
} else if segment.starts_with("ITM") { } else if segment.starts_with("ITM") {
items.push(Item::from(segment)); items.push(Item::from(segment));
} else if segment.starts_with("DLG") {
dialogues.push(Dialogue::from(segment));
} else if segment.starts_with("END") {
endings.push(Ending::from(segment));
} else if segment.starts_with("VAR") {
variables.push(Variable::from(segment));
} else if segment.starts_with("FONT") {
font_data = Some(segment);
} }
} }
assert!(avatar.is_some()); assert!(avatar.is_some());
let avatar = avatar.unwrap(); let avatar = avatar.unwrap();
Ok(Game { Ok(
name, Game {
version, name,
room_format, version,
room_type, room_format,
font, room_type,
custom_font, font,
text_direction, custom_font,
palettes, text_direction,
rooms, palettes,
tiles, rooms,
avatar, tiles,
sprites, avatar,
items, sprites,
dialogues, items,
endings, dialogues,
variables, endings,
font_data, variables,
line_endings_crlf font_data,
}) line_endings_crlf,
}
)
} }
} }