terra-plr 0.2.3

Terraria player parser
Documentation
pub mod buff;
pub mod default;
pub mod error;
pub mod inventory;
pub mod looks;
pub mod read;
pub mod write;

use self::{
	buff::BuffEffect,
	inventory::{DpadShortcuts, InventorySlot, ItemSlot, Loadouts, MiscRow, MiscRowWithVisibility},
	looks::{HairDye, Style},
};
use bounded_vector::BoundedVec;
use cs_datetime_parse::DateTimeCs;
use std::{collections::HashMap, ops::RangeInclusive};
use terra_items::Item;
use terra_types::{Color, InTiles, NonNegativeI32, Vec2};
use time::Duration;

pub const SUPPORTED_VERSIONS: RangeInclusive<i32> = 0..=279;
const MAGIC_NUMBER: &[u8; 7] = b"relogic";
const PLAYER_ENCRYPTION_KEY: [u8; 16] = [
	0x68, 0x00, 0x33, 0x00, 0x79, 0x00, 0x5F, 0x00, 0x67, 0x00, 0x55, 0x00, 0x79, 0x00, 0x5A, 0x00,
];

#[derive(Debug, Clone, PartialEq)]
pub struct Player {
	pub is_aegis_crystal_used: bool,
	pub is_aegis_fruit_used: bool,
	pub is_ambrosia_used: bool,
	pub is_arcane_crystal_used: bool,
	pub is_artisan_bread_eaten: bool,
	pub is_demon_heart_accessory_slot_unlocked: bool,
	pub is_gummy_worm_used: bool,
	pub is_galaxy_pearl_used: bool,

	pub is_auto_paint_enabled: bool,
	pub is_auto_placement_actuators_enabled: bool,
	pub is_tile_replacement_enabled: bool,
	pub is_using_biome_torches: Option<bool>,

	pub is_creature_count_info_shown: bool,
	pub is_damage_per_second_info_shown: bool,
	pub is_weather_info_shown: bool,
	pub is_depth_info_shown: bool,
	pub is_fishing_power_info_shown: bool,
	pub is_treasure_finder_info_shown: bool,
	pub is_moon_phase_info_shown: bool,
	pub is_time_info_shown: bool,
	pub is_kill_count_info_shown: bool,
	pub is_rare_creatures_finder_info_shown: bool,
	pub is_movement_speed_info_shown: bool,
	pub is_position_info_shown: bool,

	pub is_dd2_event_downed: bool,
	pub is_talked_to_bartender: bool,

	pub is_far_placement_enabled: bool,
	pub is_godmode_enabled: bool,
	pub spawn_rate_factor: f32,
	pub item_researched_count: HashMap<Item, i32>,

	pub finished_angler_quests_count: i32,
	pub golfer_score_accumulated: i32,
	pub deaths_caused_by_player_count: i32,
	pub deaths_not_caused_by_player_count: i32,
	pub tax_money_in_copper_coins: i32,

	pub is_favorite: bool,
	pub name: String,
	pub playtime: Option<Duration>,
	pub difficulty: Difficulty,
	pub last_time_player_was_saved: Option<DateTimeCs>,

	pub life: i32,
	pub max_life: i32,
	pub mana: i32,
	pub max_mana: i32,
	pub time_to_respawn: Option<Duration>,

	pub is_hotbar_locked: bool,
	pub dpad_shortcuts: DpadShortcuts,
	pub inventory: [[Option<InventorySlot>; 10]; 5],
	pub void_vault: Option<[[Option<InventorySlot>; 10]; 4]>,
	pub ammo: [Option<InventorySlot>; 4],
	pub coins: [Option<InventorySlot>; 4],
	pub defenders_forge: [[Option<ItemSlot>; 10]; 4],
	pub piggy_bank: [[Option<ItemSlot>; 10]; 4],
	pub safe: [[Option<ItemSlot>; 10]; 4],

	pub loadouts: Loadouts,
	pub is_super_cart_enabled: Option<bool>,
	pub minecart: MiscRow,
	pub mount: MiscRow,
	pub hook: MiscRow,
	pub pet: MiscRowWithVisibility,
	pub light_pet: MiscRowWithVisibility,

	pub temporary_goblin_item: Option<ItemSlot>,
	pub temporary_guide_item: Option<ItemSlot>,
	pub temporary_mouse_item: Option<ItemSlot>,
	pub temporary_research_item: Option<ItemSlot>,

	pub buffs: BoundedVec<BuffEffect, 0, 44>,
	pub spawn_points: BoundedVec<SpawnPoint, 0, 200>,

	pub style: Style,
	pub hair_dye: Option<HairDye>,
	pub hair_style: i32,
	pub hair_color: Color,
	pub pants_color: Color,
	pub shirt_color: Color,
	pub shoe_color: Color,
	pub skin_color: Color,
	pub eye_color: Color,
	pub under_shirt_color: Color,

	pub is_mechanical_ruler_enabled: bool,
	pub is_ruler_enabled: bool,
	pub is_always_showing_wires_and_actuators: bool,
	pub actuators_visibility: Visibility,
	pub blue_wires_visibility: Visibility,
	pub red_wires_visibility: Visibility,
	pub green_wires_visibility: Visibility,
	pub yellow_wires_visibility: Visibility,
}

#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
pub enum Visibility {
	#[default]
	Bright = 0,
	Faded = 1,
	Classic = 2,
}

impl Visibility {
	pub fn to_id(self) -> i32 {
		self as i32
	}

	pub fn from_id(id: i32) -> Option<Self> {
		Some(match id {
			0 => Self::Bright,
			1 => Self::Faded,
			2 => Self::Classic,
			_ => return None,
		})
	}
}

#[derive(Debug, PartialEq, Eq, Hash, Clone)]
pub struct SpawnPoint {
	pub coords: Vec2<InTiles, NonNegativeI32>,
	pub world_id: i32,
	pub world_name: String,
}

#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
pub enum Difficulty {
	#[default]
	SoftCore = 0,
	MediumCore = 1,
	Hardcore = 2,
	Journey = 3,
}

impl Difficulty {
	pub fn to_id(self) -> u8 {
		self as u8
	}

	pub fn from_id(id: u8) -> Option<Self> {
		Some(match id {
			0 => Self::SoftCore,
			1 => Self::MediumCore,
			2 => Self::Hardcore,
			3 => Self::Journey,
			_ => return None,
		})
	}
}