mirror of
https://github.com/Zenithsiz/dcb.git
synced 2026-02-09 11:48:16 +00:00
Removed card-editor.
Changed `err-impl` to a git dependency.
This commit is contained in:
897
Cargo.lock
generated
897
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
22
Cargo.toml
22
Cargo.toml
@@ -12,21 +12,17 @@ path = "src/extractor/main.rs"
|
||||
name = "patcher"
|
||||
path = "src/patcher/main.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "card-editor"
|
||||
path = "src/card-editor/main.rs"
|
||||
|
||||
[dependencies]
|
||||
# Dcb
|
||||
dcb = { path = "../dcb" }
|
||||
|
||||
# Text
|
||||
ascii = "1.0"
|
||||
strsim = "0.10"
|
||||
|
||||
# Helpers
|
||||
float-ord = "0.2"
|
||||
itertools = "0.9"
|
||||
rand = "0.7"
|
||||
|
||||
# Cmd
|
||||
clap = "2.33"
|
||||
@@ -40,24 +36,18 @@ string-err = "0.1"
|
||||
err-backtrace = { path = "../err-backtrace" }
|
||||
err-panic = { path = "../err-panic", features = ["string-err-ext"] }
|
||||
err-ext = { path = "../err-ext" }
|
||||
err-impl = { git = "https://github.com/Zenithsiz/err-impl" }
|
||||
|
||||
# Derives
|
||||
derive_more = "0.99"
|
||||
smart-default = "0.6"
|
||||
|
||||
# Serde
|
||||
serde = "1.0"
|
||||
serde_yaml = "0.8"
|
||||
|
||||
# Window / Ui
|
||||
gfx = "0.18"
|
||||
gfx_device_gl = "0.16"
|
||||
gfx_window_glutin = "0.31"
|
||||
glutin = "0.21"
|
||||
#image = "0.23"
|
||||
imgui = "0.3"
|
||||
imgui-gfx-renderer = "0.3"
|
||||
imgui-winit-support = { version = "0.3", default-features = false, features = ["winit-19"] }
|
||||
|
||||
# Build dependencies in release mode
|
||||
[profile.dev.package."*"]
|
||||
opt-level = 2
|
||||
[profile.dev.package.dcb] # Except dcb for debugging
|
||||
opt-level = 0
|
||||
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
//! Cli manager for the extractor
|
||||
|
||||
// Filesystem
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
// Clap
|
||||
use clap::{App as ClapApp, Arg as ClapArg};
|
||||
|
||||
/// Data from the command line
|
||||
#[derive(PartialEq, Clone, Debug)]
|
||||
pub struct CliData {
|
||||
/// The data directory
|
||||
pub data_dir: PathBuf,
|
||||
}
|
||||
|
||||
impl CliData {
|
||||
/// Constructs all of the cli data given and returns it
|
||||
pub fn new() -> Self {
|
||||
// Get all matches from cli
|
||||
let matches = ClapApp::new("Dcb Card Editor")
|
||||
.version("0.0")
|
||||
.author("Filipe [...] <[...]@gmail.com>")
|
||||
.about("Edits card data from Digimon Digital Card Battle extracted files")
|
||||
.arg(
|
||||
ClapArg::with_name("INPUT")
|
||||
.help("Sets the Data directory to use")
|
||||
.short("i")
|
||||
.long("input")
|
||||
.index(1)
|
||||
.takes_value(true)
|
||||
.required(true),
|
||||
)
|
||||
.get_matches();
|
||||
|
||||
// Get the data dir as either an input or the current directory
|
||||
let data_dir = matches.value_of("INPUT").map_or_else(|| Path::new("."), Path::new).to_path_buf();
|
||||
|
||||
// Return the cli data
|
||||
Self { data_dir }
|
||||
}
|
||||
}
|
||||
@@ -1,282 +0,0 @@
|
||||
//! Data patches
|
||||
//!
|
||||
//! # Details
|
||||
//! Patches data to the game file from several other files.
|
||||
//!
|
||||
//! # Syntax
|
||||
//! The executable may be called as `./patcher <game file> <directory>`
|
||||
//!
|
||||
//! Use the command `./patcher --help` for more information.
|
||||
//!
|
||||
//! # Data patched
|
||||
//! Currently only the following is patched:
|
||||
//! - Card table
|
||||
|
||||
// Features
|
||||
#![feature(box_syntax, backtrace, panic_info_message, bool_to_option)]
|
||||
// Lints
|
||||
#![warn(clippy::restriction, clippy::pedantic, clippy::nursery)]
|
||||
#![allow(
|
||||
clippy::implicit_return, // We prefer implicit returns where possible
|
||||
clippy::module_name_repetitions, // This happens often due to separating things into modules finely
|
||||
clippy::wildcard_enum_match_arm, // We only use wildcards when we truly only care about some variants
|
||||
clippy::result_expect_used,
|
||||
clippy::option_expect_used, // We use expect when there is no alternative.
|
||||
clippy::used_underscore_binding, // Useful for macros and such
|
||||
clippy::integer_arithmetic,
|
||||
clippy::float_arithmetic, // We need to use numbers my guy
|
||||
clippy::as_conversions,
|
||||
clippy::cast_sign_loss,
|
||||
clippy::cast_possible_wrap,
|
||||
clippy::cast_possible_truncation, // Needed for converting between stuff
|
||||
clippy::items_after_statements,
|
||||
)]
|
||||
|
||||
// Modules
|
||||
mod cli;
|
||||
#[path = "../logger.rs"]
|
||||
mod logger;
|
||||
#[path = "../panic.rs"]
|
||||
mod panic;
|
||||
|
||||
// Gfx / GLutin
|
||||
use gfx::Device;
|
||||
use glutin::{Event, WindowEvent};
|
||||
|
||||
// Imgui
|
||||
use imgui::{Context, FontConfig, FontGlyphRanges, FontSource, ImString};
|
||||
use imgui_gfx_renderer::{Renderer, Shaders};
|
||||
use imgui_winit_support::{HiDpiMode, WinitPlatform};
|
||||
|
||||
// Errors
|
||||
use err_backtrace::ErrBacktraceExt;
|
||||
use err_ext::ResultExt;
|
||||
use err_panic::ErrorExtPanic;
|
||||
|
||||
// Itertools
|
||||
use itertools::Itertools;
|
||||
|
||||
// Dcb
|
||||
use dcb::game::{card::Table as CardTable, deck::Table as DeckTable};
|
||||
|
||||
#[allow(clippy::too_many_lines)] // TODO: Fix
|
||||
fn main() {
|
||||
// Initialize the logger and set the panic handler
|
||||
logger::init();
|
||||
std::panic::set_hook(box panic::log_handler);
|
||||
|
||||
// Get all data from cli
|
||||
let cli::CliData { data_dir } = cli::CliData::new();
|
||||
|
||||
// Load all data files
|
||||
let cards_table_file = std::fs::File::open(data_dir.join("cards.yaml")).panic_err_msg("Unable to open `cards.yaml`");
|
||||
let decks_table_file = std::fs::File::open(data_dir.join("decks.yaml")).panic_err_msg("Unable to open `decks.yaml`");
|
||||
|
||||
// Parse everything from yaml
|
||||
let mut cards_table: CardTable = serde_yaml::from_reader(cards_table_file).panic_err_msg("Unable to parse `cards.yaml`");
|
||||
let decks_table: DeckTable = serde_yaml::from_reader(decks_table_file).panic_err_msg("Unable to parse `decks.yaml`");
|
||||
|
||||
// Create a new window
|
||||
let mut events_loop = glutin::EventsLoop::new();
|
||||
let builder = glutin::WindowBuilder::new()
|
||||
.with_title("Dcb Card Editor")
|
||||
.with_dimensions(glutin::dpi::LogicalSize::new(1024.0, 768.0));
|
||||
let context = glutin::ContextBuilder::new().with_vsync(true);
|
||||
let (windowed_context, mut device, mut factory, mut main_color, mut main_depth) =
|
||||
gfx_window_glutin::init::<gfx::format::Rgba8, gfx::format::DepthStencil>(builder, context, &events_loop)
|
||||
.panic_err_msg("Failed to initialize graphics");
|
||||
let mut encoder: gfx::Encoder<_, _> = factory.create_command_buffer().into();
|
||||
let shaders = {
|
||||
let version = device.get_info().shading_language;
|
||||
if version.is_embedded {
|
||||
if version.major >= 3 {
|
||||
Shaders::GlSlEs300
|
||||
} else {
|
||||
Shaders::GlSlEs100
|
||||
}
|
||||
} else if version.major >= 4 {
|
||||
Shaders::GlSl400
|
||||
} else if version.major >= 3 {
|
||||
if version.minor >= 2 {
|
||||
Shaders::GlSl150
|
||||
} else {
|
||||
Shaders::GlSl130
|
||||
}
|
||||
} else {
|
||||
Shaders::GlSl110
|
||||
}
|
||||
};
|
||||
|
||||
// Create a new context for `imgui`
|
||||
let mut imgui_context = Context::create();
|
||||
let mut platform = WinitPlatform::init(&mut imgui_context);
|
||||
|
||||
// Add our font to imgui
|
||||
let hidpi_factor = platform.hidpi_factor();
|
||||
let font_size = (13.0 * hidpi_factor) as f32;
|
||||
imgui_context.fonts().add_font(&[
|
||||
FontSource::DefaultFontData {
|
||||
config: Some(FontConfig {
|
||||
size_pixels: font_size,
|
||||
..FontConfig::default()
|
||||
}),
|
||||
},
|
||||
FontSource::TtfData {
|
||||
data: include_bytes!("../../resources/OpenSans-Regular.ttf"),
|
||||
size_pixels: font_size,
|
||||
config: Some(FontConfig {
|
||||
rasterizer_multiply: 1.75,
|
||||
glyph_ranges: FontGlyphRanges::japanese(),
|
||||
..FontConfig::default()
|
||||
}),
|
||||
},
|
||||
]);
|
||||
imgui_context.io_mut().font_global_scale = (1.0 / hidpi_factor) as f32;
|
||||
|
||||
// Fix `sRGB` on style colors
|
||||
let style = imgui_context.style_mut();
|
||||
#[allow(clippy::indexing_slicing)] // False positive, this is a `[f32; 4]`
|
||||
for color in style.colors.iter_mut() {
|
||||
color[0] = color[0].powf(2.2);
|
||||
color[1] = color[1].powf(2.2);
|
||||
color[2] = color[2].powf(2.2);
|
||||
color[3] = 1.0 - (1.0 - color[3]).powf(2.2);
|
||||
}
|
||||
|
||||
// Attach the window to the platform
|
||||
let mut renderer = Renderer::init(&mut imgui_context, &mut factory, shaders).panic_err_msg("Unable to initialize renderer");
|
||||
platform.attach_window(imgui_context.io_mut(), windowed_context.window(), HiDpiMode::Rounded);
|
||||
|
||||
let mut last_frame = std::time::Instant::now();
|
||||
let mut run = true;
|
||||
|
||||
// Get all digimon names as `ImString`s
|
||||
let mut digimon_names: Vec<_> = cards_table.digimons.iter().map(|digimon| ImString::new(digimon.name.clone())).collect();
|
||||
let mut digimon_filter_idx = 0;
|
||||
let mut digimon_filter_search = ImString::new("");
|
||||
|
||||
while run {
|
||||
// Check for events
|
||||
events_loop.poll_events(|event| {
|
||||
platform.handle_event(imgui_context.io_mut(), windowed_context.window(), &event);
|
||||
|
||||
if let Event::WindowEvent { event, .. } = event {
|
||||
match event {
|
||||
WindowEvent::Resized(_) => {
|
||||
gfx_window_glutin::update_views(&windowed_context, &mut main_color, &mut main_depth);
|
||||
},
|
||||
WindowEvent::CloseRequested => run = false,
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Prepare and execute ui frame
|
||||
let io = imgui_context.io_mut();
|
||||
platform
|
||||
.prepare_frame(io, windowed_context.window())
|
||||
.ignore_with_err(|err| log::warn!("Unable to prepare frame: {}", err));
|
||||
last_frame = io.update_delta_time(last_frame);
|
||||
let ui = imgui_context.frame();
|
||||
{
|
||||
ui.text("Digimon: ");
|
||||
|
||||
ui.input_text(imgui::im_str!("Digimon Filter"), &mut digimon_filter_search)
|
||||
.resize_buffer(true)
|
||||
.build();
|
||||
|
||||
let digimon_filters: Vec<_> = digimon_names
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(idx, string)| {
|
||||
(
|
||||
float_ord::FloatOrd(1.0 - strsim::jaro(string.to_str(), digimon_filter_search.to_str())),
|
||||
string,
|
||||
idx,
|
||||
)
|
||||
})
|
||||
.sorted()
|
||||
.collect();
|
||||
|
||||
let digimon_filter_names: Vec<_> = digimon_filters
|
||||
.iter()
|
||||
.filter_map(|(value, string, _)| (digimon_filter_search.is_empty() || value.0 < 0.5).then_some(string))
|
||||
.collect();
|
||||
|
||||
ui.list_box(
|
||||
imgui::im_str!("Digimon List"),
|
||||
&mut digimon_filter_idx,
|
||||
digimon_filter_names.as_slice(),
|
||||
4,
|
||||
);
|
||||
|
||||
ui.separator();
|
||||
|
||||
/*
|
||||
if let Some((_, _, idx)) = digimon_filters.get(digimon_filter_idx as usize) {
|
||||
let idx = *idx;
|
||||
std::mem::drop(digimon_filters);
|
||||
if let Some(digimon_name_buffer) = digimon_names.get_mut(idx) {
|
||||
if ui.input_text(imgui::im_str!("Name"), digimon_name_buffer).resize_buffer(true).build() {
|
||||
if let Some(digimon) = cards_table.digimons.get_mut(idx) {
|
||||
match ascii::AsciiString::from_ascii(digimon_name_buffer.to_string()) {
|
||||
Ok(name) => {
|
||||
digimon.name = name;
|
||||
},
|
||||
Err(err) => {
|
||||
ui.text(format!("Unable to set digimon name:\n{}", err.err_backtrace()));
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
//if let Some(digimon_name) = digimon_names.iter_mut().enumerate().find(|(_, name)| name == )
|
||||
|
||||
/*
|
||||
if let Some((idx, digimon)) = cards_table.digimons.iter_mut().enumerate().find(|(_, digimon)| {
|
||||
digimon_filter_names
|
||||
.get(digimon_filter_idx as usize)
|
||||
.map_or(false, |&name| name.to_str() == digimon.name)
|
||||
}) {
|
||||
let mut name_buffer = ImString::new(digimon.name.clone());
|
||||
if ui.input_text(imgui::im_str!("Name"), &mut name_buffer).resize_buffer(true).build() {
|
||||
match ascii::AsciiString::from_ascii(name_buffer.to_string()) {
|
||||
Ok(name) => {
|
||||
digimon.name = name;
|
||||
if let Some(name) = digimon_names.get_mut(idx) {
|
||||
*name = name_buffer.clone();
|
||||
}
|
||||
},
|
||||
Err(err) => {
|
||||
ui.text(format!("Unable to set digimon name:\n{}", err.err_backtrace()));
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// Clear, render everything and flush it out
|
||||
encoder.clear(&main_color, [0.2, 0.2, 0.2, 1.0]);
|
||||
platform.prepare_render(&ui, windowed_context.window());
|
||||
renderer
|
||||
.render(&mut factory, &mut encoder, &mut main_color, ui.render())
|
||||
.ignore_with_err(|err| log::warn!("Unable to render: {}", err.err_backtrace()));
|
||||
encoder.flush(&mut device);
|
||||
windowed_context
|
||||
.swap_buffers()
|
||||
.ignore_with_err(|err| log::warn!("Unable to swap buffers: {}", err.err_backtrace()));
|
||||
device.cleanup();
|
||||
}
|
||||
|
||||
// Convert everything back to yaml
|
||||
let cards_table_yaml = serde_yaml::to_string(&cards_table).panic_err_msg("Unable to serialize cards table to yaml");
|
||||
let decks_table_yaml = serde_yaml::to_string(&decks_table).panic_err_msg("Unable to serialize decks table to yaml");
|
||||
|
||||
// Ouput all data to devices
|
||||
std::fs::write(&data_dir.join("cards.yaml"), cards_table_yaml).panic_err_msg("Unable to write cards table to file");
|
||||
std::fs::write(&data_dir.join("decks.yaml"), decks_table_yaml).panic_err_msg("Unable to write decks table to file");
|
||||
}
|
||||
Reference in New Issue
Block a user