1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
//! Defines a data structure for the realm.
//!
//! This allows custom realms to be defined and used in game. Realms will be loaded from game data and can be set to generate the realm.
//!
//! Currently realms are just a collection of biomes and a primary element. This will likely be expanded into more details about the biomes
//! or possible other elements that can be included in the realm. Since the realm data is what is used to generate the "Elemental Realm" that
//! the player is able to visit, it will be important to have a good amount of detail about the realm.
//!
//! Additional details we will need are possibly special monsters and any pre-designed structures that can be found in the realm. This will
//! allow for a more unique experience when visiting the realm. The realm will also need to have a unique name and description to give it some
//! flavor and make it feel like a unique place to visit.
//!
//! One thing that would be neat is for the player to be able to choose one or maybe two elements, and a random realm matching those elements
//! will be chosen from the loaded realms. This will allow for a bit of randomness in the game and give the player a unique experience each time
//! they visit a realm. This will also allow for the player to have a bit of control over what they are going to face in the realm, as they can
//! choose the elements that they are strongest against (or that they need to gather resources from).
use bevy::prelude::*;
use std::any::Any;
use std::hash::Hash;
use crate::{
data_loader::DataFile,
enums::{GameSystem, MagicType},
BiomeData, InternalId,
};
/// Details about a realm.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Reflect)]
#[serde(rename_all = "camelCase")]
pub struct Realm {
/// The internal ID of the Realm.
pub internal_id: Option<String>,
/// Name of the realm.
pub name: String,
/// Short description of the realm.
pub description: String,
/// Biomes for the realm.
pub biomes: Vec<BiomeData>,
/// The primary element of the realm. (for now limited as magic school but should be its own.)
pub primary_element: MagicType,
}
impl InternalId for Realm {
/// Update the realms's internal ID.
fn update_internal_id(&mut self) {
self.internal_id = Some(self.get_internal_id());
}
/// Get the realms's internal ID.
#[must_use]
fn get_internal_id(&self) -> String {
if self.internal_id.is_some() {
let id = self.internal_id.clone().unwrap_or_default();
if !id.is_empty() {
return id;
}
}
format!(
"{}{}{}",
self.name.replace(' ', ""),
self.biomes.len(),
self.primary_element
)
}
}
impl Default for Realm {
fn default() -> Self {
Self {
internal_id: None,
name: "Unknown Realm".to_string(),
description: "A realm that was loaded incorrectly!".to_string(),
biomes: Vec::new(),
primary_element: MagicType::Arcane,
}
}
}
impl<D: Hash + InternalId + 'static> TryInto<Realm> for DataFile<D> {
type Error = ();
fn try_into(self) -> Result<Realm, Self::Error> {
if self.header.system != GameSystem::Realm {
return Err(());
}
(&self.data as &dyn Any)
.downcast_ref::<Realm>()
.cloned()
.ok_or(())
}
}
impl<D: Hash + InternalId + 'static> TryFrom<&DataFile<D>> for Realm {
type Error = ();
fn try_from(data_file: &DataFile<D>) -> Result<Self, Self::Error> {
if data_file.header.system != GameSystem::Realm {
return Err(());
}
(&data_file.data as &dyn Any)
.downcast_ref::<Self>()
.cloned()
.ok_or(())
}
}
impl Hash for Realm {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.name.hash(state);
self.description.hash(state);
self.primary_element.hash(state);
}
}
impl PartialEq for Realm {
fn eq(&self, other: &Self) -> bool {
self.name == other.name
&& self.description == other.description
&& self.primary_element == other.primary_element
}
}
impl Eq for Realm {}