Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configurable classes #76

Merged
merged 20 commits into from
Jul 18, 2021
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
cleanup customize interface
facundoolano committed Jul 18, 2021
commit 5557e4064a6f1fee6c8d78e87fce307d08c4f076
50 changes: 26 additions & 24 deletions src/character/class.rs
Original file line number Diff line number Diff line change
@@ -55,32 +55,14 @@ pub enum Category {

static CLASSES: OnceCell<HashMap<Category, Vec<Class>>> = OnceCell::new();

pub fn customize(bytes: &[u8]) {
CLASSES.set(from_bytes(bytes)).unwrap();
}

fn default_classes() -> HashMap<Category, Vec<Class>> {
from_bytes(include_bytes!("classes.yaml"))
}

fn from_bytes(bytes: &[u8]) -> HashMap<Category, Vec<Class>> {
// it would arguably be better for these module not to deal with deserialization
// and yaml, but at this stage it's easier to assume the defaults when customize
// is not called, especially for tests.
let mut classes: Vec<Class> = serde_yaml::from_slice(bytes).unwrap();

let mut class_groups = HashMap::new();
for class in classes.drain(..) {
let entry = class_groups
.entry(class.category.clone())
.or_insert_with(Vec::new);
entry.push(class);
impl Class {
/// Customize the classes definitions based on an input yaml byte array.
pub fn load(bytes: &[u8]) {
CLASSES.set(from_bytes(bytes)).unwrap();
}
class_groups
}

impl Class {
// TODO consider making all module level or all struct level
/// The default player class, exposed for initialization and parameterization of
/// items and equipment.
pub fn warrior() -> &'static Self {
CLASSES
.get_or_init(default_classes)
@@ -105,6 +87,26 @@ impl Class {
}
}

fn default_classes() -> HashMap<Category, Vec<Class>> {
from_bytes(include_bytes!("classes.yaml"))
}

fn from_bytes(bytes: &[u8]) -> HashMap<Category, Vec<Class>> {
// it would arguably be better for these module not to deal with deserialization
// and yaml, but at this stage it's easier allow it to pick up defaults from
// the local file when it hasn't been customized (especially for tests)
let mut classes: Vec<Class> = serde_yaml::from_slice(bytes).unwrap();

let mut class_groups = HashMap::new();
for class in classes.drain(..) {
let entry = class_groups
.entry(class.category.clone())
.or_insert_with(Vec::new);
entry.push(class);
}
class_groups
}

/// Choose an enemy randomly, with higher chance to difficult enemies the further from home.
fn weighted_choice(distance: location::Distance) -> Class {
// the weights for each group of enemies are different depending on the distance
2 changes: 1 addition & 1 deletion src/datafile.rs
Original file line number Diff line number Diff line change
@@ -24,7 +24,7 @@ pub fn remove() {

pub fn load_classes() {
if let Ok(bytes) = read(classes_file()) {
class::customize(&bytes)
class::Class::load(&bytes)
}
}