Skip to content

Commit

Permalink
Feature: Combined mods (#46)
Browse files Browse the repository at this point in the history
Description

Load both OpenZT data and Zoo Tycoon Data from each .ztd, based on ztd_type in meta.toml
Proposed Changes

    Addresses 

Combined OpenZT and vanilla mods #44
Adds lazy loading of resources rather than loading all resources on start (to be expanded in

    Unload Lazily loaded resources on load/exit or high memory usage. #51)

Checklist

Docs
* Add documentation for combined vanilla and OpenZT mods GoosiferIO/ZooBerry-Docs#2
* Manually tested
* Unit tests (where possible)
  • Loading branch information
finnhartshorn authored Sep 8, 2024
1 parent 198cf86 commit 3e2064e
Show file tree
Hide file tree
Showing 14 changed files with 1,227 additions and 860 deletions.
47 changes: 43 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ retour-utils = "0.2.1"
once_cell = "1.18.0"
num_enum = "0.7.2"
walkdir = "2.4.0"
zip = "2.1.3"
zip = "2.1.6"
bf_configparser = { git = "https://github.com/openztcc/bf-configparser", version = "1.1.1", features = ["indexmap"]}
anyhow = "1.0.80"
getset = "0.1.2"
Expand All @@ -29,6 +29,7 @@ field_accessor_as_string = { path = "libs/field_accessor_as_string" }
field_accessor_as_string_trait = { path = "libs/field_accessor_as_string_trait" }
serde = {version = "1.0.203", features = ["derive"]}
toml = "0.8.14"
regex = "1.10.5"

[lib]
name = "openzt"
Expand Down
7 changes: 7 additions & 0 deletions resources/test/meta-legacy.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
name="my fun mod"
description="a mod full of fun"
authors=["Finn"]
mod_id="finn.my_fun_mod"
version="1.0.0"
link="https://mywebsite.com/myfunmod"
ztd_type="legacy"
2 changes: 1 addition & 1 deletion rustfmt.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
group_imports = "StdExternalCrate"
imports_granularity = "Crate"
fn_call_width = 100
max_width = 167
31 changes: 6 additions & 25 deletions src/animation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,7 @@ impl Line {
pub fn calc_byte_size(&self) -> usize {
let mut size = mem::size_of::<u8>();
for draw_instruction in &self.draw_instructions {
size += mem::size_of::<u8>()
+ mem::size_of::<u8>()
+ (draw_instruction.colors.len() * mem::size_of::<u8>());
size += mem::size_of::<u8>() + mem::size_of::<u8>() + (draw_instruction.colors.len() * mem::size_of::<u8>());
}
size
}
Expand Down Expand Up @@ -116,11 +114,7 @@ impl Animation {
for _ in 0..num_colors {
colors.push(read_le_primitive(data, &mut index));
}
draw_instructions.push(DrawInstruction {
offset,
num_colors,
colors,
});
draw_instructions.push(DrawInstruction { offset, num_colors, colors });
}
lines.push(Line {
num_draw_instructions,
Expand Down Expand Up @@ -183,12 +177,7 @@ impl Animation {
(bytes, accumulator)
}

pub fn duplicate_pixel_rows(
&mut self,
frame: usize,
start_index: usize,
end_index: usize,
) -> Result<&mut Self, &'static str> {
pub fn duplicate_pixel_rows(&mut self, frame: usize, start_index: usize, end_index: usize) -> Result<&mut Self, &'static str> {
let mut additional_bytes: usize = 0;
if start_index > end_index {
return Err("Start index must be less than end index");
Expand All @@ -205,9 +194,7 @@ impl Animation {
additional_bytes += line.calc_byte_size();
}

self.frames[frame]
.lines
.splice(end_index..end_index, new_lines);
self.frames[frame].lines.splice(end_index..end_index, new_lines);

self.frames[frame].num_bytes += additional_bytes as u32;

Expand Down Expand Up @@ -243,10 +230,7 @@ mod parsing_tests {
let animation = Animation::parse(include_bytes!("../resources/test/N"));
assert!(animation.header.is_some());
assert!(!animation.header.unwrap().extra_frame);
assert_eq!(
animation.palette_filename,
"ANIMALS/01BFCC32/ICMEIOLA/ICMEIOLA.PAL".to_string()
);
assert_eq!(animation.palette_filename, "ANIMALS/01BFCC32/ICMEIOLA/ICMEIOLA.PAL".to_string());
assert_eq!(animation.num_frames, 1);
assert_eq!(animation.frames.len(), 1);
}
Expand All @@ -271,10 +255,7 @@ mod parsing_tests {
let animation = Animation::parse(include_bytes!("../resources/test/N"));
let mut animation_to_modify = animation.clone();
animation_to_modify.duplicate_pixel_rows(0, 0, 1).unwrap();
assert_eq!(
animation.frames[0].pixel_height + 1,
animation_to_modify.frames[0].pixel_height
);
assert_eq!(animation.frames[0].pixel_height + 1, animation_to_modify.frames[0].pixel_height);
animation_to_modify.set_palette_filename(animation.palette_filename.clone());
assert_eq!(animation.palette_filename_length, animation_to_modify.palette_filename_length);
let (animation_bytes, _) = animation_to_modify.write();
Expand Down
5 changes: 2 additions & 3 deletions src/bfentitytype.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1248,18 +1248,17 @@ pub struct ZTStaffType {

impl EntityType for ZTStaffType {
fn print_config_integers(&self) -> String {
format!("{}\ncWorkCheck: {}\ncChaseCheck: {}\ncMonthlyCost: {}\ncDutiesTextID: {}\ncWeaponRange: {}\n",
format!("{}\ncWorkCheck: {}\ncChaseCheck: {}\ncDutiesTextID: {}\ncWeaponRange: {}\n",
self.ztunit_type.print_config_integers(),
self.work_check,
self.chase_check,
self.monthly_cost,
self.duties_text_id,
self.weapon_range,
)
}

fn print_config_floats(&self) -> String {
self.ztunit_type.print_config_floats()
format!("{}\ncMonthlyCost: {}\n", self.ztunit_type.print_config_floats(), self.monthly_cost)
}

fn print_config_strings(&self) -> String {
Expand Down
6 changes: 1 addition & 5 deletions src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,7 @@ pub struct ZTString {

impl fmt::Display for ZTString {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"{}",
get_string_from_memory_bounded(self.start_ptr, self.end_ptr, self.buffer_end_ptr)
)
write!(f, "{}", get_string_from_memory_bounded(self.start_ptr, self.end_ptr, self.buffer_end_ptr))
}
}

Expand Down
52 changes: 12 additions & 40 deletions src/console.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,23 +107,14 @@ static COMMAND_QUEUE: Lazy<Mutex<Vec<String>>> = Lazy::new(|| Mutex::new(Vec::<S

pub fn add_to_command_register(command_name: String, command_callback: CommandCallback) {
info!("Registring command {} to registry", command_name);
let Ok(mut data_mutex) = COMMAND_REGISTRY.lock() else {
error!(
"Failed to lock command registry mutex when adding command {} to registry",
command_name
);
return;
};
let mut data_mutex = COMMAND_REGISTRY.lock().unwrap();
data_mutex.insert(command_name, command_callback);
}

fn call_command(command_name: String, args: Vec<&str>) -> Result<String, CommandError> {
info!("Calling command {} with args {:?}", command_name, args);
let command = {
let Ok(data_mutex) = COMMAND_REGISTRY.lock() else {
error!("Failed to lock command registry mutex when calling command {}", command_name);
return Err(Into::into("Failed to lock command registry mutex when calling command"));
};
let data_mutex = COMMAND_REGISTRY.lock().unwrap();
data_mutex.get(&command_name).cloned()
};
match command {
Expand All @@ -146,10 +137,7 @@ pub fn call_next_command() {
};
let args: Vec<&str> = command_args.collect();

let Ok(mut result_mutex) = COMMAND_RESULTS.lock() else {
error!("Failed to lock command results mutex when calling next command {}", command_name);
return;
};
let mut result_mutex = COMMAND_RESULTS.lock().unwrap();

match call_command(command_name.to_string(), args) {
Ok(result) => {
Expand All @@ -163,46 +151,30 @@ pub fn call_next_command() {
}

pub fn get_next_result() -> Option<String> {
let Ok(mut data_mutex) = COMMAND_RESULTS.lock() else {
error!("Failed to lock command results mutex when getting next result");
return None;
};
let mut data_mutex = COMMAND_RESULTS.lock().unwrap();
data_mutex.pop()
}

fn add_to_command_queue(command: String) {
info!("Adding command {} to queue", command);
let Ok(mut data_mutex) = COMMAND_QUEUE.lock() else {
error!("Failed to lock command queue mutex when adding command {} to queue", command);
return;
};
let mut data_mutex = COMMAND_QUEUE.lock().unwrap();
data_mutex.push(command);
}

pub fn get_from_command_queue() -> Option<String> {
let Ok(mut data_mutex) = COMMAND_QUEUE.lock() else {
error!("Failed to lock command queue mutex when getting command from queue");
return None;
};
let mut data_mutex = COMMAND_QUEUE.lock().unwrap();
data_mutex.pop()
}

pub fn command_list_commands(_args: Vec<&str>) -> Result<String, CommandError> {
info!("Getting command list");
match COMMAND_REGISTRY.lock() {
Ok(data_mutex) => {
let mut result = String::new();
for command_name in data_mutex.keys() {
info!("Found command {}", command_name);
result.push_str(&format!("{}\n", command_name));
}
Ok(result)
}
Err(err) => {
info!("Error getting command list: {}", err);
Err(Into::into("Error getting command list"))
}
let data_mutex = COMMAND_REGISTRY.lock().unwrap();
let mut result = String::new();
for command_name in data_mutex.keys() {
info!("Found command {}", command_name);
result.push_str(&format!("{}\n", command_name));
}
Ok(result)
}

fn handle_client(mut stream: TcpStream) {
Expand Down
4 changes: 4 additions & 0 deletions src/debug_dll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ pub fn log_exe_location_memory_value() {
debug_logger(&format!("exe location from rust: {}", rust_exe_location));
}

pub fn get_string_from_memory_with_size(address: u32, size: u32) -> String {
get_string_from_memory_bounded(address, address + size, address + size)
}

pub fn get_string_from_memory_bounded(start: u32, end: u32, buffer_end: u32) -> String {
let mut string = String::new();
let mut char_address = start;
Expand Down
Loading

0 comments on commit 3e2064e

Please sign in to comment.