Minor content cleanup
parent
acb5b9d31c
commit
f56fd7ea49
|
@ -1,4 +1,5 @@
|
|||
# TODO: big objects in one config
|
||||
# TODO: satisfy conditions to land
|
||||
|
||||
[system."12 Autumn Above"]
|
||||
name = "12 Autumn Above"
|
||||
|
@ -13,10 +14,9 @@ object.earth.position.angle = 0
|
|||
object.earth.position.z = 10.0
|
||||
object.earth.size = 1000
|
||||
|
||||
# TODO: satisfy conditions to land
|
||||
object.earth.landable = true
|
||||
object.earth.name = "Earth"
|
||||
object.earth.desc = """
|
||||
|
||||
object.earth.landable.name = "Earth"
|
||||
object.earth.landable.desc = """
|
||||
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.
|
||||
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
|
||||
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.position.center = "earth"
|
||||
|
|
|
@ -165,8 +165,7 @@ impl Display for ContentIndex {
|
|||
/// Stores temporary data while building context objects
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct ContentBuildContext {
|
||||
/// Map effect names to handles
|
||||
pub effect_index: HashMap<String, Arc<Effect>>,
|
||||
pub effect_index: HashMap<ContentIndex, Arc<Effect>>,
|
||||
}
|
||||
|
||||
impl ContentBuildContext {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use anyhow::{Context, Result};
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
|
||||
use crate::{Content, ContentBuildContext, Sprite};
|
||||
use crate::{Content, ContentBuildContext, ContentIndex, Sprite};
|
||||
|
||||
pub(crate) mod syntax {
|
||||
use std::sync::Arc;
|
||||
|
@ -138,12 +138,12 @@ pub(crate) mod syntax {
|
|||
#[derive(Debug, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum EffectReference {
|
||||
Label(String),
|
||||
Label(ContentIndex),
|
||||
Effect(Effect),
|
||||
}
|
||||
|
||||
impl EffectReference {
|
||||
pub fn to_handle(
|
||||
pub fn resolve(
|
||||
self,
|
||||
build_context: &mut ContentBuildContext,
|
||||
content: &mut Content,
|
||||
|
@ -246,7 +246,9 @@ impl crate::Build for Effect {
|
|||
let h = effect
|
||||
.add_to(build_context, content, &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(());
|
||||
|
|
|
@ -81,12 +81,12 @@ pub(crate) mod syntax {
|
|||
};
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
|
@ -143,7 +143,7 @@ pub struct Outfit {
|
|||
pub space: OutfitSpace,
|
||||
|
||||
/// The name of this outfit
|
||||
pub name: String,
|
||||
pub display_name: String,
|
||||
|
||||
/// Thie outfit's index
|
||||
pub index: ContentIndex,
|
||||
|
@ -281,7 +281,7 @@ impl crate::Build for Outfit {
|
|||
|
||||
let mut o = Self {
|
||||
index: ContentIndex::new(&outfit_name),
|
||||
name: outfit.name,
|
||||
display_name: outfit.name,
|
||||
thumbnail,
|
||||
gun,
|
||||
engine_thrust: 0.0,
|
||||
|
|
|
@ -298,7 +298,7 @@ impl crate::Build for Ship {
|
|||
effects.push(CollapseEffectSpawner {
|
||||
effect: e
|
||||
.effect
|
||||
.to_handle(build_context, ct, "")
|
||||
.resolve(build_context, ct, "")
|
||||
.with_context(|| format!("while loading ship `{}`", ship_name))?,
|
||||
count: e.count,
|
||||
pos: e.pos.map(|p| {
|
||||
|
@ -316,7 +316,7 @@ impl crate::Build for Ship {
|
|||
effects.push(CollapseEffectSpawner {
|
||||
effect: g
|
||||
.effect
|
||||
.to_handle(build_context, ct, "")
|
||||
.resolve(build_context, ct, "")
|
||||
.with_context(|| {
|
||||
format!("while loading ship `{}`", ship_name)
|
||||
})?,
|
||||
|
@ -360,7 +360,7 @@ impl crate::Build for Ship {
|
|||
effects.push(DamageEffectSpawner {
|
||||
effect: e
|
||||
.effect
|
||||
.to_handle(build_context, ct, "")
|
||||
.resolve(build_context, ct, "")
|
||||
.with_context(|| format!("while loading ship `{}`", ship_name))?,
|
||||
frequency: e.frequency,
|
||||
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 nalgebra::{Point2, Point3};
|
||||
use std::{
|
||||
|
@ -6,7 +6,7 @@ use std::{
|
|||
sync::Arc,
|
||||
};
|
||||
|
||||
use crate::{util::Polar, Content, ContentBuildContext, ContentIndex, Sprite};
|
||||
use crate::{util::Polar, Content, ContentBuildContext, ContentIndex, Outfit, Sprite};
|
||||
|
||||
pub(crate) mod syntax {
|
||||
use serde::Deserialize;
|
||||
|
@ -26,15 +26,18 @@ pub(crate) mod syntax {
|
|||
pub struct Object {
|
||||
pub sprite: ContentIndex,
|
||||
pub position: Position,
|
||||
|
||||
pub size: f32,
|
||||
|
||||
pub radius: Option<f32>,
|
||||
pub angle: Option<f32>,
|
||||
pub landable: Option<bool>,
|
||||
pub name: Option<String>,
|
||||
pub desc: Option<String>,
|
||||
pub image: Option<ContentIndex>,
|
||||
pub landable: Option<Landable>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct Landable {
|
||||
pub name: String,
|
||||
pub desc: String,
|
||||
pub image: ContentIndex,
|
||||
pub outfitter: Vec<ContentIndex>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
|
@ -107,9 +110,6 @@ pub struct System {
|
|||
/// System objects to not interact with the physics engine.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SystemObject {
|
||||
/// This object's name
|
||||
pub display_name: Option<String>,
|
||||
|
||||
/// This object's index
|
||||
pub index: ContentIndex,
|
||||
|
||||
|
@ -130,13 +130,22 @@ pub struct SystemObject {
|
|||
pub angle: f32,
|
||||
|
||||
/// If true, ships may land on this object
|
||||
pub landable: bool,
|
||||
pub landable: Option<LandableSystemObject>,
|
||||
}
|
||||
|
||||
/// The description of this object (shown on landed ui)
|
||||
pub desc: Option<String>,
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct LandableSystemObject {
|
||||
/// This object's name
|
||||
pub display_name: String,
|
||||
|
||||
/// This object's image (shown on landed ui)
|
||||
pub image: Option<Arc<Sprite>>,
|
||||
/// The description of this object
|
||||
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.
|
||||
|
@ -210,71 +219,64 @@ impl crate::Build for System {
|
|||
for (system_name, system) in system {
|
||||
let mut objects = HashMap::new();
|
||||
|
||||
for (index, obj) in &system.object {
|
||||
for (index, object) in &system.object {
|
||||
let mut cycle_detector = HashSet::new();
|
||||
cycle_detector.insert(index.clone());
|
||||
|
||||
let sprite = match content.sprites.get(&obj.sprite) {
|
||||
let sprite = match content.sprites.get(&object.sprite) {
|
||||
None => bail!(
|
||||
"In system `{}`: sprite `{}` doesn't exist",
|
||||
system_name,
|
||||
obj.sprite
|
||||
object.sprite
|
||||
),
|
||||
Some(t) => t.clone(),
|
||||
};
|
||||
|
||||
let image = match &obj.image {
|
||||
Some(x) => match content.sprites.get(x) {
|
||||
let landable = 'landable: {
|
||||
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!(
|
||||
"In system `{}`: sprite `{}` doesn't exist",
|
||||
system_name,
|
||||
obj.sprite
|
||||
object.sprite
|
||||
),
|
||||
Some(t) => Some(t.clone()),
|
||||
},
|
||||
None => None,
|
||||
Some(t) => t.clone(),
|
||||
};
|
||||
|
||||
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));
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
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"),
|
||||
});
|
||||
};
|
||||
|
||||
objects.insert(
|
||||
index.clone(),
|
||||
Arc::new(SystemObject {
|
||||
index: index.clone(),
|
||||
sprite,
|
||||
image,
|
||||
pos: resolve_position(&system.object, &obj, cycle_detector)
|
||||
pos: resolve_position(&system.object, &object, cycle_detector)
|
||||
.with_context(|| format!("in object {:#?}", index))?,
|
||||
size: obj.size,
|
||||
angle: to_radians(obj.angle.unwrap_or(0.0)),
|
||||
landable: obj.landable.unwrap_or(false),
|
||||
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")),
|
||||
size: object.size,
|
||||
angle: to_radians(object.angle.unwrap_or(0.0)),
|
||||
landable: landable,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -234,7 +234,8 @@ impl SpriteAutomaton {
|
|||
// Edge case: we're stopped and got a request to transition.
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue