use std::{
collections::HashMap,
fmt::{Display, Formatter},
};
use serde::{Deserialize, Serialize};
use serde_tuple::{Deserialize_tuple, Serialize_tuple};
use crate::{
maps::{
continents::{ContinentId, Dimensions},
MapId,
},
Endpoint, EndpointWithId,
};
pub type FloorId = i16;
pub type RegionId = u8;
pub type MasteryPointId = u16;
pub type PointOfInterestId = u16;
pub type GodShrineId = u8;
pub type TaskId = u16;
pub type SectorId = u16;
#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash, Serialize, Deserialize)]
pub struct ContinentFloorId {
pub continent: ContinentId,
pub floor: FloorId,
}
impl From<(ContinentId, FloorId)> for ContinentFloorId {
fn from(value: (ContinentId, FloorId)) -> Self {
Self {
continent: value.0,
floor: value.1,
}
}
}
impl Display for ContinentFloorId {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}/floors/{}", self.continent, self.floor)
}
}
#[derive(Clone, Debug, PartialOrd, PartialEq, Serialize_tuple, Deserialize_tuple)]
#[cfg_attr(test, serde(deny_unknown_fields))]
pub struct Coordinates {
pub x: f32,
pub y: f32,
}
#[derive(Clone, Debug, PartialOrd, PartialEq, Serialize_tuple, Deserialize_tuple)]
#[cfg_attr(test, serde(deny_unknown_fields))]
pub struct ContinentRectangle {
pub top_left: Coordinates,
pub bottom_right: Coordinates,
}
#[derive(Clone, Debug, PartialOrd, PartialEq, Serialize_tuple, Deserialize_tuple)]
#[cfg_attr(test, serde(deny_unknown_fields))]
pub struct MapRectangle {
pub bottom_left: Coordinates,
pub top_right: Coordinates,
}
#[derive(Clone, PartialEq, Eq, PartialOrd, Debug, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
#[cfg_attr(test, serde(deny_unknown_fields))]
pub enum PointOfInterestType {
Landmark,
Waypoint,
Vista,
Unlock,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(test, serde(deny_unknown_fields))]
pub struct PointOfInterest {
pub id: PointOfInterestId,
pub name: Option<String>,
#[serde(rename = "type")]
pub _type: PointOfInterestType,
pub floor: FloorId,
pub coord: Coordinates,
pub chat_link: String,
pub icon: Option<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(test, serde(deny_unknown_fields))]
pub struct GodShrine {
pub id: GodShrineId,
pub name: String,
pub name_contested: String,
pub coord: Coordinates,
pub poi_id: PointOfInterestId,
pub icon: String,
pub icon_contested: String,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(test, serde(deny_unknown_fields))]
pub struct Task {
pub id: TaskId,
pub objective: String,
pub level: u8,
pub coord: Coordinates,
pub bounds: Vec<Coordinates>,
pub chat_link: String,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(test, serde(deny_unknown_fields))]
pub struct SkillChallenge {
pub id: Option<String>,
pub coord: Coordinates,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(test, serde(deny_unknown_fields))]
pub struct Sector {
pub id: SectorId,
pub name: Option<String>,
pub level: u8,
pub coord: Coordinates,
pub bounds: Vec<Coordinates>,
pub chat_link: String,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(test, serde(deny_unknown_fields))]
pub struct Adventure {
pub id: String,
pub name: String,
pub description: String,
pub coord: Coordinates,
}
#[derive(Clone, PartialEq, Eq, PartialOrd, Debug, Serialize, Deserialize)]
#[cfg_attr(test, serde(deny_unknown_fields))]
pub enum MasteryPointRegion {
Tyria,
Maguuma,
Desert,
Tundra,
Unknown,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(test, serde(deny_unknown_fields))]
pub struct MasteryPoint {
pub id: MasteryPointId,
pub region: MasteryPointRegion,
pub coord: Coordinates,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(test, serde(deny_unknown_fields))]
pub struct Map {
pub id: MapId,
pub name: String,
pub min_level: u8,
pub max_level: u8,
pub default_floor: FloorId,
pub label_coord: Option<Coordinates>,
pub map_rect: MapRectangle,
pub continent_rect: ContinentRectangle,
pub points_of_interest: HashMap<PointOfInterestId, PointOfInterest>,
pub god_shrines: Option<Vec<GodShrine>>,
pub tasks: HashMap<TaskId, Task>,
pub skill_challenges: Vec<SkillChallenge>,
pub sectors: HashMap<SectorId, Sector>,
pub adventures: Vec<Adventure>,
pub mastery_points: Vec<MasteryPoint>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(test, serde(deny_unknown_fields))]
pub struct Region {
pub id: RegionId,
pub name: String,
pub label_coord: Coordinates,
pub continent_rect: ContinentRectangle,
pub maps: HashMap<MapId, Map>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(test, serde(deny_unknown_fields))]
pub struct Floor {
pub id: FloorId,
pub texture_dims: Dimensions,
pub clamped_view: Option<ContinentRectangle>,
pub regions: HashMap<RegionId, Region>,
}
impl EndpointWithId for Floor {
type IdType = ContinentFloorId;
fn format_id(id: &Self::IdType) -> String {
id.to_string()
}
}
impl Endpoint for Floor {
const AUTHENTICATED: bool = false;
const LOCALE: bool = true;
const URL: &'static str = "v2/continents";
const VERSION: &'static str = "2023-03-31T00:00:00.000Z";
}