Minor content cleanup
parent
acb5b9d31c
commit
f56fd7ea49
|
@ -1,4 +1,5 @@
|
||||||
# TODO: big objects in one config
|
# TODO: big objects in one config
|
||||||
|
# TODO: satisfy conditions to land
|
||||||
|
|
||||||
[system."12 Autumn Above"]
|
[system."12 Autumn Above"]
|
||||||
name = "12 Autumn Above"
|
name = "12 Autumn Above"
|
||||||
|
@ -13,10 +14,9 @@ object.earth.position.angle = 0
|
||||||
object.earth.position.z = 10.0
|
object.earth.position.z = 10.0
|
||||||
object.earth.size = 1000
|
object.earth.size = 1000
|
||||||
|
|
||||||
# TODO: satisfy conditions to land
|
|
||||||
object.earth.landable = true
|
object.earth.landable.name = "Earth"
|
||||||
object.earth.name = "Earth"
|
object.earth.landable.desc = """
|
||||||
object.earth.desc = """
|
|
||||||
The ancestral home world of humanity, Earth has a population twice that of any other inhabited planet.
|
The ancestral home world of humanity, Earth has a population twice that of any other inhabited planet.
|
||||||
Sprawling cities cover large portions of its surface, many of them overcrowded and dangerous.
|
Sprawling cities cover large portions of its surface, many of them overcrowded and dangerous.
|
||||||
Some people work to scrape together enough money to leave, while at the same time others, born
|
Some people work to scrape together enough money to leave, while at the same time others, born
|
||||||
|
@ -28,8 +28,13 @@ one planet has a greater population than a hundred planets elsewhere. As a resul
|
||||||
settlements of less than a million are grouped together into planetary districts that
|
settlements of less than a million are grouped together into planetary districts that
|
||||||
elect a single representative between them - a source of much frustration in the frontier worlds.
|
elect a single representative between them - a source of much frustration in the frontier worlds.
|
||||||
"""
|
"""
|
||||||
object.earth.image = "ui::landscape::test"
|
object.earth.landable.image = "ui::landscape::test"
|
||||||
|
|
||||||
|
object.earth.landable.outfitter = [
|
||||||
|
"plasma engines",
|
||||||
|
"shield generator",
|
||||||
|
"blaster",
|
||||||
|
]
|
||||||
|
|
||||||
object.luna.sprite = "planet::luna"
|
object.luna.sprite = "planet::luna"
|
||||||
object.luna.position.center = "earth"
|
object.luna.position.center = "earth"
|
||||||
|
|
|
@ -165,8 +165,7 @@ impl Display for ContentIndex {
|
||||||
/// Stores temporary data while building context objects
|
/// Stores temporary data while building context objects
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct ContentBuildContext {
|
pub(crate) struct ContentBuildContext {
|
||||||
/// Map effect names to handles
|
pub effect_index: HashMap<ContentIndex, Arc<Effect>>,
|
||||||
pub effect_index: HashMap<String, Arc<Effect>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ContentBuildContext {
|
impl ContentBuildContext {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use std::{collections::HashMap, sync::Arc};
|
use std::{collections::HashMap, sync::Arc};
|
||||||
|
|
||||||
use crate::{Content, ContentBuildContext, Sprite};
|
use crate::{Content, ContentBuildContext, ContentIndex, Sprite};
|
||||||
|
|
||||||
pub(crate) mod syntax {
|
pub(crate) mod syntax {
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -138,12 +138,12 @@ pub(crate) mod syntax {
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
pub enum EffectReference {
|
pub enum EffectReference {
|
||||||
Label(String),
|
Label(ContentIndex),
|
||||||
Effect(Effect),
|
Effect(Effect),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EffectReference {
|
impl EffectReference {
|
||||||
pub fn to_handle(
|
pub fn resolve(
|
||||||
self,
|
self,
|
||||||
build_context: &mut ContentBuildContext,
|
build_context: &mut ContentBuildContext,
|
||||||
content: &mut Content,
|
content: &mut Content,
|
||||||
|
@ -246,7 +246,9 @@ impl crate::Build for Effect {
|
||||||
let h = effect
|
let h = effect
|
||||||
.add_to(build_context, content, &effect_name)
|
.add_to(build_context, content, &effect_name)
|
||||||
.with_context(|| format!("while evaluating effect `{}`", effect_name))?;
|
.with_context(|| format!("while evaluating effect `{}`", effect_name))?;
|
||||||
build_context.effect_index.insert(effect_name, h);
|
build_context
|
||||||
|
.effect_index
|
||||||
|
.insert(ContentIndex::new(&effect_name), h);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
|
|
@ -81,12 +81,12 @@ pub(crate) mod syntax {
|
||||||
};
|
};
|
||||||
|
|
||||||
let impact_effect = match self.projectile.impact_effect {
|
let impact_effect = match self.projectile.impact_effect {
|
||||||
Some(e) => Some(e.to_handle(build_context, content, "")?),
|
Some(e) => Some(e.resolve(build_context, content, "")?),
|
||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let expire_effect = match self.projectile.expire_effect {
|
let expire_effect = match self.projectile.expire_effect {
|
||||||
Some(e) => Some(e.to_handle(build_context, content, "")?),
|
Some(e) => Some(e.resolve(build_context, content, "")?),
|
||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -143,7 +143,7 @@ pub struct Outfit {
|
||||||
pub space: OutfitSpace,
|
pub space: OutfitSpace,
|
||||||
|
|
||||||
/// The name of this outfit
|
/// The name of this outfit
|
||||||
pub name: String,
|
pub display_name: String,
|
||||||
|
|
||||||
/// Thie outfit's index
|
/// Thie outfit's index
|
||||||
pub index: ContentIndex,
|
pub index: ContentIndex,
|
||||||
|
@ -281,7 +281,7 @@ impl crate::Build for Outfit {
|
||||||
|
|
||||||
let mut o = Self {
|
let mut o = Self {
|
||||||
index: ContentIndex::new(&outfit_name),
|
index: ContentIndex::new(&outfit_name),
|
||||||
name: outfit.name,
|
display_name: outfit.name,
|
||||||
thumbnail,
|
thumbnail,
|
||||||
gun,
|
gun,
|
||||||
engine_thrust: 0.0,
|
engine_thrust: 0.0,
|
||||||
|
|
|
@ -298,7 +298,7 @@ impl crate::Build for Ship {
|
||||||
effects.push(CollapseEffectSpawner {
|
effects.push(CollapseEffectSpawner {
|
||||||
effect: e
|
effect: e
|
||||||
.effect
|
.effect
|
||||||
.to_handle(build_context, ct, "")
|
.resolve(build_context, ct, "")
|
||||||
.with_context(|| format!("while loading ship `{}`", ship_name))?,
|
.with_context(|| format!("while loading ship `{}`", ship_name))?,
|
||||||
count: e.count,
|
count: e.count,
|
||||||
pos: e.pos.map(|p| {
|
pos: e.pos.map(|p| {
|
||||||
|
@ -316,7 +316,7 @@ impl crate::Build for Ship {
|
||||||
effects.push(CollapseEffectSpawner {
|
effects.push(CollapseEffectSpawner {
|
||||||
effect: g
|
effect: g
|
||||||
.effect
|
.effect
|
||||||
.to_handle(build_context, ct, "")
|
.resolve(build_context, ct, "")
|
||||||
.with_context(|| {
|
.with_context(|| {
|
||||||
format!("while loading ship `{}`", ship_name)
|
format!("while loading ship `{}`", ship_name)
|
||||||
})?,
|
})?,
|
||||||
|
@ -360,7 +360,7 @@ impl crate::Build for Ship {
|
||||||
effects.push(DamageEffectSpawner {
|
effects.push(DamageEffectSpawner {
|
||||||
effect: e
|
effect: e
|
||||||
.effect
|
.effect
|
||||||
.to_handle(build_context, ct, "")
|
.resolve(build_context, ct, "")
|
||||||
.with_context(|| format!("while loading ship `{}`", ship_name))?,
|
.with_context(|| format!("while loading ship `{}`", ship_name))?,
|
||||||
frequency: e.frequency,
|
frequency: e.frequency,
|
||||||
pos: e.pos.map(|p| {
|
pos: e.pos.map(|p| {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use anyhow::{anyhow, bail, Context, Result};
|
use anyhow::{bail, Context, Result};
|
||||||
use galactica_util::to_radians;
|
use galactica_util::to_radians;
|
||||||
use nalgebra::{Point2, Point3};
|
use nalgebra::{Point2, Point3};
|
||||||
use std::{
|
use std::{
|
||||||
|
@ -6,7 +6,7 @@ use std::{
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{util::Polar, Content, ContentBuildContext, ContentIndex, Sprite};
|
use crate::{util::Polar, Content, ContentBuildContext, ContentIndex, Outfit, Sprite};
|
||||||
|
|
||||||
pub(crate) mod syntax {
|
pub(crate) mod syntax {
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
@ -26,15 +26,18 @@ pub(crate) mod syntax {
|
||||||
pub struct Object {
|
pub struct Object {
|
||||||
pub sprite: ContentIndex,
|
pub sprite: ContentIndex,
|
||||||
pub position: Position,
|
pub position: Position,
|
||||||
|
|
||||||
pub size: f32,
|
pub size: f32,
|
||||||
|
|
||||||
pub radius: Option<f32>,
|
pub radius: Option<f32>,
|
||||||
pub angle: Option<f32>,
|
pub angle: Option<f32>,
|
||||||
pub landable: Option<bool>,
|
pub landable: Option<Landable>,
|
||||||
pub name: Option<String>,
|
}
|
||||||
pub desc: Option<String>,
|
|
||||||
pub image: Option<ContentIndex>,
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct Landable {
|
||||||
|
pub name: String,
|
||||||
|
pub desc: String,
|
||||||
|
pub image: ContentIndex,
|
||||||
|
pub outfitter: Vec<ContentIndex>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
|
@ -107,9 +110,6 @@ pub struct System {
|
||||||
/// System objects to not interact with the physics engine.
|
/// System objects to not interact with the physics engine.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct SystemObject {
|
pub struct SystemObject {
|
||||||
/// This object's name
|
|
||||||
pub display_name: Option<String>,
|
|
||||||
|
|
||||||
/// This object's index
|
/// This object's index
|
||||||
pub index: ContentIndex,
|
pub index: ContentIndex,
|
||||||
|
|
||||||
|
@ -130,13 +130,22 @@ pub struct SystemObject {
|
||||||
pub angle: f32,
|
pub angle: f32,
|
||||||
|
|
||||||
/// If true, ships may land on this object
|
/// If true, ships may land on this object
|
||||||
pub landable: bool,
|
pub landable: Option<LandableSystemObject>,
|
||||||
|
}
|
||||||
|
|
||||||
/// The description of this object (shown on landed ui)
|
#[derive(Debug, Clone)]
|
||||||
pub desc: Option<String>,
|
pub struct LandableSystemObject {
|
||||||
|
/// This object's name
|
||||||
|
pub display_name: String,
|
||||||
|
|
||||||
/// This object's image (shown on landed ui)
|
/// The description of this object
|
||||||
pub image: Option<Arc<Sprite>>,
|
pub desc: String,
|
||||||
|
|
||||||
|
/// This object's image
|
||||||
|
pub image: Arc<Sprite>,
|
||||||
|
|
||||||
|
/// The outfits we can buy here
|
||||||
|
pub outfitter: Vec<Arc<Outfit>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper function for resolve_position, never called on its own.
|
/// Helper function for resolve_position, never called on its own.
|
||||||
|
@ -210,71 +219,64 @@ impl crate::Build for System {
|
||||||
for (system_name, system) in system {
|
for (system_name, system) in system {
|
||||||
let mut objects = HashMap::new();
|
let mut objects = HashMap::new();
|
||||||
|
|
||||||
for (index, obj) in &system.object {
|
for (index, object) in &system.object {
|
||||||
let mut cycle_detector = HashSet::new();
|
let mut cycle_detector = HashSet::new();
|
||||||
cycle_detector.insert(index.clone());
|
cycle_detector.insert(index.clone());
|
||||||
|
|
||||||
let sprite = match content.sprites.get(&obj.sprite) {
|
let sprite = match content.sprites.get(&object.sprite) {
|
||||||
None => bail!(
|
None => bail!(
|
||||||
"In system `{}`: sprite `{}` doesn't exist",
|
"In system `{}`: sprite `{}` doesn't exist",
|
||||||
system_name,
|
system_name,
|
||||||
obj.sprite
|
object.sprite
|
||||||
),
|
),
|
||||||
Some(t) => t.clone(),
|
Some(t) => t.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let image = match &obj.image {
|
let landable = 'landable: {
|
||||||
Some(x) => match content.sprites.get(x) {
|
if object.landable.is_none() {
|
||||||
|
break 'landable None;
|
||||||
|
}
|
||||||
|
let l = object.landable.as_ref().unwrap();
|
||||||
|
|
||||||
|
let image = match content.sprites.get(&l.image) {
|
||||||
None => bail!(
|
None => bail!(
|
||||||
"In system `{}`: sprite `{}` doesn't exist",
|
"In system `{}`: sprite `{}` doesn't exist",
|
||||||
system_name,
|
system_name,
|
||||||
obj.sprite
|
object.sprite
|
||||||
),
|
),
|
||||||
Some(t) => Some(t.clone()),
|
Some(t) => t.clone(),
|
||||||
},
|
};
|
||||||
None => None,
|
|
||||||
|
let mut outfitter = Vec::new();
|
||||||
|
for o in &l.outfitter {
|
||||||
|
match content.outfits.get(&o) {
|
||||||
|
Some(x) => outfitter.push(x.clone()),
|
||||||
|
None => {
|
||||||
|
bail!("In system `{}`: outfit `{}` doesn't exist", system_name, o)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break 'landable Some(LandableSystemObject {
|
||||||
|
image,
|
||||||
|
outfitter,
|
||||||
|
display_name: l.name.clone(),
|
||||||
|
// TODO: better linebreaks, handle double spaces
|
||||||
|
// Tabs
|
||||||
|
desc: l.desc.replace("\n", " ").replace("<br>", "\n"),
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
if obj.landable.unwrap_or(false) {
|
|
||||||
if obj.name.is_none() {
|
|
||||||
return Err(anyhow!("if an object is landable, it must have a name"))
|
|
||||||
.with_context(|| format!("in object labeled `{}`", index))
|
|
||||||
.with_context(|| format!("in system `{}`", system_name));
|
|
||||||
}
|
|
||||||
|
|
||||||
if obj.desc.is_none() {
|
|
||||||
return Err(anyhow!(
|
|
||||||
"if an object is landable, it must have a description"
|
|
||||||
))
|
|
||||||
.with_context(|| format!("in object labeled `{}`", index))
|
|
||||||
.with_context(|| format!("in system `{}`", system_name));
|
|
||||||
}
|
|
||||||
|
|
||||||
if obj.image.is_none() {
|
|
||||||
return Err(anyhow!("if an object is landable, it must have an image"))
|
|
||||||
.with_context(|| format!("in object labeled `{}`", index))
|
|
||||||
.with_context(|| format!("in system `{}`", system_name));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
objects.insert(
|
objects.insert(
|
||||||
index.clone(),
|
index.clone(),
|
||||||
Arc::new(SystemObject {
|
Arc::new(SystemObject {
|
||||||
index: index.clone(),
|
index: index.clone(),
|
||||||
sprite,
|
sprite,
|
||||||
image,
|
pos: resolve_position(&system.object, &object, cycle_detector)
|
||||||
pos: resolve_position(&system.object, &obj, cycle_detector)
|
|
||||||
.with_context(|| format!("in object {:#?}", index))?,
|
.with_context(|| format!("in object {:#?}", index))?,
|
||||||
size: obj.size,
|
size: object.size,
|
||||||
angle: to_radians(obj.angle.unwrap_or(0.0)),
|
angle: to_radians(object.angle.unwrap_or(0.0)),
|
||||||
landable: obj.landable.unwrap_or(false),
|
landable: landable,
|
||||||
display_name: obj.name.as_ref().map(|x| x.clone()),
|
|
||||||
// TODO: better linebreaks, handle double spaces
|
|
||||||
// Tabs
|
|
||||||
desc: obj
|
|
||||||
.desc
|
|
||||||
.as_ref()
|
|
||||||
.map(|x| x.replace("\n", " ").replace("<br>", "\n")),
|
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -234,7 +234,8 @@ impl SpriteAutomaton {
|
||||||
// Edge case: we're stopped and got a request to transition.
|
// Edge case: we're stopped and got a request to transition.
|
||||||
// we should transition right away.
|
// we should transition right away.
|
||||||
|
|
||||||
if let Some(e) = self.next_edge_override.take() {
|
if self.next_edge_override.is_some() {
|
||||||
|
let e = self.next_edge_override.take().unwrap();
|
||||||
self.take_edge(&e);
|
self.take_edge(&e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue