Skip to main content

terra_wld/
world.rs

1pub mod default;
2pub mod read;
3pub mod write;
4
5use crate::{
6	banner::Banner,
7	entity::{Entity, EntityType},
8	tile::{Tile, TileType},
9	world_manifest::WorldManifest,
10};
11use bounded_vector::BoundedVec;
12use cs_datetime_parse::DateTimeCs;
13use grid::Grid;
14use std::collections::{HashMap, HashSet};
15use terra_items::{Item, WorldItemSlot};
16use terra_types::{
17	Evil, InDays, InMph, InPixels, InTiles, MoonPhase, Rain, Value, Vec2, XAxis, YAxis,
18};
19use time::{Duration, Time};
20use uuid::Uuid;
21
22#[derive(Debug, Clone, PartialEq)]
23#[non_exhaustive]
24pub struct World {
25	pub name: String,
26	pub id: i32,
27	pub uuid: Option<Uuid>,
28	pub times_saved: u32,
29	pub is_favorite: bool,
30	pub seed: Option<String>,
31	pub generator_version: Option<u64>,
32	pub left_border: XAxis<InPixels, i32>,
33	pub right_border: XAxis<InPixels, i32>,
34	pub top_border: YAxis<InPixels, i32>,
35	pub bottom_border: YAxis<InPixels, i32>,
36	pub spawn: Vec2<InTiles, i32>,
37	pub team_spawns: Option<TeamSpawns>,
38	pub dungeon: Vec2<InTiles, i32>,
39	pub moon_type: MoonType,
40	pub moon_phase: MoonPhase,
41	pub difficulty: Difficulty,
42	pub evil: Evil,
43	pub creation_time: Option<DateTimeCs>,
44	pub last_played: Option<DateTimeCs>,
45	pub time: Time,
46	pub is_shadow_orb_or_crimson_heart_destroyed: bool,
47	pub destroyed_shadow_orb_or_crimson_heart_count: u8,
48	pub destroyed_altar_count: i32,
49	pub tier_1_hardmode_ore: Option<TileType>,
50	pub tier_2_hardmode_ore: Option<TileType>,
51	pub tier_3_hardmode_ore: Option<TileType>,
52	pub tier_1_ore: Option<TileType>,
53	pub tier_2_ore: Option<TileType>,
54	pub tier_3_ore: Option<TileType>,
55	pub tier_4_ore: Option<TileType>,
56	pub surface_level: YAxis<InTiles, f64>,
57	pub cavern_level: YAxis<InTiles, f64>,
58	pub weighted_pressure_plates: HashSet<Vec2<InTiles, i32>>,
59	pub homes: Vec<Home>,
60	pub tile_entities: Vec<TileEntity>,
61	pub bestiary: HashMap<EntityType, BestiaryEntry>,
62	pub kill_count: HashMap<Banner, i32>,
63	pub claimable_banners: HashMap<Banner, u16>,
64	pub entities: BoundedVec<Entity, 0, 201>,
65	pub signs: BoundedVec<Sign, 0, 32000>,
66	pub chests: BoundedVec<Chest, 0, 8000>,
67	pub tiles: Grid<Tile>,
68
69	pub invasion: Option<Invasion>,
70	pub slime_rain_time: Duration,
71	pub sundial_cooldown: Value<InDays, u8>,
72	pub moondial_cooldown: Value<InDays, u8>,
73	pub lantern_night_cooldown: Value<InDays, i32>,
74	pub invasion_cooldown: Value<InDays, i32>,
75	pub rain: Option<Rain>,
76	pub meteor_shower_remaining: i32,
77	pub coin_rain_remaining: i32,
78	pub cultist_delay: Duration,
79	pub party_cooldown: Duration,
80	pub party: Option<Party>,
81	pub lantern_night: Option<LanternNight>,
82	pub sandstorm: Option<Sandstorm>,
83	pub clouds_count: i16,
84	pub cloud_bg_active: i32,
85	pub wind: XAxis<InMph, f32>,
86
87	pub players_finished_angler_quest_today: Vec<String>,
88	pub angler_quest: AnglerQuest,
89
90	pub is_drunk_world: bool,
91	pub is_for_the_worthy_world: bool,
92	pub is_tenth_anniversary_world: bool,
93	pub is_dont_starve_world: bool,
94	pub is_not_the_bees_world: bool,
95	pub is_remix_world: bool,
96	pub is_no_traps_world: bool,
97	pub is_zenith_world: bool,
98	pub is_skyblock_world: bool,
99	pub is_dual_dungeon_seed: bool,
100	pub is_vampire_seed: bool,
101	pub is_infected_seed: bool,
102
103	pub is_blood_moon: bool,
104	pub is_solar_eclipse: bool,
105	pub is_sundial_forward_time_active: bool,
106	pub is_moondial_forward_time_active: bool,
107	pub is_solar_pillar_active: bool,
108	pub is_vortex_pillar_active: bool,
109	pub is_nebula_pillar_active: bool,
110	pub is_stardust_pillar_active: bool,
111	pub is_lunar_apocalypse: bool,
112	pub is_next_night_lantern_night: bool,
113
114	pub is_eye_of_cthulhu_downed: bool,
115	pub is_eater_of_worlds_or_brain_of_cthulhu_downed: bool,
116	pub is_goblin_army_downed: bool,
117	pub is_skeleton_downed: bool,
118	pub is_queen_bee_downed: bool,
119	pub is_destroyer_downed: bool,
120	pub is_twins_downed: bool,
121	pub is_skeletron_prime_downed: bool,
122	pub is_any_mechanical_boss_downed: bool,
123	pub is_plantera_downed: bool,
124	pub is_golem_downed: bool,
125	pub is_king_slime_downed: bool,
126	pub is_clown_downed: bool,
127	pub is_frost_legion_downed: bool,
128	pub is_pirate_invasion_downed: bool,
129	pub is_fishron_downed: bool,
130	pub is_martian_madness_downed: bool,
131	pub is_ancient_cultist_downed: bool,
132	pub is_moonlord_downed: bool,
133	pub is_pumpking_downed: bool,
134	pub is_mourning_wood_downed: bool,
135	pub is_ice_queen_downed: bool,
136	pub is_santa_nk1_downed: bool,
137	pub is_everscream_downed: bool,
138	pub is_solar_pillar_downed: bool,
139	pub is_vortex_pillar_downed: bool,
140	pub is_nebula_pillar_downed: bool,
141	pub is_stardust_pillar_downed: bool,
142	pub is_dd2_t1_downed: bool,
143	pub is_dd2_t2_downed: bool,
144	pub is_dd2_t3_downed: bool,
145	pub is_empress_of_light_downed: bool,
146	pub is_queen_slime_downed: bool,
147	pub is_deerclops_downed: bool,
148
149	pub is_cat_bought: bool,
150	pub is_dog_bought: bool,
151	pub is_bunny_bought: bool,
152	pub is_blue_slime_spawn_unlocked: bool,
153	pub is_green_slime_spawn_unlocked: bool,
154	pub is_old_slime_spawn_unlocked: bool,
155	pub is_purple_slime_spawn_unlocked: bool,
156	pub is_rainbow_slime_spawn_unlocked: bool,
157	pub is_red_slime_unlocked: bool,
158	pub is_yellow_slime_spawn_unlocked: bool,
159	pub is_copper_slime_spawn_unlocked: bool,
160	pub is_merchant_spawn_unlocked: bool,
161	pub is_demolitionist_spawn_unlocked: bool,
162	pub is_party_girl_spawn_unlocked: bool,
163	pub is_goblin_tinkerer_saved: bool,
164	pub is_dye_trader_spawn_unlocked: bool,
165	pub is_truffle_spawn_unlocked: bool,
166	pub is_arms_dealer_spawn_unlocked: bool,
167	pub is_nurse_spawn_unlocked: bool,
168	pub is_princess_spawn_unlocked: bool,
169	pub is_wizard_saved: bool,
170	pub is_mechanic_saved: bool,
171	pub is_stylist_saved: bool,
172	pub is_angler_saved: bool,
173	pub is_tax_collector_saved: bool,
174	pub is_golfer_saved: bool,
175	pub is_bartender_saved: bool,
176
177	pub is_merchant_shimmered: bool,
178	pub is_nurse_shimmered: bool,
179	pub is_arms_dealer_shimmered: bool,
180	pub is_dryad_shimmered: bool,
181	pub is_guide_shimmered: bool,
182	pub is_old_man_shimmered: bool,
183	pub is_demolitionist_shimmered: bool,
184	pub is_clothier_shimmered: bool,
185	pub is_goblin_tinkerer_shimmered: bool,
186	pub is_wizard_shimmered: bool,
187	pub is_mechanic_shimmered: bool,
188	pub is_santa_claus_shimmered: bool,
189	pub is_truffle_shimmered: bool,
190	pub is_steampunker_shimmered: bool,
191	pub is_dye_trader_shimmered: bool,
192	pub is_party_girl_shimmered: bool,
193	pub is_cyborg_shimmered: bool,
194	pub is_painter_shimmered: bool,
195	pub is_witch_doctor_shimmered: bool,
196	pub is_pirate_shimmered: bool,
197	pub is_stylist_shimmered: bool,
198	pub is_travelling_merchant_shimmered: bool,
199	pub is_angler_shimmered: bool,
200	pub is_tax_collector_shimmered: bool,
201	pub is_bartender_shimmered: bool,
202	pub is_golfer_shimmered: bool,
203	pub is_zoologist_shimmered: bool,
204	pub is_town_cat_shimmered: bool,
205	pub is_town_dog_shimmered: bool,
206	pub is_town_bunny_shimmered: bool,
207	pub is_princess_shimmered: bool,
208	pub is_town_slime_blue_shimmered: bool,
209	pub is_town_slime_green_shimmered: bool,
210	pub is_town_slime_old_shimmered: bool,
211	pub is_town_slime_purple_shimmered: bool,
212	pub is_town_slime_rainbow_shimmered: bool,
213	pub is_town_slime_red_shimmered: bool,
214	pub is_town_slime_yellow_shimmered: bool,
215	pub is_town_slime_copper_shimmered: bool,
216	pub is_skeleton_merchant_shimmered: bool,
217
218	pub is_hallowen_forced_today: bool,
219	pub is_xmas_forced_today: bool,
220	pub is_hallowen_forced_forever: bool,
221	pub is_xmas_forced_forever: bool,
222	pub is_meteor_to_spawn: bool,
223	pub is_hardmode: bool,
224	pub is_after_party_of_doom: bool,
225	pub is_combat_book_used: bool,
226	pub is_combat_book_volume_two_used: bool,
227	pub is_peddlers_satchel_used: bool,
228
229	pub ice_cave_background: i32,
230	pub jungle_cave_background: i32,
231	pub hell_background: i32,
232	pub forest_background: u8,
233	pub corruption_background: u8,
234	pub jungle_background: u8,
235	pub snow_background: u8,
236	pub hallow_background: u8,
237	pub crimson_background: u8,
238	pub desert_background: u8,
239	pub ocean_background: u8,
240	pub mushroom_background: u8,
241	pub underworld_background: u8,
242
243	pub tree_backgrounds: [u8; 3],
244	pub tree_styles: [i32; 4],
245	pub tree_style_changes: [XAxis<InTiles, i32>; 3],
246	pub cave_back_styles: [i32; 4],
247	pub cave_back_style_changes: [XAxis<InTiles, i32>; 3],
248	pub tree_tops_forest: [i32; 4],
249	pub tree_tops_corruption: i32,
250	pub tree_tops_jungle: i32,
251	pub tree_tops_snow: i32,
252	pub tree_tops_hallow: i32,
253	pub tree_tops_crimson: i32,
254	pub tree_tops_desert: i32,
255	pub tree_tops_ocean: i32,
256	pub tree_tops_glowing_mushroom: i32,
257	pub tree_tops_underworld: i32,
258
259	pub is_time_frozen: bool,
260	pub is_rain_frozen: bool,
261	pub is_wind_frozen: bool,
262	pub is_biome_spread_disabled: bool,
263	pub time_rate_power: f32,
264	pub difficulty_power: f32,
265
266	pub manifest: WorldManifest,
267}
268
269#[derive(Debug, Clone, Copy, PartialEq)]
270pub struct Sandstorm {
271	pub time: Duration,
272	pub current_severity: f32,
273	pub intended_severity: f32,
274}
275
276#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
277pub struct LanternNight {
278	pub is_mannual: bool,
279}
280
281#[derive(Debug, Clone, PartialEq, Eq, Hash)]
282pub struct Party {
283	pub is_mannual: bool,
284	pub celebrating_npcs: Vec<EntityType>,
285}
286
287#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
288pub struct TileEntity {
289	pub entity: TileEntityType,
290	pub position: Vec2<InTiles, i16>,
291}
292
293#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
294#[non_exhaustive]
295pub enum TileEntityType {
296	TrainingDummy {
297		entity_idx: i16,
298	},
299	ItemFrame(Option<WorldItemSlot>),
300	LogicSensor {
301		check: Option<LogicCheck>,
302		is_on: bool,
303	},
304	DisplayDoll {
305		pose: DisplayDollPose,
306		helmet: ItemDyeRow,
307		breastplate: ItemDyeRow,
308		pants: ItemDyeRow,
309		accessories: [ItemDyeRow; 5],
310		mount: ItemDyeRow,
311		hand: Option<WorldItemSlot>,
312	},
313	WeaponRack(Option<WorldItemSlot>),
314	HatRack {
315		upper: ItemDyeRow,
316		lower: ItemDyeRow,
317	},
318	FoodPlatter(Option<WorldItemSlot>),
319	Pylon,
320	DisplayJar(Option<WorldItemSlot>),
321	KiteAnchor(Option<Item>),
322	CritterAnchor(Option<Item>),
323}
324
325impl TileEntityType {
326	pub fn id(&self) -> u8 {
327		match self {
328			TileEntityType::TrainingDummy { .. } => 0,
329			TileEntityType::ItemFrame(_) => 1,
330			TileEntityType::LogicSensor { .. } => 2,
331			TileEntityType::DisplayDoll { .. } => 3,
332			TileEntityType::WeaponRack(_) => 4,
333			TileEntityType::HatRack { .. } => 5,
334			TileEntityType::FoodPlatter(_) => 6,
335			TileEntityType::Pylon => 7,
336			TileEntityType::DisplayJar(_) => 8,
337			TileEntityType::KiteAnchor(_) => 9,
338			TileEntityType::CritterAnchor(_) => 10,
339		}
340	}
341
342	fn supported_version(&self) -> i32 {
343		match self {
344			&TileEntityType::TrainingDummy { .. } | &TileEntityType::ItemFrame(_) => 146,
345			&TileEntityType::LogicSensor { .. } => 168,
346			&TileEntityType::DisplayDoll { .. }
347			| &TileEntityType::WeaponRack(_)
348			| &TileEntityType::HatRack { .. }
349			| &TileEntityType::FoodPlatter(_)
350			| &TileEntityType::Pylon => 225,
351			&TileEntityType::DisplayJar(_)
352			| TileEntityType::CritterAnchor(_)
353			| TileEntityType::KiteAnchor(_) => 315,
354		}
355	}
356}
357
358#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
359pub enum DisplayDollPose {
360	#[default]
361	Standing = 0,
362	Sitting = 1,
363	Jumping = 2,
364	Walking = 3,
365	ItemUse1 = 4,
366	ItemUse2 = 5,
367	ItemUse3 = 6,
368	ItemUse4 = 7,
369	ItemUse5 = 8,
370}
371
372impl DisplayDollPose {
373	fn to_id(self) -> u8 {
374		self as u8
375	}
376
377	fn from_id(id: u8) -> Option<DisplayDollPose> {
378		Some(match id {
379			0 => DisplayDollPose::Standing,
380			1 => DisplayDollPose::Sitting,
381			2 => DisplayDollPose::Jumping,
382			3 => DisplayDollPose::Walking,
383			4 => DisplayDollPose::ItemUse1,
384			5 => DisplayDollPose::ItemUse2,
385			6 => DisplayDollPose::ItemUse3,
386			7 => DisplayDollPose::ItemUse4,
387			8 => DisplayDollPose::ItemUse5,
388			_ => return None,
389		})
390	}
391}
392
393#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
394pub struct ItemDyeRow {
395	pub item: Option<WorldItemSlot>,
396	pub dye: Option<WorldItemSlot>,
397}
398
399#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
400#[non_exhaustive]
401pub enum LogicCheck {
402	Day = 1,
403	Night = 2,
404	PlayerAbove = 3,
405	Water = 4,
406	Lava = 5,
407	Honey = 6,
408	Liquid = 7,
409}
410
411#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
412#[non_exhaustive]
413pub struct TeamSpawns {
414	pub no_team: Vec2<InTiles, i16>,
415	pub red: Vec2<InTiles, i16>,
416	pub green: Vec2<InTiles, i16>,
417	pub blue: Vec2<InTiles, i16>,
418	pub yellow: Vec2<InTiles, i16>,
419	pub pink: Vec2<InTiles, i16>,
420}
421
422impl TeamSpawns {
423	pub const COUNT: u8 = 6;
424}
425
426impl LogicCheck {
427	pub fn from_id(id: u8) -> Option<LogicCheck> {
428		Some(match id {
429			1 => LogicCheck::Day,
430			2 => LogicCheck::Night,
431			3 => LogicCheck::PlayerAbove,
432			4 => LogicCheck::Water,
433			5 => LogicCheck::Lava,
434			6 => LogicCheck::Honey,
435			7 => LogicCheck::Liquid,
436			_ => return None,
437		})
438	}
439
440	pub fn to_id(self) -> u8 {
441		self as u8
442	}
443}
444
445#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
446pub struct BestiaryEntry {
447	pub is_chatted_with: bool,
448	pub is_seen: bool,
449	pub killed_count: i32,
450}
451
452#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
453pub struct Home {
454	pub resident: EntityType,
455	pub position: Vec2<InPixels, i32>,
456}
457
458#[derive(Debug, Clone, PartialEq, Eq, Hash)]
459pub struct Chest {
460	pub name: String,
461	pub position: Vec2<InTiles, i32>,
462	pub slots: Vec<Option<WorldItemSlot>>,
463}
464
465impl Chest {
466	pub fn new(position: Vec2<InTiles, i32>) -> Self {
467		Chest {
468			name: "".to_owned(),
469			position,
470			slots: Vec::new(),
471		}
472	}
473}
474
475#[derive(Debug, Clone, PartialEq, Eq, Hash)]
476pub struct Sign {
477	pub position: Vec2<InTiles, i32>,
478	pub text: String,
479}
480
481#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
482#[non_exhaustive]
483pub enum AnglerQuest {
484	Batfish = 0,
485	BumblebeeTuna = 1,
486	Catfish = 2,
487	Cloudfish = 3,
488	Cursedfish = 4,
489	Dirtfish = 5,
490	DynamiteFish = 6,
491	EaterOfPlankton = 7,
492	FallenStarfish = 8,
493	TheFishOfCthulu = 9,
494	Fishotron = 10,
495	Harpyfish = 11,
496	Hungerfish = 12,
497	Ichorfish = 13,
498	Jewelfish = 14,
499	MirageFish = 15,
500	MutantFlinxfin = 16,
501	Pengfish = 17,
502	Pixiefish = 18,
503	Spiderfish = 19,
504	TundraTrout = 20,
505	UnicornFish = 21,
506	GuideVoodooFish = 22,
507	Wyverntail = 23,
508	ZombieFish = 24,
509	AmanitaFungifin = 25,
510	Angelfish = 26,
511	BloodyManowar = 27,
512	Bonefish = 28,
513	Bunnyfish = 29,
514	CapnTunabeard = 30,
515	Clownfish = 31,
516	DemonicHellfish = 32,
517	Derpfish = 33,
518	Fishron = 34,
519	InfectedScabbardfish = 35,
520	Mudfish = 36,
521	Slimefish = 37,
522	TropicalBarracuda = 38,
523	ScarabFish = 39,
524	ScorpioFish = 40,
525}
526
527impl AnglerQuest {
528	pub fn from_id(id: i32) -> Option<Self> {
529		Some(match id {
530			0 => Self::Batfish,
531			1 => Self::BumblebeeTuna,
532			2 => Self::Catfish,
533			3 => Self::Cloudfish,
534			4 => Self::Cursedfish,
535			5 => Self::Dirtfish,
536			6 => Self::DynamiteFish,
537			7 => Self::EaterOfPlankton,
538			8 => Self::FallenStarfish,
539			9 => Self::TheFishOfCthulu,
540			10 => Self::Fishotron,
541			11 => Self::Harpyfish,
542			12 => Self::Hungerfish,
543			13 => Self::Ichorfish,
544			14 => Self::Jewelfish,
545			15 => Self::MirageFish,
546			16 => Self::MutantFlinxfin,
547			17 => Self::Pengfish,
548			18 => Self::Pixiefish,
549			19 => Self::Spiderfish,
550			20 => Self::TundraTrout,
551			21 => Self::UnicornFish,
552			22 => Self::GuideVoodooFish,
553			23 => Self::Wyverntail,
554			24 => Self::ZombieFish,
555			25 => Self::AmanitaFungifin,
556			26 => Self::Angelfish,
557			27 => Self::BloodyManowar,
558			28 => Self::Bonefish,
559			29 => Self::Bunnyfish,
560			30 => Self::CapnTunabeard,
561			31 => Self::Clownfish,
562			32 => Self::DemonicHellfish,
563			33 => Self::Derpfish,
564			34 => Self::Fishron,
565			35 => Self::InfectedScabbardfish,
566			36 => Self::Mudfish,
567			37 => Self::Slimefish,
568			38 => Self::TropicalBarracuda,
569			39 => Self::ScarabFish,
570			40 => Self::ScorpioFish,
571			_ => return None,
572		})
573	}
574
575	pub fn to_id(self) -> i32 {
576		self as i32
577	}
578}
579
580#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
581#[non_exhaustive]
582pub enum InvasionType {
583	GoblinArmy = 1,
584	SnowLegion = 2,
585	PirateInvasion = 3,
586	MartianMadness = 4,
587}
588
589impl InvasionType {
590	pub fn to_id(self) -> i32 {
591		self as i32
592	}
593
594	pub fn from_id(id: i32) -> Option<Self> {
595		Some(match id {
596			1 => Self::GoblinArmy,
597			2 => Self::SnowLegion,
598			3 => Self::PirateInvasion,
599			4 => Self::MartianMadness,
600			_ => return None,
601		})
602	}
603}
604
605#[derive(Debug, Clone, Copy, PartialEq)]
606pub struct Invasion {
607	pub start_size: i32,
608	pub size: i32,
609	pub invasion_type: InvasionType,
610	pub position: XAxis<InTiles, f64>,
611}
612
613#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Hash)]
614pub enum Difficulty {
615	#[default]
616	Normal = 0,
617	Expert = 1,
618	Master = 2,
619	Journey = 3,
620}
621
622impl Difficulty {
623	pub fn from_id(id: i32) -> Option<Self> {
624		Some(match id {
625			0 => Self::Normal,
626			1 => Self::Expert,
627			2 => Self::Master,
628			3 => Self::Journey,
629			_ => return None,
630		})
631	}
632
633	pub fn to_id(self) -> i32 {
634		self as i32
635	}
636}
637
638#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Hash)]
639#[non_exhaustive]
640pub enum MoonType {
641	#[default]
642	Normal = 0,
643	Yellow = 1,
644	Ringed = 2,
645	Mythril = 3,
646	BrightBlue = 4,
647	Green = 5,
648	Pink = 6,
649	Orange = 7,
650	Purple = 8,
651}
652
653impl MoonType {
654	pub fn from_id(id: u8) -> Option<Self> {
655		Some(match id {
656			0 => Self::Normal,
657			1 => Self::Yellow,
658			2 => Self::Ringed,
659			3 => Self::Mythril,
660			4 => Self::BrightBlue,
661			5 => Self::Green,
662			6 => Self::Pink,
663			7 => Self::Purple,
664			_ => return None,
665		})
666	}
667
668	pub fn to_id(self) -> u8 {
669		self as u8
670	}
671}
672
673const TILE_SIZE: i16 = 16 + 1;
674
675const TILE_IS_IMPORTANT: [bool; 693] = [
676	false, false, false, true, true, true, false, false, false, false, true, true, true, true,
677	true, true, true, true, true, true, true, true, false, false, true, false, true, true, true,
678	true, false, true, false, true, true, true, true, false, false, false, false, false, true,
679	false, false, false, false, false, false, true, true, false, false, false, false, true, false,
680	false, false, false, false, true, false, false, false, false, false, false, false, false,
681	false, true, true, true, true, false, false, true, true, true, false, true, true, true, true,
682	true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
683	true, true, true, true, true, true, false, false, false, true, false, false, true, true, false,
684	false, false, false, false, false, false, false, false, false, true, true, false, true, true,
685	false, false, true, true, true, true, true, true, true, true, false, true, true, true, true,
686	false, false, false, false, true, false, false, false, false, false, false, false, false,
687	false, false, false, false, false, false, false, true, false, false, false, false, false, true,
688	true, true, true, false, false, false, true, false, false, false, false, false, true, true,
689	true, true, false, false, false, false, false, false, false, false, false, false, false, false,
690	false, true, false, false, false, false, false, true, false, true, true, false, true, false,
691	false, true, true, true, true, true, true, false, false, false, false, false, false, true,
692	true, false, false, true, false, true, false, true, true, true, true, true, true, true, true,
693	true, true, true, true, true, false, false, false, false, false, false, true, false, false,
694	false, false, false, false, false, false, false, false, false, false, false, false, true, true,
695	true, false, false, false, true, true, true, true, true, true, true, true, true, false, true,
696	true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
697	true, true, true, true, true, true, true, true, true, false, false, false, true, false, true,
698	true, true, true, true, false, false, true, true, false, false, false, false, false, false,
699	false, false, false, true, true, false, true, true, true, false, false, false, false, false,
700	false, false, false, false, true, false, false, false, false, true, true, true, false, true,
701	true, true, true, true, true, true, false, false, false, false, false, false, false, true,
702	true, true, true, true, true, true, false, true, false, false, false, false, false, true, true,
703	true, true, true, true, true, true, true, true, false, false, false, false, false, false,
704	false, false, false, true, true, false, false, false, true, true, true, true, true, false,
705	false, false, false, true, true, false, false, true, true, true, false, true, true, true,
706	false, false, false, false, false, true, true, true, true, true, true, true, true, true, true,
707	true, false, false, false, false, false, false, true, true, true, true, true, true, false,
708	false, false, true, true, true, true, true, true, true, true, true, true, true, false, false,
709	false, true, true, false, false, false, true, false, false, false, true, true, true, true,
710	true, true, true, true, false, true, true, false, false, true, false, true, false, false,
711	false, false, false, true, true, false, false, true, true, true, false, false, false, false,
712	false, false, true, true, true, true, true, true, true, true, true, true, false, true, true,
713	true, true, true, false, false, false, false, true, false, false, false, true, true, true,
714	true, false, true, true, true, true, true, true, true, true, true, true, false, true, true,
715	true, false, false, false, true, true, false, true, true, true, true, true, true, true, false,
716	false, false, false, false, true, true, true, true, true, true, true, true, true, true, true,
717	true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
718	true, true, true, true, true, true, true, true, true, true, true, true, false, true, true,
719	true, true, true, true, false, false, false, false, true, true, true, true, false, true, false,
720	false, true, false, true, true, false, true, true, true, true, true, true, true, true, true,
721	true, true, true, true, false, true, true, true, false, true, false, false, true, true, true,
722	false, false, false, false, false, false, false, false, false, false, false, false, false,
723	false, false, false, false, false, false, false, false, false, false, false, false, false,
724	false,
725];